Search
lxdream.org :: lxdream :: r416:714df603c869
lxdream 0.9.1
released Jun 29
Download Now
changeset416:714df603c869
parent415:5e57f29bfd4d
child417:bd927df302a9
authornkeynes
dateWed Oct 03 12:19:03 2007 +0000 (16 years ago)
Remove INC %esi (and esi in general), replace with load immediates (faster)
src/sh4/sh4x86.c
src/sh4/sh4x86.in
1.1 --- a/src/sh4/sh4x86.c Wed Oct 03 09:32:09 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 }
2.1 --- a/src/sh4/sh4x86.in Wed Oct 03 09:32:09 2007 +0000
2.2 +++ b/src/sh4/sh4x86.in Wed Oct 03 12:19:03 2007 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: sh4x86.in,v 1.17 2007-09-29 05:33:02 nkeynes Exp $
2.6 + * $Id: sh4x86.in,v 1.18 2007-10-03 12:19:03 nkeynes Exp $
2.7 *
2.8 * SH4 => x86 translation. This version does no real optimization, it just
2.9 * outputs straight-line x86 code - it mainly exists to provide a baseline
2.10 @@ -293,7 +293,23 @@
2.11 }
2.12
2.13 /* Exception checks - Note that all exception checks will clobber EAX */
2.14 -static void check_priv( )
2.15 +#define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
2.16 +
2.17 +#define check_priv( ) \
2.18 + if( !sh4_x86.priv_checked ) { \
2.19 + sh4_x86.priv_checked = TRUE;\
2.20 + precheck();\
2.21 + load_spreg( R_EAX, R_SR );\
2.22 + AND_imm32_r32( SR_MD, R_EAX );\
2.23 + if( sh4_x86.in_delay_slot ) {\
2.24 + JE_exit( EXIT_SLOT_ILLEGAL );\
2.25 + } else {\
2.26 + JE_exit( EXIT_ILLEGAL );\
2.27 + }\
2.28 + }\
2.29 +
2.30 +
2.31 +static void check_priv_no_precheck()
2.32 {
2.33 if( !sh4_x86.priv_checked ) {
2.34 sh4_x86.priv_checked = TRUE;
2.35 @@ -307,7 +323,20 @@
2.36 }
2.37 }
2.38
2.39 -static void check_fpuen( )
2.40 +#define check_fpuen( ) \
2.41 + if( !sh4_x86.fpuen_checked ) {\
2.42 + sh4_x86.fpuen_checked = TRUE;\
2.43 + precheck();\
2.44 + load_spreg( R_EAX, R_SR );\
2.45 + AND_imm32_r32( SR_FD, R_EAX );\
2.46 + if( sh4_x86.in_delay_slot ) {\
2.47 + JNE_exit(EXIT_SLOT_FPU_DISABLED);\
2.48 + } else {\
2.49 + JNE_exit(EXIT_FPU_DISABLED);\
2.50 + }\
2.51 + }
2.52 +
2.53 +static void check_fpuen_no_precheck()
2.54 {
2.55 if( !sh4_x86.fpuen_checked ) {
2.56 sh4_x86.fpuen_checked = TRUE;
2.57 @@ -319,6 +348,7 @@
2.58 JNE_exit(EXIT_FPU_DISABLED);
2.59 }
2.60 }
2.61 +
2.62 }
2.63
2.64 static void check_ralign16( int x86reg )
2.65 @@ -353,7 +383,7 @@
2.66 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
2.67 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
2.68
2.69 -#define SLOTILLEGAL() JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
2.70 +#define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
2.71
2.72
2.73
2.74 @@ -366,8 +396,6 @@
2.75 PUSH_r32(R_EBP);
2.76 /* mov &sh4r, ebp */
2.77 load_imm32( R_EBP, (uint32_t)&sh4r );
2.78 - PUSH_r32(R_ESI);
2.79 - XOR_r32_r32(R_ESI, R_ESI);
2.80
2.81 sh4_x86.in_delay_slot = FALSE;
2.82 sh4_x86.priv_checked = FALSE;
2.83 @@ -379,7 +407,7 @@
2.84
2.85 /**
2.86 * Exit the block to an absolute PC
2.87 - * Bytes: 30
2.88 + * Bytes: 29
2.89 */
2.90 void exit_block( sh4addr_t pc, sh4addr_t endpc )
2.91 {
2.92 @@ -389,21 +417,19 @@
2.93 AND_imm8s_r32( 0xFC, R_EAX ); // 3
2.94 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
2.95 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
2.96 - POP_r32(R_ESI);
2.97 POP_r32(R_EBP);
2.98 RET();
2.99 }
2.100
2.101 /**
2.102 * Exit the block with sh4r.pc already written
2.103 - * Bytes: 16
2.104 + * Bytes: 15
2.105 */
2.106 void exit_block_pcset( pc )
2.107 {
2.108 XOR_r32_r32( R_EAX, R_EAX ); // 2
2.109 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
2.110 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
2.111 - POP_r32(R_ESI);
2.112 POP_r32(R_EBP);
2.113 RET();
2.114 }
2.115 @@ -437,12 +463,12 @@
2.116 JMP_TARGET(target4);
2.117 JMP_TARGET(target5);
2.118 load_spreg( R_ECX, REG_OFFSET(pc) );
2.119 - ADD_r32_r32( R_ESI, R_ECX );
2.120 - ADD_r32_r32( R_ESI, R_ECX );
2.121 + ADD_r32_r32( R_EDX, R_ECX );
2.122 + ADD_r32_r32( R_EDX, R_ECX );
2.123 store_spreg( R_ECX, REG_OFFSET(pc) );
2.124 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
2.125 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
2.126 - MUL_r32( R_ESI );
2.127 + MUL_r32( R_EDX );
2.128 ADD_r32_r32( R_EAX, R_ECX );
2.129 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
2.130
2.131 @@ -450,7 +476,6 @@
2.132 CALL_r32( R_EAX ); // 2
2.133 ADD_imm8s_r32( 4, R_ESP );
2.134 XOR_r32_r32( R_EAX, R_EAX );
2.135 - POP_r32(R_ESI);
2.136 POP_r32(R_EBP);
2.137 RET();
2.138
2.139 @@ -683,6 +708,7 @@
2.140 :}
2.141 MAC.L @Rm+, @Rn+ {:
2.142 load_reg( R_ECX, Rm );
2.143 + precheck();
2.144 check_ralign32( R_ECX );
2.145 load_reg( R_ECX, Rn );
2.146 check_ralign32( R_ECX );
2.147 @@ -705,6 +731,7 @@
2.148 :}
2.149 MAC.W @Rm+, @Rn+ {:
2.150 load_reg( R_ECX, Rm );
2.151 + precheck();
2.152 check_ralign16( R_ECX );
2.153 load_reg( R_ECX, Rn );
2.154 check_ralign16( R_ECX );
2.155 @@ -1097,12 +1124,14 @@
2.156 MOV.L Rm, @Rn {:
2.157 load_reg( R_EAX, Rm );
2.158 load_reg( R_ECX, Rn );
2.159 + precheck();
2.160 check_walign32(R_ECX);
2.161 MEM_WRITE_LONG( R_ECX, R_EAX );
2.162 :}
2.163 MOV.L Rm, @-Rn {:
2.164 load_reg( R_EAX, Rm );
2.165 load_reg( R_ECX, Rn );
2.166 + precheck();
2.167 check_walign32( R_ECX );
2.168 ADD_imm8s_r32( -4, R_ECX );
2.169 store_reg( R_ECX, Rn );
2.170 @@ -1112,6 +1141,7 @@
2.171 load_reg( R_EAX, 0 );
2.172 load_reg( R_ECX, Rn );
2.173 ADD_r32_r32( R_EAX, R_ECX );
2.174 + precheck();
2.175 check_walign32( R_ECX );
2.176 load_reg( R_EAX, Rm );
2.177 MEM_WRITE_LONG( R_ECX, R_EAX );
2.178 @@ -1120,6 +1150,7 @@
2.179 load_spreg( R_ECX, R_GBR );
2.180 load_reg( R_EAX, 0 );
2.181 ADD_imm32_r32( disp, R_ECX );
2.182 + precheck();
2.183 check_walign32( R_ECX );
2.184 MEM_WRITE_LONG( R_ECX, R_EAX );
2.185 :}
2.186 @@ -1127,17 +1158,20 @@
2.187 load_reg( R_ECX, Rn );
2.188 load_reg( R_EAX, Rm );
2.189 ADD_imm32_r32( disp, R_ECX );
2.190 + precheck();
2.191 check_walign32( R_ECX );
2.192 MEM_WRITE_LONG( R_ECX, R_EAX );
2.193 :}
2.194 MOV.L @Rm, Rn {:
2.195 load_reg( R_ECX, Rm );
2.196 + precheck();
2.197 check_ralign32( R_ECX );
2.198 MEM_READ_LONG( R_ECX, R_EAX );
2.199 store_reg( R_EAX, Rn );
2.200 :}
2.201 MOV.L @Rm+, Rn {:
2.202 load_reg( R_EAX, Rm );
2.203 + precheck();
2.204 check_ralign32( R_EAX );
2.205 MOV_r32_r32( R_EAX, R_ECX );
2.206 ADD_imm8s_r32( 4, R_EAX );
2.207 @@ -1149,6 +1183,7 @@
2.208 load_reg( R_EAX, 0 );
2.209 load_reg( R_ECX, Rm );
2.210 ADD_r32_r32( R_EAX, R_ECX );
2.211 + precheck();
2.212 check_ralign32( R_ECX );
2.213 MEM_READ_LONG( R_ECX, R_EAX );
2.214 store_reg( R_EAX, Rn );
2.215 @@ -1156,6 +1191,7 @@
2.216 MOV.L @(disp, GBR), R0 {:
2.217 load_spreg( R_ECX, R_GBR );
2.218 ADD_imm32_r32( disp, R_ECX );
2.219 + precheck();
2.220 check_ralign32( R_ECX );
2.221 MEM_READ_LONG( R_ECX, R_EAX );
2.222 store_reg( R_EAX, 0 );
2.223 @@ -1178,18 +1214,21 @@
2.224 MOV.L @(disp, Rm), Rn {:
2.225 load_reg( R_ECX, Rm );
2.226 ADD_imm8s_r32( disp, R_ECX );
2.227 + precheck();
2.228 check_ralign32( R_ECX );
2.229 MEM_READ_LONG( R_ECX, R_EAX );
2.230 store_reg( R_EAX, Rn );
2.231 :}
2.232 MOV.W Rm, @Rn {:
2.233 load_reg( R_ECX, Rn );
2.234 + precheck();
2.235 check_walign16( R_ECX );
2.236 load_reg( R_EAX, Rm );
2.237 MEM_WRITE_WORD( R_ECX, R_EAX );
2.238 :}
2.239 MOV.W Rm, @-Rn {:
2.240 load_reg( R_ECX, Rn );
2.241 + precheck();
2.242 check_walign16( R_ECX );
2.243 load_reg( R_EAX, Rm );
2.244 ADD_imm8s_r32( -2, R_ECX );
2.245 @@ -1200,6 +1239,7 @@
2.246 load_reg( R_EAX, 0 );
2.247 load_reg( R_ECX, Rn );
2.248 ADD_r32_r32( R_EAX, R_ECX );
2.249 + precheck();
2.250 check_walign16( R_ECX );
2.251 load_reg( R_EAX, Rm );
2.252 MEM_WRITE_WORD( R_ECX, R_EAX );
2.253 @@ -1208,6 +1248,7 @@
2.254 load_spreg( R_ECX, R_GBR );
2.255 load_reg( R_EAX, 0 );
2.256 ADD_imm32_r32( disp, R_ECX );
2.257 + precheck();
2.258 check_walign16( R_ECX );
2.259 MEM_WRITE_WORD( R_ECX, R_EAX );
2.260 :}
2.261 @@ -1215,17 +1256,20 @@
2.262 load_reg( R_ECX, Rn );
2.263 load_reg( R_EAX, 0 );
2.264 ADD_imm32_r32( disp, R_ECX );
2.265 + precheck();
2.266 check_walign16( R_ECX );
2.267 MEM_WRITE_WORD( R_ECX, R_EAX );
2.268 :}
2.269 MOV.W @Rm, Rn {:
2.270 load_reg( R_ECX, Rm );
2.271 + precheck();
2.272 check_ralign16( R_ECX );
2.273 MEM_READ_WORD( R_ECX, R_EAX );
2.274 store_reg( R_EAX, Rn );
2.275 :}
2.276 MOV.W @Rm+, Rn {:
2.277 load_reg( R_EAX, Rm );
2.278 + precheck();
2.279 check_ralign16( R_EAX );
2.280 MOV_r32_r32( R_EAX, R_ECX );
2.281 ADD_imm8s_r32( 2, R_EAX );
2.282 @@ -1237,6 +1281,7 @@
2.283 load_reg( R_EAX, 0 );
2.284 load_reg( R_ECX, Rm );
2.285 ADD_r32_r32( R_EAX, R_ECX );
2.286 + precheck();
2.287 check_ralign16( R_ECX );
2.288 MEM_READ_WORD( R_ECX, R_EAX );
2.289 store_reg( R_EAX, Rn );
2.290 @@ -1244,6 +1289,7 @@
2.291 MOV.W @(disp, GBR), R0 {:
2.292 load_spreg( R_ECX, R_GBR );
2.293 ADD_imm32_r32( disp, R_ECX );
2.294 + precheck();
2.295 check_ralign16( R_ECX );
2.296 MEM_READ_WORD( R_ECX, R_EAX );
2.297 store_reg( R_EAX, 0 );
2.298 @@ -1260,6 +1306,7 @@
2.299 MOV.W @(disp, Rm), R0 {:
2.300 load_reg( R_ECX, Rm );
2.301 ADD_imm32_r32( disp, R_ECX );
2.302 + precheck();
2.303 check_ralign16( R_ECX );
2.304 MEM_READ_WORD( R_ECX, R_EAX );
2.305 store_reg( R_EAX, 0 );
2.306 @@ -1275,6 +1322,7 @@
2.307 MOVCA.L R0, @Rn {:
2.308 load_reg( R_EAX, 0 );
2.309 load_reg( R_ECX, Rn );
2.310 + precheck();
2.311 check_walign32( R_ECX );
2.312 MEM_WRITE_LONG( R_ECX, R_EAX );
2.313 :}
2.314 @@ -1285,7 +1333,7 @@
2.315 SLOTILLEGAL();
2.316 } else {
2.317 CMP_imm8s_sh4r( 0, R_T );
2.318 - JNE_rel8( 30, nottaken );
2.319 + JNE_rel8( 29, nottaken );
2.320 exit_block( disp + pc + 4, pc+2 );
2.321 JMP_TARGET(nottaken);
2.322 return 2;
2.323 @@ -1364,7 +1412,7 @@
2.324 SLOTILLEGAL();
2.325 } else {
2.326 CMP_imm8s_sh4r( 0, R_T );
2.327 - JE_rel8( 30, nottaken );
2.328 + JE_rel8( 29, nottaken );
2.329 exit_block( disp + pc + 4, pc+2 );
2.330 JMP_TARGET(nottaken);
2.331 return 2;
2.332 @@ -1460,6 +1508,7 @@
2.333 if( sh4_x86.in_delay_slot ) {
2.334 SLOTILLEGAL();
2.335 } else {
2.336 + precheck();
2.337 JMP_exit(EXIT_ILLEGAL);
2.338 return 2;
2.339 }
2.340 @@ -1537,188 +1586,194 @@
2.341 }
2.342 }
2.343 :}
2.344 -FMOV FRm, @Rn {:
2.345 - check_fpuen();
2.346 - load_reg( R_EDX, Rn );
2.347 - check_walign32( R_EDX );
2.348 - load_spreg( R_ECX, R_FPSCR );
2.349 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
2.350 +FMOV FRm, @Rn {:
2.351 + precheck();
2.352 + check_fpuen_no_precheck();
2.353 + load_reg( R_ECX, Rn );
2.354 + check_walign32( R_ECX );
2.355 + load_spreg( R_EDX, R_FPSCR );
2.356 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
2.357 JNE_rel8(20, doublesize);
2.358 - load_fr_bank( R_ECX );
2.359 - load_fr( R_ECX, R_EAX, FRm );
2.360 - MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
2.361 + load_fr_bank( R_EDX );
2.362 + load_fr( R_EDX, R_EAX, FRm );
2.363 + MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
2.364 if( FRm&1 ) {
2.365 JMP_rel8( 48, end );
2.366 JMP_TARGET(doublesize);
2.367 - load_xf_bank( R_ECX );
2.368 - load_fr( R_ECX, R_EAX, FRm&0x0E );
2.369 - load_fr( R_ECX, R_ECX, FRm|0x01 );
2.370 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2.371 + load_xf_bank( R_EDX );
2.372 + load_fr( R_EDX, R_EAX, FRm&0x0E );
2.373 + load_fr( R_EDX, R_EDX, FRm|0x01 );
2.374 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2.375 JMP_TARGET(end);
2.376 } else {
2.377 JMP_rel8( 39, end );
2.378 JMP_TARGET(doublesize);
2.379 - load_fr_bank( R_ECX );
2.380 - load_fr( R_ECX, R_EAX, FRm&0x0E );
2.381 - load_fr( R_ECX, R_ECX, FRm|0x01 );
2.382 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2.383 + load_fr_bank( R_EDX );
2.384 + load_fr( R_EDX, R_EAX, FRm&0x0E );
2.385 + load_fr( R_EDX, R_EDX, FRm|0x01 );
2.386 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2.387 JMP_TARGET(end);
2.388 }
2.389 :}
2.390 FMOV @Rm, FRn {:
2.391 - check_fpuen();
2.392 - load_reg( R_EDX, Rm );
2.393 - check_ralign32( R_EDX );
2.394 - load_spreg( R_ECX, R_FPSCR );
2.395 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
2.396 + precheck();
2.397 + check_fpuen_no_precheck();
2.398 + load_reg( R_ECX, Rm );
2.399 + check_ralign32( R_ECX );
2.400 + load_spreg( R_EDX, R_FPSCR );
2.401 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
2.402 JNE_rel8(19, doublesize);
2.403 - MEM_READ_LONG( R_EDX, R_EAX );
2.404 - load_fr_bank( R_ECX );
2.405 - store_fr( R_ECX, R_EAX, FRn );
2.406 + MEM_READ_LONG( R_ECX, R_EAX );
2.407 + load_fr_bank( R_EDX );
2.408 + store_fr( R_EDX, R_EAX, FRn );
2.409 if( FRn&1 ) {
2.410 JMP_rel8(48, end);
2.411 JMP_TARGET(doublesize);
2.412 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2.413 - load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
2.414 - load_xf_bank( R_ECX );
2.415 - store_fr( R_ECX, R_EAX, FRn&0x0E );
2.416 - store_fr( R_ECX, R_EDX, FRn|0x01 );
2.417 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2.418 + load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2.419 + load_xf_bank( R_EDX );
2.420 + store_fr( R_EDX, R_EAX, FRn&0x0E );
2.421 + store_fr( R_EDX, R_ECX, FRn|0x01 );
2.422 JMP_TARGET(end);
2.423 } else {
2.424 JMP_rel8(36, end);
2.425 JMP_TARGET(doublesize);
2.426 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2.427 - load_fr_bank( R_ECX );
2.428 - store_fr( R_ECX, R_EAX, FRn&0x0E );
2.429 - store_fr( R_ECX, R_EDX, FRn|0x01 );
2.430 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2.431 + load_fr_bank( R_EDX );
2.432 + store_fr( R_EDX, R_EAX, FRn&0x0E );
2.433 + store_fr( R_EDX, R_ECX, FRn|0x01 );
2.434 JMP_TARGET(end);
2.435 }
2.436 :}
2.437 FMOV FRm, @-Rn {:
2.438 - check_fpuen();
2.439 - load_reg( R_EDX, Rn );
2.440 - check_walign32( R_EDX );
2.441 - load_spreg( R_ECX, R_FPSCR );
2.442 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
2.443 + precheck();
2.444 + check_fpuen_no_precheck();
2.445 + load_reg( R_ECX, Rn );
2.446 + check_walign32( R_ECX );
2.447 + load_spreg( R_EDX, R_FPSCR );
2.448 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
2.449 JNE_rel8(26, doublesize);
2.450 - load_fr_bank( R_ECX );
2.451 - load_fr( R_ECX, R_EAX, FRm );
2.452 - ADD_imm8s_r32(-4,R_EDX);
2.453 - store_reg( R_EDX, Rn );
2.454 - MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
2.455 + load_fr_bank( R_EDX );
2.456 + load_fr( R_EDX, R_EAX, FRm );
2.457 + ADD_imm8s_r32(-4,R_ECX);
2.458 + store_reg( R_ECX, Rn );
2.459 + MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
2.460 if( FRm&1 ) {
2.461 JMP_rel8( 54, end );
2.462 JMP_TARGET(doublesize);
2.463 - load_xf_bank( R_ECX );
2.464 - load_fr( R_ECX, R_EAX, FRm&0x0E );
2.465 - load_fr( R_ECX, R_ECX, FRm|0x01 );
2.466 - ADD_imm8s_r32(-8,R_EDX);
2.467 - store_reg( R_EDX, Rn );
2.468 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2.469 + load_xf_bank( R_EDX );
2.470 + load_fr( R_EDX, R_EAX, FRm&0x0E );
2.471 + load_fr( R_EDX, R_EDX, FRm|0x01 );
2.472 + ADD_imm8s_r32(-8,R_ECX);
2.473 + store_reg( R_ECX, Rn );
2.474 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2.475 JMP_TARGET(end);
2.476 } else {
2.477 JMP_rel8( 45, end );
2.478 JMP_TARGET(doublesize);
2.479 - load_fr_bank( R_ECX );
2.480 - load_fr( R_ECX, R_EAX, FRm&0x0E );
2.481 - load_fr( R_ECX, R_ECX, FRm|0x01 );
2.482 - ADD_imm8s_r32(-8,R_EDX);
2.483 - store_reg( R_EDX, Rn );
2.484 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2.485 + load_fr_bank( R_EDX );
2.486 + load_fr( R_EDX, R_EAX, FRm&0x0E );
2.487 + load_fr( R_EDX, R_EDX, FRm|0x01 );
2.488 + ADD_imm8s_r32(-8,R_ECX);
2.489 + store_reg( R_ECX, Rn );
2.490 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2.491 JMP_TARGET(end);
2.492 }
2.493 :}
2.494 -FMOV @Rm+, FRn {:
2.495 - check_fpuen();
2.496 - load_reg( R_EDX, Rm );
2.497 - check_ralign32( R_EDX );
2.498 - MOV_r32_r32( R_EDX, R_EAX );
2.499 - load_spreg( R_ECX, R_FPSCR );
2.500 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
2.501 +FMOV @Rm+, FRn {:
2.502 + precheck();
2.503 + check_fpuen_no_precheck();
2.504 + load_reg( R_ECX, Rm );
2.505 + check_ralign32( R_ECX );
2.506 + MOV_r32_r32( R_ECX, R_EAX );
2.507 + load_spreg( R_EDX, R_FPSCR );
2.508 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
2.509 JNE_rel8(25, doublesize);
2.510 ADD_imm8s_r32( 4, R_EAX );
2.511 store_reg( R_EAX, Rm );
2.512 - MEM_READ_LONG( R_EDX, R_EAX );
2.513 - load_fr_bank( R_ECX );
2.514 - store_fr( R_ECX, R_EAX, FRn );
2.515 + MEM_READ_LONG( R_ECX, R_EAX );
2.516 + load_fr_bank( R_EDX );
2.517 + store_fr( R_EDX, R_EAX, FRn );
2.518 if( FRn&1 ) {
2.519 JMP_rel8(54, end);
2.520 JMP_TARGET(doublesize);
2.521 ADD_imm8s_r32( 8, R_EAX );
2.522 store_reg(R_EAX, Rm);
2.523 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2.524 - load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
2.525 - load_xf_bank( R_ECX );
2.526 - store_fr( R_ECX, R_EAX, FRn&0x0E );
2.527 - store_fr( R_ECX, R_EDX, FRn|0x01 );
2.528 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2.529 + load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2.530 + load_xf_bank( R_EDX );
2.531 + store_fr( R_EDX, R_EAX, FRn&0x0E );
2.532 + store_fr( R_EDX, R_ECX, FRn|0x01 );
2.533 JMP_TARGET(end);
2.534 } else {
2.535 JMP_rel8(42, end);
2.536 ADD_imm8s_r32( 8, R_EAX );
2.537 store_reg(R_EAX, Rm);
2.538 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2.539 - load_fr_bank( R_ECX );
2.540 - store_fr( R_ECX, R_EAX, FRn&0x0E );
2.541 - store_fr( R_ECX, R_EDX, FRn|0x01 );
2.542 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2.543 + load_fr_bank( R_EDX );
2.544 + store_fr( R_EDX, R_EAX, FRn&0x0E );
2.545 + store_fr( R_EDX, R_ECX, FRn|0x01 );
2.546 JMP_TARGET(end);
2.547 }
2.548 :}
2.549 FMOV FRm, @(R0, Rn) {:
2.550 - check_fpuen();
2.551 - load_reg( R_EDX, Rn );
2.552 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
2.553 - check_walign32( R_EDX );
2.554 - load_spreg( R_ECX, R_FPSCR );
2.555 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
2.556 + precheck();
2.557 + check_fpuen_no_precheck();
2.558 + load_reg( R_ECX, Rn );
2.559 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
2.560 + check_walign32( R_ECX );
2.561 + load_spreg( R_EDX, R_FPSCR );
2.562 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
2.563 JNE_rel8(20, doublesize);
2.564 - load_fr_bank( R_ECX );
2.565 - load_fr( R_ECX, R_EAX, FRm );
2.566 - MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
2.567 + load_fr_bank( R_EDX );
2.568 + load_fr( R_EDX, R_EAX, FRm );
2.569 + MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
2.570 if( FRm&1 ) {
2.571 JMP_rel8( 48, end );
2.572 JMP_TARGET(doublesize);
2.573 - load_xf_bank( R_ECX );
2.574 - load_fr( R_ECX, R_EAX, FRm&0x0E );
2.575 - load_fr( R_ECX, R_ECX, FRm|0x01 );
2.576 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2.577 + load_xf_bank( R_EDX );
2.578 + load_fr( R_EDX, R_EAX, FRm&0x0E );
2.579 + load_fr( R_EDX, R_EDX, FRm|0x01 );
2.580 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2.581 JMP_TARGET(end);
2.582 } else {
2.583 JMP_rel8( 39, end );
2.584 JMP_TARGET(doublesize);
2.585 - load_fr_bank( R_ECX );
2.586 - load_fr( R_ECX, R_EAX, FRm&0x0E );
2.587 - load_fr( R_ECX, R_ECX, FRm|0x01 );
2.588 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2.589 + load_fr_bank( R_EDX );
2.590 + load_fr( R_EDX, R_EAX, FRm&0x0E );
2.591 + load_fr( R_EDX, R_EDX, FRm|0x01 );
2.592 + MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2.593 JMP_TARGET(end);
2.594 }
2.595 :}
2.596 FMOV @(R0, Rm), FRn {:
2.597 - check_fpuen();
2.598 - load_reg( R_EDX, Rm );
2.599 - ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
2.600 - check_ralign32( R_EDX );
2.601 - load_spreg( R_ECX, R_FPSCR );
2.602 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
2.603 + precheck();
2.604 + check_fpuen_no_precheck();
2.605 + load_reg( R_ECX, Rm );
2.606 + ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
2.607 + check_ralign32( R_ECX );
2.608 + load_spreg( R_EDX, R_FPSCR );
2.609 + TEST_imm32_r32( FPSCR_SZ, R_EDX );
2.610 JNE_rel8(19, doublesize);
2.611 - MEM_READ_LONG( R_EDX, R_EAX );
2.612 - load_fr_bank( R_ECX );
2.613 - store_fr( R_ECX, R_EAX, FRn );
2.614 + MEM_READ_LONG( R_ECX, R_EAX );
2.615 + load_fr_bank( R_EDX );
2.616 + store_fr( R_EDX, R_EAX, FRn );
2.617 if( FRn&1 ) {
2.618 JMP_rel8(48, end);
2.619 JMP_TARGET(doublesize);
2.620 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2.621 - load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
2.622 - load_xf_bank( R_ECX );
2.623 - store_fr( R_ECX, R_EAX, FRn&0x0E );
2.624 - store_fr( R_ECX, R_EDX, FRn|0x01 );
2.625 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2.626 + load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2.627 + load_xf_bank( R_EDX );
2.628 + store_fr( R_EDX, R_EAX, FRn&0x0E );
2.629 + store_fr( R_EDX, R_ECX, FRn|0x01 );
2.630 JMP_TARGET(end);
2.631 } else {
2.632 JMP_rel8(36, end);
2.633 JMP_TARGET(doublesize);
2.634 - MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2.635 - load_fr_bank( R_ECX );
2.636 - store_fr( R_ECX, R_EAX, FRn&0x0E );
2.637 - store_fr( R_ECX, R_EDX, FRn|0x01 );
2.638 + MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2.639 + load_fr_bank( R_EDX );
2.640 + store_fr( R_EDX, R_EAX, FRn&0x0E );
2.641 + store_fr( R_EDX, R_ECX, FRn|0x01 );
2.642 JMP_TARGET(end);
2.643 }
2.644 :}
2.645 @@ -2126,6 +2181,7 @@
2.646 :}
2.647 LDC.L @Rm+, GBR {:
2.648 load_reg( R_EAX, Rm );
2.649 + precheck();
2.650 check_ralign32( R_EAX );
2.651 MOV_r32_r32( R_EAX, R_ECX );
2.652 ADD_imm8s_r32( 4, R_EAX );
2.653 @@ -2137,7 +2193,8 @@
2.654 if( sh4_x86.in_delay_slot ) {
2.655 SLOTILLEGAL();
2.656 } else {
2.657 - check_priv();
2.658 + precheck();
2.659 + check_priv_no_precheck();
2.660 load_reg( R_EAX, Rm );
2.661 check_ralign32( R_EAX );
2.662 MOV_r32_r32( R_EAX, R_ECX );
2.663 @@ -2150,7 +2207,8 @@
2.664 }
2.665 :}
2.666 LDC.L @Rm+, VBR {:
2.667 - check_priv();
2.668 + precheck();
2.669 + check_priv_no_precheck();
2.670 load_reg( R_EAX, Rm );
2.671 check_ralign32( R_EAX );
2.672 MOV_r32_r32( R_EAX, R_ECX );
2.673 @@ -2160,8 +2218,10 @@
2.674 store_spreg( R_EAX, R_VBR );
2.675 :}
2.676 LDC.L @Rm+, SSR {:
2.677 - check_priv();
2.678 + precheck();
2.679 + check_priv_no_precheck();
2.680 load_reg( R_EAX, Rm );
2.681 + check_ralign32( R_EAX );
2.682 MOV_r32_r32( R_EAX, R_ECX );
2.683 ADD_imm8s_r32( 4, R_EAX );
2.684 store_reg( R_EAX, Rm );
2.685 @@ -2169,7 +2229,8 @@
2.686 store_spreg( R_EAX, R_SSR );
2.687 :}
2.688 LDC.L @Rm+, SGR {:
2.689 - check_priv();
2.690 + precheck();
2.691 + check_priv_no_precheck();
2.692 load_reg( R_EAX, Rm );
2.693 check_ralign32( R_EAX );
2.694 MOV_r32_r32( R_EAX, R_ECX );
2.695 @@ -2179,7 +2240,8 @@
2.696 store_spreg( R_EAX, R_SGR );
2.697 :}
2.698 LDC.L @Rm+, SPC {:
2.699 - check_priv();
2.700 + precheck();
2.701 + check_priv_no_precheck();
2.702 load_reg( R_EAX, Rm );
2.703 check_ralign32( R_EAX );
2.704 MOV_r32_r32( R_EAX, R_ECX );
2.705 @@ -2189,7 +2251,8 @@
2.706 store_spreg( R_EAX, R_SPC );
2.707 :}
2.708 LDC.L @Rm+, DBR {:
2.709 - check_priv();
2.710 + precheck();
2.711 + check_priv_no_precheck();
2.712 load_reg( R_EAX, Rm );
2.713 check_ralign32( R_EAX );
2.714 MOV_r32_r32( R_EAX, R_ECX );
2.715 @@ -2199,7 +2262,8 @@
2.716 store_spreg( R_EAX, R_DBR );
2.717 :}
2.718 LDC.L @Rm+, Rn_BANK {:
2.719 - check_priv();
2.720 + precheck();
2.721 + check_priv_no_precheck();
2.722 load_reg( R_EAX, Rm );
2.723 check_ralign32( R_EAX );
2.724 MOV_r32_r32( R_EAX, R_ECX );
2.725 @@ -2215,6 +2279,7 @@
2.726 :}
2.727 LDS.L @Rm+, FPSCR {:
2.728 load_reg( R_EAX, Rm );
2.729 + precheck();
2.730 check_ralign32( R_EAX );
2.731 MOV_r32_r32( R_EAX, R_ECX );
2.732 ADD_imm8s_r32( 4, R_EAX );
2.733 @@ -2229,6 +2294,7 @@
2.734 :}
2.735 LDS.L @Rm+, FPUL {:
2.736 load_reg( R_EAX, Rm );
2.737 + precheck();
2.738 check_ralign32( R_EAX );
2.739 MOV_r32_r32( R_EAX, R_ECX );
2.740 ADD_imm8s_r32( 4, R_EAX );
2.741 @@ -2242,6 +2308,7 @@
2.742 :}
2.743 LDS.L @Rm+, MACH {:
2.744 load_reg( R_EAX, Rm );
2.745 + precheck();
2.746 check_ralign32( R_EAX );
2.747 MOV_r32_r32( R_EAX, R_ECX );
2.748 ADD_imm8s_r32( 4, R_EAX );
2.749 @@ -2255,6 +2322,7 @@
2.750 :}
2.751 LDS.L @Rm+, MACL {:
2.752 load_reg( R_EAX, Rm );
2.753 + precheck();
2.754 check_ralign32( R_EAX );
2.755 MOV_r32_r32( R_EAX, R_ECX );
2.756 ADD_imm8s_r32( 4, R_EAX );
2.757 @@ -2268,6 +2336,7 @@
2.758 :}
2.759 LDS.L @Rm+, PR {:
2.760 load_reg( R_EAX, Rm );
2.761 + precheck();
2.762 check_ralign32( R_EAX );
2.763 MOV_r32_r32( R_EAX, R_ECX );
2.764 ADD_imm8s_r32( 4, R_EAX );
2.765 @@ -2293,7 +2362,6 @@
2.766 check_priv();
2.767 call_func0( sh4_sleep );
2.768 sh4_x86.in_delay_slot = FALSE;
2.769 - INC_r32(R_ESI);
2.770 return 2;
2.771 :}
2.772 STC SR, Rn {:
2.773 @@ -2336,7 +2404,8 @@
2.774 store_reg( R_EAX, Rn );
2.775 :}
2.776 STC.L SR, @-Rn {:
2.777 - check_priv();
2.778 + precheck();
2.779 + check_priv_no_precheck();
2.780 call_func0( sh4_read_sr );
2.781 load_reg( R_ECX, Rn );
2.782 check_walign32( R_ECX );
2.783 @@ -2345,7 +2414,8 @@
2.784 MEM_WRITE_LONG( R_ECX, R_EAX );
2.785 :}
2.786 STC.L VBR, @-Rn {:
2.787 - check_priv();
2.788 + precheck();
2.789 + check_priv_no_precheck();
2.790 load_reg( R_ECX, Rn );
2.791 check_walign32( R_ECX );
2.792 ADD_imm8s_r32( -4, R_ECX );
2.793 @@ -2354,7 +2424,8 @@
2.794 MEM_WRITE_LONG( R_ECX, R_EAX );
2.795 :}
2.796 STC.L SSR, @-Rn {:
2.797 - check_priv();
2.798 + precheck();
2.799 + check_priv_no_precheck();
2.800 load_reg( R_ECX, Rn );
2.801 check_walign32( R_ECX );
2.802 ADD_imm8s_r32( -4, R_ECX );
2.803 @@ -2362,8 +2433,9 @@
2.804 load_spreg( R_EAX, R_SSR );
2.805 MEM_WRITE_LONG( R_ECX, R_EAX );
2.806 :}
2.807 -STC.L SPC, @-Rn {:
2.808 - check_priv();
2.809 +STC.L SPC, @-Rn {:
2.810 + precheck();
2.811 + check_priv_no_precheck();
2.812 load_reg( R_ECX, Rn );
2.813 check_walign32( R_ECX );
2.814 ADD_imm8s_r32( -4, R_ECX );
2.815 @@ -2372,7 +2444,8 @@
2.816 MEM_WRITE_LONG( R_ECX, R_EAX );
2.817 :}
2.818 STC.L SGR, @-Rn {:
2.819 - check_priv();
2.820 + precheck();
2.821 + check_priv_no_precheck();
2.822 load_reg( R_ECX, Rn );
2.823 check_walign32( R_ECX );
2.824 ADD_imm8s_r32( -4, R_ECX );
2.825 @@ -2381,7 +2454,8 @@
2.826 MEM_WRITE_LONG( R_ECX, R_EAX );
2.827 :}
2.828 STC.L DBR, @-Rn {:
2.829 - check_priv();
2.830 + precheck();
2.831 + check_priv_no_precheck();
2.832 load_reg( R_ECX, Rn );
2.833 check_walign32( R_ECX );
2.834 ADD_imm8s_r32( -4, R_ECX );
2.835 @@ -2390,7 +2464,8 @@
2.836 MEM_WRITE_LONG( R_ECX, R_EAX );
2.837 :}
2.838 STC.L Rm_BANK, @-Rn {:
2.839 - check_priv();
2.840 + precheck();
2.841 + check_priv_no_precheck();
2.842 load_reg( R_ECX, Rn );
2.843 check_walign32( R_ECX );
2.844 ADD_imm8s_r32( -4, R_ECX );
2.845 @@ -2400,6 +2475,7 @@
2.846 :}
2.847 STC.L GBR, @-Rn {:
2.848 load_reg( R_ECX, Rn );
2.849 + precheck();
2.850 check_walign32( R_ECX );
2.851 ADD_imm8s_r32( -4, R_ECX );
2.852 store_reg( R_ECX, Rn );
2.853 @@ -2412,6 +2488,7 @@
2.854 :}
2.855 STS.L FPSCR, @-Rn {:
2.856 load_reg( R_ECX, Rn );
2.857 + precheck();
2.858 check_walign32( R_ECX );
2.859 ADD_imm8s_r32( -4, R_ECX );
2.860 store_reg( R_ECX, Rn );
2.861 @@ -2424,6 +2501,7 @@
2.862 :}
2.863 STS.L FPUL, @-Rn {:
2.864 load_reg( R_ECX, Rn );
2.865 + precheck();
2.866 check_walign32( R_ECX );
2.867 ADD_imm8s_r32( -4, R_ECX );
2.868 store_reg( R_ECX, Rn );
2.869 @@ -2436,6 +2514,7 @@
2.870 :}
2.871 STS.L MACH, @-Rn {:
2.872 load_reg( R_ECX, Rn );
2.873 + precheck();
2.874 check_walign32( R_ECX );
2.875 ADD_imm8s_r32( -4, R_ECX );
2.876 store_reg( R_ECX, Rn );
2.877 @@ -2448,6 +2527,7 @@
2.878 :}
2.879 STS.L MACL, @-Rn {:
2.880 load_reg( R_ECX, Rn );
2.881 + precheck();
2.882 check_walign32( R_ECX );
2.883 ADD_imm8s_r32( -4, R_ECX );
2.884 store_reg( R_ECX, Rn );
2.885 @@ -2460,6 +2540,7 @@
2.886 :}
2.887 STS.L PR, @-Rn {:
2.888 load_reg( R_ECX, Rn );
2.889 + precheck();
2.890 check_walign32( R_ECX );
2.891 ADD_imm8s_r32( -4, R_ECX );
2.892 store_reg( R_ECX, Rn );
2.893 @@ -2469,11 +2550,6 @@
2.894
2.895 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
2.896 %%
2.897 - if( sh4_x86.in_delay_slot ) {
2.898 - ADD_imm8s_r32(2,R_ESI);
2.899 - sh4_x86.in_delay_slot = FALSE;
2.900 - } else {
2.901 - INC_r32(R_ESI);
2.902 - }
2.903 + sh4_x86.in_delay_slot = FALSE;
2.904 return 0;
2.905 }
.