filename | src/sh4/sh4x86.in |
changeset | 1191:12fdf3aafcd4 |
prev | 1186:2dc47c67bb93 |
next | 1193:dff55bdc4f46 |
author | nkeynes |
date | Fri Dec 02 18:18:04 2011 +1000 (10 years ago) |
permissions | -rw-r--r-- |
last change | 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 |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/sh4x86.in Tue Nov 29 17:11:40 2011 +10001.2 +++ b/src/sh4/sh4x86.in Fri Dec 02 18:18:04 2011 +10001.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.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.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 exception1.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 :}
.