makeaddr.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 612 行 · 第 1/2 页

C
612
字号
    new = AddrName( Points( name, tipe ), tipe );
    BGDone( name );
    return( new );
}

extern  an      RegName( hw_reg_set reg, type_def *tipe )
/*******************************************************/
{
    an  addr;

    addr = NewAddrName();
    addr->format = NF_NAME;
    addr->tipe = tipe;
    addr->u.name = AllocRegName( reg );
    return( addr );
}

extern  an      InsName( instruction *ins, type_def *tipe )
/*********************************************************/
{
    an  addr;

    addr = NewAddrName();
    addr->u.ins = ins;
    addr->tipe = tipe;
    addr->format = NF_INS;
    return( addr );
}

extern  name    *LoadTemp( name *temp, type_class_def class )
/***********************************************************/
{
    instruction *ins;

    ins = MakeMove( temp, AllocTemp( class ), class );
    temp = ins->result;
    AddIns( ins );
    return( temp );
}


static  name    *Temporary( name *temp, type_def *tipe )
/******************************************************/
{
    if( temp->n.class != N_TEMP ) {
        temp = LoadTemp( temp, TypeClass( tipe ) /*temp->n.name_class*/ );
    }
    return( temp );
}


extern  an      AddrEval( an addr )
/*********************************/
{
    an  new;

    new = AddrName( Temporary( GenIns( addr ), addr->tipe ), addr->tipe );
    AddrFree( addr );
    return( new );
}


extern  void    MoveAddress(  an src,  an  dest )
/***********************************************/
{
    dest->format = src->format;
    dest->class = src->class;
    dest->u.name  = src->u.name;
    dest->index = src->index;
    dest->offset= src->offset;
}


extern  void    Convert( an addr, type_class_def class )
/******************************************************/
{
    instruction *ins;

    if( addr->offset != 0 ) {
        ins = MakeBinary( OP_ADD, addr->u.name,
                                AllocIntConst( addr->offset ),
                                AllocTemp( addr->u.name->n.name_class ),
                                TypeClass( addr->tipe ) );
        addr->u.name = ins->result;
        AddIns( ins );
    }
    ins = MakeUnary( OP_CONVERT, addr->u.name, AllocTemp( class ), class );
    addr->u.name = ins->result;
    addr->offset = 0;
    AddIns( ins );
}


extern  bool    PointLess( an l_addr, an r_addr )
/***********************************************/
{
    if( l_addr->class != CL_POINTER && r_addr->class != CL_POINTER )
        return( FALSE );
    if( l_addr->offset != 0 || r_addr->offset != 0 ) return( FALSE );
    return( TRUE );
}


extern  an      AddrToIns( an addr )
/**********************************/
{
    instruction *ins;
    an          new;

    if( addr->format != NF_INS ) {
        ins = MakeMove( GenIns( addr ), NULL, TypeClass( addr->tipe ) );
        new = InsName( ins, addr->tipe );
        new->flags = addr->flags;
        new->alignment = addr->alignment;
        BGDone( addr );
        AddIns( ins );
    } else {
        new = addr;
    }
    return( new );
}


extern  an      AddrDuplicate( an node )
/**************************************/
{
    an          new;
    name        *op;

    InsToAddr( node );
    op = GenIns( node );
    new = AddrName( op, node->tipe );
    CopyAddr( new, node );
    return( new );
}

extern  an      AddrCopy( an node )
/*********************************/
{
    an  new;

    InsToAddr( node );
    new = NewAddrName();
    CopyAddr( node, new );
    return( new );
}


extern  an      AddrSave( an node )
/*********************************/
{
    InsToAddr( node );
    return( node );
}


extern  void    AddrDemote( an node )
/***********************************/
{
    node->flags |= ADDR_DEMOTED;
    if( node->format == NF_INS ) {
        node->u.ins->ins_flags |= INS_DEMOTED;
    }
}


extern  name    *MaybeTemp( name *op, type_class_def kind )
/*********************************************************/
{
    if( op == NULL ) {
        op = AllocTemp( kind );
    }
    return( op );
}


