can2ms2.c

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

C
719
字号

    default:
/**/    never_reach();
    }
    put16( 0 ); /* reserved stuff */
    endRec();
}

STATIC void symbBlock( symb_handle cur ) {

    cantype     *type;
    symb_handle walk;
    fixup       *myfix;
    uint_8      buf[ 4 ];

/**/myassert( cur != NULL && cur->class == CANS_BLOCK );
    codeOffset += cur->d.block.start_offset;
    if( offsetFixup != NULL ) {
        myfix = FixDup( offsetFixup );
        WriteU32( buf, codeOffset );
    } else {
        myfix = NULL;
    }
    skipParms = 1;
    ++blockIndent;
    if( blockIndent == 1 ) {    /* this is a procedure block */
        type = CanTFind( cur->d.nat.type_hdl );
        if( type == NULL ) {
            block386 = 0;
        } else {
/**/        myassert( type->class == CANT_PROCEDURE );
            block386 = ( type->d.proc.class & CANT_PROC_386 ) ?
                MS_SYM_386_FLAG : 0;
        }
        newRec( block386 | MS_SYM_PROCEDURE_START );
        if( myfix != NULL ) {
            putAddr( myfix, buf, ( block386 | Can2MSMetaware ) ? 4 : 2 );
        } else {
            putEither( codeOffset );
        }
        if( type == NULL ) {
            put16( 0 );
        } else {
            put16( type->extra );
        }
        /* FIXME we should warn about block sizes too large */
        putMetaware( cur->d.block.size );
        walk = cur;
        while( walk->class != CANS_PROLOG ) {
            walk = CanSFwd( walk );
/**/        myassert( walk != NULL );
        }
/**/    myassert( walk->class == CANS_PROLOG );
        put16( walk->d.prolog.size );       /* debug start */
        walk = cur->d.block.end;
/**/    myassert( walk != NULL );
        walk = CanSBwd( walk );
/**/    myassert( walk != NULL && walk->class == CANS_EPILOG );
            /* debug end */
        putMetaware( cur->d.block.size - walk->d.epilog.size );
        put16( 0 ); /* reserved */
        if( type == NULL ) {
            switch( CanMisc.memory_model ) {
            case CAN_MODEL_SMALL:
            case CAN_MODEL_COMPACT:
            case CAN_MODEL_FLAT:
            case CAN_MODEL_TINY:
                put8( MS_SYM_NEAR );    /* default to NEAR */
                break;
            default:
                put8( MS_SYM_FAR );     /* default to FAR */
            }
        } else {
            if( type->d.proc.class & CANT_PROC_FAR ) {
                put8( MS_SYM_FAR );
            } else {
                put8( MS_SYM_NEAR );
            }
        }
        putName( cur->d.nat.name_hdl );
        endRec();
        if( Can2MSMetaware ) {
            /* metaware outputs an extra block for each function scope */
            newRec( MS_SYM_BLOCK_START );
            if( myfix != NULL ) {
                putAddr( FixDup( myfix ), buf,
                    ( block386 | Can2MSMetaware ) ? 4 : 2 );
            } else {
                putEither( codeOffset );
            }
            putMetaware( cur->d.block.size );
            endRec();
        }
    } else {        /* this is an inner code block */
        newRec( block386 | MS_SYM_BLOCK_START );
        if( myfix != NULL ) {
            putAddr( myfix, buf, block386 ? 4 : 2 );
        } else {
            putEither( codeOffset );
        }
        putMetaware( cur->d.block.size );
        endRec();
    }
}

STATIC void symbBPOffset( symb_handle cur ) {

    cantype *type;

/**/myassert( cur != NULL && cur->class == CANS_BP_OFFSET );
    if( skipParms ) {
        return;
    }
    if( skipALocal ) {
        skipALocal = 0;
        return;
    }
    newRec( block386 | MS_SYM_BP_RELATIVE );
    putEither( cur->d.bpoff.offset );
    type = CanTFind( cur->d.nat.type_hdl );
    if( type == NULL ) {
        put16( 0 );
    } else {
        put16( type->extra );
    }
    putName( cur->d.nat.name_hdl );
    endRec();
}

