revision 601:d8d1af0d133c
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 601:d8d1af0d133c |
parent | 600:3b0f94d0faed |
child | 602:a3aae8cbd1d7 |
author | nkeynes |
date | Tue Jan 22 10:11:45 2008 +0000 (15 years ago) |
Invoke emulator single-step for untranslatable delay slots (and fix a few
related bugs)
related bugs)
![]() | src/sh4/sh4x86.c | view | annotate | diff | log | |
![]() | src/sh4/sh4x86.in | view | annotate | diff | log | |
![]() | src/sh4/x86op.h | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4x86.c Tue Jan 22 10:10:46 2008 +00001.2 +++ b/src/sh4/sh4x86.c Tue Jan 22 10:11:45 2008 +00001.3 @@ -371,29 +371,39 @@1.4 call_func1( sh4_translate_breakpoint_hit, R_EAX );1.5 }1.7 +1.8 +#define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)1.9 +1.10 /**1.11 * Embed a call to sh4_execute_instruction for situations that we1.12 - * can't translate (mainly page-crossing delay slots at the moment).1.13 - * Caller is responsible for setting new_pc.1.14 + * can't translate (just page-crossing delay slots at the moment).1.15 + * Caller is responsible for setting new_pc before calling this function.1.16 + *1.17 + * Performs:1.18 + * Set PC = endpc1.19 + * Set sh4r.in_delay_slot = sh4_x86.in_delay_slot1.20 + * Update slice_cycle for endpc+2 (single step doesn't update slice_cycle)1.21 + * Call sh4_execute_instruction1.22 + * Call xlat_get_code_by_vma / xlat_get_code as for normal exit1.23 */1.24 -void sh4_emulator_exit( sh4vma_t endpc )1.25 +void exit_block_emu( sh4vma_t endpc )1.26 {1.27 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 51.28 ADD_r32_sh4r( R_ECX, R_PC );1.30 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 51.31 + load_imm32( R_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 51.32 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 61.33 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );1.34 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );1.36 call_func0( sh4_execute_instruction );1.37 - load_imm32( R_EAX, R_PC );1.38 + load_spreg( R_EAX, R_PC );1.39 if( sh4_x86.tlb_on ) {1.40 call_func1(xlat_get_code_by_vma,R_EAX);1.41 } else {1.42 call_func1(xlat_get_code,R_EAX);1.43 }1.44 - AND_imm8s_r32( 0xFC, R_EAX ); // 31.45 + AND_imm8s_rptr( 0xFC, R_EAX );1.46 POP_r32(R_EBP);1.47 RET();1.48 }1.49 @@ -507,11 +517,17 @@1.50 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );1.51 store_spreg( R_EAX, R_NEW_PC );1.53 + sh4_x86.in_delay_slot = DELAY_PC;1.54 sh4_x86.tstate = TSTATE_NONE;1.55 - sh4_translate_instruction( pc + 2 );1.56 - exit_block_newpcset(pc+2);1.57 sh4_x86.branch_taken = TRUE;1.58 - return 4;1.59 + if( UNTRANSLATABLE(pc+2) ) {1.60 + exit_block_emu(pc+2);1.61 + return 2;1.62 + } else {1.63 + sh4_translate_instruction( pc + 2 );1.64 + exit_block_newpcset(pc+2);1.65 + return 4;1.66 + }1.67 }1.68 }1.69 break;1.70 @@ -527,10 +543,15 @@1.71 store_spreg( R_EAX, R_NEW_PC );1.72 sh4_x86.in_delay_slot = DELAY_PC;1.73 sh4_x86.tstate = TSTATE_NONE;1.74 - sh4_translate_instruction( pc + 2 );1.75 - exit_block_newpcset(pc+2);1.76 sh4_x86.branch_taken = TRUE;1.77 - return 4;1.78 + if( UNTRANSLATABLE(pc+2) ) {1.79 + exit_block_emu(pc+2);1.80 + return 2;1.81 + } else {1.82 + sh4_translate_instruction( pc + 2 );1.83 + exit_block_newpcset(pc+2);1.84 + return 4;1.85 + }1.86 }1.87 }1.88 break;1.89 @@ -774,10 +795,15 @@1.90 load_spreg( R_ECX, R_PR );1.91 store_spreg( R_ECX, R_NEW_PC );1.92 sh4_x86.in_delay_slot = DELAY_PC;1.93 - sh4_translate_instruction(pc+2);1.94 - exit_block_newpcset(pc+2);1.95 sh4_x86.branch_taken = TRUE;1.96 - return 4;1.97 + if( UNTRANSLATABLE(pc+2) ) {1.98 + exit_block_emu(pc+2);1.99 + return 2;1.100 + } else {1.101 + sh4_translate_instruction(pc+2);1.102 + exit_block_newpcset(pc+2);1.103 + return 4;1.104 + }1.105 }1.106 }1.107 break;1.108 @@ -804,10 +830,15 @@1.109 sh4_x86.priv_checked = FALSE;1.110 sh4_x86.fpuen_checked = FALSE;1.111 sh4_x86.tstate = TSTATE_NONE;1.112 - sh4_translate_instruction(pc+2);1.113 - exit_block_newpcset(pc+2);1.114 sh4_x86.branch_taken = TRUE;1.115 - return 4;1.116 + if( UNTRANSLATABLE(pc+2) ) {1.117 + exit_block_emu(pc+2);1.118 + return 2;1.119 + } else {1.120 + sh4_translate_instruction(pc+2);1.121 + exit_block_newpcset(pc+2);1.122 + return 4;1.123 + }1.124 }1.125 }1.126 break;1.127 @@ -1947,10 +1978,17 @@1.128 store_spreg( R_EAX, R_PR );1.129 load_reg( R_ECX, Rn );1.130 store_spreg( R_ECX, R_NEW_PC );1.131 - sh4_translate_instruction(pc+2);1.132 - exit_block_newpcset(pc+2);1.133 + sh4_x86.in_delay_slot = DELAY_PC;1.134 sh4_x86.branch_taken = TRUE;1.135 - return 4;1.136 + sh4_x86.tstate = TSTATE_NONE;1.137 + if( UNTRANSLATABLE(pc+2) ) {1.138 + exit_block_emu(pc+2);1.139 + return 2;1.140 + } else {1.141 + sh4_translate_instruction(pc+2);1.142 + exit_block_newpcset(pc+2);1.143 + return 4;1.144 + }1.145 }1.146 }1.147 break;1.148 @@ -1978,10 +2016,15 @@1.149 load_reg( R_ECX, Rn );1.150 store_spreg( R_ECX, R_NEW_PC );1.151 sh4_x86.in_delay_slot = DELAY_PC;1.152 - sh4_translate_instruction(pc+2);1.153 - exit_block_newpcset(pc+2);1.154 sh4_x86.branch_taken = TRUE;1.155 - return 4;1.156 + if( UNTRANSLATABLE(pc+2) ) {1.157 + exit_block_emu(pc+2);1.158 + return 2;1.159 + } else {1.160 + sh4_translate_instruction(pc+2);1.161 + exit_block_newpcset(pc+2);1.162 + return 4;1.163 + }1.164 }1.165 }1.166 break;1.167 @@ -2277,7 +2320,7 @@1.168 { /* SWAP.B Rm, Rn */1.169 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.170 load_reg( R_EAX, Rm );1.171 - XCHG_r8_r8( R_AL, R_AH );1.172 + XCHG_r8_r8( R_AL, R_AH ); // NB: does not touch EFLAGS1.173 store_reg( R_EAX, Rn );1.174 }1.175 break;1.176 @@ -2449,17 +2492,29 @@1.177 SLOTILLEGAL();1.178 } else {1.179 sh4_x86.in_delay_slot = DELAY_PC;1.180 - if( sh4_x86.tstate == TSTATE_NONE ) {1.181 - CMP_imm8s_sh4r( 1, R_T );1.182 - sh4_x86.tstate = TSTATE_E;1.183 + if( UNTRANSLATABLE(pc+2) ) {1.184 + load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );1.185 + JF_rel8(6,nottaken);1.186 + ADD_imm32_r32( disp, R_EAX );1.187 + JMP_TARGET(nottaken);1.188 + ADD_sh4r_r32( R_PC, R_EAX );1.189 + store_spreg( R_EAX, R_NEW_PC );1.190 + exit_block_emu(pc+2);1.191 + sh4_x86.branch_taken = TRUE;1.192 + return 2;1.193 + } else {1.194 + if( sh4_x86.tstate == TSTATE_NONE ) {1.195 + CMP_imm8s_sh4r( 1, R_T );1.196 + sh4_x86.tstate = TSTATE_E;1.197 + }1.198 + OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JF rel321.199 + sh4_translate_instruction(pc+2);1.200 + exit_block_rel( disp + pc + 4, pc+4 );1.201 + // not taken1.202 + *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.203 + sh4_translate_instruction(pc+2);1.204 + return 4;1.205 }1.206 - OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel321.207 - sh4_translate_instruction(pc+2);1.208 - exit_block_rel( disp + pc + 4, pc+4 );1.209 - // not taken1.210 - *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.211 - sh4_translate_instruction(pc+2);1.212 - return 4;1.213 }1.214 }1.215 break;1.216 @@ -2469,19 +2524,32 @@1.217 if( sh4_x86.in_delay_slot ) {1.218 SLOTILLEGAL();1.219 } else {1.220 - sh4vma_t target = disp + pc + 4;1.221 sh4_x86.in_delay_slot = DELAY_PC;1.222 - if( sh4_x86.tstate == TSTATE_NONE ) {1.223 - CMP_imm8s_sh4r( 1, R_T );1.224 - sh4_x86.tstate = TSTATE_E;1.225 + if( UNTRANSLATABLE(pc+2) ) {1.226 + load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );1.227 + JT_rel8(6,nottaken);1.228 + ADD_imm32_r32( disp, R_EAX );1.229 + JMP_TARGET(nottaken);1.230 + ADD_sh4r_r32( R_PC, R_EAX );1.231 + store_spreg( R_EAX, R_NEW_PC );1.232 + exit_block_emu(pc+2);1.233 + sh4_x86.branch_taken = TRUE;1.234 + return 2;1.235 + } else {1.236 + if( sh4_x86.tstate == TSTATE_NONE ) {1.237 + CMP_imm8s_sh4r( 1, R_T );1.238 + sh4_x86.tstate = TSTATE_E;1.239 + }1.240 + sh4vma_t target = disp + pc + 4;1.241 + OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JT rel321.242 + sh4_translate_instruction(pc+2);1.243 + exit_block_rel( target, pc+4 );1.244 +1.245 + // not taken1.246 + *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.247 + sh4_translate_instruction(pc+2);1.248 + return 4;1.249 }1.250 - OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel321.251 - sh4_translate_instruction(pc+2);1.252 - exit_block_rel( target, pc+4 );1.253 - // not taken1.254 - *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.255 - sh4_translate_instruction(pc+2);1.256 - return 4;1.257 }1.258 }1.259 break;1.260 @@ -2520,10 +2588,18 @@1.261 SLOTILLEGAL();1.262 } else {1.263 sh4_x86.in_delay_slot = DELAY_PC;1.264 - sh4_translate_instruction( pc + 2 );1.265 - exit_block_rel( disp + pc + 4, pc+4 );1.266 sh4_x86.branch_taken = TRUE;1.267 - return 4;1.268 + if( UNTRANSLATABLE(pc+2) ) {1.269 + load_spreg( R_EAX, R_PC );1.270 + ADD_imm32_r32( pc + disp + 4 - sh4_x86.block_start_pc, R_EAX );1.271 + store_spreg( R_EAX, R_NEW_PC );1.272 + exit_block_emu(pc+2);1.273 + return 2;1.274 + } else {1.275 + sh4_translate_instruction( pc + 2 );1.276 + exit_block_rel( disp + pc + 4, pc+4 );1.277 + return 4;1.278 + }1.279 }1.280 }1.281 break;1.282 @@ -2537,10 +2613,18 @@1.283 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );1.284 store_spreg( R_EAX, R_PR );1.285 sh4_x86.in_delay_slot = DELAY_PC;1.286 - sh4_translate_instruction( pc + 2 );1.287 - exit_block_rel( disp + pc + 4, pc+4 );1.288 sh4_x86.branch_taken = TRUE;1.289 - return 4;1.290 + sh4_x86.tstate = TSTATE_NONE;1.291 + if( UNTRANSLATABLE(pc+2) ) {1.292 + ADD_imm32_r32( disp, R_EAX );1.293 + store_spreg( R_EAX, R_NEW_PC );1.294 + exit_block_emu(pc+2);1.295 + return 2;1.296 + } else {1.297 + sh4_translate_instruction( pc + 2 );1.298 + exit_block_rel( disp + pc + 4, pc+4 );1.299 + return 4;1.300 + }1.301 }1.302 }1.303 break;
2.1 --- a/src/sh4/sh4x86.in Tue Jan 22 10:10:46 2008 +00002.2 +++ b/src/sh4/sh4x86.in Tue Jan 22 10:11:45 2008 +00002.3 @@ -371,29 +371,39 @@2.4 call_func1( sh4_translate_breakpoint_hit, R_EAX );2.5 }2.7 +2.8 +#define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)2.9 +2.10 /**2.11 * Embed a call to sh4_execute_instruction for situations that we2.12 - * can't translate (mainly page-crossing delay slots at the moment).2.13 - * Caller is responsible for setting new_pc.2.14 + * can't translate (just page-crossing delay slots at the moment).2.15 + * Caller is responsible for setting new_pc before calling this function.2.16 + *2.17 + * Performs:2.18 + * Set PC = endpc2.19 + * Set sh4r.in_delay_slot = sh4_x86.in_delay_slot2.20 + * Update slice_cycle for endpc+2 (single step doesn't update slice_cycle)2.21 + * Call sh4_execute_instruction2.22 + * Call xlat_get_code_by_vma / xlat_get_code as for normal exit2.23 */2.24 -void sh4_emulator_exit( sh4vma_t endpc )2.25 +void exit_block_emu( sh4vma_t endpc )2.26 {2.27 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 52.28 ADD_r32_sh4r( R_ECX, R_PC );2.30 - load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 52.31 + load_imm32( R_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 52.32 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 62.33 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );2.34 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );2.36 call_func0( sh4_execute_instruction );2.37 - load_imm32( R_EAX, R_PC );2.38 + load_spreg( R_EAX, R_PC );2.39 if( sh4_x86.tlb_on ) {2.40 call_func1(xlat_get_code_by_vma,R_EAX);2.41 } else {2.42 call_func1(xlat_get_code,R_EAX);2.43 }2.44 - AND_imm8s_r32( 0xFC, R_EAX ); // 32.45 + AND_imm8s_rptr( 0xFC, R_EAX );2.46 POP_r32(R_EBP);2.47 RET();2.48 }2.49 @@ -987,7 +997,7 @@2.50 :}2.51 SWAP.B Rm, Rn {:2.52 load_reg( R_EAX, Rm );2.53 - XCHG_r8_r8( R_AL, R_AH );2.54 + XCHG_r8_r8( R_AL, R_AH ); // NB: does not touch EFLAGS2.55 store_reg( R_EAX, Rn );2.56 :}2.57 SWAP.W Rm, Rn {:2.58 @@ -1426,19 +1436,32 @@2.59 if( sh4_x86.in_delay_slot ) {2.60 SLOTILLEGAL();2.61 } else {2.62 - sh4vma_t target = disp + pc + 4;2.63 sh4_x86.in_delay_slot = DELAY_PC;2.64 - if( sh4_x86.tstate == TSTATE_NONE ) {2.65 - CMP_imm8s_sh4r( 1, R_T );2.66 - sh4_x86.tstate = TSTATE_E;2.67 + if( UNTRANSLATABLE(pc+2) ) {2.68 + load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );2.69 + JT_rel8(6,nottaken);2.70 + ADD_imm32_r32( disp, R_EAX );2.71 + JMP_TARGET(nottaken);2.72 + ADD_sh4r_r32( R_PC, R_EAX );2.73 + store_spreg( R_EAX, R_NEW_PC );2.74 + exit_block_emu(pc+2);2.75 + sh4_x86.branch_taken = TRUE;2.76 + return 2;2.77 + } else {2.78 + if( sh4_x86.tstate == TSTATE_NONE ) {2.79 + CMP_imm8s_sh4r( 1, R_T );2.80 + sh4_x86.tstate = TSTATE_E;2.81 + }2.82 + sh4vma_t target = disp + pc + 4;2.83 + OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JT rel322.84 + sh4_translate_instruction(pc+2);2.85 + exit_block_rel( target, pc+4 );2.86 +2.87 + // not taken2.88 + *patch = (xlat_output - ((uint8_t *)patch)) - 4;2.89 + sh4_translate_instruction(pc+2);2.90 + return 4;2.91 }2.92 - OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel322.93 - sh4_translate_instruction(pc+2);2.94 - exit_block_rel( target, pc+4 );2.95 - // not taken2.96 - *patch = (xlat_output - ((uint8_t *)patch)) - 4;2.97 - sh4_translate_instruction(pc+2);2.98 - return 4;2.99 }2.100 :}2.101 BRA disp {:2.102 @@ -1446,10 +1469,18 @@2.103 SLOTILLEGAL();2.104 } else {2.105 sh4_x86.in_delay_slot = DELAY_PC;2.106 - sh4_translate_instruction( pc + 2 );2.107 - exit_block_rel( disp + pc + 4, pc+4 );2.108 sh4_x86.branch_taken = TRUE;2.109 - return 4;2.110 + if( UNTRANSLATABLE(pc+2) ) {2.111 + load_spreg( R_EAX, R_PC );2.112 + ADD_imm32_r32( pc + disp + 4 - sh4_x86.block_start_pc, R_EAX );2.113 + store_spreg( R_EAX, R_NEW_PC );2.114 + exit_block_emu(pc+2);2.115 + return 2;2.116 + } else {2.117 + sh4_translate_instruction( pc + 2 );2.118 + exit_block_rel( disp + pc + 4, pc+4 );2.119 + return 4;2.120 + }2.121 }2.122 :}2.123 BRAF Rn {:2.124 @@ -1462,10 +1493,15 @@2.125 store_spreg( R_EAX, R_NEW_PC );2.126 sh4_x86.in_delay_slot = DELAY_PC;2.127 sh4_x86.tstate = TSTATE_NONE;2.128 - sh4_translate_instruction( pc + 2 );2.129 - exit_block_newpcset(pc+2);2.130 sh4_x86.branch_taken = TRUE;2.131 - return 4;2.132 + if( UNTRANSLATABLE(pc+2) ) {2.133 + exit_block_emu(pc+2);2.134 + return 2;2.135 + } else {2.136 + sh4_translate_instruction( pc + 2 );2.137 + exit_block_newpcset(pc+2);2.138 + return 4;2.139 + }2.140 }2.141 :}2.142 BSR disp {:2.143 @@ -1476,10 +1512,18 @@2.144 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );2.145 store_spreg( R_EAX, R_PR );2.146 sh4_x86.in_delay_slot = DELAY_PC;2.147 - sh4_translate_instruction( pc + 2 );2.148 - exit_block_rel( disp + pc + 4, pc+4 );2.149 sh4_x86.branch_taken = TRUE;2.150 - return 4;2.151 + sh4_x86.tstate = TSTATE_NONE;2.152 + if( UNTRANSLATABLE(pc+2) ) {2.153 + ADD_imm32_r32( disp, R_EAX );2.154 + store_spreg( R_EAX, R_NEW_PC );2.155 + exit_block_emu(pc+2);2.156 + return 2;2.157 + } else {2.158 + sh4_translate_instruction( pc + 2 );2.159 + exit_block_rel( disp + pc + 4, pc+4 );2.160 + return 4;2.161 + }2.162 }2.163 :}2.164 BSRF Rn {:2.165 @@ -1492,11 +1536,17 @@2.166 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );2.167 store_spreg( R_EAX, R_NEW_PC );2.169 + sh4_x86.in_delay_slot = DELAY_PC;2.170 sh4_x86.tstate = TSTATE_NONE;2.171 - sh4_translate_instruction( pc + 2 );2.172 - exit_block_newpcset(pc+2);2.173 sh4_x86.branch_taken = TRUE;2.174 - return 4;2.175 + if( UNTRANSLATABLE(pc+2) ) {2.176 + exit_block_emu(pc+2);2.177 + return 2;2.178 + } else {2.179 + sh4_translate_instruction( pc + 2 );2.180 + exit_block_newpcset(pc+2);2.181 + return 4;2.182 + }2.183 }2.184 :}2.185 BT disp {:2.186 @@ -1515,17 +1565,29 @@2.187 SLOTILLEGAL();2.188 } else {2.189 sh4_x86.in_delay_slot = DELAY_PC;2.190 - if( sh4_x86.tstate == TSTATE_NONE ) {2.191 - CMP_imm8s_sh4r( 1, R_T );2.192 - sh4_x86.tstate = TSTATE_E;2.193 + if( UNTRANSLATABLE(pc+2) ) {2.194 + load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );2.195 + JF_rel8(6,nottaken);2.196 + ADD_imm32_r32( disp, R_EAX );2.197 + JMP_TARGET(nottaken);2.198 + ADD_sh4r_r32( R_PC, R_EAX );2.199 + store_spreg( R_EAX, R_NEW_PC );2.200 + exit_block_emu(pc+2);2.201 + sh4_x86.branch_taken = TRUE;2.202 + return 2;2.203 + } else {2.204 + if( sh4_x86.tstate == TSTATE_NONE ) {2.205 + CMP_imm8s_sh4r( 1, R_T );2.206 + sh4_x86.tstate = TSTATE_E;2.207 + }2.208 + OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JF rel322.209 + sh4_translate_instruction(pc+2);2.210 + exit_block_rel( disp + pc + 4, pc+4 );2.211 + // not taken2.212 + *patch = (xlat_output - ((uint8_t *)patch)) - 4;2.213 + sh4_translate_instruction(pc+2);2.214 + return 4;2.215 }2.216 - OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel322.217 - sh4_translate_instruction(pc+2);2.218 - exit_block_rel( disp + pc + 4, pc+4 );2.219 - // not taken2.220 - *patch = (xlat_output - ((uint8_t *)patch)) - 4;2.221 - sh4_translate_instruction(pc+2);2.222 - return 4;2.223 }2.224 :}2.225 JMP @Rn {:2.226 @@ -1535,10 +1597,15 @@2.227 load_reg( R_ECX, Rn );2.228 store_spreg( R_ECX, R_NEW_PC );2.229 sh4_x86.in_delay_slot = DELAY_PC;2.230 - sh4_translate_instruction(pc+2);2.231 - exit_block_newpcset(pc+2);2.232 sh4_x86.branch_taken = TRUE;2.233 - return 4;2.234 + if( UNTRANSLATABLE(pc+2) ) {2.235 + exit_block_emu(pc+2);2.236 + return 2;2.237 + } else {2.238 + sh4_translate_instruction(pc+2);2.239 + exit_block_newpcset(pc+2);2.240 + return 4;2.241 + }2.242 }2.243 :}2.244 JSR @Rn {:2.245 @@ -1550,10 +1617,17 @@2.246 store_spreg( R_EAX, R_PR );2.247 load_reg( R_ECX, Rn );2.248 store_spreg( R_ECX, R_NEW_PC );2.249 - sh4_translate_instruction(pc+2);2.250 - exit_block_newpcset(pc+2);2.251 + sh4_x86.in_delay_slot = DELAY_PC;2.252 sh4_x86.branch_taken = TRUE;2.253 - return 4;2.254 + sh4_x86.tstate = TSTATE_NONE;2.255 + if( UNTRANSLATABLE(pc+2) ) {2.256 + exit_block_emu(pc+2);2.257 + return 2;2.258 + } else {2.259 + sh4_translate_instruction(pc+2);2.260 + exit_block_newpcset(pc+2);2.261 + return 4;2.262 + }2.263 }2.264 :}2.265 RTE {:2.266 @@ -1569,10 +1643,15 @@2.267 sh4_x86.priv_checked = FALSE;2.268 sh4_x86.fpuen_checked = FALSE;2.269 sh4_x86.tstate = TSTATE_NONE;2.270 - sh4_translate_instruction(pc+2);2.271 - exit_block_newpcset(pc+2);2.272 sh4_x86.branch_taken = TRUE;2.273 - return 4;2.274 + if( UNTRANSLATABLE(pc+2) ) {2.275 + exit_block_emu(pc+2);2.276 + return 2;2.277 + } else {2.278 + sh4_translate_instruction(pc+2);2.279 + exit_block_newpcset(pc+2);2.280 + return 4;2.281 + }2.282 }2.283 :}2.284 RTS {:2.285 @@ -1582,10 +1661,15 @@2.286 load_spreg( R_ECX, R_PR );2.287 store_spreg( R_ECX, R_NEW_PC );2.288 sh4_x86.in_delay_slot = DELAY_PC;2.289 - sh4_translate_instruction(pc+2);2.290 - exit_block_newpcset(pc+2);2.291 sh4_x86.branch_taken = TRUE;2.292 - return 4;2.293 + if( UNTRANSLATABLE(pc+2) ) {2.294 + exit_block_emu(pc+2);2.295 + return 2;2.296 + } else {2.297 + sh4_translate_instruction(pc+2);2.298 + exit_block_newpcset(pc+2);2.299 + return 4;2.300 + }2.301 }2.302 :}2.303 TRAPA #imm {:
3.1 --- a/src/sh4/x86op.h Tue Jan 22 10:10:46 2008 +00003.2 +++ b/src/sh4/x86op.h Tue Jan 22 10:11:45 2008 +00003.3 @@ -55,6 +55,8 @@3.4 #define OP64(x) *((uint64_t *)xlat_output) = (x); xlat_output+=83.5 #if SH4_TRANSLATOR == TARGET_X86_643.6 #define OPPTR(x) OP64((uint64_t)(x))3.7 +#define AND_imm8s_rptr(imm, r1) REXW(); AND_imm8s_r32( imm, r1 )3.8 +#define MOV_moffptr_EAX(offptr) REXW(); MOV_moff32_EAX( offptr )3.9 #define STACK_ALIGN 163.10 #define POP_r32(r1) OP(0x58 + r1);3.11 #define POP_realigned_r32(r1) OP(0x58 + r1); REXW(); ADD_imm8s_r32(8,R_ESP)3.12 @@ -64,6 +66,8 @@3.13 #define PUSH_imm64(imm) REXW(); OP(0x68); OP64(imm);3.14 #else3.15 #define OPPTR(x) OP32((uint32_t)(x))3.16 +#define AND_imm8s_rptr(imm, r1) AND_imm8s_r32( imm, r1 )3.17 +#define MOV_moffptr_EAX(offptr) MOV_moff32_EAX( offptr )3.18 #define POP_realigned_r32(r1) POP_r32(r1)3.19 #define PUSH_realigned_r32(r1) PUSH_r32(r1)3.20 #ifdef APPLE_BUILD
.