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