STATIC void symbMemLoc( symb_handle cur ) {

    cantype     *type;
    fixup       *newfix;
    addr_info   *mem_loc;
    uint_8      do32;

/**/myassert( cur != NULL && cur->class == CANS_MEM_LOC );
    if( skipParms ) {
        return;
    }
    if( skipALocal ) {
        skipALocal = 0;
        return;
    }
    mem_loc = CanAFind( cur->d.memloc.mem_hdl );
    do32 = ( mem_loc->data_len == 6 ) ? MS_SYM_386_FLAG : 0;
/**/myassert( do32 || mem_loc->data_len == 4 );
    newRec( do32 | MS_SYM_LOCAL_SYM );
    newfix = FixDup( mem_loc->fixup );
/**/myassert( newfix->loc_method == FIX_POINTER ||
                newfix->loc_method == FIX_POINTER386 );
    putAddr( newfix, mem_loc->data, do32 ? 6 : 4 );
    type = CanTFind( cur->d.nat.type_hdl );
    if( type == NULL ) {
        put16( 0 );
    } else {
        put16( type->extra );
    }
    putName( cur->d.nat.name_hdl );
    endRec();
}

STATIC const uint_8 msRegMap[] = {
/*CANS_REG_AL   */  MS_REG_AL,
/*CANS_REG_AH   */  MS_REG_AH,
/*CANS_REG_BL   */  MS_REG_BL,
/*CANS_REG_BH   */  MS_REG_BH,
/*CANS_REG_CL   */  MS_REG_CL,
/*CANS_REG_CH   */  MS_REG_CH,
/*CANS_REG_DL   */  MS_REG_DL,
/*CANS_REG_DH   */  MS_REG_DH,
/*CANS_REG_AX   */  MS_REG_AX,
/*CANS_REG_BX   */  MS_REG_BX,
/*CANS_REG_CX   */  MS_REG_CX,
/*CANS_REG_DX   */  MS_REG_DX,
/*CANS_REG_SI   */  MS_REG_SI,
/*CANS_REG_DI   */  MS_REG_DI,
/*CANS_REG_BP   */  MS_REG_BP,
/*CANS_REG_SP   */  MS_REG_SP,
/*CANS_REG_CS   */  MS_REG_CS,
/*CANS_REG_SS   */  MS_REG_SS,
/*CANS_REG_DS   */  MS_REG_DS,
/*CANS_REG_ES   */  MS_REG_ES,
/*CANS_REG_ST0  */  MS_REG_ST0,
/*CANS_REG_ST1  */  MS_REG_ST1,
/*CANS_REG_ST2  */  MS_REG_ST2,
/*CANS_REG_ST3  */  MS_REG_ST3,
/*CANS_REG_ST4  */  MS_REG_ST4,
/*CANS_REG_ST5  */  MS_REG_ST5,
/*CANS_REG_ST6  */  MS_REG_ST6,
/*CANS_REG_ST7  */  MS_REG_ST7,
/*CANS_REG_EAX  */  MS_REG_EAX,
/*CANS_REG_EBX  */  MS_REG_EBX,
/*CANS_REG_ECX  */  MS_REG_ECX,
/*CANS_REG_EDX  */  MS_REG_EDX,
/*CANS_REG_ESI  */  MS_REG_ESI,
/*CANS_REG_EDI  */  MS_REG_EDI,
/*CANS_REG_EBP  */  MS_REG_EBP,
/*CANS_REG_ESP  */  MS_REG_ESP,
/*CANS_REG_FS   */  MS_REG_FS,
/*CANS_REG_GS   */  MS_REG_GS,
/*CANS_REG_FLAGS*/  MS_REG_FLAGS
};

STATIC uint_8 canReg2MsReg( register_type can ) {

    if( can > CANS_REG_FLAGS ) {
        PrtMsg( WRN|MSG_UNK_REGISTER );
        return( MS_REG_AX );
    }
    if( Can2MSMetaware && can >= CANS_REG_EAX && can <= CANS_REG_ESP ) {
        can -= CANS_REG_EAX - CANS_REG_AX;
    }
    return( msRegMap[ can ] );
}

