Search
lxdream.org :: lxdream/src/sh4/sh4x86.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.c
changeset 416:714df603c869
prev409:549e00835448
next417:bd927df302a9
author nkeynes
date Wed Oct 03 12:19:03 2007 +0000 (14 years ago)
permissions -rw-r--r--
last change Remove INC %esi (and esi in general), replace with load immediates (faster)
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.c Sat Sep 29 05:33:02 2007 +0000
1.2 +++ b/src/sh4/sh4x86.c Wed Oct 03 12:19:03 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4x86.c,v 1.16 2007-09-29 05:33:02 nkeynes Exp $
1.6 + * $Id: sh4x86.c,v 1.17 2007-10-03 12:19:03 nkeynes Exp $
1.7 *
1.8 * SH4 => x86 translation. This version does no real optimization, it just
1.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
1.10 @@ -293,7 +293,23 @@
1.11 }
1.12
1.13 /* Exception checks - Note that all exception checks will clobber EAX */
1.14 -static void check_priv( )
1.15 +#define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
1.16 +
1.17 +#define check_priv( ) \
1.18 + if( !sh4_x86.priv_checked ) { \
1.19 + sh4_x86.priv_checked = TRUE;\
1.20 + precheck();\
1.21 + load_spreg( R_EAX, R_SR );\
1.22 + AND_imm32_r32( SR_MD, R_EAX );\
1.23 + if( sh4_x86.in_delay_slot ) {\
1.24 + JE_exit( EXIT_SLOT_ILLEGAL );\
1.25 + } else {\
1.26 + JE_exit( EXIT_ILLEGAL );\
1.27 + }\
1.28 + }\
1.29 +
1.30 +
1.31 +static void check_priv_no_precheck()
1.32 {
1.33 if( !sh4_x86.priv_checked ) {
1.34 sh4_x86.priv_checked = TRUE;
1.35 @@ -307,7 +323,20 @@
1.36 }
1.37 }
1.38
1.39 -static void check_fpuen( )
1.40 +#define check_fpuen( ) \
1.41 + if( !sh4_x86.fpuen_checked ) {\
1.42 + sh4_x86.fpuen_checked = TRUE;\
1.43 + precheck();\
1.44 + load_spreg( R_EAX, R_SR );\
1.45 + AND_imm32_r32( SR_FD, R_EAX );\
1.46 + if( sh4_x86.in_delay_slot ) {\
1.47 + JNE_exit(EXIT_SLOT_FPU_DISABLED);\
1.48 + } else {\
1.49 + JNE_exit(EXIT_FPU_DISABLED);\
1.50 + }\
1.51 + }
1.52 +
1.53 +static void check_fpuen_no_precheck()
1.54 {
1.55 if( !sh4_x86.fpuen_checked ) {
1.56 sh4_x86.fpuen_checked = TRUE;
1.57 @@ -319,6 +348,7 @@
1.58 JNE_exit(EXIT_FPU_DISABLED);
1.59 }
1.60 }
1.61 +
1.62 }
1.63
1.64 static void check_ralign16( int x86reg )
1.65 @@ -353,7 +383,7 @@
1.66 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
1.67 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
1.68
1.69 -#define SLOTILLEGAL() JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.70 +#define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.71
1.72
1.73
1.74 @@ -366,8 +396,6 @@
1.75 PUSH_r32(R_EBP);
1.76 /* mov &sh4r, ebp */
1.77 load_imm32( R_EBP, (uint32_t)&sh4r );
1.78 - PUSH_r32(R_ESI);
1.79 - XOR_r32_r32(R_ESI, R_ESI);
1.80
1.81 sh4_x86.in_delay_slot = FALSE;
1.82 sh4_x86.priv_checked = FALSE;
1.83 @@ -379,7 +407,7 @@
1.84
1.85 /**
1.86 * Exit the block to an absolute PC
1.87 - * Bytes: 30
1.88 + * Bytes: 29
1.89 */
1.90 void exit_block( sh4addr_t pc, sh4addr_t endpc )
1.91 {
1.92 @@ -389,21 +417,19 @@
1.93 AND_imm8s_r32( 0xFC, R_EAX ); // 3
1.94 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
1.95 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
1.96 - POP_r32(R_ESI);
1.97 POP_r32(R_EBP);
1.98 RET();
1.99 }
1.100
1.101 /**
1.102 * Exit the block with sh4r.pc already written
1.103 - * Bytes: 16
1.104 + * Bytes: 15
1.105 */
1.106 void exit_block_pcset( pc )
1.107 {
1.108 XOR_r32_r32( R_EAX, R_EAX ); // 2
1.109 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
1.110 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
1.111 - POP_r32(R_ESI);
1.112 POP_r32(R_EBP);
1.113 RET();
1.114 }
1.115 @@ -437,12 +463,12 @@
1.116 JMP_TARGET(target4);
1.117 JMP_TARGET(target5);
1.118 load_spreg( R_ECX, REG_OFFSET(pc) );
1.119 - ADD_r32_r32( R_ESI, R_ECX );
1.120 - ADD_r32_r32( R_ESI, R_ECX );
1.121 + ADD_r32_r32( R_EDX, R_ECX );
1.122 + ADD_r32_r32( R_EDX, R_ECX );
1.123 store_spreg( R_ECX, REG_OFFSET(pc) );
1.124 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
1.125 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
1.126 - MUL_r32( R_ESI );
1.127 + MUL_r32( R_EDX );
1.128 ADD_r32_r32( R_EAX, R_ECX );
1.129 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
1.130
1.131 @@ -450,7 +476,6 @@
1.132 CALL_r32( R_EAX ); // 2
1.133 ADD_imm8s_r32( 4, R_ESP );
1.134 XOR_r32_r32( R_EAX, R_EAX );
1.135 - POP_r32(R_ESI);
1.136 POP_r32(R_EBP);
1.137 RET();
1.138
1.139 @@ -623,6 +648,7 @@
1.140 uint32_t Rn = ((ir>>8)&0xF);
1.141 load_reg( R_EAX, 0 );
1.142 load_reg( R_ECX, Rn );
1.143 + precheck();
1.144 check_walign32( R_ECX );
1.145 MEM_WRITE_LONG( R_ECX, R_EAX );
1.146 }
1.147 @@ -648,6 +674,7 @@
1.148 load_reg( R_EAX, 0 );
1.149 load_reg( R_ECX, Rn );
1.150 ADD_r32_r32( R_EAX, R_ECX );
1.151 + precheck();
1.152 check_walign16( R_ECX );
1.153 load_reg( R_EAX, Rm );
1.154 MEM_WRITE_WORD( R_ECX, R_EAX );
1.155 @@ -659,6 +686,7 @@
1.156 load_reg( R_EAX, 0 );
1.157 load_reg( R_ECX, Rn );
1.158 ADD_r32_r32( R_EAX, R_ECX );
1.159 + precheck();
1.160 check_walign32( R_ECX );
1.161 load_reg( R_EAX, Rm );
1.162 MEM_WRITE_LONG( R_ECX, R_EAX );
1.163 @@ -822,7 +850,6 @@
1.164 check_priv();
1.165 call_func0( sh4_sleep );
1.166 sh4_x86.in_delay_slot = FALSE;
1.167 - INC_r32(R_ESI);
1.168 return 2;
1.169 }
1.170 break;
1.171 @@ -867,6 +894,7 @@
1.172 load_reg( R_EAX, 0 );
1.173 load_reg( R_ECX, Rm );
1.174 ADD_r32_r32( R_EAX, R_ECX );
1.175 + precheck();
1.176 check_ralign16( R_ECX );
1.177 MEM_READ_WORD( R_ECX, R_EAX );
1.178 store_reg( R_EAX, Rn );
1.179 @@ -878,6 +906,7 @@
1.180 load_reg( R_EAX, 0 );
1.181 load_reg( R_ECX, Rm );
1.182 ADD_r32_r32( R_EAX, R_ECX );
1.183 + precheck();
1.184 check_ralign32( R_ECX );
1.185 MEM_READ_LONG( R_ECX, R_EAX );
1.186 store_reg( R_EAX, Rn );
1.187 @@ -887,6 +916,7 @@
1.188 { /* MAC.L @Rm+, @Rn+ */
1.189 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.190 load_reg( R_ECX, Rm );
1.191 + precheck();
1.192 check_ralign32( R_ECX );
1.193 load_reg( R_ECX, Rn );
1.194 check_ralign32( R_ECX );
1.195 @@ -919,6 +949,7 @@
1.196 load_reg( R_ECX, Rn );
1.197 load_reg( R_EAX, Rm );
1.198 ADD_imm32_r32( disp, R_ECX );
1.199 + precheck();
1.200 check_walign32( R_ECX );
1.201 MEM_WRITE_LONG( R_ECX, R_EAX );
1.202 }
1.203 @@ -937,6 +968,7 @@
1.204 { /* MOV.W Rm, @Rn */
1.205 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.206 load_reg( R_ECX, Rn );
1.207 + precheck();
1.208 check_walign16( R_ECX );
1.209 load_reg( R_EAX, Rm );
1.210 MEM_WRITE_WORD( R_ECX, R_EAX );
1.211 @@ -947,6 +979,7 @@
1.212 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.213 load_reg( R_EAX, Rm );
1.214 load_reg( R_ECX, Rn );
1.215 + precheck();
1.216 check_walign32(R_ECX);
1.217 MEM_WRITE_LONG( R_ECX, R_EAX );
1.218 }
1.219 @@ -965,6 +998,7 @@
1.220 { /* MOV.W Rm, @-Rn */
1.221 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.222 load_reg( R_ECX, Rn );
1.223 + precheck();
1.224 check_walign16( R_ECX );
1.225 load_reg( R_EAX, Rm );
1.226 ADD_imm8s_r32( -2, R_ECX );
1.227 @@ -977,6 +1011,7 @@
1.228 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.229 load_reg( R_EAX, Rm );
1.230 load_reg( R_ECX, Rn );
1.231 + precheck();
1.232 check_walign32( R_ECX );
1.233 ADD_imm8s_r32( -4, R_ECX );
1.234 store_reg( R_ECX, Rn );
1.235 @@ -1318,6 +1353,7 @@
1.236 { /* STS.L MACH, @-Rn */
1.237 uint32_t Rn = ((ir>>8)&0xF);
1.238 load_reg( R_ECX, Rn );
1.239 + precheck();
1.240 check_walign32( R_ECX );
1.241 ADD_imm8s_r32( -4, R_ECX );
1.242 store_reg( R_ECX, Rn );
1.243 @@ -1329,6 +1365,7 @@
1.244 { /* STS.L MACL, @-Rn */
1.245 uint32_t Rn = ((ir>>8)&0xF);
1.246 load_reg( R_ECX, Rn );
1.247 + precheck();
1.248 check_walign32( R_ECX );
1.249 ADD_imm8s_r32( -4, R_ECX );
1.250 store_reg( R_ECX, Rn );
1.251 @@ -1340,6 +1377,7 @@
1.252 { /* STS.L PR, @-Rn */
1.253 uint32_t Rn = ((ir>>8)&0xF);
1.254 load_reg( R_ECX, Rn );
1.255 + precheck();
1.256 check_walign32( R_ECX );
1.257 ADD_imm8s_r32( -4, R_ECX );
1.258 store_reg( R_ECX, Rn );
1.259 @@ -1350,7 +1388,8 @@
1.260 case 0x3:
1.261 { /* STC.L SGR, @-Rn */
1.262 uint32_t Rn = ((ir>>8)&0xF);
1.263 - check_priv();
1.264 + precheck();
1.265 + check_priv_no_precheck();
1.266 load_reg( R_ECX, Rn );
1.267 check_walign32( R_ECX );
1.268 ADD_imm8s_r32( -4, R_ECX );
1.269 @@ -1363,6 +1402,7 @@
1.270 { /* STS.L FPUL, @-Rn */
1.271 uint32_t Rn = ((ir>>8)&0xF);
1.272 load_reg( R_ECX, Rn );
1.273 + precheck();
1.274 check_walign32( R_ECX );
1.275 ADD_imm8s_r32( -4, R_ECX );
1.276 store_reg( R_ECX, Rn );
1.277 @@ -1374,6 +1414,7 @@
1.278 { /* STS.L FPSCR, @-Rn */
1.279 uint32_t Rn = ((ir>>8)&0xF);
1.280 load_reg( R_ECX, Rn );
1.281 + precheck();
1.282 check_walign32( R_ECX );
1.283 ADD_imm8s_r32( -4, R_ECX );
1.284 store_reg( R_ECX, Rn );
1.285 @@ -1384,7 +1425,8 @@
1.286 case 0xF:
1.287 { /* STC.L DBR, @-Rn */
1.288 uint32_t Rn = ((ir>>8)&0xF);
1.289 - check_priv();
1.290 + precheck();
1.291 + check_priv_no_precheck();
1.292 load_reg( R_ECX, Rn );
1.293 check_walign32( R_ECX );
1.294 ADD_imm8s_r32( -4, R_ECX );
1.295 @@ -1405,7 +1447,8 @@
1.296 case 0x0:
1.297 { /* STC.L SR, @-Rn */
1.298 uint32_t Rn = ((ir>>8)&0xF);
1.299 - check_priv();
1.300 + precheck();
1.301 + check_priv_no_precheck();
1.302 call_func0( sh4_read_sr );
1.303 load_reg( R_ECX, Rn );
1.304 check_walign32( R_ECX );
1.305 @@ -1418,6 +1461,7 @@
1.306 { /* STC.L GBR, @-Rn */
1.307 uint32_t Rn = ((ir>>8)&0xF);
1.308 load_reg( R_ECX, Rn );
1.309 + precheck();
1.310 check_walign32( R_ECX );
1.311 ADD_imm8s_r32( -4, R_ECX );
1.312 store_reg( R_ECX, Rn );
1.313 @@ -1428,7 +1472,8 @@
1.314 case 0x2:
1.315 { /* STC.L VBR, @-Rn */
1.316 uint32_t Rn = ((ir>>8)&0xF);
1.317 - check_priv();
1.318 + precheck();
1.319 + check_priv_no_precheck();
1.320 load_reg( R_ECX, Rn );
1.321 check_walign32( R_ECX );
1.322 ADD_imm8s_r32( -4, R_ECX );
1.323 @@ -1440,7 +1485,8 @@
1.324 case 0x3:
1.325 { /* STC.L SSR, @-Rn */
1.326 uint32_t Rn = ((ir>>8)&0xF);
1.327 - check_priv();
1.328 + precheck();
1.329 + check_priv_no_precheck();
1.330 load_reg( R_ECX, Rn );
1.331 check_walign32( R_ECX );
1.332 ADD_imm8s_r32( -4, R_ECX );
1.333 @@ -1452,7 +1498,8 @@
1.334 case 0x4:
1.335 { /* STC.L SPC, @-Rn */
1.336 uint32_t Rn = ((ir>>8)&0xF);
1.337 - check_priv();
1.338 + precheck();
1.339 + check_priv_no_precheck();
1.340 load_reg( R_ECX, Rn );
1.341 check_walign32( R_ECX );
1.342 ADD_imm8s_r32( -4, R_ECX );
1.343 @@ -1469,7 +1516,8 @@
1.344 case 0x1:
1.345 { /* STC.L Rm_BANK, @-Rn */
1.346 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1.347 - check_priv();
1.348 + precheck();
1.349 + check_priv_no_precheck();
1.350 load_reg( R_ECX, Rn );
1.351 check_walign32( R_ECX );
1.352 ADD_imm8s_r32( -4, R_ECX );
1.353 @@ -1546,6 +1594,7 @@
1.354 { /* LDS.L @Rm+, MACH */
1.355 uint32_t Rm = ((ir>>8)&0xF);
1.356 load_reg( R_EAX, Rm );
1.357 + precheck();
1.358 check_ralign32( R_EAX );
1.359 MOV_r32_r32( R_EAX, R_ECX );
1.360 ADD_imm8s_r32( 4, R_EAX );
1.361 @@ -1558,6 +1607,7 @@
1.362 { /* LDS.L @Rm+, MACL */
1.363 uint32_t Rm = ((ir>>8)&0xF);
1.364 load_reg( R_EAX, Rm );
1.365 + precheck();
1.366 check_ralign32( R_EAX );
1.367 MOV_r32_r32( R_EAX, R_ECX );
1.368 ADD_imm8s_r32( 4, R_EAX );
1.369 @@ -1570,6 +1620,7 @@
1.370 { /* LDS.L @Rm+, PR */
1.371 uint32_t Rm = ((ir>>8)&0xF);
1.372 load_reg( R_EAX, Rm );
1.373 + precheck();
1.374 check_ralign32( R_EAX );
1.375 MOV_r32_r32( R_EAX, R_ECX );
1.376 ADD_imm8s_r32( 4, R_EAX );
1.377 @@ -1581,7 +1632,8 @@
1.378 case 0x3:
1.379 { /* LDC.L @Rm+, SGR */
1.380 uint32_t Rm = ((ir>>8)&0xF);
1.381 - check_priv();
1.382 + precheck();
1.383 + check_priv_no_precheck();
1.384 load_reg( R_EAX, Rm );
1.385 check_ralign32( R_EAX );
1.386 MOV_r32_r32( R_EAX, R_ECX );
1.387 @@ -1595,6 +1647,7 @@
1.388 { /* LDS.L @Rm+, FPUL */
1.389 uint32_t Rm = ((ir>>8)&0xF);
1.390 load_reg( R_EAX, Rm );
1.391 + precheck();
1.392 check_ralign32( R_EAX );
1.393 MOV_r32_r32( R_EAX, R_ECX );
1.394 ADD_imm8s_r32( 4, R_EAX );
1.395 @@ -1607,6 +1660,7 @@
1.396 { /* LDS.L @Rm+, FPSCR */
1.397 uint32_t Rm = ((ir>>8)&0xF);
1.398 load_reg( R_EAX, Rm );
1.399 + precheck();
1.400 check_ralign32( R_EAX );
1.401 MOV_r32_r32( R_EAX, R_ECX );
1.402 ADD_imm8s_r32( 4, R_EAX );
1.403 @@ -1619,7 +1673,8 @@
1.404 case 0xF:
1.405 { /* LDC.L @Rm+, DBR */
1.406 uint32_t Rm = ((ir>>8)&0xF);
1.407 - check_priv();
1.408 + precheck();
1.409 + check_priv_no_precheck();
1.410 load_reg( R_EAX, Rm );
1.411 check_ralign32( R_EAX );
1.412 MOV_r32_r32( R_EAX, R_ECX );
1.413 @@ -1644,7 +1699,8 @@
1.414 if( sh4_x86.in_delay_slot ) {
1.415 SLOTILLEGAL();
1.416 } else {
1.417 - check_priv();
1.418 + precheck();
1.419 + check_priv_no_precheck();
1.420 load_reg( R_EAX, Rm );
1.421 check_ralign32( R_EAX );
1.422 MOV_r32_r32( R_EAX, R_ECX );
1.423 @@ -1661,6 +1717,7 @@
1.424 { /* LDC.L @Rm+, GBR */
1.425 uint32_t Rm = ((ir>>8)&0xF);
1.426 load_reg( R_EAX, Rm );
1.427 + precheck();
1.428 check_ralign32( R_EAX );
1.429 MOV_r32_r32( R_EAX, R_ECX );
1.430 ADD_imm8s_r32( 4, R_EAX );
1.431 @@ -1672,7 +1729,8 @@
1.432 case 0x2:
1.433 { /* LDC.L @Rm+, VBR */
1.434 uint32_t Rm = ((ir>>8)&0xF);
1.435 - check_priv();
1.436 + precheck();
1.437 + check_priv_no_precheck();
1.438 load_reg( R_EAX, Rm );
1.439 check_ralign32( R_EAX );
1.440 MOV_r32_r32( R_EAX, R_ECX );
1.441 @@ -1685,8 +1743,10 @@
1.442 case 0x3:
1.443 { /* LDC.L @Rm+, SSR */
1.444 uint32_t Rm = ((ir>>8)&0xF);
1.445 - check_priv();
1.446 + precheck();
1.447 + check_priv_no_precheck();
1.448 load_reg( R_EAX, Rm );
1.449 + check_ralign32( R_EAX );
1.450 MOV_r32_r32( R_EAX, R_ECX );
1.451 ADD_imm8s_r32( 4, R_EAX );
1.452 store_reg( R_EAX, Rm );
1.453 @@ -1697,7 +1757,8 @@
1.454 case 0x4:
1.455 { /* LDC.L @Rm+, SPC */
1.456 uint32_t Rm = ((ir>>8)&0xF);
1.457 - check_priv();
1.458 + precheck();
1.459 + check_priv_no_precheck();
1.460 load_reg( R_EAX, Rm );
1.461 check_ralign32( R_EAX );
1.462 MOV_r32_r32( R_EAX, R_ECX );
1.463 @@ -1715,7 +1776,8 @@
1.464 case 0x1:
1.465 { /* LDC.L @Rm+, Rn_BANK */
1.466 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1.467 - check_priv();
1.468 + precheck();
1.469 + check_priv_no_precheck();
1.470 load_reg( R_EAX, Rm );
1.471 check_ralign32( R_EAX );
1.472 MOV_r32_r32( R_EAX, R_ECX );
1.473 @@ -2022,6 +2084,7 @@
1.474 { /* MAC.W @Rm+, @Rn+ */
1.475 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.476 load_reg( R_ECX, Rm );
1.477 + precheck();
1.478 check_ralign16( R_ECX );
1.479 load_reg( R_ECX, Rn );
1.480 check_ralign16( R_ECX );
1.481 @@ -2067,6 +2130,7 @@
1.482 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1.483 load_reg( R_ECX, Rm );
1.484 ADD_imm8s_r32( disp, R_ECX );
1.485 + precheck();
1.486 check_ralign32( R_ECX );
1.487 MEM_READ_LONG( R_ECX, R_EAX );
1.488 store_reg( R_EAX, Rn );
1.489 @@ -2086,6 +2150,7 @@
1.490 { /* MOV.W @Rm, Rn */
1.491 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.492 load_reg( R_ECX, Rm );
1.493 + precheck();
1.494 check_ralign16( R_ECX );
1.495 MEM_READ_WORD( R_ECX, R_EAX );
1.496 store_reg( R_EAX, Rn );
1.497 @@ -2095,6 +2160,7 @@
1.498 { /* MOV.L @Rm, Rn */
1.499 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.500 load_reg( R_ECX, Rm );
1.501 + precheck();
1.502 check_ralign32( R_ECX );
1.503 MEM_READ_LONG( R_ECX, R_EAX );
1.504 store_reg( R_EAX, Rn );
1.505 @@ -2122,6 +2188,7 @@
1.506 { /* MOV.W @Rm+, Rn */
1.507 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.508 load_reg( R_EAX, Rm );
1.509 + precheck();
1.510 check_ralign16( R_EAX );
1.511 MOV_r32_r32( R_EAX, R_ECX );
1.512 ADD_imm8s_r32( 2, R_EAX );
1.513 @@ -2134,6 +2201,7 @@
1.514 { /* MOV.L @Rm+, Rn */
1.515 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.516 load_reg( R_EAX, Rm );
1.517 + precheck();
1.518 check_ralign32( R_EAX );
1.519 MOV_r32_r32( R_EAX, R_ECX );
1.520 ADD_imm8s_r32( 4, R_EAX );
1.521 @@ -2247,6 +2315,7 @@
1.522 load_reg( R_ECX, Rn );
1.523 load_reg( R_EAX, 0 );
1.524 ADD_imm32_r32( disp, R_ECX );
1.525 + precheck();
1.526 check_walign16( R_ECX );
1.527 MEM_WRITE_WORD( R_ECX, R_EAX );
1.528 }
1.529 @@ -2265,6 +2334,7 @@
1.530 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1.531 load_reg( R_ECX, Rm );
1.532 ADD_imm32_r32( disp, R_ECX );
1.533 + precheck();
1.534 check_ralign16( R_ECX );
1.535 MEM_READ_WORD( R_ECX, R_EAX );
1.536 store_reg( R_EAX, 0 );
1.537 @@ -2285,7 +2355,7 @@
1.538 SLOTILLEGAL();
1.539 } else {
1.540 CMP_imm8s_sh4r( 0, R_T );
1.541 - JE_rel8( 30, nottaken );
1.542 + JE_rel8( 29, nottaken );
1.543 exit_block( disp + pc + 4, pc+2 );
1.544 JMP_TARGET(nottaken);
1.545 return 2;
1.546 @@ -2299,7 +2369,7 @@
1.547 SLOTILLEGAL();
1.548 } else {
1.549 CMP_imm8s_sh4r( 0, R_T );
1.550 - JNE_rel8( 30, nottaken );
1.551 + JNE_rel8( 29, nottaken );
1.552 exit_block( disp + pc + 4, pc+2 );
1.553 JMP_TARGET(nottaken);
1.554 return 2;
1.555 @@ -2406,6 +2476,7 @@
1.556 load_spreg( R_ECX, R_GBR );
1.557 load_reg( R_EAX, 0 );
1.558 ADD_imm32_r32( disp, R_ECX );
1.559 + precheck();
1.560 check_walign16( R_ECX );
1.561 MEM_WRITE_WORD( R_ECX, R_EAX );
1.562 }
1.563 @@ -2416,6 +2487,7 @@
1.564 load_spreg( R_ECX, R_GBR );
1.565 load_reg( R_EAX, 0 );
1.566 ADD_imm32_r32( disp, R_ECX );
1.567 + precheck();
1.568 check_walign32( R_ECX );
1.569 MEM_WRITE_LONG( R_ECX, R_EAX );
1.570 }
1.571 @@ -2449,6 +2521,7 @@
1.572 uint32_t disp = (ir&0xFF)<<1;
1.573 load_spreg( R_ECX, R_GBR );
1.574 ADD_imm32_r32( disp, R_ECX );
1.575 + precheck();
1.576 check_ralign16( R_ECX );
1.577 MEM_READ_WORD( R_ECX, R_EAX );
1.578 store_reg( R_EAX, 0 );
1.579 @@ -2459,6 +2532,7 @@
1.580 uint32_t disp = (ir&0xFF)<<2;
1.581 load_spreg( R_ECX, R_GBR );
1.582 ADD_imm32_r32( disp, R_ECX );
1.583 + precheck();
1.584 check_ralign32( R_ECX );
1.585 MEM_READ_LONG( R_ECX, R_EAX );
1.586 store_reg( R_EAX, 0 );
1.587 @@ -2713,32 +2787,33 @@
1.588 case 0x6:
1.589 { /* FMOV @(R0, Rm), FRn */
1.590 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.591 - check_fpuen();
1.592 - load_reg( R_EDX, Rm );
1.593 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
1.594 - check_ralign32( R_EDX );
1.595 - load_spreg( R_ECX, R_FPSCR );
1.596 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.597 + precheck();
1.598 + check_fpuen_no_precheck();
1.599 + load_reg( R_ECX, Rm );
1.600 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
1.601 + check_ralign32( R_ECX );
1.602 + load_spreg( R_EDX, R_FPSCR );
1.603 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.604 JNE_rel8(19, doublesize);
1.605 - MEM_READ_LONG( R_EDX, R_EAX );
1.606 - load_fr_bank( R_ECX );
1.607 - store_fr( R_ECX, R_EAX, FRn );
1.608 + MEM_READ_LONG( R_ECX, R_EAX );
1.609 + load_fr_bank( R_EDX );
1.610 + store_fr( R_EDX, R_EAX, FRn );
1.611 if( FRn&1 ) {
1.612 JMP_rel8(48, end);
1.613 JMP_TARGET(doublesize);
1.614 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.615 - load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.616 - load_xf_bank( R_ECX );
1.617 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.618 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.619 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.620 + load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.621 + load_xf_bank( R_EDX );
1.622 + store_fr( R_EDX, R_EAX, FRn&0x0E );
1.623 + store_fr( R_EDX, R_ECX, FRn|0x01 );
1.624 JMP_TARGET(end);
1.625 } else {
1.626 JMP_rel8(36, end);
1.627 JMP_TARGET(doublesize);
1.628 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.629 - load_fr_bank( R_ECX );
1.630 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.631 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.632 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.633 + load_fr_bank( R_EDX );
1.634 + store_fr( R_EDX, R_EAX, FRn&0x0E );
1.635 + store_fr( R_EDX, R_ECX, FRn|0x01 );
1.636 JMP_TARGET(end);
1.637 }
1.638 }
1.639 @@ -2746,31 +2821,32 @@
1.640 case 0x7:
1.641 { /* FMOV FRm, @(R0, Rn) */
1.642 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.643 - check_fpuen();
1.644 - load_reg( R_EDX, Rn );
1.645 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
1.646 - check_walign32( R_EDX );
1.647 - load_spreg( R_ECX, R_FPSCR );
1.648 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.649 + precheck();
1.650 + check_fpuen_no_precheck();
1.651 + load_reg( R_ECX, Rn );
1.652 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
1.653 + check_walign32( R_ECX );
1.654 + load_spreg( R_EDX, R_FPSCR );
1.655 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.656 JNE_rel8(20, doublesize);
1.657 - load_fr_bank( R_ECX );
1.658 - load_fr( R_ECX, R_EAX, FRm );
1.659 - MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.660 + load_fr_bank( R_EDX );
1.661 + load_fr( R_EDX, R_EAX, FRm );
1.662 + MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.663 if( FRm&1 ) {
1.664 JMP_rel8( 48, end );
1.665 JMP_TARGET(doublesize);
1.666 - load_xf_bank( R_ECX );
1.667 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.668 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.669 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.670 + load_xf_bank( R_EDX );
1.671 + load_fr( R_EDX, R_EAX, FRm&0x0E );
1.672 + load_fr( R_EDX, R_EDX, FRm|0x01 );
1.673 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.674 JMP_TARGET(end);
1.675 } else {
1.676 JMP_rel8( 39, end );
1.677 JMP_TARGET(doublesize);
1.678 - load_fr_bank( R_ECX );
1.679 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.680 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.681 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.682 + load_fr_bank( R_EDX );
1.683 + load_fr( R_EDX, R_EAX, FRm&0x0E );
1.684 + load_fr( R_EDX, R_EDX, FRm|0x01 );
1.685 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.686 JMP_TARGET(end);
1.687 }
1.688 }
1.689 @@ -2778,31 +2854,32 @@
1.690 case 0x8:
1.691 { /* FMOV @Rm, FRn */
1.692 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.693 - check_fpuen();
1.694 - load_reg( R_EDX, Rm );
1.695 - check_ralign32( R_EDX );
1.696 - load_spreg( R_ECX, R_FPSCR );
1.697 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.698 + precheck();
1.699 + check_fpuen_no_precheck();
1.700 + load_reg( R_ECX, Rm );
1.701 + check_ralign32( R_ECX );
1.702 + load_spreg( R_EDX, R_FPSCR );
1.703 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.704 JNE_rel8(19, doublesize);
1.705 - MEM_READ_LONG( R_EDX, R_EAX );
1.706 - load_fr_bank( R_ECX );
1.707 - store_fr( R_ECX, R_EAX, FRn );
1.708 + MEM_READ_LONG( R_ECX, R_EAX );
1.709 + load_fr_bank( R_EDX );
1.710 + store_fr( R_EDX, R_EAX, FRn );
1.711 if( FRn&1 ) {
1.712 JMP_rel8(48, end);
1.713 JMP_TARGET(doublesize);
1.714 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.715 - load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.716 - load_xf_bank( R_ECX );
1.717 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.718 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.719 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.720 + load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.721 + load_xf_bank( R_EDX );
1.722 + store_fr( R_EDX, R_EAX, FRn&0x0E );
1.723 + store_fr( R_EDX, R_ECX, FRn|0x01 );
1.724 JMP_TARGET(end);
1.725 } else {
1.726 JMP_rel8(36, end);
1.727 JMP_TARGET(doublesize);
1.728 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.729 - load_fr_bank( R_ECX );
1.730 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.731 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.732 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.733 + load_fr_bank( R_EDX );
1.734 + store_fr( R_EDX, R_EAX, FRn&0x0E );
1.735 + store_fr( R_EDX, R_ECX, FRn|0x01 );
1.736 JMP_TARGET(end);
1.737 }
1.738 }
1.739 @@ -2810,37 +2887,38 @@
1.740 case 0x9:
1.741 { /* FMOV @Rm+, FRn */
1.742 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1.743 - check_fpuen();
1.744 - load_reg( R_EDX, Rm );
1.745 - check_ralign32( R_EDX );
1.746 - MOV_r32_r32( R_EDX, R_EAX );
1.747 - load_spreg( R_ECX, R_FPSCR );
1.748 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.749 + precheck();
1.750 + check_fpuen_no_precheck();
1.751 + load_reg( R_ECX, Rm );
1.752 + check_ralign32( R_ECX );
1.753 + MOV_r32_r32( R_ECX, R_EAX );
1.754 + load_spreg( R_EDX, R_FPSCR );
1.755 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.756 JNE_rel8(25, doublesize);
1.757 ADD_imm8s_r32( 4, R_EAX );
1.758 store_reg( R_EAX, Rm );
1.759 - MEM_READ_LONG( R_EDX, R_EAX );
1.760 - load_fr_bank( R_ECX );
1.761 - store_fr( R_ECX, R_EAX, FRn );
1.762 + MEM_READ_LONG( R_ECX, R_EAX );
1.763 + load_fr_bank( R_EDX );
1.764 + store_fr( R_EDX, R_EAX, FRn );
1.765 if( FRn&1 ) {
1.766 JMP_rel8(54, end);
1.767 JMP_TARGET(doublesize);
1.768 ADD_imm8s_r32( 8, R_EAX );
1.769 store_reg(R_EAX, Rm);
1.770 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.771 - load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.772 - load_xf_bank( R_ECX );
1.773 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.774 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.775 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.776 + load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1.777 + load_xf_bank( R_EDX );
1.778 + store_fr( R_EDX, R_EAX, FRn&0x0E );
1.779 + store_fr( R_EDX, R_ECX, FRn|0x01 );
1.780 JMP_TARGET(end);
1.781 } else {
1.782 JMP_rel8(42, end);
1.783 ADD_imm8s_r32( 8, R_EAX );
1.784 store_reg(R_EAX, Rm);
1.785 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.786 - load_fr_bank( R_ECX );
1.787 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.788 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.789 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
1.790 + load_fr_bank( R_EDX );
1.791 + store_fr( R_EDX, R_EAX, FRn&0x0E );
1.792 + store_fr( R_EDX, R_ECX, FRn|0x01 );
1.793 JMP_TARGET(end);
1.794 }
1.795 }
1.796 @@ -2848,30 +2926,31 @@
1.797 case 0xA:
1.798 { /* FMOV FRm, @Rn */
1.799 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.800 - check_fpuen();
1.801 - load_reg( R_EDX, Rn );
1.802 - check_walign32( R_EDX );
1.803 - load_spreg( R_ECX, R_FPSCR );
1.804 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.805 + precheck();
1.806 + check_fpuen_no_precheck();
1.807 + load_reg( R_ECX, Rn );
1.808 + check_walign32( R_ECX );
1.809 + load_spreg( R_EDX, R_FPSCR );
1.810 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.811 JNE_rel8(20, doublesize);
1.812 - load_fr_bank( R_ECX );
1.813 - load_fr( R_ECX, R_EAX, FRm );
1.814 - MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.815 + load_fr_bank( R_EDX );
1.816 + load_fr( R_EDX, R_EAX, FRm );
1.817 + MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.818 if( FRm&1 ) {
1.819 JMP_rel8( 48, end );
1.820 JMP_TARGET(doublesize);
1.821 - load_xf_bank( R_ECX );
1.822 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.823 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.824 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.825 + load_xf_bank( R_EDX );
1.826 + load_fr( R_EDX, R_EAX, FRm&0x0E );
1.827 + load_fr( R_EDX, R_EDX, FRm|0x01 );
1.828 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.829 JMP_TARGET(end);
1.830 } else {
1.831 JMP_rel8( 39, end );
1.832 JMP_TARGET(doublesize);
1.833 - load_fr_bank( R_ECX );
1.834 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.835 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.836 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.837 + load_fr_bank( R_EDX );
1.838 + load_fr( R_EDX, R_EAX, FRm&0x0E );
1.839 + load_fr( R_EDX, R_EDX, FRm|0x01 );
1.840 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.841 JMP_TARGET(end);
1.842 }
1.843 }
1.844 @@ -2879,36 +2958,37 @@
1.845 case 0xB:
1.846 { /* FMOV FRm, @-Rn */
1.847 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
1.848 - check_fpuen();
1.849 - load_reg( R_EDX, Rn );
1.850 - check_walign32( R_EDX );
1.851 - load_spreg( R_ECX, R_FPSCR );
1.852 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.853 + precheck();
1.854 + check_fpuen_no_precheck();
1.855 + load_reg( R_ECX, Rn );
1.856 + check_walign32( R_ECX );
1.857 + load_spreg( R_EDX, R_FPSCR );
1.858 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.859 JNE_rel8(26, doublesize);
1.860 - load_fr_bank( R_ECX );
1.861 - load_fr( R_ECX, R_EAX, FRm );
1.862 - ADD_imm8s_r32(-4,R_EDX);
1.863 - store_reg( R_EDX, Rn );
1.864 - MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.865 + load_fr_bank( R_EDX );
1.866 + load_fr( R_EDX, R_EAX, FRm );
1.867 + ADD_imm8s_r32(-4,R_ECX);
1.868 + store_reg( R_ECX, Rn );
1.869 + MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
1.870 if( FRm&1 ) {
1.871 JMP_rel8( 54, end );
1.872 JMP_TARGET(doublesize);
1.873 - load_xf_bank( R_ECX );
1.874 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.875 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.876 - ADD_imm8s_r32(-8,R_EDX);
1.877 - store_reg( R_EDX, Rn );
1.878 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.879 + load_xf_bank( R_EDX );
1.880 + load_fr( R_EDX, R_EAX, FRm&0x0E );
1.881 + load_fr( R_EDX, R_EDX, FRm|0x01 );
1.882 + ADD_imm8s_r32(-8,R_ECX);
1.883 + store_reg( R_ECX, Rn );
1.884 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.885 JMP_TARGET(end);
1.886 } else {
1.887 JMP_rel8( 45, end );
1.888 JMP_TARGET(doublesize);
1.889 - load_fr_bank( R_ECX );
1.890 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.891 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.892 - ADD_imm8s_r32(-8,R_EDX);
1.893 - store_reg( R_EDX, Rn );
1.894 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.895 + load_fr_bank( R_EDX );
1.896 + load_fr( R_EDX, R_EAX, FRm&0x0E );
1.897 + load_fr( R_EDX, R_EDX, FRm|0x01 );
1.898 + ADD_imm8s_r32(-8,R_ECX);
1.899 + store_reg( R_ECX, Rn );
1.900 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
1.901 JMP_TARGET(end);
1.902 }
1.903 }
1.904 @@ -3249,6 +3329,7 @@
1.905 if( sh4_x86.in_delay_slot ) {
1.906 SLOTILLEGAL();
1.907 } else {
1.908 + precheck();
1.909 JMP_exit(EXIT_ILLEGAL);
1.910 return 2;
1.911 }
1.912 @@ -3300,11 +3381,6 @@
1.913 break;
1.914 }
1.915
1.916 - if( sh4_x86.in_delay_slot ) {
1.917 - ADD_imm8s_r32(2,R_ESI);
1.918 - sh4_x86.in_delay_slot = FALSE;
1.919 - } else {
1.920 - INC_r32(R_ESI);
1.921 - }
1.922 + sh4_x86.in_delay_slot = FALSE;
1.923 return 0;
1.924 }
.