Search
lxdream.org :: lxdream :: r1191:12fdf3aafcd4
lxdream 0.9.1
released Jun 29
Download Now
changeset1191:12fdf3aafcd4
parent1190:2e66e9053037
child1192:ba3df0bf2c23
authornkeynes
dateFri Dec 02 18:18:04 2011 +1000 (12 years ago)
SH4 shadow-mode tweaks
- Fix exceptions generated by the translator to account for the excepting
instruction(s) in the cycle counts.
- Compare floating point regs bitwise rather than with FP comparisons
(otherwise can fail due to nan != nan)
- Dump the translated block when we abort with an inconsistency
src/sh4/sh4x86.in
src/sh4/shadow.c
src/xlat/x86/x86op.h
1.1 --- a/src/sh4/sh4x86.in Fri Dec 02 18:14:27 2011 +1000
1.2 +++ b/src/sh4/sh4x86.in Fri Dec 02 18:18:04 2011 +1000
1.3 @@ -130,6 +130,7 @@
1.4 { "sh4_write_fpscr", sh4_write_fpscr },
1.5 { "sh4_write_sr", sh4_write_sr },
1.6 { "sh4_read_sr", sh4_read_sr },
1.7 + { "sh4_raise_exception", sh4_raise_exception },
1.8 { "sh4_sleep", sh4_sleep },
1.9 { "sh4_fsca", sh4_fsca },
1.10 { "sh4_ftrv", sh4_ftrv },
1.11 @@ -365,9 +366,9 @@
1.12 #define check_priv( ) \
1.13 if( (sh4_x86.sh4_mode & SR_MD) == 0 ) { \
1.14 if( sh4_x86.in_delay_slot ) { \
1.15 - exit_block_exc(EXC_SLOT_ILLEGAL, (pc-2) ); \
1.16 + exit_block_exc(EXC_SLOT_ILLEGAL, (pc-2), 4 ); \
1.17 } else { \
1.18 - exit_block_exc(EXC_ILLEGAL, pc); \
1.19 + exit_block_exc(EXC_ILLEGAL, pc, 2); \
1.20 } \
1.21 sh4_x86.branch_taken = TRUE; \
1.22 sh4_x86.in_delay_slot = DELAY_NONE; \
1.23 @@ -486,7 +487,7 @@
1.24 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_long), pc)
1.25 #define MEM_PREFETCH( addr_reg ) call_read_func(addr_reg, REG_RESULT1, MEM_REGION_PTR(prefetch), pc)
1.26
1.27 -#define SLOTILLEGAL() exit_block_exc(EXC_SLOT_ILLEGAL, pc-2); sh4_x86.in_delay_slot = DELAY_NONE; return 2;
1.28 +#define SLOTILLEGAL() exit_block_exc(EXC_SLOT_ILLEGAL, pc-2, 4); sh4_x86.in_delay_slot = DELAY_NONE; return 2;
1.29
1.30 /** Offset of xlat_sh4_mode field relative to the code pointer */
1.31 #define XLAT_SH4_MODE_CODE_OFFSET (int32_t)(offsetof(struct xlat_cache_block, xlat_sh4_mode) - offsetof(struct xlat_cache_block,code) )
1.32 @@ -763,11 +764,11 @@
1.33 /**
1.34 * Exit unconditionally with a general exception
1.35 */
1.36 -void exit_block_exc( int code, sh4addr_t pc )
1.37 +void exit_block_exc( int code, sh4addr_t pc, int inst_adjust )
1.38 {
1.39 MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );
1.40 ADDL_r32_rbpdisp( REG_ECX, R_PC );
1.41 - MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
1.42 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc + inst_adjust)>>1)*sh4_cpu_period, REG_ECX );
1.43 ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
1.44 MOVL_imm32_r32( code, REG_ARG1 );
1.45 CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );
1.46 @@ -816,6 +817,7 @@
1.47 ADDL_r32_r32( REG_EDX, REG_ECX );
1.48 ADDL_r32_rbpdisp( REG_ECX, R_SPC );
1.49 MOVL_moffptr_eax( &sh4_cpu_period );
1.50 + INC_r32( REG_EDX ); /* Add 1 for the aborting instruction itself */
1.51 MULL_r32( REG_EDX );
1.52 ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );
1.53 exit_block();
1.54 @@ -2208,9 +2210,9 @@
1.55 UNDEF {:
1.56 COUNT_INST(I_UNDEF);
1.57 if( sh4_x86.in_delay_slot ) {
1.58 - exit_block_exc(EXC_SLOT_ILLEGAL, pc-2);
1.59 + exit_block_exc(EXC_SLOT_ILLEGAL, pc-2, 4);
1.60 } else {
1.61 - exit_block_exc(EXC_ILLEGAL, pc);
1.62 + exit_block_exc(EXC_ILLEGAL, pc, 2);
1.63 return 2;
1.64 }
1.65 :}
2.1 --- a/src/sh4/shadow.c Fri Dec 02 18:14:27 2011 +1000
2.2 +++ b/src/sh4/shadow.c Fri Dec 02 18:18:04 2011 +1000
2.3 @@ -129,15 +129,23 @@
2.4 }
2.5 }
2.6 for( unsigned i=0; i<16; i++ ) {
2.7 - if( xsh4r->fr[0][i] != esh4r->fr[0][i] ) {
2.8 + if( *((uint32_t *)&xsh4r->fr[0][i]) != *((uint32_t *)&esh4r->fr[0][i]) ) {
2.9 isgood = FALSE;
2.10 - fprintf( stderr, "FR%d Xlt = %f, Emu = %f\n", i, xsh4r->fr[0][i], esh4r->fr[0][i] );
2.11 + fprintf( stderr, "FR%d Xlt = %f (0x%08X), Emu = %f (0x%08X)\n", i, xsh4r->fr[0][i],
2.12 + *((uint32_t *)&xsh4r->fr[0][i]),
2.13 + esh4r->fr[0][i],
2.14 + *((uint32_t *)&esh4r->fr[0][i])
2.15 + );
2.16 }
2.17 }
2.18 for( unsigned i=0; i<16; i++ ) {
2.19 - if( xsh4r->fr[1][i] != esh4r->fr[1][i] ) {
2.20 + if( *((uint32_t *)&xsh4r->fr[1][i]) != *((uint32_t *)&esh4r->fr[1][i]) ) {
2.21 isgood = FALSE;
2.22 - fprintf( stderr, "XF%d Xlt = %f, Emu = %f\n", i, xsh4r->fr[1][i], esh4r->fr[1][i] );
2.23 + fprintf( stderr, "XF%d Xlt = %f (0x%08X), Emu = %f (0x%08X)\n", i, xsh4r->fr[1][i],
2.24 + *((uint32_t *)&xsh4r->fr[1][i]),
2.25 + esh4r->fr[1][i],
2.26 + *((uint32_t *)&esh4r->fr[1][i])
2.27 + );
2.28 }
2.29 }
2.30
2.31 @@ -306,6 +314,8 @@
2.32
2.33 if( !check_registers( &temp_sh4r, &sh4r ) ) {
2.34 fprintf( stderr, "After executing block at %08X\n", shadow_sh4r.pc );
2.35 + fprintf( stderr, "Translated block was:\n" );
2.36 + sh4_translate_dump_block(shadow_sh4r.pc);
2.37 abort();
2.38 }
2.39 if( mem_check_posn < mem_log_posn ) {
3.1 --- a/src/xlat/x86/x86op.h Fri Dec 02 18:14:27 2011 +1000
3.2 +++ b/src/xlat/x86/x86op.h Fri Dec 02 18:18:04 2011 +1000
3.3 @@ -422,6 +422,8 @@
3.4 #define IMULQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x6B,0x69, r1, imm, r1)
3.5 #define IMULQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x0FAF, r2, r1)
3.6
3.7 +#define INC_r32(r1) x86_encode_r32_rm32(0xFF, 0, r1)
3.8 +
3.9 #define LEAL_r32disp_r32(r1,disp,r2) x86_encode_r32_mem32(0x8D, r2, r1, -1, 0, disp)
3.10 #define LEAL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x8D, r1, disp)
3.11 #define LEAL_sib_r32(ss,ii,bb,d,r1) x86_encode_r32_mem32(0x8D, r1, bb, ii, ss, d)
.