mipsreg.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 828 行 · 第 1/2 页
C
828 行
*disp_type = MIPST_WORD;
*reg = &RegListHalf[idx - IDX_r0].info;
}
}
//NYI: if extended & ~ 64 bit mode, downshift to 32-bit display.
// Also, if 64 <=> 32 bit switch, tell client to redraw window
if( !(MADState->reg_state[CPU_REG_SET] & CT_HEX) ) {
switch( *disp_type ) {
case MIPST_DWORD:
*disp_type = MIPST_UINT64;
break;
case MIPST_WORD:
*disp_type = MIPST_ULONG;
break;
}
}
*descript = DescriptBuff;
*max_descript = 0;
*max_value = 0;
strcpy( DescriptBuff, (*reg)->name );
return( MS_OK );
}
// NYI: FPUs with real 64-bit registers
static const reg_display_entry FPUList[] = {
{ IDX_f0, 16, MIPST_DOUBLE },
{ IDX_fpcsr, 1, RT_WORD },
{ 0, 0, 0 }
};
static mad_status FPUGetPiece( unsigned piece,
char **descript,
unsigned *max_descript,
const mad_reg_info **reg,
mad_type_handle *disp_type,
unsigned *max_value )
{
unsigned idx;
if( !FindEntry( FPUList, piece, &idx, disp_type ) ) return( MS_FAIL );
if( MADState->reg_state[FPU_REG_SET] & FT_HEX ) {
switch( *disp_type ) {
case MIPST_DOUBLE:
*disp_type = MIPST_HDOUBLE;
break;
}
}
*descript = DescriptBuff;
*max_descript = 0;
*max_value = 0;
*reg = &RegList[idx].info;
strcpy( DescriptBuff, (*reg)->name );
return( MS_OK );
}
mad_status DIGENTRY MIRegSetDisplayGetPiece( const mad_reg_set_data *rsd,
mad_registers const *mr,
unsigned piece,
char **descript,
unsigned *max_descript,
const mad_reg_info **reg,
mad_type_handle *disp_type,
unsigned *max_value )
{
return( rsd->get_piece( piece, descript, max_descript, reg,
disp_type, max_value ) );
}
static const mad_modify_list WordReg = { NULL, MIPST_WORD, MSTR_NIL };
static const mad_modify_list DWordReg = { NULL, MIPST_DWORD, MSTR_NIL };
static const mad_modify_list FltReg = { NULL, MIPST_DOUBLE, MSTR_NIL };
mad_status DIGENTRY MIRegSetDisplayModify( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_modify_list **possible_p, unsigned *num_possible_p )
{
*num_possible_p = 1;
switch( ri->type ) {
case MIPST_DOUBLE:
*possible_p = &FltReg;
break;
case MIPST_DWORD:
//NYI: have to check for 64-bit mode
*possible_p = &DWordReg;
break;
default:
*possible_p = &WordReg;
break;
}
return( MS_OK );
}
mad_status DIGENTRY MIRegModified( const mad_reg_set_data *rsd, const mad_reg_info *ri, const mad_registers *old, const mad_registers *cur )
{
unsigned_64 new_ip;
unsigned_8 *p_old;
unsigned_8 *p_cur;
unsigned mask;
unsigned size;
if( ri->bit_start == BIT_OFF( pc ) ) {
new_ip = old->mips.pc;
//NYI: 64 bit
new_ip.u._32[I64LO32] += sizeof( unsigned_32 );
if( new_ip.u._32[I64LO32] != cur->mips.pc.u._32[I64LO32] ) {
return( MS_MODIFIED_SIGNIFICANTLY );
} else if( old->mips.pc.u._32[I64LO32] != cur->mips.pc.u._32[I64LO32] ) {
return( MS_MODIFIED );
}
} else {
p_old = (unsigned_8 *)old + (ri->bit_start / BITS_PER_BYTE);
p_cur = (unsigned_8 *)cur + (ri->bit_start / BITS_PER_BYTE);
size = ri->bit_size;
if( size >= BITS_PER_BYTE ) {
/* it's going to be byte aligned */
return( memcmp( p_old, p_cur, size / BITS_PER_BYTE ) != 0 ? MS_MODIFIED_SIGNIFICANTLY : MS_OK );
} else {
mask = (1 << size) - 1;
#define GET_VAL( w ) (((*p_##w >> (ri->bit_start % BITS_PER_BYTE))) & mask)
return( GET_VAL( old ) != GET_VAL( cur ) ? MS_MODIFIED_SIGNIFICANTLY : MS_OK );
}
}
return( MS_OK );
}
mad_status DIGENTRY MIRegInspectAddr( const mad_reg_info *ri, mad_registers const *mr, address *a )
{
unsigned bit_start;
unsigned_64 *p;
memset( a, 0, sizeof( *a ) );
bit_start = ri->bit_start;
if( bit_start == BIT_OFF( pc ) ) {
a->mach.offset = mr->mips.pc.u._32[I64LO32];
return( MS_OK );
}
if( bit_start >= BIT_OFF( f0 ) && bit_start < (BIT_OFF( f31 ) + 64) ) {
return( MS_FAIL );
}
p = (unsigned_64 *)((unsigned_8 *)mr + (bit_start / BITS_PER_BYTE));
a->mach.offset = p->u._32[I64LO32];
return( MS_OK );
}
const mad_toggle_strings *DIGENTRY MIRegSetDisplayToggleList( const mad_reg_set_data *rsd )
{
return( rsd->togglelist );
}
unsigned DIGENTRY MIRegSetDisplayToggle( const mad_reg_set_data *rsd, unsigned on, unsigned off )
{
unsigned toggle;
unsigned *bits;
unsigned index;
unsigned old;
toggle = on & off;
index = rsd - &RegSet[CPU_REG_SET];
bits = &MADState->reg_state[index];
old = *bits;
*bits ^= toggle;
*bits |= on & ~toggle;
*bits &= ~off | toggle;
if( index == CPU_REG_SET && ((old ^ *bits) & CT_SYMBOLIC_NAMES) ) {
/* We've changed from numeric regs to symbolic or vice versa.
* Have to force a redraw of the disassembly window.
*/
MCNotify( MNT_REDRAW_DISASM, NULL );
}
return( *bits );
}
walk_result DIGENTRY MIRegWalk( const mad_reg_set_data *rsd, const mad_reg_info *ri, MI_REG_WALKER *wk, void *d )
{
const mips_reg_info *curr;
walk_result wr;
unsigned reg_set;
if( ri != NULL ) {
switch( ((mips_reg_info *)ri)->sublist_code ) {
case RS_DWORD:
curr = RegSubList[ri->bit_start / (sizeof( unsigned_64 ) * BITS_PER_BYTE)];
break;
default:
curr = SubList[((mips_reg_info *)ri)->sublist_code];
break;
}
if( curr != NULL ) {
while( curr->info.name != NULL ) {
wr = wk( &curr->info, 0, d );
if( wr != WR_CONTINUE ) return( wr );
++curr;
}
}
} else {
reg_set = rsd - RegSet;
curr = RegList;
while( curr < &RegList[ IDX_LAST_ONE ] ) {
if( curr->reg_set == reg_set ) {
wr = wk( &curr->info, curr->sublist_code != 0, d );
if( wr != WR_CONTINUE ) return( wr );
}
++curr;
}
}
return( WR_CONTINUE );
}
void DIGENTRY MIRegSpecialGet( mad_special_reg sr, mad_registers const *mr, addr_ptr *ma )
{
ma->segment = 0;
switch( sr ) {
case MSR_IP:
ma->offset = mr->mips.pc.u._32[I64LO32];
break;
case MSR_SP:
ma->offset = mr->mips.sp.u._32[I64LO32];
break;
case MSR_FP:
//NYI: may not be used?
ma->offset = mr->mips.r30.u._32[I64LO32];
break;
}
}
void DIGENTRY MIRegSpecialSet( mad_special_reg sr, mad_registers *mr, addr_ptr const *ma )
{
switch( sr ) {
case MSR_IP:
mr->mips.pc.u._32[I64LO32] = ma->offset;
break;
case MSR_SP:
mr->mips.sp.u._32[I64LO32] = ma->offset;
break;
case MSR_FP:
//NYI: may not be used?
mr->mips.r30.u._32[I64LO32] = ma->offset;
break;
}
}
unsigned DIGENTRY MIRegSpecialName( mad_special_reg sr, mad_registers const *mr, mad_address_format af, unsigned max, char *buff )
{
unsigned idx;
unsigned len;
char const *p;
switch( sr ) {
case MSR_IP:
idx = IDX_pc;
break;
case MSR_SP:
idx = IDX_sp;
break;
case MSR_FP:
idx = IDX_r30;
break;
default:
idx = 0;
break;
}
p = RegList[idx].info.name;
len = strlen( p );
if( max > 0 ) {
--max;
if( max > len ) max = len;
memcpy( buff, p, max );
buff[max] = '\0';
}
return( len );
}
const mad_reg_info *DIGENTRY MIRegFromContextItem( context_item ci )
{
const mad_reg_info *reg;
reg = NULL;
switch( ci ) {
case CI_MIPS_pc:
reg = &RegList[IDX_pc].info;
break;
case CI_MIPS_lo:
reg = &RegList[IDX_lo].info;
break;
case CI_MIPS_hi:
reg = &RegList[IDX_hi].info;
break;
default:
if( ci >= CI_MIPS_r0 && ci <= CI_MIPS_r31 ) {
reg = &RegList[ci - CI_MIPS_r0 + IDX_r0].info;
} else if( ci >= CI_MIPS_f0 && ci <= CI_MIPS_f31 ) {
reg = &RegList[ci - CI_MIPS_f0 + IDX_f0].info;
}
}
return( reg );
}
void DIGENTRY MIRegUpdateStart( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size )
{
}
void DIGENTRY MIRegUpdateEnd( mad_registers *mr, unsigned flags, unsigned bit_start, unsigned bit_size )
{
unsigned i;
unsigned bit_end;
bit_end = bit_start + bit_size;
#define IN_RANGE( i, bit ) \
((bit) >= RegList[i].info.bit_start && (bit) < RegList[i].info.bit_start+RegList[i].info.bit_size)
for( i = 0; i < IDX_LAST_ONE; ++i ) {
if( (IN_RANGE(i, bit_start) || IN_RANGE( i, bit_end ))) {
MCNotify( MNT_MODIFY_REG, (void *)&RegSet[RegList[i].reg_set] );
break;
}
}
switch( bit_start ) {
case BIT_OFF( pc ):
MCNotify( MNT_MODIFY_IP, NULL );
break;
case BIT_OFF( sp ):
MCNotify( MNT_MODIFY_SP, NULL );
break;
case BIT_OFF( r30 ): //NYI: may not be used?
MCNotify( MNT_MODIFY_FP, NULL );
break;
}
}
static mad_status AddSubList( unsigned idx, const sublist_data *sub, unsigned num )
{
unsigned i;
unsigned j;
i = RegList[idx].info.bit_start / (sizeof( unsigned_64 )*BITS_PER_BYTE);
if( RegSubList[i] != NULL )
return( MS_OK );
RegSubList[i] = MCAlloc( sizeof( mips_reg_info ) * (num+1) );
if( RegSubList[i] == NULL )
return( MS_ERR | MS_NO_MEM );
memset( RegSubList[i], 0, sizeof( mips_reg_info ) * (num+1) );
for( j = 0; j < num; ++j ) {
RegSubList[i][j] = RegList[idx];
RegSubList[i][j].info.name = sub[j].name;
RegSubList[i][j].info.type = sub[j].mth;
RegSubList[i][j].info.bit_start += sub[j].start;
RegSubList[i][j].info.bit_size = TypeArray[ sub[j].mth ].u.b->bits;
RegSubList[i][j].sublist_code = RS_NONE;
}
return( MS_OK );
}
mad_status RegInit( void )
{
unsigned i;
unsigned max;
unsigned curr;
unsigned half_idx = 0;
mad_status ms;
max = 0;
for( i = 0; i < NUM_ELTS( RegList ); ++i ) {
switch( RegList[i].sublist_code ) {
case RS_DWORD:
curr = RegList[i].info.bit_start / (sizeof(unsigned_64)*BITS_PER_BYTE);
if( curr > max )
max = curr;
RegListHalf[half_idx] = RegList[i];
#if defined( __BIG_ENDIAN__ )
// kludge for 64-bit registers displayed as 32-bit - need to
// skip 32 bits!
RegListHalf[half_idx].info.bit_start += 32;
#endif
RegListHalf[half_idx].info.bit_size = 32;
++half_idx;
break;
}
}
RegSubList = MCAlloc( (max+1) * sizeof( *RegSubList ) );
if( RegSubList == NULL )
return( MS_ERR | MS_NO_MEM );
memset( RegSubList, 0, (max+1) * sizeof( *RegSubList ) );
for( i = 0; i < NUM_ELTS( RegList ); ++i ) {
switch( RegList[i].sublist_code ) {
case RS_DWORD:
ms = AddSubList( i, DwordRegSubData, NUM_ELTS( DwordRegSubData ) );
if( ms != MS_OK )
return( ms );
break;
}
}
return( MS_OK );
}
void RegFini( void )
{
unsigned i;
unsigned max;
unsigned curr;
max = 0;
for( i = 0; i < NUM_ELTS( RegList ); ++i ) {
switch( RegList[i].sublist_code ) {
case RS_DWORD:
curr = RegList[i].info.bit_start / (sizeof( unsigned_64 ) * BITS_PER_BYTE);
if( curr > max )
max = curr;
break;
}
}
for( i = 0; i <= max; ++i )
MCFree( RegSubList[i] );
MCFree( RegSubList );
RegSubList = NULL;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?