x86reg.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,979 行 · 第 1/5 页
C
1,979 行
mad_string name;
const x86_reg_info * const *reglist;
unsigned_8 grouping;
};
static const mad_toggle_strings CPUToggleList[] =
{
{MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
{MSTR_MEXTENDED,MSTR_REG_EXTENDED,MSTR_REG_NORMAL},
{MSTR_MOS,MSTR_REG_OS,MSTR_REG_USER},
{MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
static const mad_toggle_strings FPUToggleList[] =
{
{MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
{MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
static const mad_toggle_strings MMXToggleList[] =
{
{MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
{MSTR_SIGNED,MSTR_SIGNED,MSTR_UNSIGNED},
{MSTR_BYTE,MSTR_BYTE,MSTR_NIL},
{MSTR_WORD,MSTR_WORD,MSTR_NIL},
{MSTR_DWORD,MSTR_DWORD,MSTR_NIL},
{MSTR_QWORD,MSTR_QWORD,MSTR_NIL},
{MSTR_FLOAT,MSTR_FLOAT,MSTR_NIL},
{MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
static const mad_toggle_strings XMMToggleList[] =
{
{MSTR_MHEX,MSTR_HEX,MSTR_DECIMAL},
{MSTR_SIGNED,MSTR_SIGNED,MSTR_UNSIGNED},
{MSTR_BYTE,MSTR_BYTE,MSTR_NIL},
{MSTR_WORD,MSTR_WORD,MSTR_NIL},
{MSTR_DWORD,MSTR_DWORD,MSTR_NIL},
{MSTR_QWORD,MSTR_QWORD,MSTR_NIL},
{MSTR_FLOAT,MSTR_FLOAT,MSTR_NIL},
{MSTR_DOUBLE,MSTR_DOUBLE,MSTR_NIL},
{MSTR_NIL,MSTR_NIL,MSTR_NIL}
};
#define FPU_GROUPING 6
static mad_status CPUGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static mad_status FPUGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static mad_status MMXGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static mad_status XMMGetPiece( const mad_registers *, unsigned piece, char **, unsigned *, const mad_reg_info **, mad_type_handle *, unsigned * );
static const mad_reg_set_data RegSet[] = {
{ CPUGetPiece, CPUToggleList, MSTR_CPU, CPURegList, 0 },
{ FPUGetPiece, FPUToggleList, MSTR_FPU, FPURegList, FPU_GROUPING },
{ MMXGetPiece, MMXToggleList, MSTR_MMX, MMXRegList, 1 },
{ XMMGetPiece, XMMToggleList, MSTR_XMM, XMMRegList, 1 } };
unsigned DIGENTRY MIRegistersSize( void )
{
return( sizeof( struct x86_mad_registers ) );
}
#define EXTRACT_ST( mr ) (((unsigned_16)(mr)->x86.fpu.sw >> SHIFT_st) & ((1<<LEN_st)-1))
mad_status DIGENTRY MIRegistersHost( mad_registers *mr )
{
unsigned st;
unsigned_16 tag;
/* normalize the tag bits to tag[0..1] refer to ST(0), etc */
st = EXTRACT_ST(mr)*2;
tag = mr->x86.fpu.tag;
tag = (tag >> (st)) | (tag << (16-st));
mr->x86.fpu.tag &= ~0xffffUL;
mr->x86.fpu.tag |= tag;
return( MS_MODIFIED );
}
mad_status DIGENTRY MIRegistersTarget( mad_registers *mr )
{
unsigned st;
unsigned_16 tag;
/* put the tag bits back the stupid way the x87 wants them */
st = EXTRACT_ST(mr)*2;
tag = mr->x86.fpu.tag;
tag = (tag << (st)) | (tag >> (16-st));
mr->x86.fpu.tag &= ~0xffffUL;
mr->x86.fpu.tag |= tag;
return( MS_MODIFIED );
}
walk_result DIGENTRY MIRegSetWalk( mad_type_kind tk, MI_REG_SET_WALKER *wk, void *d )
{
walk_result wr;
if( tk & (MTK_INTEGER|MTK_ADDRESS) ) {
wr = wk( &RegSet[CPU_REG_SET], d );
if( wr != WR_CONTINUE ) {
return( wr );
}
}
if( tk & MTK_FLOAT ) {
wr = wk( &RegSet[FPU_REG_SET], d );
if( wr != WR_CONTINUE ) {
return( wr );
}
}
if( (tk & MTK_CUSTOM) && (MCSystemConfig()->cpu & X86_MMX) ) {
wr = wk( &RegSet[MMX_REG_SET], d );
if( wr != WR_CONTINUE ) {
return( wr );
}
}
if( (tk & MTK_XMM) && (MCSystemConfig()->cpu & X86_XMM) ) {
wr = wk( &RegSet[XMM_REG_SET], d );
if( wr != WR_CONTINUE ) {
return( wr );
}
}
return( WR_CONTINUE );
}
mad_string DIGENTRY MIRegSetName( const mad_reg_set_data *rsd )
{
return( rsd->name );
}
unsigned DIGENTRY MIRegSetLevel( const mad_reg_set_data *rsd, unsigned max, char *buff )
{
char str[80];
unsigned len;
switch( rsd - RegSet ) {
case CPU_REG_SET:
switch( MCSystemConfig()->cpu & X86_CPU_MASK ) {
case X86_86:
strcpy( str, "8086" );
break;
case X86_586:
strcpy( str, "Pentium" );
break;
case X86_686:
strcpy( str, "Pentium Pro" );
break;
case X86_P4:
strcpy( str, "Pentium 4/Xeon" );
break;
default:
str[0] = MCSystemConfig()->cpu + '0';
strcpy( &str[1], "86" );
break;
}
break;
case FPU_REG_SET:
switch( MCSystemConfig()->fpu ) {
case X86_NO:
MCString( MSTR_NONE, sizeof( str ), str );
break;
case X86_EMU:
MCString( MSTR_EMULATOR, sizeof( str ), str );
break;
case X86_87:
strcpy( str, "8087" );
break;
case X86_587:
strcpy( str, "Pentium" );
break;
case X86_687:
strcpy( str, "Pentium Pro" );
break;
case X86_P47:
strcpy( str, "Pentium 4/Xeon" );
break;
default:
str[0] = MCSystemConfig()->fpu + '0';
strcpy( &str[1], "87" );
break;
}
break;
default:
str[0] = '\0';
break;
}
len = strlen( str );
if( max > 0 ) {
--max;
if( max > len )
max = len;
memcpy( buff, str, max );
buff[max] = '\0';
}
return( len );
}
unsigned DIGENTRY MIRegSetDisplayGrouping( const mad_reg_set_data *rsd )
{
switch( rsd - RegSet ) {
case MMX_REG_SET:
if( MADState->reg_state[MMX_REG_SET] & MT_BYTE ) {
return( 8 );
} else if( MADState->reg_state[MMX_REG_SET] & MT_WORD ) {
return( 4 );
} else if( MADState->reg_state[MMX_REG_SET] & MT_DWORD ) {
return( 2 );
} else if( MADState->reg_state[MMX_REG_SET] & MT_FLOAT ) {
return( 2 );
} else {
return( 1 );
}
case XMM_REG_SET:
if( MADState->reg_state[XMM_REG_SET] & XT_BYTE ) {
return( 16 + 2 );
} else if( MADState->reg_state[XMM_REG_SET] & XT_WORD ) {
return( 8 + 2 );
} else if( MADState->reg_state[XMM_REG_SET] & XT_DWORD ) {
return( 4 + 2 );
} else if( MADState->reg_state[XMM_REG_SET] & XT_QWORD ) {
return( 2 + 2 );
} else if( MADState->reg_state[XMM_REG_SET] & XT_FLOAT ) {
return( 4 + 2 );
} else { // double
return( 2 + 2 );
}
default:
return( rsd->grouping );
}
}
static char DescriptBuff[40];
static mad_status CPUGetPiece(
const mad_registers *mr,
unsigned piece,
char **descript_p,
unsigned *max_descript_p,
const mad_reg_info **reg_p,
mad_type_handle *disp_type_p,
unsigned *max_value_p )
{
static const x86_reg_info *list16[] = {
&CPU_ax, &CPU_bx, &CPU_cx, &CPU_dx,
&CPU_si, &CPU_di, &CPU_bp, &CPU_sp, &CPU_ip,
&CPU_ds, &CPU_es, &CPU_ss, &CPU_cs,
&CPU_fl, &CPU_c, &CPU_p, &CPU_a, &CPU_z, &CPU_s, &CPU_i, &CPU_d, &CPU_o,
};
static const x86_reg_info *list32[] = {
&CPU_eax, &CPU_ebx, &CPU_ecx, &CPU_edx,
&CPU_esi, &CPU_edi, &CPU_ebp, &CPU_esp, &CPU_eip,
&CPU_efl, &CPU_c, &CPU_p, &CPU_a, &CPU_z, &CPU_s, &CPU_i, &CPU_d, &CPU_o,
&CPU_ds, &CPU_es, &CPU_fs, &CPU_gs, &CPU_ss, &CPU_cs,
};
static const x86_reg_info *listOS[] = {
&CPU_iopl, &CPU_nt, &CPU_rf, &CPU_vm,
};
const x86_reg_info *curr;
const x86_reg_info **list;
unsigned list_num;
char *p;
static const void **last_list;
if( (MADState->reg_state[CPU_REG_SET] & CT_EXTENDED) || BIG_SEG( GetRegIP( mr ) ) ) {
list = list32;
list_num = NUM_ELTS( list32 );
} else {
list = list16;
list_num = NUM_ELTS( list16 );
}
if( last_list == NULL )
last_list = list;
if( last_list != list ) {
last_list = list;
MCNotify( MNT_REDRAW_REG, (void *)&RegSet[CPU_REG_SET] );
}
if( MADState->reg_state[CPU_REG_SET] & CT_OS ) {
*max_descript_p = 4;
if( piece >= list_num ) {
piece -= list_num;
if( piece >= NUM_ELTS( listOS ) )
return( MS_FAIL );
list = listOS;
}
} else {
*max_descript_p = 3;
if( piece >= list_num ) {
return( MS_FAIL );
}
}
curr = list[ piece ];
*max_value_p = 0;
*reg_p = &curr->info;
*descript_p = DescriptBuff;
strcpy( DescriptBuff, curr->info.name );
p = DescriptBuff;
while( *p != '\0' ) {
*p = toupper( *p );
++p;
}
*p = '\0';
if( curr->info.bit_size <= 3 ) {
*disp_type_p = X86T_BIT;
} else if( curr->info.bit_size <= 16 ) {
if( MADState->reg_state[CPU_REG_SET] & CT_HEX ) {
*disp_type_p = X86T_WORD;
} else {
*disp_type_p = X86T_USHORT;
}
} else {
if( MADState->reg_state[CPU_REG_SET] & CT_HEX ) {
*disp_type_p = X86T_DWORD;
} else {
*disp_type_p = X86T_ULONG;
}
}
return( MS_OK );
}
static const byte zero = 0;
static const byte one = 1;
static const byte two = 2;
static const byte three = 3;
static const byte four = 4;
static const byte five = 5;
static const byte six = 6;
static const byte seven = 7;
static const mad_modify_list ModBit[] = {
{ &zero, X86T_BYTE, MSTR_NIL },
{ &one, X86T_BYTE, MSTR_NIL },
};
static const mad_modify_list ModByte[] = {
{ NULL, X86T_BYTE, MSTR_NIL },
};
static const mad_modify_list ModWord[] = {
{ NULL, X86T_WORD, MSTR_NIL },
};
static const mad_modify_list ModDWord[] = {
{ NULL, X86T_DWORD, MSTR_NIL },
};
static const mad_modify_list ModQWord[] = {
{ NULL, X86T_QWORD, MSTR_NIL },
};
static const mad_modify_list ModFPUTag[] = {
{ &zero, X86T_BYTE, MSTR_VALID },
{ &one, X86T_BYTE, MSTR_ZERO },
{ &two, X86T_BYTE, MSTR_NAN },
{ &three, X86T_BYTE, MSTR_EMPTY },
};
static const mad_modify_list ModFPUStack[] = {
{ NULL, X86T_EXTENDED, MSTR_NIL },
};
static const mad_modify_list ModFPUSt[] = {
{ &zero, X86T_BIT, MSTR_NIL },
{ &one, X86T_BIT, MSTR_NIL },
{ &two, X86T_BIT, MSTR_NIL },
{ &three,X86T_BIT, MSTR_NIL },
{ &four, X86T_BIT, MSTR_NIL },
{ &five, X86T_BIT, MSTR_NIL },
{ &six, X86T_BIT, MSTR_NIL },
{ &seven,X86T_BIT, MSTR_NIL },
};
static const mad_modify_list ModFPUPc[] = {
{ &zero, X86T_BYTE, MSTR_PCSINGLE },
{ &one, X86T_BYTE, MSTR_NIL },
{ &two, X86T_BYTE, MSTR_PCDOUBLE },
{ &three, X86T_BYTE, MSTR_PCEXTENDED },
};
static const mad_modify_list ModFPURc[] = {
{ &zero, X86T_BYTE, MSTR_NEAREST },
{ &one, X86T_BYTE, MSTR_DOWN },
{ &two, X86T_BYTE, MSTR_UP },
{ &three, X86T_BYTE, MSTR_CHOP },
};
static const mad_modify_list ModFPUIc[] = {
{ &zero, X86T_BYTE, MSTR_PROJECTIVE },
{ &one, X86T_BYTE, MSTR_AFFINE },
};
#define MODLEN( name ) MaxModLen( name, NUM_ELTS( name ) )
static unsigned MaxModLen( const mad_modify_list *list, unsigned num )
{
unsigned max;
unsigned len;
max = 0;
while( num != 0 ) {
--num;
len = MCString( list[num].name, 0, NULL );
if( len > max ) {
max = len;
}
}
return( max );
}
#define LIST( num, r1, r2, r3, r4, r5, r6, r7, r8 ) \
static const x86_reg_info * const list##num[] \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?