watloc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 594 行 · 第 1/2 页
C
594 行
}
break;
case NOLOCATION :
default:
location->locvoid.class = NOLOCATION;
break;
}
return( ptr );
}
typedef struct {
unsigned ci : 5;
unsigned start : 4;
unsigned len : 7;
} reg_entry;
static const reg_entry RegTable[] = {
{ CI_EAX, 0, 8 },
{ CI_EAX, 8, 8 },
{ CI_EBX, 0, 8 },
{ CI_EBX, 8, 8 },
{ CI_ECX, 0, 8 },
{ CI_ECX, 8, 8 },
{ CI_EDX, 0, 8 },
{ CI_EDX, 8, 8 },
{ CI_EAX, 0, 16 },
{ CI_EBX, 0, 16 },
{ CI_ECX, 0, 16 },
{ CI_EDX, 0, 16 },
{ CI_ESI, 0, 16 },
{ CI_EDI, 0, 16 },
{ CI_EBP, 0, 16 },
{ CI_ESP, 0, 16 },
{ CI_CS, 0, 16 },
{ CI_SS, 0, 16 },
{ CI_DS, 0, 16 },
{ CI_ES, 0, 16 },
{ CI_ST0, 0, 80 },
{ CI_ST1, 0, 80 },
{ CI_ST2, 0, 80 },
{ CI_ST3, 0, 80 },
{ CI_ST4, 0, 80 },
{ CI_ST5, 0, 80 },
{ CI_ST6, 0, 80 },
{ CI_ST7, 0, 80 },
{ CI_EAX, 0, 32 },
{ CI_EBX, 0, 32 },
{ CI_ECX, 0, 32 },
{ CI_EDX, 0, 32 },
{ CI_ESI, 0, 32 },
{ CI_EDI, 0, 32 },
{ CI_EBP, 0, 32 },
{ CI_ESP, 0, 32 },
{ CI_FS, 0, 16 },
{ CI_GS, 0, 16 },
};
unsigned RegSize( unsigned idx )
{
return( RegTable[idx].len / 8 );
}
struct loc_stack_entry {
union {
unsigned_32 num;
location_list ll;
} u;
enum {
LS_NUM,
LS_ADDR,
} type;
};
#define MAX_LOC_STACK 10
static struct loc_stack_entry LocStack[MAX_LOC_STACK];
static int LocStkPtr = 0;
void PushBaseLocation( location_list *ll )
{
LocStack[LocStkPtr].u.ll = *ll;
LocStack[LocStkPtr].type = LS_ADDR;
++LocStkPtr;
}
dip_status EvalLocation( imp_image_handle *ii, location_context *lc, loc_expr e,
location_list *ll )
{
char *end;
struct loc_stack_entry *sp, *op1, *start;
int i;
int j;
loc_entry loc;
union {
struct loc_stack_entry lse;
location_list ll;
unsigned_32 num;
address addr;
} tmp;
union {
unsigned_16 so;
unsigned_32 lo;
addr32_ptr sa;
addr48_ptr la;
} item;
unsigned item_size;
reg_entry const *reg;
int item_addr;
dip_status ok;
end = SkipLocation( e );
if( *e & LOC_EXPR_IND ) {
++e;
}
ok = DS_OK;
sp = &LocStack[LocStkPtr-1];
start = sp;
while( e < end ) {
e = ParseLocEntry( ii, e, &loc );
switch( loc.locvoid.class ) {
case BP_OFFSET:
++sp;
sp->type = LS_ADDR;
ok = DCItemLocation( lc, CI_FRAME, &sp->u.ll );
if( ok != DS_OK ) {
DCStatus( ok );
goto done;
}
LocationAdd( &sp->u.ll, loc.bp_offset.offset*8 );
break;
case CONSTANT + ADDR386:
++sp;
sp->type = LS_ADDR;
LocationCreate( &sp->u.ll, LT_ADDR, &loc.memory.addr );
break;
case CONSTANT + INT_4:
++sp;
sp->type = LS_NUM;
sp->u.num = loc.constant.val;
break;
case MULTI_REG:
++sp;
sp->type = LS_ADDR;
sp->u.ll.flags = 0;
j = 0;
for( i = 0; i < loc.multi_reg.numregs; ++i ) {
reg = &RegTable[loc.multi_reg.regs[i]];
ok = DCItemLocation( lc, reg->ci, &tmp.ll );
if( ok != DS_OK ) {
DCStatus( ok );
goto done;
}
memcpy( &sp->u.ll.e[j], &tmp.ll.e[0],
tmp.ll.num * sizeof( tmp.ll.e[0] ) );
sp->u.ll.e[j].bit_start += reg->start;
sp->u.ll.e[j].bit_length = reg->len;
j += tmp.ll.num;
sp->u.ll.flags |= tmp.ll.flags;
}
sp->u.ll.num = j;
break;
case OPERATOR + LOP_IND_2:
item_addr = 0;
item_size = 2;
goto do_ind;
case OPERATOR + LOP_IND_4:
item_addr = 0;
item_size = 4;
goto do_ind;
case OPERATOR + LOP_IND_ADDR286:
item_addr = 1;
item_size = 4;
goto do_ind;
case OPERATOR + LOP_IND_ADDR386:
item_addr = 1;
item_size = 6;
do_ind:
if( sp->type == LS_NUM ) {
tmp.num = sp->u.num;
ok = DCItemLocation( lc, CI_DEF_ADDR_SPACE, &sp->u.ll );
if( ok != DS_OK ) goto done;
sp->u.ll.e[0].u.addr.mach.offset = tmp.num;
}
LocationCreate( &tmp.ll, LT_INTERNAL, &item );
ok = DCAssignLocation( &tmp.ll, &sp->u.ll, item_size );
if( ok != DS_OK ) {
DCStatus( ok );
goto done;
}
if( item_addr ) {
if( item_size == 4 ) {
ConvAddr32ToAddr48( item.sa, tmp.addr.mach );
} else {
tmp.addr.mach = item.la;
}
DCAddrSection( &tmp.addr );
LocationCreate( &sp->u.ll, LT_ADDR, &tmp.addr );
sp->type = LS_ADDR;
} else {
if( item_size == 2 ) {
sp->u.num = item.so;
} else {
sp->u.num = item.lo;
}
sp->type = LS_NUM;
}
break;
case OPERATOR + LOP_ZEB:
sp->u.num &= (unsigned_32) 0xff;
break;
case OPERATOR + LOP_ZEW:
sp->u.num &= (unsigned_32) 0xffff;
break;
case OPERATOR + LOP_MK_FP:
op1 = &sp[0];
--sp;
if( sp->type == LS_NUM ) {
tmp.addr = NilAddr;
tmp.addr.mach.segment = sp->u.num;
} else {
if( sp->u.ll.num != 1 || sp->u.ll.e[0].type != LT_ADDR ) {
ok = DS_ERR|DS_BAD_PARM;
goto done;
}
tmp.addr = sp->u.ll.e[0].u.addr;
}
if( op1->type == LS_NUM ) {
tmp.addr.mach.offset = op1->u.num;
} else {
if( op1->u.ll.num != 1 || op1->u.ll.e[0].type != LT_ADDR ) {
ok = DS_ERR|DS_BAD_LOCATION;
goto done;
}
tmp.addr.mach.offset = op1->u.ll.e[0].u.addr.mach.offset;
}
if( sp->type == LS_NUM ) {
DCAddrSection( &tmp.addr );
}
LocationCreate( &sp->u.ll, LT_ADDR, &tmp.addr );
sp->type = LS_ADDR;
break;
case OPERATOR + LOP_POP:
--sp;
break;
case OPERATOR + LOP_XCHG:
tmp.lse = sp[0];
sp[0] = sp[-loc.op.stk];
sp[-loc.op.stk] = tmp.lse;
break;
case OPERATOR + LOP_ADD:
op1 = &sp[0];
--sp;
if( op1->type == LS_ADDR ) {
/* get the address into sp */
tmp.lse = *sp;
*sp = *op1;
*op1 = tmp.lse;
}
if( sp->type == LS_ADDR ) {
if( op1->type == LS_ADDR ) {
tmp.num = op1->u.ll.e[0].u.addr.mach.offset;
} else {
tmp.num = op1->u.num;
}
LocationAdd( &sp->u.ll, tmp.num*8 );
sp->type = LS_ADDR;
} else {
sp->u.num += op1->u.num;
sp->type = LS_NUM;
}
break;
case OPERATOR + LOP_DUP:
sp[1] = sp[0];
++sp;
break;
case OPERATOR + LOP_NOP:
/* well, what did you expect? */
break;
}
}
if( LocStkPtr == 0 && sp == start ) {
/* empty location */
ok = DS_ERR|DS_BAD_LOCATION;
goto done;
}
if( sp->type == LS_ADDR ) {
*ll = sp->u.ll;
} else {
DCItemLocation( lc, CI_DEF_ADDR_SPACE, ll );
ll->e[0].u.addr.mach.offset = sp->u.num;
}
done:
LocStkPtr = 0;
return( ok );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?