extern  void    CheckPointer( an addr )
/*************************************/
{
    InsToAddr( addr );
    if( addr->format == NF_NAME
     && ( addr->tipe->attr & TYPE_POINTER ) ) {
        addr->index = Temporary( addr->u.name, addr->tipe );
        addr->u.name = NULL;
        addr->offset = 0;
        addr->class = CL_POINTER;
        addr->format = NF_ADDR;
    }
}


extern  void    FixCodePtr( an addr )
/***********************************/
{
    instruction *ins;

    if( addr->format == NF_INS ) {
        ins = addr->u.ins;
        ins->ins_flags |= INS_CODE_POINTER;
    }
}


extern  bool    NeedPtrConvert( an addr, type_def * tipe )
/********************************************************/
{
    if( addr->format != NF_ADDR ) return( TRUE );
    if( addr->class == CL_ADDR_GLOBAL || addr->class == CL_ADDR_TEMP ) {
        if( tipe->refno == T_NEAR_POINTER ) return( FALSE );
        if( tipe->refno == T_LONG_POINTER ) return( FALSE );
        if( tipe->refno == T_HUGE_POINTER ) return( FALSE );
    }
    return( TRUE );
}


extern  name    *LoadAddress( name *op, name *suggest, type_def *type_ptr )
/*************************************************************************/
{
    name                *new;
    type_class_def      class;

    if( op->n.class == N_INDEXED && !HasTrueBase( op ) ) {
        if( op->i.constant != 0 ) {
            class = op->i.index->n.name_class;
            new = MaybeTemp( suggest, class );
            AddIns( MakeBinary( OP_ADD, op->i.index,
                         AllocS32Const( op->i.constant ),
                         new, class ) );
        } else {
            new = op->i.index;
        }
    } else {
        if( suggest != NULL ) {
            class = suggest->n.name_class;
        } else {
            if( type_ptr->length == WORD_SIZE ) {
                class = WD;
            } else {
                class = CP;
            }
        }
        new = MaybeTemp( suggest, class );
        AddIns( MakeUnary( OP_LA, op, new, class ) );
    }
    return( new );
}


extern  an      MakeAddrName( cg_class class, sym_handle sym, type_def *tipe )
/****************************************************************************/
{
    an          addr;
    fe_attr     attr;
    int         level;
    name        *op;

    addr = NewAddrName();
    addr->format = NF_ADDR;
    if( class != CG_FE ) {
        op = SAllocMemory( sym, 0, class, TypeClass( tipe ), tipe->length );
        addr->u.name = op;
        addr->class = CL_ADDR_GLOBAL;
    } else {
        attr = FEAttr( sym );
        level = FELexLevel( sym );
        if( attr & FE_STATIC ) {
            op = SAllocMemory( sym, 0, class, TypeClass(tipe), tipe->length );
            if( ( attr & FE_MEMORY ) != EMPTY ) {
                op->v.usage |= NEEDS_MEMORY | USE_MEMORY;
            }
            addr->u.name = op;
            addr->class = CL_ADDR_GLOBAL;
            if( attr & FE_VOLATILE ) {
                op->v.usage |= VAR_VOLATILE | NEEDS_MEMORY | USE_MEMORY;
            }
            if( attr & FE_UNALIGNED ) {
                op->v.usage |= VAR_UNALIGNED;
            }
            if( attr & FE_CONSTANT ) {
                op->v.usage |= VAR_CONSTANT;
            }
        } else if( level != CurrProc->lex_level ) {
            op = Display( sym, level );
            addr->u.name = op;
            addr->format = NF_NAME;
        } else {
            op = SAllocUserTemp( sym, TypeClass( tipe ), tipe->length );
            if( attr & FE_MEMORY ) {
                op->v.usage |= NEEDS_MEMORY | USE_MEMORY;
            }
            if( attr & FE_ADDR_TAKEN ) {
                op->v.usage |= USE_ADDRESS;
            }
            addr->u.name = op;
            addr->class = CL_ADDR_TEMP;
            op->v.usage |= USE_IN_ANOTHER_BLOCK;
            if( attr & FE_VOLATILE ) {
                op->v.usage |= VAR_VOLATILE | NEEDS_MEMORY | USE_MEMORY;
            }
        }
    }
    addr->tipe = TypeAddress( NamePtrType( op ) );
    return( addr );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?