filename | src/sh4/sh4x86.in |
changeset | 601:d8d1af0d133c |
prev | 596:dfc0c93d882e |
next | 604:1024c3a9cb88 |
author | nkeynes |
date | Tue Jan 22 10:11:45 2008 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Invoke emulator single-step for untranslatable delay slots (and fix a few related bugs) |
file | annotate | diff | log | raw |
1.1 --- a/src/sh4/sh4x86.in Mon Jan 21 11:59:46 2008 +00001.2 +++ b/src/sh4/sh4x86.in 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 @@ -987,7 +997,7 @@1.50 :}1.51 SWAP.B Rm, Rn {:1.52 load_reg( R_EAX, Rm );1.53 - XCHG_r8_r8( R_AL, R_AH );1.54 + XCHG_r8_r8( R_AL, R_AH ); // NB: does not touch EFLAGS1.55 store_reg( R_EAX, Rn );1.56 :}1.57 SWAP.W Rm, Rn {:1.58 @@ -1426,19 +1436,32 @@1.59 if( sh4_x86.in_delay_slot ) {1.60 SLOTILLEGAL();1.61 } else {1.62 - sh4vma_t target = disp + pc + 4;1.63 sh4_x86.in_delay_slot = DELAY_PC;1.64 - if( sh4_x86.tstate == TSTATE_NONE ) {1.65 - CMP_imm8s_sh4r( 1, R_T );1.66 - sh4_x86.tstate = TSTATE_E;1.67 + if( UNTRANSLATABLE(pc+2) ) {1.68 + load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );1.69 + JT_rel8(6,nottaken);1.70 + ADD_imm32_r32( disp, R_EAX );1.71 + JMP_TARGET(nottaken);1.72 + ADD_sh4r_r32( R_PC, R_EAX );1.73 + store_spreg( R_EAX, R_NEW_PC );1.74 + exit_block_emu(pc+2);1.75 + sh4_x86.branch_taken = TRUE;1.76 + return 2;1.77 + } else {1.78 + if( sh4_x86.tstate == TSTATE_NONE ) {1.79 + CMP_imm8s_sh4r( 1, R_T );1.80 + sh4_x86.tstate = TSTATE_E;1.81 + }1.82 + sh4vma_t target = disp + pc + 4;1.83 + OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JT rel321.84 + sh4_translate_instruction(pc+2);1.85 + exit_block_rel( target, pc+4 );1.86 +1.87 + // not taken1.88 + *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.89 + sh4_translate_instruction(pc+2);1.90 + return 4;1.91 }1.92 - OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel321.93 - sh4_translate_instruction(pc+2);1.94 - exit_block_rel( target, pc+4 );1.95 - // not taken1.96 - *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.97 - sh4_translate_instruction(pc+2);1.98 - return 4;1.99 }1.100 :}1.101 BRA disp {:1.102 @@ -1446,10 +1469,18 @@1.103 SLOTILLEGAL();1.104 } else {1.105 sh4_x86.in_delay_slot = DELAY_PC;1.106 - sh4_translate_instruction( pc + 2 );1.107 - exit_block_rel( disp + pc + 4, pc+4 );1.108 sh4_x86.branch_taken = TRUE;1.109 - return 4;1.110 + if( UNTRANSLATABLE(pc+2) ) {1.111 + load_spreg( R_EAX, R_PC );1.112 + ADD_imm32_r32( pc + disp + 4 - sh4_x86.block_start_pc, R_EAX );1.113 + store_spreg( R_EAX, R_NEW_PC );1.114 + exit_block_emu(pc+2);1.115 + return 2;1.116 + } else {1.117 + sh4_translate_instruction( pc + 2 );1.118 + exit_block_rel( disp + pc + 4, pc+4 );1.119 + return 4;1.120 + }1.121 }1.122 :}1.123 BRAF Rn {:1.124 @@ -1462,10 +1493,15 @@1.125 store_spreg( R_EAX, R_NEW_PC );1.126 sh4_x86.in_delay_slot = DELAY_PC;1.127 sh4_x86.tstate = TSTATE_NONE;1.128 - sh4_translate_instruction( pc + 2 );1.129 - exit_block_newpcset(pc+2);1.130 sh4_x86.branch_taken = TRUE;1.131 - return 4;1.132 + if( UNTRANSLATABLE(pc+2) ) {1.133 + exit_block_emu(pc+2);1.134 + return 2;1.135 + } else {1.136 + sh4_translate_instruction( pc + 2 );1.137 + exit_block_newpcset(pc+2);1.138 + return 4;1.139 + }1.140 }1.141 :}1.142 BSR disp {:1.143 @@ -1476,10 +1512,18 @@1.144 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );1.145 store_spreg( R_EAX, R_PR );1.146 sh4_x86.in_delay_slot = DELAY_PC;1.147 - sh4_translate_instruction( pc + 2 );1.148 - exit_block_rel( disp + pc + 4, pc+4 );1.149 sh4_x86.branch_taken = TRUE;1.150 - return 4;1.151 + sh4_x86.tstate = TSTATE_NONE;1.152 + if( UNTRANSLATABLE(pc+2) ) {1.153 + ADD_imm32_r32( disp, R_EAX );1.154 + store_spreg( R_EAX, R_NEW_PC );1.155 + exit_block_emu(pc+2);1.156 + return 2;1.157 + } else {1.158 + sh4_translate_instruction( pc + 2 );1.159 + exit_block_rel( disp + pc + 4, pc+4 );1.160 + return 4;1.161 + }1.162 }1.163 :}1.164 BSRF Rn {:1.165 @@ -1492,11 +1536,17 @@1.166 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );1.167 store_spreg( R_EAX, R_NEW_PC );1.169 + sh4_x86.in_delay_slot = DELAY_PC;1.170 sh4_x86.tstate = TSTATE_NONE;1.171 - sh4_translate_instruction( pc + 2 );1.172 - exit_block_newpcset(pc+2);1.173 sh4_x86.branch_taken = TRUE;1.174 - return 4;1.175 + if( UNTRANSLATABLE(pc+2) ) {1.176 + exit_block_emu(pc+2);1.177 + return 2;1.178 + } else {1.179 + sh4_translate_instruction( pc + 2 );1.180 + exit_block_newpcset(pc+2);1.181 + return 4;1.182 + }1.183 }1.184 :}1.185 BT disp {:1.186 @@ -1515,17 +1565,29 @@1.187 SLOTILLEGAL();1.188 } else {1.189 sh4_x86.in_delay_slot = DELAY_PC;1.190 - if( sh4_x86.tstate == TSTATE_NONE ) {1.191 - CMP_imm8s_sh4r( 1, R_T );1.192 - sh4_x86.tstate = TSTATE_E;1.193 + if( UNTRANSLATABLE(pc+2) ) {1.194 + load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );1.195 + JF_rel8(6,nottaken);1.196 + ADD_imm32_r32( disp, R_EAX );1.197 + JMP_TARGET(nottaken);1.198 + ADD_sh4r_r32( R_PC, R_EAX );1.199 + store_spreg( R_EAX, R_NEW_PC );1.200 + exit_block_emu(pc+2);1.201 + sh4_x86.branch_taken = TRUE;1.202 + return 2;1.203 + } else {1.204 + if( sh4_x86.tstate == TSTATE_NONE ) {1.205 + CMP_imm8s_sh4r( 1, R_T );1.206 + sh4_x86.tstate = TSTATE_E;1.207 + }1.208 + OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JF rel321.209 + sh4_translate_instruction(pc+2);1.210 + exit_block_rel( disp + pc + 4, pc+4 );1.211 + // not taken1.212 + *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.213 + sh4_translate_instruction(pc+2);1.214 + return 4;1.215 }1.216 - OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel321.217 - sh4_translate_instruction(pc+2);1.218 - exit_block_rel( disp + pc + 4, pc+4 );1.219 - // not taken1.220 - *patch = (xlat_output - ((uint8_t *)patch)) - 4;1.221 - sh4_translate_instruction(pc+2);1.222 - return 4;1.223 }1.224 :}1.225 JMP @Rn {:1.226 @@ -1535,10 +1597,15 @@1.227 load_reg( R_ECX, Rn );1.228 store_spreg( R_ECX, R_NEW_PC );1.229 sh4_x86.in_delay_slot = DELAY_PC;1.230 - sh4_translate_instruction(pc+2);1.231 - exit_block_newpcset(pc+2);1.232 sh4_x86.branch_taken = TRUE;1.233 - return 4;1.234 + if( UNTRANSLATABLE(pc+2) ) {1.235 + exit_block_emu(pc+2);1.236 + return 2;1.237 + } else {1.238 + sh4_translate_instruction(pc+2);1.239 + exit_block_newpcset(pc+2);1.240 + return 4;1.241 + }1.242 }1.243 :}1.244 JSR @Rn {:1.245 @@ -1550,10 +1617,17 @@1.246 store_spreg( R_EAX, R_PR );1.247 load_reg( R_ECX, Rn );1.248 store_spreg( R_ECX, R_NEW_PC );1.249 - sh4_translate_instruction(pc+2);1.250 - exit_block_newpcset(pc+2);1.251 + sh4_x86.in_delay_slot = DELAY_PC;1.252 sh4_x86.branch_taken = TRUE;1.253 - return 4;1.254 + sh4_x86.tstate = TSTATE_NONE;1.255 + if( UNTRANSLATABLE(pc+2) ) {1.256 + exit_block_emu(pc+2);1.257 + return 2;1.258 + } else {1.259 + sh4_translate_instruction(pc+2);1.260 + exit_block_newpcset(pc+2);1.261 + return 4;1.262 + }1.263 }1.264 :}1.265 RTE {:1.266 @@ -1569,10 +1643,15 @@1.267 sh4_x86.priv_checked = FALSE;1.268 sh4_x86.fpuen_checked = FALSE;1.269 sh4_x86.tstate = TSTATE_NONE;1.270 - sh4_translate_instruction(pc+2);1.271 - exit_block_newpcset(pc+2);1.272 sh4_x86.branch_taken = TRUE;1.273 - return 4;1.274 + if( UNTRANSLATABLE(pc+2) ) {1.275 + exit_block_emu(pc+2);1.276 + return 2;1.277 + } else {1.278 + sh4_translate_instruction(pc+2);1.279 + exit_block_newpcset(pc+2);1.280 + return 4;1.281 + }1.282 }1.283 :}1.284 RTS {:1.285 @@ -1582,10 +1661,15 @@1.286 load_spreg( R_ECX, R_PR );1.287 store_spreg( R_ECX, R_NEW_PC );1.288 sh4_x86.in_delay_slot = DELAY_PC;1.289 - sh4_translate_instruction(pc+2);1.290 - exit_block_newpcset(pc+2);1.291 sh4_x86.branch_taken = TRUE;1.292 - return 4;1.293 + if( UNTRANSLATABLE(pc+2) ) {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_newpcset(pc+2);1.299 + return 4;1.300 + }1.301 }1.302 :}1.303 TRAPA #imm {:
.