STATIC void symbRegister( symb_handle cur ) {

    cantype         *type;
    uint_8          ms_reg;
    register_type   *reg;

/**/myassert( cur != NULL && cur->class == CANS_REGISTER );
    if( skipParms ) {
        return;
    }
    if( skipALocal ) {
        skipALocal = 0;
        return;
    }
    reg = cur->d.reg.reg;
    if( cur->d.reg.num_regs == 2 ) {
        if( reg[ 0 ] == CANS_REG_AX && reg[ 1 ] == CANS_REG_DX ) {
            ms_reg = MS_REG_DX_AX;
        } else if( reg[ 0 ] == CANS_REG_ES && reg[ 1 ] == CANS_REG_BX ) {
            ms_reg = MS_REG_ES_BX;
        } else {
            PrtMsg( WRN|MSG_NO_MULTI_REG );
            ms_reg = MS_REG_DX_AX;
        }
    } else if( cur->d.reg.num_regs > 1 ) {
        PrtMsg( WRN|MSG_NO_MULTI_REG );
        ms_reg = MS_REG_DX_AX;
    } else {
        ms_reg = canReg2MsReg( reg[ 0 ] );
    }
    newRec( MS_SYM_REGISTER_SYM );
    type = CanTFind( cur->d.nat.type_hdl );
    if( type == NULL ) {
        put16( 0 );
    } else {
        put16( type->extra );
    }
    put8( ms_reg );
    putName( cur->d.nat.name_hdl );
    endRec();
}

STATIC void symbProlog( symb_handle cur ) {

/**/myassert( cur != NULL && cur->class == CANS_PROLOG );
    skipParms = 0;
    skipALocal = cur->d.prolog.has_ret_val;
}

STATIC void symbEpilog( symb_handle cur ) {

/**/myassert( cur != NULL && cur->class == CANS_EPILOG );
    cur = cur;
}

STATIC void symbBlockEnd( symb_handle cur ) {

/**/myassert( cur != NULL && cur->class == CANS_BLOCK_END );
/**/myassert( blockIndent > 0 );
    cur = cur->d.end.start;
/**/myassert( cur != NULL && cur->class == CANS_BLOCK );
    codeOffset -= cur->d.block.start_offset;
    --blockIndent;
    if( blockIndent == 0 && Can2MSMetaware ) {
        /* there's an extra scope on every function */
        newRec( MS_SYM_END_RECORD );
        endRec();
    }
    newRec( block386 | MS_SYM_END_RECORD );
    endRec();
}

STATIC void symbIndReg( symb_handle cur ) {

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

STATIC void putInitialRecs( void ) {
/********************************/

    fixup *newfix;
    uint_16 seg_fixup;

/**/myassert( ObjDGROUPIndex != 0 );
    newfix = FixNew();
    newfix->loc_method = FIX_BASE;
    newfix->self_relative = 0;
    newfix->loader_resolved = 0;
    newfix->lr.frame = FRAME_TARG;
    newfix->lr.target = TARGET_GRP;
    newfix->lr.frame_datum = 0;
    newfix->lr.target_datum = ObjDGROUPIndex;
    newfix->lr.is_secondary = 1;
    newfix->lr.target_offset = 0;

    newRec( MS_SYM_CHANGE_DEF_SEG );
    seg_fixup = 0;
    putAddr( newfix, (void *) &seg_fixup, 2 );
    put16( 0 ); /* reserved stuff */
    endRec();
}

void Can2MsS( void ) {
/******************/

    symb_handle head;
    symb_handle cur;

    head = CanSGetHead();
    if( head != NULL ) {
        setupObjIO();
        blockIndent = 0;
        block386 = CanMisc.processor >= CAN_PROC_80386 ? MS_SYM_386_FLAG : 0;
        codeOffset = 0;
        putInitialRecs();
        cur = head;
        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:
                if( cur->d.memloc.is_static ) {
                    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 );

        finishObjIO();
    }
}

⌨️ 快捷键说明

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