can2td2.c

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

C
534
字号
/*CANS_REG_SS   */  TD_REG_SS,
/*CANS_REG_DS   */  TD_REG_DS,
/*CANS_REG_ES   */  TD_REG_ES,
/*CANS_REG_ST0  */  TD_REG_ST0,
/*CANS_REG_ST1  */  TD_REG_ST1,
/*CANS_REG_ST2  */  TD_REG_ST2,
/*CANS_REG_ST3  */  TD_REG_ST3,
/*CANS_REG_ST4  */  TD_REG_ST4,
/*CANS_REG_ST5  */  TD_REG_ST5,
/*CANS_REG_ST6  */  TD_REG_ST6,
/*CANS_REG_ST7  */  TD_REG_ST7,
/*CANS_REG_EAX  */  TD_REG_EAX,
/*CANS_REG_EBX  */  TD_REG_EBX,
/*CANS_REG_ECX  */  TD_REG_ECX,
/*CANS_REG_EDX  */  TD_REG_EDX,
/*CANS_REG_ESI  */  TD_REG_ESI,
/*CANS_REG_EDI  */  TD_REG_EDI,
/*CANS_REG_EBP  */  TD_REG_EBP,
/*CANS_REG_ESP  */  TD_REG_ESP,
/*CANS_REG_FS   */  TD_REG_FS,
/*CANS_REG_GS   */  TD_REG_GS
};

STATIC uint_8 multiReg( register_type canreg ) {

    switch( canreg ) {
    case CANS_REG_AX:   return( TD_REG_MULTI_AX );
    case CANS_REG_CX:   return( TD_REG_MULTI_CX );
    case CANS_REG_DX:   return( TD_REG_MULTI_DX );
    case CANS_REG_BX:   return( TD_REG_MULTI_BX );
    case CANS_REG_SI:   return( TD_REG_MULTI_SI );
    case CANS_REG_DI:   return( TD_REG_MULTI_DI );
    case CANS_REG_ES:   return( TD_REG_MULTI_ES );
    case CANS_REG_DS:   return( TD_REG_MULTI_DS );
    }
    PrtMsg( WRN|MSG_UNK_REGISTER );
    return( TD_REG_AX );
}

STATIC void symbRegister( symb_handle symb ) {

    obj_rec         *coment;
    cantype         *type;
    uint_16         type_idx;
    const char      *name;
    size_t          name_len;
    uint_8          treg;
    register_type   *reg;

/**/myassert( symb != NULL && symb->class == CANS_REGISTER );
    if( skipALocal ) {
        skipALocal = 0;
        return;
    }
    reg = symb->d.reg.reg;
    if( symb->d.reg.num_regs == 4 ) {
        if( reg[ 0 ] == CANS_REG_AX &&
            reg[ 1 ] == CANS_REG_BX &&
            reg[ 2 ] == CANS_REG_CX &&
            reg[ 3 ] == CANS_REG_DX ) {
            treg = TD_REG_MULTI_AXBXCXDX;
        } else {
            Fatal( MSG_IMPOSSIBLE_REG );
        }
    } else if( symb->d.reg.num_regs == 2 ) {
        treg = TD_REG_MULTI
            | ( multiReg( reg[ 0 ] ) << TD_REG_MULTI_LO_SHIFT )
            | ( multiReg( reg[ 1 ] ) << TD_REG_MULTI_HI_SHIFT );
    } else if( symb->d.reg.num_regs > 1 ) {
        Fatal( MSG_IMPOSSIBLE_REG );
    } else if( reg[ 0 ] == CANS_REG_FLAGS ) {
        Fatal( MSG_IMPOSSIBLE_REG );
    } else {
        treg = tdRegs[ reg[ 0 ] ];
    }
    type = CanTFind( symb->d.nat.type_hdl );
    if( type == NULL ) {
        type_idx = 0;
    } else {
        type_idx = type->extra;
    }
    name = NameGet( symb->d.nat.name_hdl );
    name_len = strlen( name );
/**/myassert( name_len < 256 );
    /* 1 for name_len, 2 for type_idx, 1 for class byte, 1 for treg byte */
    coment = Can2TDNewRec( TD_CMT_LOCAL_DEFN, name_len + ( 1 + 2 + 1 + 1 ) );
    ObjPutName( coment, name, name_len );
    ObjPutIndex( coment, type_idx );
    ObjPut8( coment, inParms | TD_LOCAL_REGISTER );
    ObjPut8( coment, treg );
    Can2TDEndRec( coment );
}

STATIC void symbProlog( symb_handle symb ) {

/**/myassert( symb != NULL && symb->class == CANS_PROLOG );
/**/myassert( blockIndent > 0 );
    skipALocal = symb->d.prolog.has_ret_val;
    if( blockIndent > 1 ) {
        return;   /* not a procedure block */
    }
    blockBegin( codeSeg, codeOffset + symb->d.prolog.size );
    inParms = 0;
}

STATIC void blockEnd( uint_32 offset ) {
    obj_rec *coment;

    if( offset > 0xffff ) {
        coment = Can2TDNewRec( TD_CMT_LARGE_END_SCOPE, 4 );
        ObjPut32( coment, offset );
    } else {
        coment = Can2TDNewRec( TD_CMT_END_SCOPE, 2 );
        ObjPut16( coment, offset );
    }
    Can2TDEndRec( coment );
}

