revision 380:2e8166bf6832
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 380:2e8166bf6832 |
parent | 379:7e1c33a184d8 |
child | 381:aade6c9aca4d |
author | nkeynes |
date | Wed Sep 12 11:31:16 2007 +0000 (16 years ago) |
Fix load_spreg/store_spreg
Fix PREF
Add jump target debug checking
Fix PREF
Add jump target debug checking
src/sh4/sh4x86.c | view | annotate | diff | log | ||
src/sh4/sh4x86.in | view | annotate | diff | log | ||
src/sh4/x86op.h | view | annotate | diff | log |
1.1 --- a/src/sh4/sh4x86.c Wed Sep 12 09:21:01 2007 +00001.2 +++ b/src/sh4/sh4x86.c Wed Sep 12 11:31:16 2007 +00001.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 just1.9 * outputs straight-line x86 code - it mainly exists to provide a baseline1.10 @@ -20,6 +20,10 @@1.12 #include <assert.h>1.14 +#ifndef NDEBUG1.15 +#define DEBUG_JUMPS 11.16 +#endif1.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.25 -#ifndef NDEBUG1.26 -#define MARK_JMP(x,n) uint8_t *_mark_jmp_##x = xlat_output + n1.27 -#define CHECK_JMP(x) assert( _mark_jmp_##x == xlat_output )1.28 -#else1.29 -#define MARK_JMP(x,n)1.30 -#define CHECK_JMP(x)1.31 -#endif1.32 -1.33 -1.34 /**1.35 * Emit an instruction to load an SH4 reg into a real register1.36 */1.37 @@ -112,14 +107,8 @@1.39 }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 register1.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.66 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))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.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 // target1.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 ); // 21.122 - JE_rel8(9);1.123 + JE_rel8(9, target2);1.124 SHR_imm8_r32( 16, R_EAX ); // 31.125 TEST_r8_r8( R_AL, R_AL ); // 21.126 - JE_rel8(2);1.127 + JE_rel8(2, target3);1.128 TEST_r8_r8( R_AH, R_AH ); // 21.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 ); // Q1.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 // TODO1.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.157 NEG_r32( R_ECX ); // 21.158 AND_imm8_r8( 0x1F, R_CL ); // 31.159 SAR_r32_CL( R_EAX ); // 21.160 - JMP_rel8(5); // 21.161 -1.162 + JMP_rel8(5, end); // 21.163 + JMP_TARGET(doshl);1.164 AND_imm8_r8( 0x1F, R_CL ); // 31.165 SHL_r32_CL( R_EAX ); // 21.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 it1.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 ); // 121.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 it1.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 it1.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 ); // 121.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 ); // 121.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 branch1.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); // 31.635 FABS_st0(); // 21.636 pop_fr( R_EDX, FRn); //31.637 - JMP_rel8(8); // 21.638 + JMP_rel8(8,end); // 21.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 only1.671 + JNE_rel8(12, end); // PR=0 only1.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=11.712 + JE_rel8(9, end); // only when PR=11.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=11.725 + JE_rel8(9, end); // only when PR=11.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:
2.1 --- a/src/sh4/sh4x86.in Wed Sep 12 09:21:01 2007 +00002.2 +++ b/src/sh4/sh4x86.in Wed Sep 12 11:31:16 2007 +00002.3 @@ -1,5 +1,5 @@2.4 /**2.5 - * $Id: sh4x86.in,v 1.6 2007-09-12 09:17:24 nkeynes Exp $2.6 + * $Id: sh4x86.in,v 1.7 2007-09-12 11:31:16 nkeynes Exp $2.7 *2.8 * SH4 => x86 translation. This version does no real optimization, it just2.9 * outputs straight-line x86 code - it mainly exists to provide a baseline2.10 @@ -20,6 +20,10 @@2.12 #include <assert.h>2.14 +#ifndef NDEBUG2.15 +#define DEBUG_JUMPS 12.16 +#endif2.17 +2.18 #include "sh4/sh4core.h"2.19 #include "sh4/sh4trans.h"2.20 #include "sh4/x86op.h"2.21 @@ -77,15 +81,6 @@2.22 }2.23 }2.25 -#ifndef NDEBUG2.26 -#define MARK_JMP(x,n) uint8_t *_mark_jmp_##x = xlat_output + n2.27 -#define CHECK_JMP(x) assert( _mark_jmp_##x == xlat_output )2.28 -#else2.29 -#define MARK_JMP(x,n)2.30 -#define CHECK_JMP(x)2.31 -#endif2.32 -2.33 -2.34 /**2.35 * Emit an instruction to load an SH4 reg into a real register2.36 */2.37 @@ -112,14 +107,8 @@2.39 }2.41 -static inline void load_spreg( int x86reg, int regoffset )2.42 -{2.43 - /* mov [bp+n], reg */2.44 - OP(0x8B);2.45 - OP(0x45 + (x86reg<<3));2.46 - OP(regoffset);2.47 -}2.48 -2.49 +#define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )2.50 +#define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )2.51 /**2.52 * Emit an instruction to load an immediate value into a register2.53 */2.54 @@ -138,13 +127,6 @@2.55 OP(0x45 + (x86reg<<3));2.56 OP(REG_OFFSET(r[sh4reg]));2.57 }2.58 -void static inline store_spreg( int x86reg, int regoffset ) {2.59 - /* mov reg, [bp+n] */2.60 - OP(0x89);2.61 - OP(0x45 + (x86reg<<3));2.62 - OP(regoffset);2.63 -}2.64 -2.66 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))2.68 @@ -368,6 +350,7 @@2.69 load_imm32( R_EBP, (uint32_t)&sh4r );2.70 PUSH_r32(R_EDI);2.71 PUSH_r32(R_ESI);2.72 + XOR_r32_r32(R_ESI, R_ESI);2.74 sh4_x86.in_delay_slot = FALSE;2.75 sh4_x86.priv_checked = FALSE;2.76 @@ -404,17 +387,22 @@2.77 uint8_t *end_ptr = xlat_output;2.78 // Exception termination. Jump block for various exception codes:2.79 PUSH_imm32( EXC_DATA_ADDR_READ );2.80 - JMP_rel8( 33 );2.81 + JMP_rel8( 33, target1 );2.82 PUSH_imm32( EXC_DATA_ADDR_WRITE );2.83 - JMP_rel8( 26 );2.84 + JMP_rel8( 26, target2 );2.85 PUSH_imm32( EXC_ILLEGAL );2.86 - JMP_rel8( 19 );2.87 + JMP_rel8( 19, target3 );2.88 PUSH_imm32( EXC_SLOT_ILLEGAL );2.89 - JMP_rel8( 12 );2.90 + JMP_rel8( 12, target4 );2.91 PUSH_imm32( EXC_FPU_DISABLED );2.92 - JMP_rel8( 5 );2.93 + JMP_rel8( 5, target5 );2.94 PUSH_imm32( EXC_SLOT_FPU_DISABLED );2.95 // target2.96 + JMP_TARGET(target1);2.97 + JMP_TARGET(target2);2.98 + JMP_TARGET(target3);2.99 + JMP_TARGET(target4);2.100 + JMP_TARGET(target5);2.101 load_spreg( R_ECX, REG_OFFSET(pc) );2.102 ADD_r32_r32( R_ESI, R_ECX );2.103 ADD_r32_r32( R_ESI, R_ECX );2.104 @@ -542,13 +530,16 @@2.105 load_reg( R_ECX, Rn );2.106 XOR_r32_r32( R_ECX, R_EAX );2.107 TEST_r8_r8( R_AL, R_AL );2.108 - JE_rel8(13);2.109 + JE_rel8(13, target1);2.110 TEST_r8_r8( R_AH, R_AH ); // 22.111 - JE_rel8(9);2.112 + JE_rel8(9, target2);2.113 SHR_imm8_r32( 16, R_EAX ); // 32.114 TEST_r8_r8( R_AL, R_AL ); // 22.115 - JE_rel8(2);2.116 + JE_rel8(2, target3);2.117 TEST_r8_r8( R_AH, R_AH ); // 22.118 + JMP_TARGET(target1);2.119 + JMP_TARGET(target2);2.120 + JMP_TARGET(target3);2.121 SETE_t();2.122 :}2.123 DIV0S Rm, Rn {:2.124 @@ -574,10 +565,12 @@2.125 SETC_r32( R_EDX ); // Q2.126 load_spreg( R_EAX, R_Q );2.127 CMP_sh4r_r32( R_M, R_EAX );2.128 - JE_rel8(8);2.129 + JE_rel8(8,mqequal);2.130 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );2.131 - JMP_rel8(3);2.132 + JMP_rel8(3, mqnotequal);2.133 + JMP_TARGET(mqequal);2.134 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );2.135 + JMP_TARGET(mqnotequal);2.136 // TODO2.137 :}2.138 DMULS.L Rm, Rn {:2.139 @@ -712,16 +705,16 @@2.140 load_reg( R_EAX, Rn );2.141 load_reg( R_ECX, Rm );2.142 CMP_imm32_r32( 0, R_ECX );2.143 - JAE_rel8(9);2.144 + JAE_rel8(9, doshl);2.146 NEG_r32( R_ECX ); // 22.147 AND_imm8_r8( 0x1F, R_CL ); // 32.148 SAR_r32_CL( R_EAX ); // 22.149 - JMP_rel8(5); // 22.150 -2.151 + JMP_rel8(5, end); // 22.152 + JMP_TARGET(doshl);2.153 AND_imm8_r8( 0x1F, R_CL ); // 32.154 SHL_r32_CL( R_EAX ); // 22.155 -2.156 + JMP_TARGET(end);2.157 store_reg( R_EAX, Rn );2.158 :}2.159 SHLD Rm, Rn {:2.160 @@ -1131,8 +1124,9 @@2.161 } else {2.162 load_imm32( R_EDI, pc + 2 );2.163 CMP_imm8s_sh4r( 0, R_T );2.164 - JNE_rel8( 5 );2.165 + JNE_rel8( 5, nottaken );2.166 load_imm32( R_EDI, disp + pc + 4 );2.167 + JMP_TARGET(nottaken);2.168 INC_r32(R_ESI);2.169 return 1;2.170 }2.171 @@ -1143,8 +1137,9 @@2.172 } else {2.173 load_imm32( R_EDI, pc + 2 );2.174 CMP_imm8s_sh4r( 0, R_T );2.175 - JNE_rel8( 5 );2.176 + JNE_rel8( 5, nottaken );2.177 load_imm32( R_EDI, disp + pc + 4 );2.178 + JMP_TARGET(nottaken);2.179 sh4_x86.in_delay_slot = TRUE;2.180 INC_r32(R_ESI);2.181 return 0;2.182 @@ -1201,8 +1196,9 @@2.183 } else {2.184 load_imm32( R_EDI, pc + 2 );2.185 CMP_imm8s_sh4r( 0, R_T );2.186 - JE_rel8( 5 );2.187 + JE_rel8( 5, nottaken );2.188 load_imm32( R_EDI, disp + pc + 4 );2.189 + JMP_TARGET(nottaken);2.190 INC_r32(R_ESI);2.191 return 1;2.192 }2.193 @@ -1213,8 +1209,9 @@2.194 } else {2.195 load_imm32( R_EDI, pc + 2 );2.196 CMP_imm8s_sh4r( 0, R_T );2.197 - JE_rel8( 5 );2.198 + JE_rel8( 5, nottaken );2.199 load_imm32( R_EDI, disp + pc + 4 );2.200 + JMP_TARGET(nottaken);2.201 sh4_x86.in_delay_slot = TRUE;2.202 INC_r32(R_ESI);2.203 return 0;2.204 @@ -1319,11 +1316,12 @@2.205 load_spreg( R_ECX, R_FPSCR );2.206 load_fr_bank( R_EDX );2.207 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.208 - JNE_rel8(8);2.209 + JNE_rel8(8, doublesize);2.210 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch2.211 store_fr( R_EDX, R_EAX, FRn );2.212 if( FRm&1 ) {2.213 - JMP_rel8(22);2.214 + JMP_rel8(22, end);2.215 + JMP_TARGET(doublesize);2.216 load_xf_bank( R_ECX );2.217 load_fr( R_ECX, R_EAX, FRm-1 );2.218 if( FRn&1 ) {2.219 @@ -1335,20 +1333,23 @@2.220 store_fr( R_EDX, R_EAX, FRn-1 );2.221 store_fr( R_EDX, R_ECX, FRn );2.222 }2.223 + JMP_TARGET(end);2.224 } else /* FRm&1 == 0 */ {2.225 if( FRn&1 ) {2.226 - JMP_rel8(22);2.227 + JMP_rel8(22, end);2.228 load_xf_bank( R_ECX );2.229 load_fr( R_EDX, R_EAX, FRm );2.230 load_fr( R_EDX, R_EDX, FRm+1 );2.231 store_fr( R_ECX, R_EAX, FRn-1 );2.232 store_fr( R_ECX, R_EDX, FRn );2.233 + JMP_TARGET(end);2.234 } else /* FRn&1 == 0 */ {2.235 - JMP_rel8(12);2.236 + JMP_rel8(12, end);2.237 load_fr( R_EDX, R_EAX, FRm );2.238 load_fr( R_EDX, R_ECX, FRm+1 );2.239 store_fr( R_EDX, R_EAX, FRn );2.240 store_fr( R_EDX, R_ECX, FRn+1 );2.241 + JMP_TARGET(end);2.242 }2.243 }2.244 :}2.245 @@ -1358,20 +1359,27 @@2.246 check_walign32( R_EDX );2.247 load_spreg( R_ECX, R_FPSCR );2.248 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.249 - JNE_rel8(20);2.250 + JNE_rel8(20, doublesize);2.251 load_fr_bank( R_ECX );2.252 load_fr( R_ECX, R_EAX, FRm );2.253 MEM_WRITE_LONG( R_EDX, R_EAX ); // 122.254 if( FRm&1 ) {2.255 - JMP_rel8( 46 );2.256 + JMP_rel8( 46, end );2.257 + JMP_TARGET(doublesize);2.258 load_xf_bank( R_ECX );2.259 + load_fr( R_ECX, R_EAX, FRm&0x0E );2.260 + load_fr( R_ECX, R_ECX, FRm|0x01 );2.261 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.262 + JMP_TARGET(end);2.263 } else {2.264 - JMP_rel8( 39 );2.265 + JMP_rel8( 39, end );2.266 + JMP_TARGET(doublesize);2.267 load_fr_bank( R_ECX );2.268 + load_fr( R_ECX, R_EAX, FRm&0x0E );2.269 + load_fr( R_ECX, R_ECX, FRm|0x01 );2.270 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.271 + JMP_TARGET(end);2.272 }2.273 - load_fr( R_ECX, R_EAX, FRm&0x0E );2.274 - load_fr( R_ECX, R_ECX, FRm|0x01 );2.275 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.276 :}2.277 FMOV @Rm, FRn {:2.278 check_fpuen();2.279 @@ -1379,22 +1387,28 @@2.280 check_ralign32( R_EDX );2.281 load_spreg( R_ECX, R_FPSCR );2.282 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.283 - JNE_rel8(19);2.284 + JNE_rel8(19, doublesize);2.285 MEM_READ_LONG( R_EDX, R_EAX );2.286 load_fr_bank( R_ECX );2.287 store_fr( R_ECX, R_EAX, FRn );2.288 if( FRn&1 ) {2.289 - JMP_rel8(46);2.290 + JMP_rel8(46, end);2.291 + JMP_TARGET(doublesize);2.292 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.293 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it2.294 load_xf_bank( R_ECX );2.295 + store_fr( R_ECX, R_EAX, FRn&0x0E );2.296 + store_fr( R_ECX, R_EDX, FRn|0x01 );2.297 + JMP_TARGET(end);2.298 } else {2.299 - JMP_rel8(36);2.300 + JMP_rel8(36, end);2.301 + JMP_TARGET(doublesize);2.302 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.303 load_fr_bank( R_ECX );2.304 + store_fr( R_ECX, R_EAX, FRn&0x0E );2.305 + store_fr( R_ECX, R_EDX, FRn|0x01 );2.306 + JMP_TARGET(end);2.307 }2.308 - store_fr( R_ECX, R_EAX, FRn&0x0E );2.309 - store_fr( R_ECX, R_EDX, FRn|0x01 );2.310 :}2.311 FMOV FRm, @-Rn {:2.312 check_fpuen();2.313 @@ -1402,24 +1416,33 @@2.314 check_walign32( R_EDX );2.315 load_spreg( R_ECX, R_FPSCR );2.316 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.317 - JNE_rel8(20);2.318 + JNE_rel8(20, doublesize);2.319 load_fr_bank( R_ECX );2.320 load_fr( R_ECX, R_EAX, FRm );2.321 ADD_imm8s_r32(-4,R_EDX);2.322 store_reg( R_EDX, Rn );2.323 MEM_WRITE_LONG( R_EDX, R_EAX ); // 122.324 if( FRm&1 ) {2.325 - JMP_rel8( 46 );2.326 + JMP_rel8( 46, end );2.327 + JMP_TARGET(doublesize);2.328 load_xf_bank( R_ECX );2.329 + load_fr( R_ECX, R_EAX, FRm&0x0E );2.330 + load_fr( R_ECX, R_ECX, FRm|0x01 );2.331 + ADD_imm8s_r32(-8,R_EDX);2.332 + store_reg( R_EDX, Rn );2.333 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.334 + JMP_TARGET(end);2.335 } else {2.336 - JMP_rel8( 39 );2.337 + JMP_rel8( 39, end );2.338 + JMP_TARGET(doublesize);2.339 load_fr_bank( R_ECX );2.340 + load_fr( R_ECX, R_EAX, FRm&0x0E );2.341 + load_fr( R_ECX, R_ECX, FRm|0x01 );2.342 + ADD_imm8s_r32(-8,R_EDX);2.343 + store_reg( R_EDX, Rn );2.344 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.345 + JMP_TARGET(end);2.346 }2.347 - load_fr( R_ECX, R_EAX, FRm&0x0E );2.348 - load_fr( R_ECX, R_ECX, FRm|0x01 );2.349 - ADD_imm8s_r32(-8,R_EDX);2.350 - store_reg( R_EDX, Rn );2.351 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.352 :}2.353 FMOV @Rm+, FRn {:2.354 check_fpuen();2.355 @@ -1428,28 +1451,33 @@2.356 MOV_r32_r32( R_EDX, R_EAX );2.357 load_spreg( R_ECX, R_FPSCR );2.358 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.359 - JNE_rel8(25);2.360 + JNE_rel8(25, doublesize);2.361 ADD_imm8s_r32( 4, R_EAX );2.362 store_reg( R_EAX, Rm );2.363 MEM_READ_LONG( R_EDX, R_EAX );2.364 load_fr_bank( R_ECX );2.365 store_fr( R_ECX, R_EAX, FRn );2.366 if( FRn&1 ) {2.367 - JMP_rel8(52);2.368 + JMP_rel8(52, end);2.369 + JMP_TARGET(doublesize);2.370 ADD_imm8s_r32( 8, R_EAX );2.371 store_reg(R_EAX, Rm);2.372 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.373 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it2.374 load_xf_bank( R_ECX );2.375 + store_fr( R_ECX, R_EAX, FRn&0x0E );2.376 + store_fr( R_ECX, R_EDX, FRn|0x01 );2.377 + JMP_TARGET(end);2.378 } else {2.379 - JMP_rel8(42);2.380 + JMP_rel8(42, end);2.381 ADD_imm8s_r32( 8, R_EAX );2.382 store_reg(R_EAX, Rm);2.383 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.384 load_fr_bank( R_ECX );2.385 + store_fr( R_ECX, R_EAX, FRn&0x0E );2.386 + store_fr( R_ECX, R_EDX, FRn|0x01 );2.387 + JMP_TARGET(end);2.388 }2.389 - store_fr( R_ECX, R_EAX, FRn&0x0E );2.390 - store_fr( R_ECX, R_EDX, FRn|0x01 );2.391 :}2.392 FMOV FRm, @(R0, Rn) {:2.393 check_fpuen();2.394 @@ -1458,20 +1486,27 @@2.395 check_walign32( R_EDX );2.396 load_spreg( R_ECX, R_FPSCR );2.397 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.398 - JNE_rel8(20);2.399 + JNE_rel8(20, doublesize);2.400 load_fr_bank( R_ECX );2.401 load_fr( R_ECX, R_EAX, FRm );2.402 MEM_WRITE_LONG( R_EDX, R_EAX ); // 122.403 if( FRm&1 ) {2.404 - JMP_rel8( 46 );2.405 + JMP_rel8( 46, end );2.406 + JMP_TARGET(doublesize);2.407 load_xf_bank( R_ECX );2.408 + load_fr( R_ECX, R_EAX, FRm&0x0E );2.409 + load_fr( R_ECX, R_ECX, FRm|0x01 );2.410 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.411 + JMP_TARGET(end);2.412 } else {2.413 - JMP_rel8( 39 );2.414 + JMP_rel8( 39, end );2.415 + JMP_TARGET(doublesize);2.416 load_fr_bank( R_ECX );2.417 + load_fr( R_ECX, R_EAX, FRm&0x0E );2.418 + load_fr( R_ECX, R_ECX, FRm|0x01 );2.419 + MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.420 + JMP_TARGET(end);2.421 }2.422 - load_fr( R_ECX, R_EAX, FRm&0x0E );2.423 - load_fr( R_ECX, R_ECX, FRm|0x01 );2.424 - MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );2.425 :}2.426 FMOV @(R0, Rm), FRn {:2.427 check_fpuen();2.428 @@ -1480,40 +1515,48 @@2.429 check_ralign32( R_EDX );2.430 load_spreg( R_ECX, R_FPSCR );2.431 TEST_imm32_r32( FPSCR_SZ, R_ECX );2.432 - JNE_rel8(19);2.433 + JNE_rel8(19, doublesize);2.434 MEM_READ_LONG( R_EDX, R_EAX );2.435 load_fr_bank( R_ECX );2.436 store_fr( R_ECX, R_EAX, FRn );2.437 if( FRn&1 ) {2.438 - JMP_rel8(46);2.439 + JMP_rel8(46, end);2.440 + JMP_TARGET(doublesize);2.441 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.442 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it2.443 load_xf_bank( R_ECX );2.444 + store_fr( R_ECX, R_EAX, FRn&0x0E );2.445 + store_fr( R_ECX, R_EDX, FRn|0x01 );2.446 + JMP_TARGET(end);2.447 } else {2.448 - JMP_rel8(36);2.449 + JMP_rel8(36, end);2.450 + JMP_TARGET(doublesize);2.451 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.452 load_fr_bank( R_ECX );2.453 + store_fr( R_ECX, R_EAX, FRn&0x0E );2.454 + store_fr( R_ECX, R_EDX, FRn|0x01 );2.455 + JMP_TARGET(end);2.456 }2.457 - store_fr( R_ECX, R_EAX, FRn&0x0E );2.458 - store_fr( R_ECX, R_EDX, FRn|0x01 );2.459 :}2.460 FLDI0 FRn {: /* IFF PR=0 */2.461 check_fpuen();2.462 load_spreg( R_ECX, R_FPSCR );2.463 TEST_imm32_r32( FPSCR_PR, R_ECX );2.464 - JNE_rel8(8);2.465 + JNE_rel8(8, end);2.466 XOR_r32_r32( R_EAX, R_EAX );2.467 load_spreg( R_ECX, REG_OFFSET(fr_bank) );2.468 store_fr( R_ECX, R_EAX, FRn );2.469 + JMP_TARGET(end);2.470 :}2.471 FLDI1 FRn {: /* IFF PR=0 */2.472 check_fpuen();2.473 load_spreg( R_ECX, R_FPSCR );2.474 TEST_imm32_r32( FPSCR_PR, R_ECX );2.475 - JNE_rel8(11);2.476 + JNE_rel8(11, end);2.477 load_imm32(R_EAX, 0x3F800000);2.478 load_spreg( R_ECX, REG_OFFSET(fr_bank) );2.479 store_fr( R_ECX, R_EAX, FRn );2.480 + JMP_TARGET(end);2.481 :}2.483 FLOAT FPUL, FRn {:2.484 @@ -1522,10 +1565,12 @@2.485 load_spreg(R_EDX, REG_OFFSET(fr_bank));2.486 FILD_sh4r(R_FPUL);2.487 TEST_imm32_r32( FPSCR_PR, R_ECX );2.488 - JNE_rel8(5);2.489 + JNE_rel8(5, doubleprec);2.490 pop_fr( R_EDX, FRn );2.491 - JMP_rel8(3);2.492 + JMP_rel8(3, end);2.493 + JMP_TARGET(doubleprec);2.494 pop_dr( R_EDX, FRn );2.495 + JMP_TARGET(end);2.496 :}2.497 FTRC FRm, FPUL {:2.498 check_fpuen();2.499 @@ -1547,20 +1592,22 @@2.500 check_fpuen();2.501 load_spreg( R_ECX, R_FPSCR );2.502 TEST_imm32_r32( FPSCR_PR, R_ECX );2.503 - JE_rel8(9); // only when PR=12.504 + JE_rel8(9, end); // only when PR=12.505 load_fr_bank( R_ECX );2.506 push_dr( R_ECX, FRm );2.507 pop_fpul();2.508 + JMP_TARGET(end);2.509 :}2.510 FCNVSD FPUL, FRn {:2.511 check_fpuen();2.512 check_fpuen();2.513 load_spreg( R_ECX, R_FPSCR );2.514 TEST_imm32_r32( FPSCR_PR, R_ECX );2.515 - JE_rel8(9); // only when PR=12.516 + JE_rel8(9, end); // only when PR=12.517 load_fr_bank( R_ECX );2.518 push_fpul();2.519 pop_dr( R_ECX, FRn );2.520 + JMP_TARGET(end);2.521 :}2.523 /* Floating point instructions */2.524 @@ -1569,66 +1616,74 @@2.525 load_spreg( R_ECX, R_FPSCR );2.526 load_fr_bank( R_EDX );2.527 TEST_imm32_r32( FPSCR_PR, R_ECX );2.528 - JNE_rel8(10);2.529 + JNE_rel8(10, doubleprec);2.530 push_fr(R_EDX, FRn); // 32.531 FABS_st0(); // 22.532 pop_fr( R_EDX, FRn); //32.533 - JMP_rel8(8); // 22.534 + JMP_rel8(8,end); // 22.535 + JMP_TARGET(doubleprec);2.536 push_dr(R_EDX, FRn);2.537 FABS_st0();2.538 pop_dr(R_EDX, FRn);2.539 + JMP_TARGET(end);2.540 :}2.541 FADD FRm, FRn {:2.542 check_fpuen();2.543 load_spreg( R_ECX, R_FPSCR );2.544 TEST_imm32_r32( FPSCR_PR, R_ECX );2.545 load_fr_bank( R_EDX );2.546 - JNE_rel8(13);2.547 + JNE_rel8(13,doubleprec);2.548 push_fr(R_EDX, FRm);2.549 push_fr(R_EDX, FRn);2.550 FADDP_st(1);2.551 pop_fr(R_EDX, FRn);2.552 - JMP_rel8(11);2.553 + JMP_rel8(11,end);2.554 + JMP_TARGET(doubleprec);2.555 push_dr(R_EDX, FRm);2.556 push_dr(R_EDX, FRn);2.557 FADDP_st(1);2.558 pop_dr(R_EDX, FRn);2.559 + JMP_TARGET(end);2.560 :}2.561 FDIV FRm, FRn {:2.562 check_fpuen();2.563 load_spreg( R_ECX, R_FPSCR );2.564 TEST_imm32_r32( FPSCR_PR, R_ECX );2.565 load_fr_bank( R_EDX );2.566 - JNE_rel8(13);2.567 + JNE_rel8(13, doubleprec);2.568 push_fr(R_EDX, FRn);2.569 push_fr(R_EDX, FRm);2.570 FDIVP_st(1);2.571 pop_fr(R_EDX, FRn);2.572 - JMP_rel8(11);2.573 + JMP_rel8(11, end);2.574 + JMP_TARGET(doubleprec);2.575 push_dr(R_EDX, FRn);2.576 push_dr(R_EDX, FRm);2.577 FDIVP_st(1);2.578 pop_dr(R_EDX, FRn);2.579 + JMP_TARGET(end);2.580 :}2.581 FMAC FR0, FRm, FRn {:2.582 check_fpuen();2.583 load_spreg( R_ECX, R_FPSCR );2.584 load_spreg( R_EDX, REG_OFFSET(fr_bank));2.585 TEST_imm32_r32( FPSCR_PR, R_ECX );2.586 - JNE_rel8(18);2.587 + JNE_rel8(18, doubleprec);2.588 push_fr( R_EDX, 0 );2.589 push_fr( R_EDX, FRm );2.590 FMULP_st(1);2.591 push_fr( R_EDX, FRn );2.592 FADDP_st(1);2.593 pop_fr( R_EDX, FRn );2.594 - JMP_rel8(16);2.595 + JMP_rel8(16, end);2.596 + JMP_TARGET(doubleprec);2.597 push_dr( R_EDX, 0 );2.598 push_dr( R_EDX, FRm );2.599 FMULP_st(1);2.600 push_dr( R_EDX, FRn );2.601 FADDP_st(1);2.602 pop_dr( R_EDX, FRn );2.603 + JMP_TARGET(end);2.604 :}2.606 FMUL FRm, FRn {:2.607 @@ -1636,72 +1691,81 @@2.608 load_spreg( R_ECX, R_FPSCR );2.609 TEST_imm32_r32( FPSCR_PR, R_ECX );2.610 load_fr_bank( R_EDX );2.611 - JNE_rel8(13);2.612 + JNE_rel8(13, doubleprec);2.613 push_fr(R_EDX, FRm);2.614 push_fr(R_EDX, FRn);2.615 FMULP_st(1);2.616 pop_fr(R_EDX, FRn);2.617 - JMP_rel8(11);2.618 + JMP_rel8(11, end);2.619 + JMP_TARGET(doubleprec);2.620 push_dr(R_EDX, FRm);2.621 push_dr(R_EDX, FRn);2.622 FMULP_st(1);2.623 pop_dr(R_EDX, FRn);2.624 + JMP_TARGET(end);2.625 :}2.626 FNEG FRn {:2.627 check_fpuen();2.628 load_spreg( R_ECX, R_FPSCR );2.629 TEST_imm32_r32( FPSCR_PR, R_ECX );2.630 load_fr_bank( R_EDX );2.631 - JNE_rel8(10);2.632 + JNE_rel8(10, doubleprec);2.633 push_fr(R_EDX, FRn);2.634 FCHS_st0();2.635 pop_fr(R_EDX, FRn);2.636 - JMP_rel8(8);2.637 + JMP_rel8(8, end);2.638 + JMP_TARGET(doubleprec);2.639 push_dr(R_EDX, FRn);2.640 FCHS_st0();2.641 pop_dr(R_EDX, FRn);2.642 + JMP_TARGET(end);2.643 :}2.644 FSRRA FRn {:2.645 check_fpuen();2.646 load_spreg( R_ECX, R_FPSCR );2.647 TEST_imm32_r32( FPSCR_PR, R_ECX );2.648 load_fr_bank( R_EDX );2.649 - JNE_rel8(12); // PR=0 only2.650 + JNE_rel8(12, end); // PR=0 only2.651 FLD1_st0();2.652 push_fr(R_EDX, FRn);2.653 FSQRT_st0();2.654 FDIVP_st(1);2.655 pop_fr(R_EDX, FRn);2.656 + JMP_TARGET(end);2.657 :}2.658 FSQRT FRn {:2.659 check_fpuen();2.660 load_spreg( R_ECX, R_FPSCR );2.661 TEST_imm32_r32( FPSCR_PR, R_ECX );2.662 load_fr_bank( R_EDX );2.663 - JNE_rel8(10);2.664 + JNE_rel8(10, doubleprec);2.665 push_fr(R_EDX, FRn);2.666 FSQRT_st0();2.667 pop_fr(R_EDX, FRn);2.668 - JMP_rel8(8);2.669 + JMP_rel8(8, end);2.670 + JMP_TARGET(doubleprec);2.671 push_dr(R_EDX, FRn);2.672 FSQRT_st0();2.673 pop_dr(R_EDX, FRn);2.674 + JMP_TARGET(end);2.675 :}2.676 FSUB FRm, FRn {:2.677 check_fpuen();2.678 load_spreg( R_ECX, R_FPSCR );2.679 TEST_imm32_r32( FPSCR_PR, R_ECX );2.680 load_fr_bank( R_EDX );2.681 - JNE_rel8(13);2.682 + JNE_rel8(13, doubleprec);2.683 push_fr(R_EDX, FRn);2.684 push_fr(R_EDX, FRm);2.685 FMULP_st(1);2.686 pop_fr(R_EDX, FRn);2.687 - JMP_rel8(11);2.688 + JMP_rel8(11, end);2.689 + JMP_TARGET(doubleprec);2.690 push_dr(R_EDX, FRn);2.691 push_dr(R_EDX, FRm);2.692 FMULP_st(1);2.693 pop_dr(R_EDX, FRn);2.694 + JMP_TARGET(end);2.695 :}2.697 FCMP/EQ FRm, FRn {:2.698 @@ -1709,27 +1773,31 @@2.699 load_spreg( R_ECX, R_FPSCR );2.700 TEST_imm32_r32( FPSCR_PR, R_ECX );2.701 load_fr_bank( R_EDX );2.702 - JNE_rel8(8);2.703 + JNE_rel8(8, doubleprec);2.704 push_fr(R_EDX, FRm);2.705 push_fr(R_EDX, FRn);2.706 - JMP_rel8(6);2.707 + JMP_rel8(6, end);2.708 + JMP_TARGET(doubleprec);2.709 push_dr(R_EDX, FRm);2.710 push_dr(R_EDX, FRn);2.711 FCOMIP_st(1);2.712 SETE_t();2.713 FPOP_st();2.714 + JMP_TARGET(end);2.715 :}2.716 FCMP/GT FRm, FRn {:2.717 check_fpuen();2.718 load_spreg( R_ECX, R_FPSCR );2.719 TEST_imm32_r32( FPSCR_PR, R_ECX );2.720 load_fr_bank( R_EDX );2.721 - JNE_rel8(8);2.722 + JNE_rel8(8, doubleprec);2.723 push_fr(R_EDX, FRm);2.724 push_fr(R_EDX, FRn);2.725 - JMP_rel8(6);2.726 + JMP_rel8(6, end);2.727 + JMP_TARGET(doubleprec);2.728 push_dr(R_EDX, FRm);2.729 push_dr(R_EDX, FRn);2.730 + JMP_TARGET(end);2.731 FCOMIP_st(1);2.732 SETA_t();2.733 FPOP_st();2.734 @@ -1929,8 +1997,9 @@2.735 PUSH_r32( R_EAX );2.736 AND_imm32_r32( 0xFC000000, R_EAX );2.737 CMP_imm32_r32( 0xE0000000, R_EAX );2.738 - JNE_rel8(8);2.739 + JNE_rel8(7, end);2.740 call_func0( sh4_flush_store_queue );2.741 + JMP_TARGET(end);2.742 ADD_imm8s_r32( 4, R_ESP );2.743 :}2.744 SLEEP {: /* TODO */ :}
3.1 --- a/src/sh4/x86op.h Wed Sep 12 09:21:01 2007 +00003.2 +++ b/src/sh4/x86op.h Wed Sep 12 11:31:16 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: x86op.h,v 1.6 2007-09-12 09:17:24 nkeynes Exp $3.6 + * $Id: x86op.h,v 1.7 2007-09-12 11:31:16 nkeynes Exp $3.7 *3.8 * Definitions of x86 opcodes for use by the translator.3.9 *3.10 @@ -38,6 +38,17 @@3.11 #define R_DH 63.12 #define R_BH 73.14 +#ifdef DEBUG_JUMPS3.15 +#define MARK_JMP(n,x) uint8_t *_mark_jmp_##x = xlat_output + n3.16 +#define JMP_TARGET(x) assert( _mark_jmp_##x == xlat_output )3.17 +#else3.18 +#define MARK_JMP(n, x)3.19 +#define JMP_TARGET(x)3.20 +#endif3.21 +3.22 +3.23 +3.24 +3.26 #define OP(x) *xlat_output++ = (x)3.27 #define OP32(x) *((uint32_t *)xlat_output) = (x); xlat_output+=43.28 @@ -100,7 +111,7 @@3.29 #define DEC_r32(r1) OP(0x48+r1)3.30 #define IMUL_r32(r1) OP(0xF7); MODRM_rm32_r32(r1,5)3.31 #define INC_r32(r1) OP(0x40+r1)3.32 -#define JMP_rel8(rel) OP(0xEB); OP(rel)3.33 +#define JMP_rel8(rel, label) OP(0xEB); OP(rel); MARK_JMP(rel,label)3.34 #define MOV_r32_r32(r1,r2) OP(0x89); MODRM_r32_rm32(r1,r2)3.35 #define MOV_r32_sh4r(r1,disp) OP(0x89); MODRM_r32_sh4r(r1,disp)3.36 #define MOV_moff32_EAX(off) OP(0xA1); OP32(off)3.37 @@ -163,20 +174,20 @@3.38 #define FSQRT_st0() OP(0xD9); OP(0xFA)3.40 /* Conditional branches */3.41 -#define JE_rel8(rel) OP(0x74); OP(rel)3.42 -#define JA_rel8(rel) OP(0x77); OP(rel)3.43 -#define JAE_rel8(rel) OP(0x73); OP(rel)3.44 -#define JG_rel8(rel) OP(0x7F); OP(rel)3.45 -#define JGE_rel8(rel) OP(0x7D); OP(rel)3.46 -#define JC_rel8(rel) OP(0x72); OP(rel)3.47 -#define JO_rel8(rel) OP(0x70); OP(rel)3.48 -#define JNE_rel8(rel) OP(0x75); OP(rel)3.49 -#define JNA_rel8(rel) OP(0x76); OP(rel)3.50 -#define JNAE_rel8(rel) OP(0x72); OP(rel)3.51 -#define JNG_rel8(rel) OP(0x7E); OP(rel)3.52 -#define JNGE_rel8(rel) OP(0x7C); OP(rel)3.53 -#define JNC_rel8(rel) OP(0x73); OP(rel)3.54 -#define JNO_rel8(rel) OP(0x71); OP(rel)3.55 +#define JE_rel8(rel,label) OP(0x74); OP(rel); MARK_JMP(rel,label)3.56 +#define JA_rel8(rel,label) OP(0x77); OP(rel); MARK_JMP(rel,label)3.57 +#define JAE_rel8(rel,label) OP(0x73); OP(rel); MARK_JMP(rel,label)3.58 +#define JG_rel8(rel,label) OP(0x7F); OP(rel); MARK_JMP(rel,label)3.59 +#define JGE_rel8(rel,label) OP(0x7D); OP(rel); MARK_JMP(rel,label)3.60 +#define JC_rel8(rel,label) OP(0x72); OP(rel); MARK_JMP(rel,label)3.61 +#define JO_rel8(rel,label) OP(0x70); OP(rel); MARK_JMP(rel,label)3.62 +#define JNE_rel8(rel,label) OP(0x75); OP(rel); MARK_JMP(rel,label)3.63 +#define JNA_rel8(rel,label) OP(0x76); OP(rel); MARK_JMP(rel,label)3.64 +#define JNAE_rel8(rel,label) OP(0x72); OP(rel); MARK_JMP(rel,label)3.65 +#define JNG_rel8(rel,label) OP(0x7E); OP(rel); MARK_JMP(rel,label)3.66 +#define JNGE_rel8(rel,label) OP(0x7C); OP(rel); MARK_JMP(rel,label)3.67 +#define JNC_rel8(rel,label) OP(0x73); OP(rel); MARK_JMP(rel,label)3.68 +#define JNO_rel8(rel,label) OP(0x71); OP(rel); MARK_JMP(rel,label)3.70 /* 32-bit long forms w/ backpatching to an exit routine */3.71 #define JE_exit(rel) OP(0x0F); OP(0x84); sh4_x86_add_backpatch(xlat_output); OP32(rel)
.