Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 901:32c5cf5e206f
prev879:a07af43e03c4
next903:1337c7a7dd6b
author nkeynes
date Sun Oct 26 02:28:29 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Move the precision/size tests to translation-time rather than execution-time,
and flush/retranslate on a mismatch. Shaves a few percent off the core runtime
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.in Sun Oct 19 05:42:05 2008 +0000
1.2 +++ b/src/sh4/sh4x86.in Sun Oct 26 02:28:29 2008 +0000
1.3 @@ -55,6 +55,8 @@
1.4 gboolean priv_checked; /* true if we've already checked the cpu mode. */
1.5 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
1.6 gboolean branch_taken; /* true if we branched unconditionally */
1.7 + gboolean double_prec; /* true if FPU is in double-precision mode */
1.8 + gboolean double_size; /* true if FPU is in double-size mode */
1.9 uint32_t block_start_pc;
1.10 uint32_t stack_posn; /* Trace stack height for alignment purposes */
1.11 int tstate;
1.12 @@ -311,12 +313,28 @@
1.13 #endif
1.14 #endif
1.15
1.16 +void sh4_translate_begin_block( sh4addr_t pc )
1.17 +{
1.18 + enter_block();
1.19 + sh4_x86.in_delay_slot = FALSE;
1.20 + sh4_x86.priv_checked = FALSE;
1.21 + sh4_x86.fpuen_checked = FALSE;
1.22 + sh4_x86.branch_taken = FALSE;
1.23 + sh4_x86.backpatch_posn = 0;
1.24 + sh4_x86.block_start_pc = pc;
1.25 + sh4_x86.tlb_on = IS_MMU_ENABLED();
1.26 + sh4_x86.tstate = TSTATE_NONE;
1.27 + sh4_x86.double_prec = sh4r.fpscr & FPSCR_PR;
1.28 + sh4_x86.double_size = sh4r.fpscr & FPSCR_SZ;
1.29 +}
1.30 +
1.31 +
1.32 uint32_t sh4_translate_end_block_size()
1.33 {
1.34 if( sh4_x86.backpatch_posn <= 3 ) {
1.35 - return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
1.36 + return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
1.37 } else {
1.38 - return EPILOGUE_SIZE + 48 + (sh4_x86.backpatch_posn-3)*15;
1.39 + return EPILOGUE_SIZE + 48 + (sh4_x86.backpatch_posn-3)*15;
1.40 }
1.41 }
1.42
1.43 @@ -1812,118 +1830,92 @@
1.44 FMOV FRm, FRn {:
1.45 COUNT_INST(I_FMOV1);
1.46 check_fpuen();
1.47 - load_spreg( R_ECX, R_FPSCR );
1.48 - TEST_imm32_r32( FPSCR_SZ, R_ECX );
1.49 - JNE_rel8(doublesize);
1.50 - load_fr( R_EAX, FRm ); // SZ=0 branch
1.51 - store_fr( R_EAX, FRn );
1.52 - JMP_rel8(end);
1.53 - JMP_TARGET(doublesize);
1.54 - load_dr0( R_EAX, FRm );
1.55 - load_dr1( R_ECX, FRm );
1.56 - store_dr0( R_EAX, FRn );
1.57 - store_dr1( R_ECX, FRn );
1.58 - JMP_TARGET(end);
1.59 - sh4_x86.tstate = TSTATE_NONE;
1.60 + if( sh4_x86.double_size ) {
1.61 + load_dr0( R_EAX, FRm );
1.62 + load_dr1( R_ECX, FRm );
1.63 + store_dr0( R_EAX, FRn );
1.64 + store_dr1( R_ECX, FRn );
1.65 + } else {
1.66 + load_fr( R_EAX, FRm ); // SZ=0 branch
1.67 + store_fr( R_EAX, FRn );
1.68 + }
1.69 :}
1.70 FMOV FRm, @Rn {:
1.71 COUNT_INST(I_FMOV2);
1.72 check_fpuen();
1.73 load_reg( R_EAX, Rn );
1.74 - load_spreg( R_EDX, R_FPSCR );
1.75 - TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.76 - JNE_rel8(doublesize);
1.77 -
1.78 - check_walign32( R_EAX );
1.79 - MMU_TRANSLATE_WRITE( R_EAX );
1.80 - load_fr( R_ECX, FRm );
1.81 - MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.82 - JMP_rel8(end);
1.83 -
1.84 - JMP_TARGET(doublesize);
1.85 - check_walign64( R_EAX );
1.86 - MMU_TRANSLATE_WRITE( R_EAX );
1.87 - load_dr0( R_ECX, FRm );
1.88 - load_dr1( R_EDX, FRm );
1.89 - MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.90 - JMP_TARGET(end);
1.91 + if( sh4_x86.double_size ) {
1.92 + check_walign64( R_EAX );
1.93 + MMU_TRANSLATE_WRITE( R_EAX );
1.94 + load_dr0( R_ECX, FRm );
1.95 + load_dr1( R_EDX, FRm );
1.96 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.97 + } else {
1.98 + check_walign32( R_EAX );
1.99 + MMU_TRANSLATE_WRITE( R_EAX );
1.100 + load_fr( R_ECX, FRm );
1.101 + MEM_WRITE_LONG( R_EAX, R_ECX );
1.102 + }
1.103 sh4_x86.tstate = TSTATE_NONE;
1.104 :}
1.105 FMOV @Rm, FRn {:
1.106 COUNT_INST(I_FMOV5);
1.107 check_fpuen();
1.108 load_reg( R_EAX, Rm );
1.109 - load_spreg( R_EDX, R_FPSCR );
1.110 - TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.111 - JNE_rel8(doublesize);
1.112 -
1.113 - check_ralign32( R_EAX );
1.114 - MMU_TRANSLATE_READ( R_EAX );
1.115 - MEM_READ_LONG( R_EAX, R_EAX );
1.116 - store_fr( R_EAX, FRn );
1.117 - JMP_rel8(end);
1.118 -
1.119 - JMP_TARGET(doublesize);
1.120 - check_ralign64( R_EAX );
1.121 - MMU_TRANSLATE_READ( R_EAX );
1.122 - MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.123 - store_dr0( R_ECX, FRn );
1.124 - store_dr1( R_EAX, FRn );
1.125 - JMP_TARGET(end);
1.126 + if( sh4_x86.double_size ) {
1.127 + check_ralign64( R_EAX );
1.128 + MMU_TRANSLATE_READ( R_EAX );
1.129 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.130 + store_dr0( R_ECX, FRn );
1.131 + store_dr1( R_EAX, FRn );
1.132 + } else {
1.133 + check_ralign32( R_EAX );
1.134 + MMU_TRANSLATE_READ( R_EAX );
1.135 + MEM_READ_LONG( R_EAX, R_EAX );
1.136 + store_fr( R_EAX, FRn );
1.137 + }
1.138 sh4_x86.tstate = TSTATE_NONE;
1.139 :}
1.140 FMOV FRm, @-Rn {:
1.141 COUNT_INST(I_FMOV3);
1.142 check_fpuen();
1.143 load_reg( R_EAX, Rn );
1.144 - load_spreg( R_EDX, R_FPSCR );
1.145 - TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.146 - JNE_rel8(doublesize);
1.147 -
1.148 - check_walign32( R_EAX );
1.149 - ADD_imm8s_r32( -4, R_EAX );
1.150 - MMU_TRANSLATE_WRITE( R_EAX );
1.151 - load_fr( R_ECX, FRm );
1.152 - ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
1.153 - MEM_WRITE_LONG( R_EAX, R_ECX );
1.154 - JMP_rel8(end);
1.155 -
1.156 - JMP_TARGET(doublesize);
1.157 - check_walign64( R_EAX );
1.158 - ADD_imm8s_r32(-8,R_EAX);
1.159 - MMU_TRANSLATE_WRITE( R_EAX );
1.160 - load_dr0( R_ECX, FRm );
1.161 - load_dr1( R_EDX, FRm );
1.162 - ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1.163 - MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.164 - JMP_TARGET(end);
1.165 -
1.166 + if( sh4_x86.double_size ) {
1.167 + check_walign64( R_EAX );
1.168 + ADD_imm8s_r32(-8,R_EAX);
1.169 + MMU_TRANSLATE_WRITE( R_EAX );
1.170 + load_dr0( R_ECX, FRm );
1.171 + load_dr1( R_EDX, FRm );
1.172 + ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1.173 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.174 + } else {
1.175 + check_walign32( R_EAX );
1.176 + ADD_imm8s_r32( -4, R_EAX );
1.177 + MMU_TRANSLATE_WRITE( R_EAX );
1.178 + load_fr( R_ECX, FRm );
1.179 + ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
1.180 + MEM_WRITE_LONG( R_EAX, R_ECX );
1.181 + }
1.182 sh4_x86.tstate = TSTATE_NONE;
1.183 :}
1.184 FMOV @Rm+, FRn {:
1.185 COUNT_INST(I_FMOV6);
1.186 check_fpuen();
1.187 load_reg( R_EAX, Rm );
1.188 - load_spreg( R_EDX, R_FPSCR );
1.189 - TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.190 - JNE_rel8(doublesize);
1.191 -
1.192 - check_ralign32( R_EAX );
1.193 - MMU_TRANSLATE_READ( R_EAX );
1.194 - ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.195 - MEM_READ_LONG( R_EAX, R_EAX );
1.196 - store_fr( R_EAX, FRn );
1.197 - JMP_rel8(end);
1.198 -
1.199 - JMP_TARGET(doublesize);
1.200 - check_ralign64( R_EAX );
1.201 - MMU_TRANSLATE_READ( R_EAX );
1.202 - ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1.203 - MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.204 - store_dr0( R_ECX, FRn );
1.205 - store_dr1( R_EAX, FRn );
1.206 - JMP_TARGET(end);
1.207 -
1.208 + if( sh4_x86.double_size ) {
1.209 + check_ralign64( R_EAX );
1.210 + MMU_TRANSLATE_READ( R_EAX );
1.211 + ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1.212 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.213 + store_dr0( R_ECX, FRn );
1.214 + store_dr1( R_EAX, FRn );
1.215 + } else {
1.216 + check_ralign32( R_EAX );
1.217 + MMU_TRANSLATE_READ( R_EAX );
1.218 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.219 + MEM_READ_LONG( R_EAX, R_EAX );
1.220 + store_fr( R_EAX, FRn );
1.221 + }
1.222 sh4_x86.tstate = TSTATE_NONE;
1.223 :}
1.224 FMOV FRm, @(R0, Rn) {:
1.225 @@ -1931,24 +1923,18 @@
1.226 check_fpuen();
1.227 load_reg( R_EAX, Rn );
1.228 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1.229 - load_spreg( R_EDX, R_FPSCR );
1.230 - TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.231 - JNE_rel8(doublesize);
1.232 -
1.233 - check_walign32( R_EAX );
1.234 - MMU_TRANSLATE_WRITE( R_EAX );
1.235 - load_fr( R_ECX, FRm );
1.236 - MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.237 - JMP_rel8(end);
1.238 -
1.239 - JMP_TARGET(doublesize);
1.240 - check_walign64( R_EAX );
1.241 - MMU_TRANSLATE_WRITE( R_EAX );
1.242 - load_dr0( R_ECX, FRm );
1.243 - load_dr1( R_EDX, FRm );
1.244 - MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.245 - JMP_TARGET(end);
1.246 -
1.247 + if( sh4_x86.double_size ) {
1.248 + check_walign64( R_EAX );
1.249 + MMU_TRANSLATE_WRITE( R_EAX );
1.250 + load_dr0( R_ECX, FRm );
1.251 + load_dr1( R_EDX, FRm );
1.252 + MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1.253 + } else {
1.254 + check_walign32( R_EAX );
1.255 + MMU_TRANSLATE_WRITE( R_EAX );
1.256 + load_fr( R_ECX, FRm );
1.257 + MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1.258 + }
1.259 sh4_x86.tstate = TSTATE_NONE;
1.260 :}
1.261 FMOV @(R0, Rm), FRn {:
1.262 @@ -1956,74 +1942,56 @@
1.263 check_fpuen();
1.264 load_reg( R_EAX, Rm );
1.265 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1.266 - load_spreg( R_EDX, R_FPSCR );
1.267 - TEST_imm32_r32( FPSCR_SZ, R_EDX );
1.268 - JNE_rel8(doublesize);
1.269 -
1.270 - check_ralign32( R_EAX );
1.271 - MMU_TRANSLATE_READ( R_EAX );
1.272 - MEM_READ_LONG( R_EAX, R_EAX );
1.273 - store_fr( R_EAX, FRn );
1.274 - JMP_rel8(end);
1.275 -
1.276 - JMP_TARGET(doublesize);
1.277 - check_ralign64( R_EAX );
1.278 - MMU_TRANSLATE_READ( R_EAX );
1.279 - MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.280 - store_dr0( R_ECX, FRn );
1.281 - store_dr1( R_EAX, FRn );
1.282 - JMP_TARGET(end);
1.283 -
1.284 + if( sh4_x86.double_size ) {
1.285 + check_ralign64( R_EAX );
1.286 + MMU_TRANSLATE_READ( R_EAX );
1.287 + MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1.288 + store_dr0( R_ECX, FRn );
1.289 + store_dr1( R_EAX, FRn );
1.290 + } else {
1.291 + check_ralign32( R_EAX );
1.292 + MMU_TRANSLATE_READ( R_EAX );
1.293 + MEM_READ_LONG( R_EAX, R_EAX );
1.294 + store_fr( R_EAX, FRn );
1.295 + }
1.296 sh4_x86.tstate = TSTATE_NONE;
1.297 :}
1.298 FLDI0 FRn {: /* IFF PR=0 */
1.299 COUNT_INST(I_FLDI0);
1.300 check_fpuen();
1.301 - load_spreg( R_ECX, R_FPSCR );
1.302 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.303 - JNE_rel8(end);
1.304 - XOR_r32_r32( R_EAX, R_EAX );
1.305 - store_fr( R_EAX, FRn );
1.306 - JMP_TARGET(end);
1.307 + if( sh4_x86.double_prec == 0 ) {
1.308 + XOR_r32_r32( R_EAX, R_EAX );
1.309 + store_fr( R_EAX, FRn );
1.310 + }
1.311 sh4_x86.tstate = TSTATE_NONE;
1.312 :}
1.313 FLDI1 FRn {: /* IFF PR=0 */
1.314 COUNT_INST(I_FLDI1);
1.315 check_fpuen();
1.316 - load_spreg( R_ECX, R_FPSCR );
1.317 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.318 - JNE_rel8(end);
1.319 - load_imm32(R_EAX, 0x3F800000);
1.320 - store_fr( R_EAX, FRn );
1.321 - JMP_TARGET(end);
1.322 - sh4_x86.tstate = TSTATE_NONE;
1.323 + if( sh4_x86.double_prec == 0 ) {
1.324 + load_imm32(R_EAX, 0x3F800000);
1.325 + store_fr( R_EAX, FRn );
1.326 + }
1.327 :}
1.328
1.329 FLOAT FPUL, FRn {:
1.330 COUNT_INST(I_FLOAT);
1.331 check_fpuen();
1.332 - load_spreg( R_ECX, R_FPSCR );
1.333 FILD_sh4r(R_FPUL);
1.334 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.335 - JNE_rel8(doubleprec);
1.336 - pop_fr( FRn );
1.337 - JMP_rel8(end);
1.338 - JMP_TARGET(doubleprec);
1.339 - pop_dr( FRn );
1.340 - JMP_TARGET(end);
1.341 - sh4_x86.tstate = TSTATE_NONE;
1.342 + if( sh4_x86.double_prec ) {
1.343 + pop_dr( FRn );
1.344 + } else {
1.345 + pop_fr( FRn );
1.346 + }
1.347 :}
1.348 FTRC FRm, FPUL {:
1.349 COUNT_INST(I_FTRC);
1.350 check_fpuen();
1.351 - load_spreg( R_ECX, R_FPSCR );
1.352 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.353 - JNE_rel8(doubleprec);
1.354 - push_fr( FRm );
1.355 - JMP_rel8(doop);
1.356 - JMP_TARGET(doubleprec);
1.357 - push_dr( FRm );
1.358 - JMP_TARGET( doop );
1.359 + if( sh4_x86.double_prec ) {
1.360 + push_dr( FRm );
1.361 + } else {
1.362 + push_fr( FRm );
1.363 + }
1.364 load_ptr( R_ECX, &max_int );
1.365 FILD_r32ind( R_ECX );
1.366 FCOMIP_st(1);
1.367 @@ -2053,289 +2021,232 @@
1.368 check_fpuen();
1.369 load_fr( R_EAX, FRm );
1.370 store_spreg( R_EAX, R_FPUL );
1.371 - sh4_x86.tstate = TSTATE_NONE;
1.372 :}
1.373 FSTS FPUL, FRn {:
1.374 COUNT_INST(I_FSTS);
1.375 check_fpuen();
1.376 load_spreg( R_EAX, R_FPUL );
1.377 store_fr( R_EAX, FRn );
1.378 - sh4_x86.tstate = TSTATE_NONE;
1.379 :}
1.380 FCNVDS FRm, FPUL {:
1.381 COUNT_INST(I_FCNVDS);
1.382 check_fpuen();
1.383 - load_spreg( R_ECX, R_FPSCR );
1.384 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.385 - JE_rel8(end); // only when PR=1
1.386 - push_dr( FRm );
1.387 - pop_fpul();
1.388 - JMP_TARGET(end);
1.389 - sh4_x86.tstate = TSTATE_NONE;
1.390 + if( sh4_x86.double_prec ) {
1.391 + push_dr( FRm );
1.392 + pop_fpul();
1.393 + }
1.394 :}
1.395 FCNVSD FPUL, FRn {:
1.396 COUNT_INST(I_FCNVSD);
1.397 check_fpuen();
1.398 - load_spreg( R_ECX, R_FPSCR );
1.399 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.400 - JE_rel8(end); // only when PR=1
1.401 - push_fpul();
1.402 - pop_dr( FRn );
1.403 - JMP_TARGET(end);
1.404 - sh4_x86.tstate = TSTATE_NONE;
1.405 + if( sh4_x86.double_prec ) {
1.406 + push_fpul();
1.407 + pop_dr( FRn );
1.408 + }
1.409 :}
1.410
1.411 /* Floating point instructions */
1.412 FABS FRn {:
1.413 COUNT_INST(I_FABS);
1.414 check_fpuen();
1.415 - load_spreg( R_ECX, R_FPSCR );
1.416 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.417 - JNE_rel8(doubleprec);
1.418 - push_fr(FRn); // 6
1.419 - FABS_st0(); // 2
1.420 - pop_fr(FRn); //6
1.421 - JMP_rel8(end); // 2
1.422 - JMP_TARGET(doubleprec);
1.423 - push_dr(FRn);
1.424 - FABS_st0();
1.425 - pop_dr(FRn);
1.426 - JMP_TARGET(end);
1.427 - sh4_x86.tstate = TSTATE_NONE;
1.428 + if( sh4_x86.double_prec ) {
1.429 + push_dr(FRn);
1.430 + FABS_st0();
1.431 + pop_dr(FRn);
1.432 + } else {
1.433 + push_fr(FRn);
1.434 + FABS_st0();
1.435 + pop_fr(FRn);
1.436 + }
1.437 :}
1.438 FADD FRm, FRn {:
1.439 COUNT_INST(I_FADD);
1.440 check_fpuen();
1.441 - load_spreg( R_ECX, R_FPSCR );
1.442 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.443 - JNE_rel8(doubleprec);
1.444 - push_fr(FRm);
1.445 - push_fr(FRn);
1.446 - FADDP_st(1);
1.447 - pop_fr(FRn);
1.448 - JMP_rel8(end);
1.449 - JMP_TARGET(doubleprec);
1.450 - push_dr(FRm);
1.451 - push_dr(FRn);
1.452 - FADDP_st(1);
1.453 - pop_dr(FRn);
1.454 - JMP_TARGET(end);
1.455 - sh4_x86.tstate = TSTATE_NONE;
1.456 + if( sh4_x86.double_prec ) {
1.457 + push_dr(FRm);
1.458 + push_dr(FRn);
1.459 + FADDP_st(1);
1.460 + pop_dr(FRn);
1.461 + } else {
1.462 + push_fr(FRm);
1.463 + push_fr(FRn);
1.464 + FADDP_st(1);
1.465 + pop_fr(FRn);
1.466 + }
1.467 :}
1.468 FDIV FRm, FRn {:
1.469 COUNT_INST(I_FDIV);
1.470 check_fpuen();
1.471 - load_spreg( R_ECX, R_FPSCR );
1.472 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.473 - JNE_rel8(doubleprec);
1.474 - push_fr(FRn);
1.475 - push_fr(FRm);
1.476 - FDIVP_st(1);
1.477 - pop_fr(FRn);
1.478 - JMP_rel8(end);
1.479 - JMP_TARGET(doubleprec);
1.480 - push_dr(FRn);
1.481 - push_dr(FRm);
1.482 - FDIVP_st(1);
1.483 - pop_dr(FRn);
1.484 - JMP_TARGET(end);
1.485 - sh4_x86.tstate = TSTATE_NONE;
1.486 + if( sh4_x86.double_prec ) {
1.487 + push_dr(FRn);
1.488 + push_dr(FRm);
1.489 + FDIVP_st(1);
1.490 + pop_dr(FRn);
1.491 + } else {
1.492 + push_fr(FRn);
1.493 + push_fr(FRm);
1.494 + FDIVP_st(1);
1.495 + pop_fr(FRn);
1.496 + }
1.497 :}
1.498 FMAC FR0, FRm, FRn {:
1.499 COUNT_INST(I_FMAC);
1.500 check_fpuen();
1.501 - load_spreg( R_ECX, R_FPSCR );
1.502 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.503 - JNE_rel8(doubleprec);
1.504 - push_fr( 0 );
1.505 - push_fr( FRm );
1.506 - FMULP_st(1);
1.507 - push_fr( FRn );
1.508 - FADDP_st(1);
1.509 - pop_fr( FRn );
1.510 - JMP_rel8(end);
1.511 - JMP_TARGET(doubleprec);
1.512 - push_dr( 0 );
1.513 - push_dr( FRm );
1.514 - FMULP_st(1);
1.515 - push_dr( FRn );
1.516 - FADDP_st(1);
1.517 - pop_dr( FRn );
1.518 - JMP_TARGET(end);
1.519 - sh4_x86.tstate = TSTATE_NONE;
1.520 + if( sh4_x86.double_prec ) {
1.521 + push_dr( 0 );
1.522 + push_dr( FRm );
1.523 + FMULP_st(1);
1.524 + push_dr( FRn );
1.525 + FADDP_st(1);
1.526 + pop_dr( FRn );
1.527 + } else {
1.528 + push_fr( 0 );
1.529 + push_fr( FRm );
1.530 + FMULP_st(1);
1.531 + push_fr( FRn );
1.532 + FADDP_st(1);
1.533 + pop_fr( FRn );
1.534 + }
1.535 :}
1.536
1.537 FMUL FRm, FRn {:
1.538 COUNT_INST(I_FMUL);
1.539 check_fpuen();
1.540 - load_spreg( R_ECX, R_FPSCR );
1.541 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.542 - JNE_rel8(doubleprec);
1.543 - push_fr(FRm);
1.544 - push_fr(FRn);
1.545 - FMULP_st(1);
1.546 - pop_fr(FRn);
1.547 - JMP_rel8(end);
1.548 - JMP_TARGET(doubleprec);
1.549 - push_dr(FRm);
1.550 - push_dr(FRn);
1.551 - FMULP_st(1);
1.552 - pop_dr(FRn);
1.553 - JMP_TARGET(end);
1.554 - sh4_x86.tstate = TSTATE_NONE;
1.555 + if( sh4_x86.double_prec ) {
1.556 + push_dr(FRm);
1.557 + push_dr(FRn);
1.558 + FMULP_st(1);
1.559 + pop_dr(FRn);
1.560 + } else {
1.561 + push_fr(FRm);
1.562 + push_fr(FRn);
1.563 + FMULP_st(1);
1.564 + pop_fr(FRn);
1.565 + }
1.566 :}
1.567 FNEG FRn {:
1.568 COUNT_INST(I_FNEG);
1.569 check_fpuen();
1.570 - load_spreg( R_ECX, R_FPSCR );
1.571 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.572 - JNE_rel8(doubleprec);
1.573 - push_fr(FRn);
1.574 - FCHS_st0();
1.575 - pop_fr(FRn);
1.576 - JMP_rel8(end);
1.577 - JMP_TARGET(doubleprec);
1.578 - push_dr(FRn);
1.579 - FCHS_st0();
1.580 - pop_dr(FRn);
1.581 - JMP_TARGET(end);
1.582 - sh4_x86.tstate = TSTATE_NONE;
1.583 + if( sh4_x86.double_prec ) {
1.584 + push_dr(FRn);
1.585 + FCHS_st0();
1.586 + pop_dr(FRn);
1.587 + } else {
1.588 + push_fr(FRn);
1.589 + FCHS_st0();
1.590 + pop_fr(FRn);
1.591 + }
1.592 :}
1.593 FSRRA FRn {:
1.594 COUNT_INST(I_FSRRA);
1.595 check_fpuen();
1.596 - load_spreg( R_ECX, R_FPSCR );
1.597 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.598 - JNE_rel8(end); // PR=0 only
1.599 - FLD1_st0();
1.600 - push_fr(FRn);
1.601 - FSQRT_st0();
1.602 - FDIVP_st(1);
1.603 - pop_fr(FRn);
1.604 - JMP_TARGET(end);
1.605 - sh4_x86.tstate = TSTATE_NONE;
1.606 + if( sh4_x86.double_prec == 0 ) {
1.607 + FLD1_st0();
1.608 + push_fr(FRn);
1.609 + FSQRT_st0();
1.610 + FDIVP_st(1);
1.611 + pop_fr(FRn);
1.612 + }
1.613 :}
1.614 FSQRT FRn {:
1.615 COUNT_INST(I_FSQRT);
1.616 check_fpuen();
1.617 - load_spreg( R_ECX, R_FPSCR );
1.618 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.619 - JNE_rel8(doubleprec);
1.620 - push_fr(FRn);
1.621 - FSQRT_st0();
1.622 - pop_fr(FRn);
1.623 - JMP_rel8(end);
1.624 - JMP_TARGET(doubleprec);
1.625 - push_dr(FRn);
1.626 - FSQRT_st0();
1.627 - pop_dr(FRn);
1.628 - JMP_TARGET(end);
1.629 - sh4_x86.tstate = TSTATE_NONE;
1.630 + if( sh4_x86.double_prec ) {
1.631 + push_dr(FRn);
1.632 + FSQRT_st0();
1.633 + pop_dr(FRn);
1.634 + } else {
1.635 + push_fr(FRn);
1.636 + FSQRT_st0();
1.637 + pop_fr(FRn);
1.638 + }
1.639 :}
1.640 FSUB FRm, FRn {:
1.641 COUNT_INST(I_FSUB);
1.642 check_fpuen();
1.643 - load_spreg( R_ECX, R_FPSCR );
1.644 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.645 - JNE_rel8(doubleprec);
1.646 - push_fr(FRn);
1.647 - push_fr(FRm);
1.648 - FSUBP_st(1);
1.649 - pop_fr(FRn);
1.650 - JMP_rel8(end);
1.651 - JMP_TARGET(doubleprec);
1.652 - push_dr(FRn);
1.653 - push_dr(FRm);
1.654 - FSUBP_st(1);
1.655 - pop_dr(FRn);
1.656 - JMP_TARGET(end);
1.657 - sh4_x86.tstate = TSTATE_NONE;
1.658 + if( sh4_x86.double_prec ) {
1.659 + push_dr(FRn);
1.660 + push_dr(FRm);
1.661 + FSUBP_st(1);
1.662 + pop_dr(FRn);
1.663 + } else {
1.664 + push_fr(FRn);
1.665 + push_fr(FRm);
1.666 + FSUBP_st(1);
1.667 + pop_fr(FRn);
1.668 + }
1.669 :}
1.670
1.671 FCMP/EQ FRm, FRn {:
1.672 COUNT_INST(I_FCMPEQ);
1.673 check_fpuen();
1.674 - load_spreg( R_ECX, R_FPSCR );
1.675 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.676 - JNE_rel8(doubleprec);
1.677 - push_fr(FRm);
1.678 - push_fr(FRn);
1.679 - JMP_rel8(end);
1.680 - JMP_TARGET(doubleprec);
1.681 - push_dr(FRm);
1.682 - push_dr(FRn);
1.683 - JMP_TARGET(end);
1.684 + if( sh4_x86.double_prec ) {
1.685 + push_dr(FRm);
1.686 + push_dr(FRn);
1.687 + } else {
1.688 + push_fr(FRm);
1.689 + push_fr(FRn);
1.690 + }
1.691 FCOMIP_st(1);
1.692 SETE_t();
1.693 FPOP_st();
1.694 - sh4_x86.tstate = TSTATE_NONE;
1.695 + sh4_x86.tstate = TSTATE_E;
1.696 :}
1.697 FCMP/GT FRm, FRn {:
1.698 COUNT_INST(I_FCMPGT);
1.699 check_fpuen();
1.700 - load_spreg( R_ECX, R_FPSCR );
1.701 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.702 - JNE_rel8(doubleprec);
1.703 - push_fr(FRm);
1.704 - push_fr(FRn);
1.705 - JMP_rel8(end);
1.706 - JMP_TARGET(doubleprec);
1.707 - push_dr(FRm);
1.708 - push_dr(FRn);
1.709 - JMP_TARGET(end);
1.710 + if( sh4_x86.double_prec ) {
1.711 + push_dr(FRm);
1.712 + push_dr(FRn);
1.713 + } else {
1.714 + push_fr(FRm);
1.715 + push_fr(FRn);
1.716 + }
1.717 FCOMIP_st(1);
1.718 SETA_t();
1.719 FPOP_st();
1.720 - sh4_x86.tstate = TSTATE_NONE;
1.721 + sh4_x86.tstate = TSTATE_A;
1.722 :}
1.723
1.724 FSCA FPUL, FRn {:
1.725 COUNT_INST(I_FSCA);
1.726 check_fpuen();
1.727 - load_spreg( R_ECX, R_FPSCR );
1.728 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.729 - JNE_rel8(doubleprec );
1.730 - LEA_sh4r_rptr( REG_OFFSET(fr[0][FRn&0x0E]), R_ECX );
1.731 - load_spreg( R_EDX, R_FPUL );
1.732 - call_func2( sh4_fsca, R_EDX, R_ECX );
1.733 - JMP_TARGET(doubleprec);
1.734 + if( sh4_x86.double_prec == 0 ) {
1.735 + LEA_sh4r_rptr( REG_OFFSET(fr[0][FRn&0x0E]), R_ECX );
1.736 + load_spreg( R_EDX, R_FPUL );
1.737 + call_func2( sh4_fsca, R_EDX, R_ECX );
1.738 + }
1.739 sh4_x86.tstate = TSTATE_NONE;
1.740 :}
1.741 FIPR FVm, FVn {:
1.742 COUNT_INST(I_FIPR);
1.743 check_fpuen();
1.744 - load_spreg( R_ECX, R_FPSCR );
1.745 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.746 - JNE_rel8( doubleprec);
1.747 -
1.748 - push_fr( FVm<<2 );
1.749 - push_fr( FVn<<2 );
1.750 - FMULP_st(1);
1.751 - push_fr( (FVm<<2)+1);
1.752 - push_fr( (FVn<<2)+1);
1.753 - FMULP_st(1);
1.754 - FADDP_st(1);
1.755 - push_fr( (FVm<<2)+2);
1.756 - push_fr( (FVn<<2)+2);
1.757 - FMULP_st(1);
1.758 - FADDP_st(1);
1.759 - push_fr( (FVm<<2)+3);
1.760 - push_fr( (FVn<<2)+3);
1.761 - FMULP_st(1);
1.762 - FADDP_st(1);
1.763 - pop_fr( (FVn<<2)+3);
1.764 - JMP_TARGET(doubleprec);
1.765 - sh4_x86.tstate = TSTATE_NONE;
1.766 + if( sh4_x86.double_prec == 0 ) {
1.767 + push_fr( FVm<<2 );
1.768 + push_fr( FVn<<2 );
1.769 + FMULP_st(1);
1.770 + push_fr( (FVm<<2)+1);
1.771 + push_fr( (FVn<<2)+1);
1.772 + FMULP_st(1);
1.773 + FADDP_st(1);
1.774 + push_fr( (FVm<<2)+2);
1.775 + push_fr( (FVn<<2)+2);
1.776 + FMULP_st(1);
1.777 + FADDP_st(1);
1.778 + push_fr( (FVm<<2)+3);
1.779 + push_fr( (FVn<<2)+3);
1.780 + FMULP_st(1);
1.781 + FADDP_st(1);
1.782 + pop_fr( (FVn<<2)+3);
1.783 + }
1.784 :}
1.785 FTRV XMTRX, FVn {:
1.786 COUNT_INST(I_FTRV);
1.787 check_fpuen();
1.788 - load_spreg( R_ECX, R_FPSCR );
1.789 - TEST_imm32_r32( FPSCR_PR, R_ECX );
1.790 - JNE_rel8( doubleprec );
1.791 - LEA_sh4r_rptr( REG_OFFSET(fr[0][FVn<<2]), R_EDX );
1.792 - call_func1( sh4_ftrv, R_EDX ); // 12
1.793 - JMP_TARGET(doubleprec);
1.794 + if( sh4_x86.double_prec == 0 ) {
1.795 + LEA_sh4r_rptr( REG_OFFSET(fr[0][FVn<<2]), R_EDX );
1.796 + call_func1( sh4_ftrv, R_EDX );
1.797 + }
1.798 sh4_x86.tstate = TSTATE_NONE;
1.799 :}
1.800
1.801 @@ -2355,6 +2266,7 @@
1.802 XOR_imm32_r32( FPSCR_SZ, R_ECX );
1.803 store_spreg( R_ECX, R_FPSCR );
1.804 sh4_x86.tstate = TSTATE_NONE;
1.805 + sh4_x86.double_size = !sh4_x86.double_size;
1.806 :}
1.807
1.808 /* Processor control instructions */
1.809 @@ -2517,6 +2429,7 @@
1.810 load_reg( R_EAX, Rm );
1.811 call_func1( sh4_write_fpscr, R_EAX );
1.812 sh4_x86.tstate = TSTATE_NONE;
1.813 + return 2;
1.814 :}
1.815 LDS.L @Rm+, FPSCR {:
1.816 COUNT_INST(I_LDSFPSCRM);
1.817 @@ -2528,6 +2441,7 @@
1.818 MEM_READ_LONG( R_EAX, R_EAX );
1.819 call_func1( sh4_write_fpscr, R_EAX );
1.820 sh4_x86.tstate = TSTATE_NONE;
1.821 + return 2;
1.822 :}
1.823 LDS Rm, FPUL {:
1.824 COUNT_INST(I_LDS);
.