STATIC void symbEpilog( symb_handle symb ) {

    symb_handle block_end;
    symb_handle block_start;

/**/myassert( symb != NULL && symb->class == CANS_EPILOG );
/**/myassert( blockIndent > 0 );
    if( blockIndent > 1 ) {
        return;     /* not a procedure epilog */
    }
    block_end = CanSFwd( symb );
/**/myassert( block_end->class == CANS_BLOCK_END );
    block_start = block_end->d.end.start;
    blockEnd( codeOffset + block_start->d.block.size - symb->d.epilog.size );
}

STATIC void symbBlockEnd( symb_handle symb ) {

    symb_handle start;

/**/myassert( symb != NULL && symb->class == CANS_BLOCK_END );
/**/myassert( blockIndent > 0 );
    start = symb->d.end.start;
    blockEnd( codeOffset + start->d.block.size );
    codeOffset -= start->d.block.start_offset;
    --blockIndent;
}

STATIC void symbIndReg( symb_handle symb ) {

/**/myassert( symb != NULL && symb->class == CANS_IND_REG );
    symb = symb;
    PrtMsg( WRN|MSG_UNS_IND_REG );
}

void Can2TDS( void ) {
/******************/

    symb_handle head;
    symb_handle cur;

    head = CanSGetHead();
    if( head != NULL ) {
        codeOffset = 0;
        codeSeg = 0;
        blockIndent = 0;
        skipALocal = 0;
        inParms = 0;
        /*
            Slight gotcha in the Turbo debugging format... static locals and
            static functions must appear together after all the scope records
            and so on... Well, I'm unsure if they must appear after all or if
            they must just appear together.

            We simply scan ahead over the locals and pretend our head is in
            a different spot.  (Rings are fun :)
        */
        cur = head;
        do {
            if( cur->class == CANS_BLOCK ) break;
            if( cur->class == CANS_CHANGE_SEG ) {
                symbChangeSeg( cur );
            }
            cur = CanSFwd( cur );
        } while( cur != head ); /* in case it is a module with no functions */
        head = cur;
        do {
            switch( cur->class ) {
            case CANS_CHANGE_SEG:   symbChangeSeg( cur );   break;
            case CANS_BLOCK:        symbBlock( cur );       break;
            case CANS_BP_OFFSET:    symbBPOffset( cur );    break;
            case CANS_MEM_LOC:      symbMemLoc( cur );      break;
            case CANS_REGISTER:     symbRegister( cur );    break;
            case CANS_PROLOG:       symbProlog( cur );      break;
            case CANS_EPILOG:       symbEpilog( cur );      break;
            case CANS_BLOCK_END:    symbBlockEnd( cur );    break;
            case CANS_IND_REG:      symbIndReg( cur );      break;
            default:
/**/            never_reach();
            }
            cur = CanSFwd( cur );
        } while( cur != head );
    }
}


void Can2TDStatic( void ) {
/***********************/

    symb_handle head;
    symb_handle cur;
    symb_handle end;
    obj_rec     *coment;
    uint_8      tbyte;
    size_t      name_len;
    const char  *name;
    uint_32     offset;
    cantype     *type;

    head = CanSGetHead();
    if( head != NULL ) {
        cur = head;
        do {
            switch( cur->class ) {
            case CANS_BLOCK:
                if( cur->extra & TD_HAS_A_PUBDEF ) {
                    break;  /* has a PUBDEF for it already */
                }
                /* otherwise it is a static fcn, so we generate a local for it*/
                tbyte = Can2TDBPOffset( cur );
                type = CanTFind( cur->d.nat.type_hdl );
                name = NameGet( cur->d.nat.name_hdl );
                name_len = strlen( name );
/**/            myassert( name_len < 256 );
                end = cur->d.block.end;
/**/            myassert( end != NULL );
                offset = end->extra;        /* saved here by symbBlock() */
                if( offset > 0xffff ) {
                    coment = Can2TDNewRec( TD_CMT_LOCAL_DEFN_LARGE,
                        name_len + ( 1 + 2 + 1 + 1 + 2 + 4 ) );
                } else {
                    coment = Can2TDNewRec( TD_CMT_LOCAL_DEFN,
                        name_len + ( 1 + 2 + 1 + 1 + 2 + 2 ) );
                }
                ObjPutName( coment, name, name_len );
                if( type != NULL ) {
                    ObjPutIndex( coment, type->extra );
                } else {
                    ObjPutIndex( coment, 0 );
                }
                if( tbyte != 0 ) {
                    ObjPut8( coment, tbyte );
                }
                ObjPut8( coment, TD_LOCAL_STATIC );
                /* ObjPutIndex( coment, 0 );   grp_idx not reqd?? */
                ObjPutIndex( coment, (uint_16)cur->extra );
                if( offset > 0xffff ) {
                    ObjPut32( coment, offset );
                } else {
                    ObjPut16( coment, offset );
                }
                Can2TDEndRec( coment );
                break;
            }
            cur = CanSFwd( cur );
        } while( cur != head );
    }
}

⌨️ 快捷键说明

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