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 + -
显示快捷键?