Search
lxdream.org :: lxdream/src/sh4/sh4x86.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.c
changeset 380:2e8166bf6832
prev377:fa18743f6905
next381:aade6c9aca4d
author nkeynes
date Wed Sep 12 11:31:16 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Fix load_spreg/store_spreg
Fix PREF
Add jump target debug checking
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.c Wed Sep 12 09:17:52 2007 +0000
1.2 +++ b/src/sh4/sh4x86.c Wed Sep 12 11:31:16 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4x86.c,v 1.6 2007-09-12 09:17:52 nkeynes Exp $
1.6 + * $Id: sh4x86.c,v 1.7 2007-09-12 11:31:16 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 @@ -20,6 +20,10 @@
1.11
1.12 #include <assert.h>
1.13
1.14 +#ifndef NDEBUG
1.15 +#define DEBUG_JUMPS 1
1.16 +#endif
1.17 +
1.18 #include "sh4/sh4core.h"
1.19 #include "sh4/sh4trans.h"
1.20 #include "sh4/x86op.h"
1.21 @@ -77,15 +81,6 @@
1.22 }
1.23 }
1.24
1.25 -#ifndef NDEBUG
1.26 -#define MARK_JMP(x,n) uint8_t *_mark_jmp_##x = xlat_output + n
1.27 -#define CHECK_JMP(x) assert( _mark_jmp_##x == xlat_output )
1.28 -#else
1.29 -#define MARK_JMP(x,n)
1.30 -#define CHECK_JMP(x)
1.31 -#endif
1.32 -
1.33 -
1.34 /**
1.35 * Emit an instruction to load an SH4 reg into a real register
1.36 */
1.37 @@ -112,14 +107,8 @@
1.38
1.39 }
1.40
1.41 -static inline void load_spreg( int x86reg, int regoffset )
1.42 -{
1.43 - /* mov [bp+n], reg */
1.44 - OP(0x8B);
1.45 - OP(0x45 + (x86reg<<3));
1.46 - OP(regoffset);
1.47 -}
1.48 -
1.49 +#define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
1.50 +#define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
1.51 /**
1.52 * Emit an instruction to load an immediate value into a register
1.53 */
1.54 @@ -138,13 +127,6 @@
1.55 OP(0x45 + (x86reg<<3));
1.56 OP(REG_OFFSET(r[sh4reg]));
1.57 }
1.58 -void static inline store_spreg( int x86reg, int regoffset ) {
1.59 - /* mov reg, [bp+n] */
1.60 - OP(0x89);
1.61 - OP(0x45 + (x86reg<<3));
1.62 - OP(regoffset);
1.63 -}
1.64 -
1.65
1.66 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
1.67
1.68 @@ -368,6 +350,7 @@
1.69 load_imm32( R_EBP, (uint32_t)&sh4r );
1.70 PUSH_r32(R_EDI);
1.71 PUSH_r32(R_ESI);
1.72 + XOR_r32_r32(R_ESI, R_ESI);
1.73
1.74 sh4_x86.in_delay_slot = FALSE;
1.75 sh4_x86.priv_checked = FALSE;
1.76 @@ -404,17 +387,22 @@
1.77 uint8_t *end_ptr = xlat_output;
1.78 // Exception termination. Jump block for various exception codes:
1.79 PUSH_imm32( EXC_DATA_ADDR_READ );
1.80 - JMP_rel8( 33 );
1.81 + JMP_rel8( 33, target1 );
1.82 PUSH_imm32( EXC_DATA_ADDR_WRITE );
1.83 - JMP_rel8( 26 );
1.84 + JMP_rel8( 26, target2 );
1.85 PUSH_imm32( EXC_ILLEGAL );
1.86 - JMP_rel8( 19 );
1.87 + JMP_rel8( 19, target3 );
1.88 PUSH_imm32( EXC_SLOT_ILLEGAL );
1.89 - JMP_rel8( 12 );
1.90 + JMP_rel8( 12, target4 );
1.91 PUSH_imm32( EXC_FPU_DISABLED );
1.92 - JMP_rel8( 5 );
1.93 + JMP_rel8( 5, target5 );
1.94 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
1.95 // target
1.96 + JMP_TARGET(target1);
1.97 + JMP_TARGET(target2);
1.98 + JMP_TARGET(target3);
1.99 + JMP_TARGET(target4);
1.100 + JMP_TARGET(target5);
1.101 load_spreg( R_ECX, REG_OFFSET(pc) );
1.102 ADD_r32_r32( R_ESI, R_ECX );
1.103 ADD_r32_r32( R_ESI, R_ECX );
1.104 @@ -539,8 +527,9 @@
1.105 PUSH_r32( R_EAX );
1.106 AND_imm32_r32( 0xFC000000, R_EAX );
1.107 CMP_imm32_r32( 0xE0000000, R_EAX );
1.108 - JNE_rel8(8);
1.109 + JNE_rel8(7, end);
1.110 call_func0( sh4_flush_store_queue );
1.111 + JMP_TARGET(end);
1.112 ADD_imm8s_r32( 4, R_ESP );
1.113 }
1.114 break;
1.115 @@ -947,13 +936,16 @@
1.116 load_reg( R_ECX, Rn );
1.117 XOR_r32_r32( R_ECX, R_EAX );
1.118 TEST_r8_r8( R_AL, R_AL );
1.119 - JE_rel8(13);
1.120 + JE_rel8(13, target1);
1.121 TEST_r8_r8( R_AH, R_AH ); // 2
1.122 - JE_rel8(9);
1.123 + JE_rel8(9, target2);
1.124 SHR_imm8_r32( 16, R_EAX ); // 3
1.125 TEST_r8_r8( R_AL, R_AL ); // 2
1.126 - JE_rel8(2);
1.127 + JE_rel8(2, target3);
1.128 TEST_r8_r8( R_AH, R_AH ); // 2
1.129 + JMP_TARGET(target1);
1.130 + JMP_TARGET(target2);
1.131 + JMP_TARGET(target3);
1.132 SETE_t();
1.133 }
1.134 break;
1.135 @@ -1029,10 +1021,12 @@
1.136 SETC_r32( R_EDX ); // Q
1.137 load_spreg( R_EAX, R_Q );
1.138 CMP_sh4r_r32( R_M, R_EAX );
1.139 - JE_rel8(8);
1.140 + JE_rel8(8,mqequal);
1.141 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
1.142 - JMP_rel8(3);
1.143 + JMP_rel8(3, mqnotequal);
1.144 + JMP_TARGET(mqequal);
1.145 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
1.146 + JMP_TARGET(mqnotequal);
1.147 // TODO
1.148 }
1.149 break;
1.150 @@ -1745,16 +1739,16 @@
1.151 load_reg( R_EAX, Rn );
1.152 load_reg( R_ECX, Rm );
1.153 CMP_imm32_r32( 0, R_ECX );
1.154 - JAE_rel8(9);
1.155 + JAE_rel8(9, doshl);
1.156
1.157 NEG_r32( R_ECX ); // 2
1.158 AND_imm8_r8( 0x1F, R_CL ); // 3
1.159 SAR_r32_CL( R_EAX ); // 2
1.160 - JMP_rel8(5); // 2
1.161 -
1.162 + JMP_rel8(5, end); // 2
1.163 + JMP_TARGET(doshl);
1.164 AND_imm8_r8( 0x1F, R_CL ); // 3
1.165 SHL_r32_CL( R_EAX ); // 2
1.166 -
1.167 + JMP_TARGET(end);
1.168 store_reg( R_EAX, Rn );
1.169 }
1.170 break;
1.171 @@ -2059,8 +2053,9 @@
1.172 } else {
1.173 load_imm32( R_EDI, pc + 2 );
1.174 CMP_imm8s_sh4r( 0, R_T );
1.175 - JE_rel8( 5 );
1.176 + JE_rel8( 5, nottaken );
1.177 load_imm32( R_EDI, disp + pc + 4 );
1.178 + JMP_TARGET(nottaken);
1.179 INC_r32(R_ESI);
1.180 return 1;
1.181 }
1.182 @@ -2074,8 +2069,9 @@
1.183 } else {
1.184 load_imm32( R_EDI, pc + 2 );
1.185 CMP_imm8s_sh4r( 0, R_T );
1.186 - JNE_rel8( 5 );
1.187 + JNE_rel8( 5, nottaken );
1.188 load_imm32( R_EDI, disp + pc + 4 );
1.189 + JMP_TARGET(nottaken);
1.190 INC_r32(R_ESI);
1.191 return 1;
1.192 }
1.193 @@ -2089,8 +2085,9 @@
1.194 } else {
1.195 load_imm32( R_EDI, pc + 2 );
1.196 CMP_imm8s_sh4r( 0, R_T );
1.197 - JE_rel8( 5 );
1.198 + JE_rel8( 5, nottaken );
1.199 load_imm32( R_EDI, disp + pc + 4 );
1.200 + JMP_TARGET(nottaken);
1.201 sh4_x86.in_delay_slot = TRUE;
1.202 INC_r32(R_ESI);
1.203 return 0;
1.204 @@ -2105,8 +2102,9 @@
1.205 } else {
1.206 load_imm32( R_EDI, pc + 2 );
1.207 CMP_imm8s_sh4r( 0, R_T );
1.208 - JNE_rel8( 5 );
1.209 + JNE_rel8( 5, nottaken );
1.210 load_imm32( R_EDI, disp + pc + 4 );
1.211 + JMP_TARGET(nottaken);
1.212 sh4_x86.in_delay_slot = TRUE;
1.213 INC_r32(R_ESI);
1.214 return 0;
1.215 @@ -2346,16 +2344,18 @@
1.216 load_spreg( R_ECX, R_FPSCR );
1.217 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.218 load_fr_bank( R_EDX );
1.219 - JNE_rel8(13);
1.220 + JNE_rel8(13,doubleprec);
1.221 push_fr(R_EDX, FRm);
1.222 push_fr(R_EDX, FRn);
1.223 FADDP_st(1);
1.224 pop_fr(R_EDX, FRn);
1.225 - JMP_rel8(11);
1.226 + JMP_rel8(11,end);
1.227 + JMP_TARGET(doubleprec);
1.228 push_dr(R_EDX, FRm);
1.229 push_dr(R_EDX, FRn);
1.230 FADDP_st(1);
1.231 pop_dr(R_EDX, FRn);
1.232 + JMP_TARGET(end);
1.233 }
1.234 break;
1.235 case 0x1:
1.236 @@ -2365,16 +2365,18 @@
1.237 load_spreg( R_ECX, R_FPSCR );
1.238 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.239 load_fr_bank( R_EDX );
1.240 - JNE_rel8(13);
1.241 + JNE_rel8(13, doubleprec);
1.242 push_fr(R_EDX, FRn);
1.243 push_fr(R_EDX, FRm);
1.244 FMULP_st(1);
1.245 pop_fr(R_EDX, FRn);
1.246 - JMP_rel8(11);
1.247 + JMP_rel8(11, end);
1.248 + JMP_TARGET(doubleprec);
1.249 push_dr(R_EDX, FRn);
1.250 push_dr(R_EDX, FRm);
1.251 FMULP_st(1);
1.252 pop_dr(R_EDX, FRn);
1.253 + JMP_TARGET(end);
1.254 }
1.255 break;
1.256 case 0x2:
1.257 @@ -2384,16 +2386,18 @@
1.258 load_spreg( R_ECX, R_FPSCR );
1.259 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.260 load_fr_bank( R_EDX );
1.261 - JNE_rel8(13);
1.262 + JNE_rel8(13, doubleprec);
1.263 push_fr(R_EDX, FRm);
1.264 push_fr(R_EDX, FRn);
1.265 FMULP_st(1);
1.266 pop_fr(R_EDX, FRn);
1.267 - JMP_rel8(11);
1.268 + JMP_rel8(11, end);
1.269 + JMP_TARGET(doubleprec);
1.270 push_dr(R_EDX, FRm);
1.271 push_dr(R_EDX, FRn);
1.272 FMULP_st(1);
1.273 pop_dr(R_EDX, FRn);
1.274 + JMP_TARGET(end);
1.275 }
1.276 break;
1.277 case 0x3:
1.278 @@ -2403,16 +2407,18 @@
1.279 load_spreg( R_ECX, R_FPSCR );
1.280 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.281 load_fr_bank( R_EDX );
1.282 - JNE_rel8(13);
1.283 + JNE_rel8(13, doubleprec);
1.284 push_fr(R_EDX, FRn);
1.285 push_fr(R_EDX, FRm);
1.286 FDIVP_st(1);
1.287 pop_fr(R_EDX, FRn);
1.288 - JMP_rel8(11);
1.289 + JMP_rel8(11, end);
1.290 + JMP_TARGET(doubleprec);
1.291 push_dr(R_EDX, FRn);
1.292 push_dr(R_EDX, FRm);
1.293 FDIVP_st(1);
1.294 pop_dr(R_EDX, FRn);
1.295 + JMP_TARGET(end);
1.296 }
1.297 break;
1.298 case 0x4:
1.299 @@ -2422,15 +2428,17 @@
1.300 load_spreg( R_ECX, R_FPSCR );
1.301 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.302 load_fr_bank( R_EDX );
1.303 - JNE_rel8(8);
1.304 + JNE_rel8(8, doubleprec);
1.305 push_fr(R_EDX, FRm);
1.306 push_fr(R_EDX, FRn);
1.307 - JMP_rel8(6);
1.308 + JMP_rel8(6, end);
1.309 + JMP_TARGET(doubleprec);
1.310 push_dr(R_EDX, FRm);
1.311 push_dr(R_EDX, FRn);
1.312 FCOMIP_st(1);
1.313 SETE_t();
1.314 FPOP_st();
1.315 + JMP_TARGET(end);
1.316 }
1.317 break;
1.318 case 0x5:
1.319 @@ -2440,12 +2448,14 @@
1.320 load_spreg( R_ECX, R_FPSCR );
1.321 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.322 load_fr_bank( R_EDX );
1.323 - JNE_rel8(8);
1.324 + JNE_rel8(8, doubleprec);
1.325 push_fr(R_EDX, FRm);
1.326 push_fr(R_EDX, FRn);
1.327 - JMP_rel8(6);
1.328 + JMP_rel8(6, end);
1.329 + JMP_TARGET(doubleprec);
1.330 push_dr(R_EDX, FRm);
1.331 push_dr(R_EDX, FRn);
1.332 + JMP_TARGET(end);
1.333 FCOMIP_st(1);
1.334 SETA_t();
1.335 FPOP_st();
1.336 @@ -2460,22 +2470,28 @@
1.337 check_ralign32( R_EDX );
1.338 load_spreg( R_ECX, R_FPSCR );
1.339 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.340 - JNE_rel8(19);
1.341 + JNE_rel8(19, doublesize);
1.342 MEM_READ_LONG( R_EDX, R_EAX );
1.343 load_fr_bank( R_ECX );
1.344 store_fr( R_ECX, R_EAX, FRn );
1.345 if( FRn&1 ) {
1.346 - JMP_rel8(46);
1.347 + JMP_rel8(46, end);
1.348 + JMP_TARGET(doublesize);
1.349 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.350 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.351 load_xf_bank( R_ECX );
1.352 + store_fr( R_ECX, R_EAX, FRn&0x0E );
1.353 + store_fr( R_ECX, R_EDX, FRn|0x01 );
1.354 + JMP_TARGET(end);
1.355 } else {
1.356 - JMP_rel8(36);
1.357 + JMP_rel8(36, end);
1.358 + JMP_TARGET(doublesize);
1.359 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.360 load_fr_bank( R_ECX );
1.361 + store_fr( R_ECX, R_EAX, FRn&0x0E );
1.362 + store_fr( R_ECX, R_EDX, FRn|0x01 );
1.363 + JMP_TARGET(end);
1.364 }
1.365 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.366 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.367 }
1.368 break;
1.369 case 0x7:
1.370 @@ -2487,20 +2503,27 @@
1.371 check_walign32( R_EDX );
1.372 load_spreg( R_ECX, R_FPSCR );
1.373 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.374 - JNE_rel8(20);
1.375 + JNE_rel8(20, doublesize);
1.376 load_fr_bank( R_ECX );
1.377 load_fr( R_ECX, R_EAX, FRm );
1.378 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.379 if( FRm&1 ) {
1.380 - JMP_rel8( 46 );
1.381 + JMP_rel8( 46, end );
1.382 + JMP_TARGET(doublesize);
1.383 load_xf_bank( R_ECX );
1.384 + load_fr( R_ECX, R_EAX, FRm&0x0E );
1.385 + load_fr( R_ECX, R_ECX, FRm|0x01 );
1.386 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.387 + JMP_TARGET(end);
1.388 } else {
1.389 - JMP_rel8( 39 );
1.390 + JMP_rel8( 39, end );
1.391 + JMP_TARGET(doublesize);
1.392 load_fr_bank( R_ECX );
1.393 + load_fr( R_ECX, R_EAX, FRm&0x0E );
1.394 + load_fr( R_ECX, R_ECX, FRm|0x01 );
1.395 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.396 + JMP_TARGET(end);
1.397 }
1.398 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.399 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.400 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.401 }
1.402 break;
1.403 case 0x8:
1.404 @@ -2511,22 +2534,28 @@
1.405 check_ralign32( R_EDX );
1.406 load_spreg( R_ECX, R_FPSCR );
1.407 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.408 - JNE_rel8(19);
1.409 + JNE_rel8(19, doublesize);
1.410 MEM_READ_LONG( R_EDX, R_EAX );
1.411 load_fr_bank( R_ECX );
1.412 store_fr( R_ECX, R_EAX, FRn );
1.413 if( FRn&1 ) {
1.414 - JMP_rel8(46);
1.415 + JMP_rel8(46, end);
1.416 + JMP_TARGET(doublesize);
1.417 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.418 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.419 load_xf_bank( R_ECX );
1.420 + store_fr( R_ECX, R_EAX, FRn&0x0E );
1.421 + store_fr( R_ECX, R_EDX, FRn|0x01 );
1.422 + JMP_TARGET(end);
1.423 } else {
1.424 - JMP_rel8(36);
1.425 + JMP_rel8(36, end);
1.426 + JMP_TARGET(doublesize);
1.427 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.428 load_fr_bank( R_ECX );
1.429 + store_fr( R_ECX, R_EAX, FRn&0x0E );
1.430 + store_fr( R_ECX, R_EDX, FRn|0x01 );
1.431 + JMP_TARGET(end);
1.432 }
1.433 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.434 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.435 }
1.436 break;
1.437 case 0x9:
1.438 @@ -2538,28 +2567,33 @@
1.439 MOV_r32_r32( R_EDX, R_EAX );
1.440 load_spreg( R_ECX, R_FPSCR );
1.441 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.442 - JNE_rel8(25);
1.443 + JNE_rel8(25, doublesize);
1.444 ADD_imm8s_r32( 4, R_EAX );
1.445 store_reg( R_EAX, Rm );
1.446 MEM_READ_LONG( R_EDX, R_EAX );
1.447 load_fr_bank( R_ECX );
1.448 store_fr( R_ECX, R_EAX, FRn );
1.449 if( FRn&1 ) {
1.450 - JMP_rel8(52);
1.451 + JMP_rel8(52, end);
1.452 + JMP_TARGET(doublesize);
1.453 ADD_imm8s_r32( 8, R_EAX );
1.454 store_reg(R_EAX, Rm);
1.455 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.456 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.457 load_xf_bank( R_ECX );
1.458 + store_fr( R_ECX, R_EAX, FRn&0x0E );
1.459 + store_fr( R_ECX, R_EDX, FRn|0x01 );
1.460 + JMP_TARGET(end);
1.461 } else {
1.462 - JMP_rel8(42);
1.463 + JMP_rel8(42, end);
1.464 ADD_imm8s_r32( 8, R_EAX );
1.465 store_reg(R_EAX, Rm);
1.466 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.467 load_fr_bank( R_ECX );
1.468 + store_fr( R_ECX, R_EAX, FRn&0x0E );
1.469 + store_fr( R_ECX, R_EDX, FRn|0x01 );
1.470 + JMP_TARGET(end);
1.471 }
1.472 - store_fr( R_ECX, R_EAX, FRn&0x0E );
1.473 - store_fr( R_ECX, R_EDX, FRn|0x01 );
1.474 }
1.475 break;
1.476 case 0xA:
1.477 @@ -2570,20 +2604,27 @@
1.478 check_walign32( R_EDX );
1.479 load_spreg( R_ECX, R_FPSCR );
1.480 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.481 - JNE_rel8(20);
1.482 + JNE_rel8(20, doublesize);
1.483 load_fr_bank( R_ECX );
1.484 load_fr( R_ECX, R_EAX, FRm );
1.485 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.486 if( FRm&1 ) {
1.487 - JMP_rel8( 46 );
1.488 + JMP_rel8( 46, end );
1.489 + JMP_TARGET(doublesize);
1.490 load_xf_bank( R_ECX );
1.491 + load_fr( R_ECX, R_EAX, FRm&0x0E );
1.492 + load_fr( R_ECX, R_ECX, FRm|0x01 );
1.493 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.494 + JMP_TARGET(end);
1.495 } else {
1.496 - JMP_rel8( 39 );
1.497 + JMP_rel8( 39, end );
1.498 + JMP_TARGET(doublesize);
1.499 load_fr_bank( R_ECX );
1.500 + load_fr( R_ECX, R_EAX, FRm&0x0E );
1.501 + load_fr( R_ECX, R_ECX, FRm|0x01 );
1.502 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.503 + JMP_TARGET(end);
1.504 }
1.505 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.506 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.507 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.508 }
1.509 break;
1.510 case 0xB:
1.511 @@ -2594,24 +2635,33 @@
1.512 check_walign32( R_EDX );
1.513 load_spreg( R_ECX, R_FPSCR );
1.514 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.515 - JNE_rel8(20);
1.516 + JNE_rel8(20, doublesize);
1.517 load_fr_bank( R_ECX );
1.518 load_fr( R_ECX, R_EAX, FRm );
1.519 ADD_imm8s_r32(-4,R_EDX);
1.520 store_reg( R_EDX, Rn );
1.521 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.522 if( FRm&1 ) {
1.523 - JMP_rel8( 46 );
1.524 + JMP_rel8( 46, end );
1.525 + JMP_TARGET(doublesize);
1.526 load_xf_bank( R_ECX );
1.527 + load_fr( R_ECX, R_EAX, FRm&0x0E );
1.528 + load_fr( R_ECX, R_ECX, FRm|0x01 );
1.529 + ADD_imm8s_r32(-8,R_EDX);
1.530 + store_reg( R_EDX, Rn );
1.531 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.532 + JMP_TARGET(end);
1.533 } else {
1.534 - JMP_rel8( 39 );
1.535 + JMP_rel8( 39, end );
1.536 + JMP_TARGET(doublesize);
1.537 load_fr_bank( R_ECX );
1.538 + load_fr( R_ECX, R_EAX, FRm&0x0E );
1.539 + load_fr( R_ECX, R_ECX, FRm|0x01 );
1.540 + ADD_imm8s_r32(-8,R_EDX);
1.541 + store_reg( R_EDX, Rn );
1.542 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.543 + JMP_TARGET(end);
1.544 }
1.545 - load_fr( R_ECX, R_EAX, FRm&0x0E );
1.546 - load_fr( R_ECX, R_ECX, FRm|0x01 );
1.547 - ADD_imm8s_r32(-8,R_EDX);
1.548 - store_reg( R_EDX, Rn );
1.549 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1.550 }
1.551 break;
1.552 case 0xC:
1.553 @@ -2628,11 +2678,12 @@
1.554 load_spreg( R_ECX, R_FPSCR );
1.555 load_fr_bank( R_EDX );
1.556 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.557 - JNE_rel8(8);
1.558 + JNE_rel8(8, doublesize);
1.559 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
1.560 store_fr( R_EDX, R_EAX, FRn );
1.561 if( FRm&1 ) {
1.562 - JMP_rel8(22);
1.563 + JMP_rel8(22, end);
1.564 + JMP_TARGET(doublesize);
1.565 load_xf_bank( R_ECX );
1.566 load_fr( R_ECX, R_EAX, FRm-1 );
1.567 if( FRn&1 ) {
1.568 @@ -2644,20 +2695,23 @@
1.569 store_fr( R_EDX, R_EAX, FRn-1 );
1.570 store_fr( R_EDX, R_ECX, FRn );
1.571 }
1.572 + JMP_TARGET(end);
1.573 } else /* FRm&1 == 0 */ {
1.574 if( FRn&1 ) {
1.575 - JMP_rel8(22);
1.576 + JMP_rel8(22, end);
1.577 load_xf_bank( R_ECX );
1.578 load_fr( R_EDX, R_EAX, FRm );
1.579 load_fr( R_EDX, R_EDX, FRm+1 );
1.580 store_fr( R_ECX, R_EAX, FRn-1 );
1.581 store_fr( R_ECX, R_EDX, FRn );
1.582 + JMP_TARGET(end);
1.583 } else /* FRn&1 == 0 */ {
1.584 - JMP_rel8(12);
1.585 + JMP_rel8(12, end);
1.586 load_fr( R_EDX, R_EAX, FRm );
1.587 load_fr( R_EDX, R_ECX, FRm+1 );
1.588 store_fr( R_EDX, R_EAX, FRn );
1.589 store_fr( R_EDX, R_ECX, FRn+1 );
1.590 + JMP_TARGET(end);
1.591 }
1.592 }
1.593 }
1.594 @@ -2690,10 +2744,12 @@
1.595 load_spreg(R_EDX, REG_OFFSET(fr_bank));
1.596 FILD_sh4r(R_FPUL);
1.597 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.598 - JNE_rel8(5);
1.599 + JNE_rel8(5, doubleprec);
1.600 pop_fr( R_EDX, FRn );
1.601 - JMP_rel8(3);
1.602 + JMP_rel8(3, end);
1.603 + JMP_TARGET(doubleprec);
1.604 pop_dr( R_EDX, FRn );
1.605 + JMP_TARGET(end);
1.606 }
1.607 break;
1.608 case 0x3:
1.609 @@ -2710,14 +2766,16 @@
1.610 load_spreg( R_ECX, R_FPSCR );
1.611 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.612 load_fr_bank( R_EDX );
1.613 - JNE_rel8(10);
1.614 + JNE_rel8(10, doubleprec);
1.615 push_fr(R_EDX, FRn);
1.616 FCHS_st0();
1.617 pop_fr(R_EDX, FRn);
1.618 - JMP_rel8(8);
1.619 + JMP_rel8(8, end);
1.620 + JMP_TARGET(doubleprec);
1.621 push_dr(R_EDX, FRn);
1.622 FCHS_st0();
1.623 pop_dr(R_EDX, FRn);
1.624 + JMP_TARGET(end);
1.625 }
1.626 break;
1.627 case 0x5:
1.628 @@ -2727,14 +2785,16 @@
1.629 load_spreg( R_ECX, R_FPSCR );
1.630 load_fr_bank( R_EDX );
1.631 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.632 - JNE_rel8(10);
1.633 + JNE_rel8(10, doubleprec);
1.634 push_fr(R_EDX, FRn); // 3
1.635 FABS_st0(); // 2
1.636 pop_fr( R_EDX, FRn); //3
1.637 - JMP_rel8(8); // 2
1.638 + JMP_rel8(8,end); // 2
1.639 + JMP_TARGET(doubleprec);
1.640 push_dr(R_EDX, FRn);
1.641 FABS_st0();
1.642 pop_dr(R_EDX, FRn);
1.643 + JMP_TARGET(end);
1.644 }
1.645 break;
1.646 case 0x6:
1.647 @@ -2744,14 +2804,16 @@
1.648 load_spreg( R_ECX, R_FPSCR );
1.649 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.650 load_fr_bank( R_EDX );
1.651 - JNE_rel8(10);
1.652 + JNE_rel8(10, doubleprec);
1.653 push_fr(R_EDX, FRn);
1.654 FSQRT_st0();
1.655 pop_fr(R_EDX, FRn);
1.656 - JMP_rel8(8);
1.657 + JMP_rel8(8, end);
1.658 + JMP_TARGET(doubleprec);
1.659 push_dr(R_EDX, FRn);
1.660 FSQRT_st0();
1.661 pop_dr(R_EDX, FRn);
1.662 + JMP_TARGET(end);
1.663 }
1.664 break;
1.665 case 0x7:
1.666 @@ -2761,12 +2823,13 @@
1.667 load_spreg( R_ECX, R_FPSCR );
1.668 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.669 load_fr_bank( R_EDX );
1.670 - JNE_rel8(12); // PR=0 only
1.671 + JNE_rel8(12, end); // PR=0 only
1.672 FLD1_st0();
1.673 push_fr(R_EDX, FRn);
1.674 FSQRT_st0();
1.675 FDIVP_st(1);
1.676 pop_fr(R_EDX, FRn);
1.677 + JMP_TARGET(end);
1.678 }
1.679 break;
1.680 case 0x8:
1.681 @@ -2776,10 +2839,11 @@
1.682 check_fpuen();
1.683 load_spreg( R_ECX, R_FPSCR );
1.684 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.685 - JNE_rel8(8);
1.686 + JNE_rel8(8, end);
1.687 XOR_r32_r32( R_EAX, R_EAX );
1.688 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1.689 store_fr( R_ECX, R_EAX, FRn );
1.690 + JMP_TARGET(end);
1.691 }
1.692 break;
1.693 case 0x9:
1.694 @@ -2789,10 +2853,11 @@
1.695 check_fpuen();
1.696 load_spreg( R_ECX, R_FPSCR );
1.697 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.698 - JNE_rel8(11);
1.699 + JNE_rel8(11, end);
1.700 load_imm32(R_EAX, 0x3F800000);
1.701 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1.702 store_fr( R_ECX, R_EAX, FRn );
1.703 + JMP_TARGET(end);
1.704 }
1.705 break;
1.706 case 0xA:
1.707 @@ -2802,10 +2867,11 @@
1.708 check_fpuen();
1.709 load_spreg( R_ECX, R_FPSCR );
1.710 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.711 - JE_rel8(9); // only when PR=1
1.712 + JE_rel8(9, end); // only when PR=1
1.713 load_fr_bank( R_ECX );
1.714 push_fpul();
1.715 pop_dr( R_ECX, FRn );
1.716 + JMP_TARGET(end);
1.717 }
1.718 break;
1.719 case 0xB:
1.720 @@ -2814,10 +2880,11 @@
1.721 check_fpuen();
1.722 load_spreg( R_ECX, R_FPSCR );
1.723 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.724 - JE_rel8(9); // only when PR=1
1.725 + JE_rel8(9, end); // only when PR=1
1.726 load_fr_bank( R_ECX );
1.727 push_dr( R_ECX, FRm );
1.728 pop_fpul();
1.729 + JMP_TARGET(end);
1.730 }
1.731 break;
1.732 case 0xE:
1.733 @@ -2891,20 +2958,22 @@
1.734 load_spreg( R_ECX, R_FPSCR );
1.735 load_spreg( R_EDX, REG_OFFSET(fr_bank));
1.736 TEST_imm32_r32( FPSCR_PR, R_ECX );
1.737 - JNE_rel8(18);
1.738 + JNE_rel8(18, doubleprec);
1.739 push_fr( R_EDX, 0 );
1.740 push_fr( R_EDX, FRm );
1.741 FMULP_st(1);
1.742 push_fr( R_EDX, FRn );
1.743 FADDP_st(1);
1.744 pop_fr( R_EDX, FRn );
1.745 - JMP_rel8(16);
1.746 + JMP_rel8(16, end);
1.747 + JMP_TARGET(doubleprec);
1.748 push_dr( R_EDX, 0 );
1.749 push_dr( R_EDX, FRm );
1.750 FMULP_st(1);
1.751 push_dr( R_EDX, FRn );
1.752 FADDP_st(1);
1.753 pop_dr( R_EDX, FRn );
1.754 + JMP_TARGET(end);
1.755 }
1.756 break;
1.757 default:
.