disx86.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,201 行 · 第 1/5 页
C
2,201 行
/**********************************************************************
* Get ST (Floating Point) Register w - not used
*/
{
switch( reg ) {
case RM_0: return( DR_X86_st );
case RM_1: return( DR_X86_st1 );
case RM_2: return( DR_X86_st2 );
case RM_3: return( DR_X86_st3 );
case RM_4: return( DR_X86_st4 );
case RM_5: return( DR_X86_st5 );
case RM_6: return( DR_X86_st6 );
case RM_7: return( DR_X86_st7 );
default: return( DR_NONE );
}
}
dis_register X86GetMMReg(WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get MM (Multimedia) Register w - not used
*/
{
switch( reg ) {
case RM_0: return( DR_X86_mm0 );
case RM_1: return( DR_X86_mm1 );
case RM_2: return( DR_X86_mm2 );
case RM_3: return( DR_X86_mm3 );
case RM_4: return( DR_X86_mm4 );
case RM_5: return( DR_X86_mm5 );
case RM_6: return( DR_X86_mm6 );
case RM_7: return( DR_X86_mm7 );
default: return( DR_NONE );
}
}
dis_register X86GetXMMReg(WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get SSE (Streaming SIMD Extensions) Register w - not used
*/
{
switch( reg ) {
case RM_0: return( DR_X86_xmm0 );
case RM_1: return( DR_X86_xmm1 );
case RM_2: return( DR_X86_xmm2 );
case RM_3: return( DR_X86_xmm3 );
case RM_4: return( DR_X86_xmm4 );
case RM_5: return( DR_X86_xmm5 );
case RM_6: return( DR_X86_xmm6 );
case RM_7: return( DR_X86_xmm7 );
default: return( DR_NONE );
}
}
dis_register X86GetCRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get Control Register
*/
{
switch( reg ) {
case REG_CR0: return( DR_X86_cr0 );
case REG_CR2: return( DR_X86_cr2 );
case REG_CR3: return( DR_X86_cr3 );
case REG_CR4: return( DR_X86_cr4 );
default : return( DR_NONE );
}
}
dis_register X86GetDRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get Debug Register
*/
{
switch( reg ) {
case REG_DR0: return( DR_X86_dr0 );
case REG_DR1: return( DR_X86_dr1 );
case REG_DR2: return( DR_X86_dr2 );
case REG_DR3: return( DR_X86_dr3 );
case REG_DR6: return( DR_X86_dr6 );
case REG_DR7: return( DR_X86_dr7 );
default : return( DR_NONE );
}
}
dis_register X86GetTRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get Test Register 80486
*/
{
switch( reg ) {
case REG_TR3: return( DR_X86_tr3 );
case REG_TR4: return( DR_X86_tr4 );
case REG_TR5: return( DR_X86_tr5 );
case REG_TR6: return( DR_X86_tr6 );
case REG_TR7: return( DR_X86_tr7 );
default : return( DR_NONE );
}
}
dis_register X86GetSRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get Segment Register
*/
{
switch( reg ) {
case REG_ES: return( DR_X86_es );
case REG_CS: return( DR_X86_cs );
case REG_SS: return( DR_X86_ss );
case REG_DS: return( DR_X86_ds );
case REG_FS: return( DR_X86_fs );
case REG_GS: return( DR_X86_gs );
default : return( DR_NONE );
}
}
dis_register X86GetRegister( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get Register
* w = 1 (default) use full width of operand
* = 0 use byte size operand
*/
{
switch( ins->type ) {
case DI_X86_lldt:
case DI_X86_sldt:
case DI_X86_ltr:
case DI_X86_lmsw:
case DI_X86_smsw:
case DI_X86_str:
case DI_X86_verr:
case DI_X86_verw:
case DI_X86_arpl:
return( X86GetRegister_W( w, reg, ins ) );
case DI_X86_bswap:
return( X86GetRegister_D( w, reg, ins ) );
default:
if( w != W_FULL ) {
return( X86GetRegister_B ( w, reg, ins ) );
} else if( DIF_X86_OPND_LONG & ins->flags ) {
return( X86GetRegister_D( w, reg, ins ) );
} else {
return( X86GetRegister_W( w, reg, ins ) );
}
}
}
dis_register X86GetRegisterAddr( WBIT w, RM reg, dis_dec_ins *ins )
/**********************************************************************
* Get Register
* w = 1 (default) use full width of operand
* = 0 use byte size operand
*/
{
switch(ins->type) {
default:
if( w != W_FULL ) {
return( X86GetRegister_B ( w, reg, ins ) );
} else if( DIF_X86_ADDR_LONG & ins->flags ) {
return( X86GetRegister_D( w, reg, ins ) );
} else {
return( X86GetRegister_W( w, reg, ins ) );
}
}
}
static void X86GetModRM_S( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type,
dis_register (*func)( WBIT w,RM reg, dis_dec_ins* ins ) )
/**********************************************************************
* Get Mod RM - 16-Bit Operand Version
*/
{
int oper;
oper = ins->num_ops;
++ins->num_ops;
ins->op[oper].type = DO_MEMORY_ABS;
ins->op[oper].ref_type = ref_type;
ins->op[oper].value = 0;
ins->op[oper].scale = 1;
switch(rm) {
case RM_0:
ins->op[oper].base = DR_X86_bx;
ins->op[oper].index = DR_X86_si;
break;
case RM_1:
ins->op[oper].base = DR_X86_bx;
ins->op[oper].index = DR_X86_di;
break;
case RM_2:
ins->op[oper].base = DR_X86_bp;
ins->op[oper].index = DR_X86_si;
break;
case RM_3:
ins->op[oper].base = DR_X86_bp;
ins->op[oper].index = DR_X86_di;
break;
case RM_4:
ins->op[oper].base = DR_X86_si;
ins->op[oper].index = DR_NONE;
break;
case RM_5:
ins->op[oper].base = DR_X86_di;
ins->op[oper].index = DR_NONE;
break;
case RM_6:
ins->op[oper].base = DR_X86_bp;
ins->op[oper].index = DR_NONE;
break;
case RM_7:
ins->op[oper].base = DR_X86_bx;
ins->op[oper].index = DR_NONE;
break;
}
switch( mod ) {
case MOD_0:
if(rm == RM_6) {
ins->op[oper].base = DR_NONE;
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetUShort( d, ins->size );
ins->size += 2;
}
break;
case MOD_1:
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetSByte( d, ins->size );
ins->size += 1;
break;
case MOD_2:
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetSShort( d, ins->size);
ins->size += 2;
break;
case MOD_3:
ins->op[oper].type = DO_REG;
ins->op[oper].base = func( w, rm, ins );
ins->op[oper].index = DR_NONE;
break;
}
}
static void X86GetSIB( unsigned_8 scale, RM base, RM index,
dis_dec_ins *ins, unsigned oper )
/**********************************************************************
* Get SIB - only used in 32-Bit Operand Mode
*/
{
ins->op[oper].base = X86GetRegister_D( W_DEFAULT, base, ins );
if( index == RM_4 ) {
ins->op[oper].scale = 1;
ins->op[oper].index = DR_NONE;
} else {
ins->op[oper].scale = 1 << scale;
ins->op[oper].index = X86GetRegister_D( W_DEFAULT, index, ins );
}
}
static void X86GetModRM_L( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type,
dis_register (*func)( WBIT w, RM reg, dis_dec_ins* ins ) ) {
/**********************************************************************
* Get MOD RM - 32-Bit Version
*/
SIB sib;
int oper;
oper = ins->num_ops;
++ins->num_ops;
ins->op[oper].type = DO_MEMORY_ABS;
ins->op[oper].ref_type = ref_type;
ins->op[oper].value = 0;
ins->op[oper].scale = 1;
ins->op[oper].index = DR_NONE;
ins->op[oper].base = DR_NONE;
switch( rm ) {
case RM_0:
ins->op[oper].base = DR_X86_eax;
break;
case RM_1:
ins->op[oper].base = DR_X86_ecx;
break;
case RM_2:
ins->op[oper].base = DR_X86_edx;
break;
case RM_3:
ins->op[oper].base = DR_X86_ebx;
break;
case RM_4:
if( mod != MOD_3) {
sib.full = GetUByte( d, ins->size );
ins->size += 1;
X86GetSIB( sib.split.scale,
sib.split.base,
sib.split.index,
ins,
oper );
if( mod == MOD_0 ) {
if( ins->op[oper].base == DR_X86_ebp ) {
ins->op[oper].base = DR_NONE;
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetULong( d, ins->size );
ins->size += 4;
}
}
}
break;
case RM_5:
ins->op[oper].base = DR_X86_ebp;
break;
case RM_6:
ins->op[oper].base = DR_X86_esi;
break;
case RM_7:
ins->op[oper].base = DR_X86_edi;
break;
}
switch( mod ) {
case MOD_0:
if( rm == RM_5 ) {
ins->op[oper].base = DR_NONE;
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetULong( d, ins->size );
ins->size += 4;
}
break;
case MOD_1:
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetSByte( d, ins->size );
ins->size += 1;
break;
case MOD_2:
ins->op[oper].op_position = ins->size;
ins->op[oper].value = GetULong( d, ins->size );
ins->size += 4;
break;
case MOD_3:
ins->op[oper].type = DO_REG;
ins->op[oper].base = func( w, rm, ins );
break;
}
}
/*=====================================================================*/
/* Get MOD/RM as Operand */
/*=====================================================================*/
static void X86GetModRM( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
*/
{
if( DIF_X86_ADDR_LONG & ins->flags ) {
X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetRegister );
} else {
X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetRegister );
}
}
static void X86GetModRM_D( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
* 32-Bit Operand Version
*/
{
if( DIF_X86_ADDR_LONG & ins->flags ) {
X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetRegister_D );
} else {
X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetRegister_D );
}
}
static void X86GetModRM_W( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
* 16-Bit Operand Version
*/
{
if( DIF_X86_ADDR_LONG & ins->flags ) {
X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetRegister_W );
} else {
X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetRegister_W );
}
}
static void X86GetModRM_B( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins )
/**********************************************************************
* 8-Bit Operand Version
*/
{
if( DIF_X86_ADDR_LONG & ins->flags ) {
X86GetModRM_L( w, mod, rm, d ,ins, DRT_X86_BYTE, X86GetRegister_B );
} else {
X86GetModRM_S( w, mod, rm, d ,ins, DRT_X86_BYTE, X86GetRegister_B );
}
}
static void X86FGetModRM( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
* Gets the Floating Point MOD/RM
* NOT the same with X86GetModRM it returns ST instead of a register
* if MOD = MOD_3
*/
{
if( DIF_X86_ADDR_LONG & ins->flags ) {
X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86FGetSTReg );
} else {
X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86FGetSTReg );
}
}
static void X86MMGetModRM( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
* Gets the Floating Point MOD/RM
* NOT the same with X86GetModRM it returns MM instead of a register
* if MOD = MOD_3
*/
{
if( DIF_X86_ADDR_LONG & ins->flags ) {
X86GetModRM_L( w, mod, rm, d ,ins, ref_type, X86GetMMReg );
} else {
X86GetModRM_S( w, mod, rm, d ,ins, ref_type, X86GetMMReg );
}
}
static void X86XMMGetModRM( WBIT w, MOD mod, RM rm, void * d,
dis_dec_ins *ins, dis_ref_type ref_type )
/**********************************************************************
* Gets the Floating Point MOD/RM
* NOT the same with X86GetModRM it returns XMM instead of a register
* if MOD = MOD_3
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?