Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 386:6fb10951326a
prev382:fce3f4da92ab
next388:13bae2fb0373
author nkeynes
date Sun Sep 16 07:03:23 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Implement MAC.W, MAC.L and DIV1
Correct SHAD/SHLD
Fix privilege and slot illegal checks on LDC/STC opcodes
Fix various other small bugs
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.in Thu Sep 13 08:28:01 2007 +0000
1.2 +++ b/src/sh4/sh4x86.in Sun Sep 16 07:03:23 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: sh4x86.in,v 1.9 2007-09-13 08:28:01 nkeynes Exp $
1.6 + * $Id: sh4x86.in,v 1.10 2007-09-16 07:03:23 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 @@ -56,6 +56,15 @@
1.11
1.12 static struct sh4_x86_state sh4_x86;
1.13
1.14 +void signsat48( void )
1.15 +{
1.16 + if( ((int64_t)sh4r.mac) < (int64_t)0xFFFF800000000000LL )
1.17 + sh4r.mac = 0xFFFF800000000000LL;
1.18 + else if( ((int64_t)sh4r.mac) > (int64_t)0x00007FFFFFFFFFFFLL )
1.19 + sh4r.mac = 0x00007FFFFFFFFFFFLL;
1.20 +}
1.21 +
1.22 +
1.23 void sh4_x86_init()
1.24 {
1.25 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
1.26 @@ -156,12 +165,23 @@
1.27 */
1.28 static inline void load_xf_bank( int bankreg )
1.29 {
1.30 + NOT_r32( bankreg );
1.31 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
1.32 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
1.33 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
1.34 }
1.35
1.36 /**
1.37 + * Update the fr_bank pointer based on the current fpscr value.
1.38 + */
1.39 +static inline void update_fr_bank( int fpscrreg )
1.40 +{
1.41 + SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
1.42 + AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
1.43 + OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
1.44 + store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
1.45 +}
1.46 +/**
1.47 * Push FPUL (as a 32-bit float) onto the FPU stack
1.48 */
1.49 static inline void push_fpul( )
1.50 @@ -242,11 +262,11 @@
1.51 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
1.52 {
1.53 ADD_imm8s_r32( 4, addr );
1.54 + PUSH_r32(arg2b);
1.55 PUSH_r32(addr);
1.56 - PUSH_r32(arg2b);
1.57 ADD_imm8s_r32( -4, addr );
1.58 + PUSH_r32(arg2a);
1.59 PUSH_r32(addr);
1.60 - PUSH_r32(arg2a);
1.61 call_func0(sh4_write_long);
1.62 ADD_imm8s_r32( 8, R_ESP );
1.63 call_func0(sh4_write_long);
1.64 @@ -324,6 +344,13 @@
1.65 JNE_exit(EXIT_DATA_ADDR_WRITE);
1.66 }
1.67
1.68 +static inline void raise_exception( int exc )
1.69 +{
1.70 + PUSH_imm32(exc);
1.71 + call_func0(sh4_raise_exception);
1.72 + ADD_imm8s_r32( 4, R_ESP );
1.73 + sh4_x86.in_delay_slot = FALSE;
1.74 +}
1.75
1.76 #define UNDEF()
1.77 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
1.78 @@ -334,8 +361,8 @@
1.79 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
1.80 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
1.81
1.82 -#define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);
1.83 -#define SLOTILLEGAL() RAISE_EXCEPTION(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1
1.84 +#define RAISE_EXCEPTION( exc ) raise_exception(exc); return 1;
1.85 +#define SLOTILLEGAL() JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
1.86
1.87
1.88
1.89 @@ -479,8 +506,10 @@
1.90 load_reg( R_EAX, 0 );
1.91 load_spreg( R_ECX, R_GBR );
1.92 ADD_r32_r32( R_EAX, R_ECX );
1.93 - MEM_READ_BYTE( R_ECX, R_EAX );
1.94 - AND_imm32_r32(imm, R_ECX );
1.95 + PUSH_r32(R_ECX);
1.96 + call_func0(sh4_read_byte);
1.97 + POP_r32(R_ECX);
1.98 + AND_imm32_r32(imm, R_EAX );
1.99 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.100 :}
1.101 CMP/EQ Rm, Rn {:
1.102 @@ -547,13 +576,13 @@
1.103 :}
1.104 DIV0S Rm, Rn {:
1.105 load_reg( R_EAX, Rm );
1.106 - load_reg( R_ECX, Rm );
1.107 + load_reg( R_ECX, Rn );
1.108 SHR_imm8_r32( 31, R_EAX );
1.109 SHR_imm8_r32( 31, R_ECX );
1.110 store_spreg( R_EAX, R_M );
1.111 store_spreg( R_ECX, R_Q );
1.112 CMP_r32_r32( R_EAX, R_ECX );
1.113 - SETE_t();
1.114 + SETNE_t();
1.115 :}
1.116 DIV0U {:
1.117 XOR_r32_r32( R_EAX, R_EAX );
1.118 @@ -561,20 +590,27 @@
1.119 store_spreg( R_EAX, R_M );
1.120 store_spreg( R_EAX, R_T );
1.121 :}
1.122 -DIV1 Rm, Rn {:
1.123 - load_reg( R_ECX, Rn );
1.124 +DIV1 Rm, Rn {:
1.125 + load_spreg( R_ECX, R_M );
1.126 + load_reg( R_EAX, Rn );
1.127 LDC_t();
1.128 - RCL1_r32( R_ECX ); // OP2
1.129 - SETC_r32( R_EDX ); // Q
1.130 - load_spreg( R_EAX, R_Q );
1.131 - CMP_sh4r_r32( R_M, R_EAX );
1.132 - JE_rel8(8,mqequal);
1.133 - ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
1.134 - JMP_rel8(3, mqnotequal);
1.135 + RCL1_r32( R_EAX );
1.136 + SETC_r8( R_DL ); // Q'
1.137 + CMP_sh4r_r32( R_Q, R_ECX );
1.138 + JE_rel8(5, mqequal);
1.139 + ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1.140 + JMP_rel8(3, end);
1.141 JMP_TARGET(mqequal);
1.142 - SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
1.143 - JMP_TARGET(mqnotequal);
1.144 - // TODO
1.145 + SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1.146 + JMP_TARGET(end);
1.147 + store_reg( R_EAX, Rn ); // Done with Rn now
1.148 + SETC_r8(R_AL); // tmp1
1.149 + XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1.150 + XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1.151 + store_spreg( R_ECX, R_Q );
1.152 + XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1.153 + MOVZX_r8_r32( R_AL, R_EAX );
1.154 + store_spreg( R_EAX, R_T );
1.155 :}
1.156 DMULS.L Rm, Rn {:
1.157 load_reg( R_EAX, Rm );
1.158 @@ -616,8 +652,67 @@
1.159 MOVZX_r16_r32( R_EAX, R_EAX );
1.160 store_reg( R_EAX, Rn );
1.161 :}
1.162 -MAC.L @Rm+, @Rn+ {: :}
1.163 -MAC.W @Rm+, @Rn+ {: :}
1.164 +MAC.L @Rm+, @Rn+ {:
1.165 + load_reg( R_ECX, Rm );
1.166 + check_ralign32( R_ECX );
1.167 + load_reg( R_ECX, Rn );
1.168 + check_ralign32( R_ECX );
1.169 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1.170 + MEM_READ_LONG( R_ECX, R_EAX );
1.171 + PUSH_r32( R_EAX );
1.172 + load_reg( R_ECX, Rm );
1.173 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1.174 + MEM_READ_LONG( R_ECX, R_EAX );
1.175 + POP_r32( R_ECX );
1.176 + IMUL_r32( R_ECX );
1.177 + ADD_r32_sh4r( R_EAX, R_MACL );
1.178 + ADC_r32_sh4r( R_EDX, R_MACH );
1.179 +
1.180 + load_spreg( R_ECX, R_S );
1.181 + TEST_r32_r32(R_ECX, R_ECX);
1.182 + JE_rel8( 7, nosat );
1.183 + call_func0( signsat48 );
1.184 + JMP_TARGET( nosat );
1.185 +:}
1.186 +MAC.W @Rm+, @Rn+ {:
1.187 + load_reg( R_ECX, Rm );
1.188 + check_ralign16( R_ECX );
1.189 + load_reg( R_ECX, Rn );
1.190 + check_ralign16( R_ECX );
1.191 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
1.192 + MEM_READ_WORD( R_ECX, R_EAX );
1.193 + PUSH_r32( R_EAX );
1.194 + load_reg( R_ECX, Rm );
1.195 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1.196 + MEM_READ_WORD( R_ECX, R_EAX );
1.197 + POP_r32( R_ECX );
1.198 + IMUL_r32( R_ECX );
1.199 +
1.200 + load_spreg( R_ECX, R_S );
1.201 + TEST_r32_r32( R_ECX, R_ECX );
1.202 + JE_rel8( 47, nosat );
1.203 +
1.204 + ADD_r32_sh4r( R_EAX, R_MACL ); // 6
1.205 + JNO_rel8( 51, end ); // 2
1.206 + load_imm32( R_EDX, 1 ); // 5
1.207 + store_spreg( R_EDX, R_MACH ); // 6
1.208 + JS_rel8( 13, positive ); // 2
1.209 + load_imm32( R_EAX, 0x80000000 );// 5
1.210 + store_spreg( R_EAX, R_MACL ); // 6
1.211 + JMP_rel8( 25, end2 ); // 2
1.212 +
1.213 + JMP_TARGET(positive);
1.214 + load_imm32( R_EAX, 0x7FFFFFFF );// 5
1.215 + store_spreg( R_EAX, R_MACL ); // 6
1.216 + JMP_rel8( 12, end3); // 2
1.217 +
1.218 + JMP_TARGET(nosat);
1.219 + ADD_r32_sh4r( R_EAX, R_MACL ); // 6
1.220 + ADC_r32_sh4r( R_EDX, R_MACH ); // 6
1.221 + JMP_TARGET(end);
1.222 + JMP_TARGET(end2);
1.223 + JMP_TARGET(end3);
1.224 +:}
1.225 MOVT Rn {:
1.226 load_spreg( R_EAX, R_T );
1.227 store_reg( R_EAX, Rn );
1.228 @@ -673,8 +768,10 @@
1.229 load_reg( R_EAX, 0 );
1.230 load_spreg( R_ECX, R_GBR );
1.231 ADD_r32_r32( R_EAX, R_ECX );
1.232 - MEM_READ_BYTE( R_ECX, R_EAX );
1.233 - OR_imm32_r32(imm, R_ECX );
1.234 + PUSH_r32(R_ECX);
1.235 + call_func0(sh4_read_byte);
1.236 + POP_r32(R_ECX);
1.237 + OR_imm32_r32(imm, R_EAX );
1.238 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.239 :}
1.240 ROTCL Rn {:
1.241 @@ -708,34 +805,46 @@
1.242 load_reg( R_EAX, Rn );
1.243 load_reg( R_ECX, Rm );
1.244 CMP_imm32_r32( 0, R_ECX );
1.245 - JGE_rel8(9, doshl);
1.246 + JGE_rel8(16, doshl);
1.247
1.248 NEG_r32( R_ECX ); // 2
1.249 AND_imm8_r8( 0x1F, R_CL ); // 3
1.250 + JE_rel8( 4, emptysar); // 2
1.251 SAR_r32_CL( R_EAX ); // 2
1.252 - JMP_rel8(5, end); // 2
1.253 + JMP_rel8(10, end); // 2
1.254 +
1.255 + JMP_TARGET(emptysar);
1.256 + SAR_imm8_r32(31, R_EAX ); // 3
1.257 + JMP_rel8(5, end2);
1.258
1.259 JMP_TARGET(doshl);
1.260 AND_imm8_r8( 0x1F, R_CL ); // 3
1.261 SHL_r32_CL( R_EAX ); // 2
1.262 JMP_TARGET(end);
1.263 + JMP_TARGET(end2);
1.264 store_reg( R_EAX, Rn );
1.265 :}
1.266 SHLD Rm, Rn {:
1.267 load_reg( R_EAX, Rn );
1.268 load_reg( R_ECX, Rm );
1.269 CMP_imm32_r32( 0, R_ECX );
1.270 - JGE_rel8(9, doshl);
1.271 + JGE_rel8(15, doshl);
1.272
1.273 NEG_r32( R_ECX ); // 2
1.274 AND_imm8_r8( 0x1F, R_CL ); // 3
1.275 + JE_rel8( 4, emptyshr );
1.276 SHR_r32_CL( R_EAX ); // 2
1.277 - JMP_rel8(5, end); // 2
1.278 + JMP_rel8(9, end); // 2
1.279 +
1.280 + JMP_TARGET(emptyshr);
1.281 + XOR_r32_r32( R_EAX, R_EAX );
1.282 + JMP_rel8(5, end2);
1.283
1.284 JMP_TARGET(doshl);
1.285 AND_imm8_r8( 0x1F, R_CL ); // 3
1.286 SHL_r32_CL( R_EAX ); // 2
1.287 JMP_TARGET(end);
1.288 + JMP_TARGET(end2);
1.289 store_reg( R_EAX, Rn );
1.290 :}
1.291 SHAL Rn {:
1.292 @@ -827,6 +936,7 @@
1.293 TEST_r8_r8( R_AL, R_AL );
1.294 SETE_t();
1.295 OR_imm8_r8( 0x80, R_AL );
1.296 + load_reg( R_ECX, Rn );
1.297 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.298 :}
1.299 TST Rm, Rn {:
1.300 @@ -863,7 +973,9 @@
1.301 load_reg( R_EAX, 0 );
1.302 load_spreg( R_ECX, R_GBR );
1.303 ADD_r32_r32( R_EAX, R_ECX );
1.304 - MEM_READ_BYTE( R_ECX, R_EAX );
1.305 + PUSH_r32(R_ECX);
1.306 + call_func0(sh4_read_byte);
1.307 + POP_r32(R_ECX);
1.308 XOR_imm32_r32( imm, R_EAX );
1.309 MEM_WRITE_BYTE( R_ECX, R_EAX );
1.310 :}
1.311 @@ -919,7 +1031,7 @@
1.312 MOV.B @Rm, Rn {:
1.313 load_reg( R_ECX, Rm );
1.314 MEM_READ_BYTE( R_ECX, R_EAX );
1.315 - store_reg( R_ECX, Rn );
1.316 + store_reg( R_EAX, Rn );
1.317 :}
1.318 MOV.B @Rm+, Rn {:
1.319 load_reg( R_ECX, Rm );
1.320 @@ -1145,13 +1257,12 @@
1.321 if( sh4_x86.in_delay_slot ) {
1.322 SLOTILLEGAL();
1.323 } else {
1.324 - load_imm32( R_EDI, pc + 2 );
1.325 + load_imm32( R_EDI, pc + 4 );
1.326 CMP_imm8s_sh4r( 0, R_T );
1.327 JNE_rel8( 5, nottaken );
1.328 load_imm32( R_EDI, disp + pc + 4 );
1.329 JMP_TARGET(nottaken);
1.330 sh4_x86.in_delay_slot = TRUE;
1.331 - INC_r32(R_ESI);
1.332 return 0;
1.333 }
1.334 :}
1.335 @@ -1161,7 +1272,6 @@
1.336 } else {
1.337 load_imm32( R_EDI, disp + pc + 4 );
1.338 sh4_x86.in_delay_slot = TRUE;
1.339 - INC_r32(R_ESI);
1.340 return 0;
1.341 }
1.342 :}
1.343 @@ -1172,7 +1282,6 @@
1.344 load_reg( R_EDI, Rn );
1.345 ADD_imm32_r32( pc + 4, R_EDI );
1.346 sh4_x86.in_delay_slot = TRUE;
1.347 - INC_r32(R_ESI);
1.348 return 0;
1.349 }
1.350 :}
1.351 @@ -1184,7 +1293,6 @@
1.352 store_spreg( R_EAX, R_PR );
1.353 load_imm32( R_EDI, disp + pc + 4 );
1.354 sh4_x86.in_delay_slot = TRUE;
1.355 - INC_r32(R_ESI);
1.356 return 0;
1.357 }
1.358 :}
1.359 @@ -1197,7 +1305,6 @@
1.360 load_reg( R_EDI, Rn );
1.361 ADD_r32_r32( R_EAX, R_EDI );
1.362 sh4_x86.in_delay_slot = TRUE;
1.363 - INC_r32(R_ESI);
1.364 return 0;
1.365 }
1.366 :}
1.367 @@ -1218,13 +1325,12 @@
1.368 if( sh4_x86.in_delay_slot ) {
1.369 SLOTILLEGAL();
1.370 } else {
1.371 - load_imm32( R_EDI, pc + 2 );
1.372 + load_imm32( R_EDI, pc + 4 );
1.373 CMP_imm8s_sh4r( 0, R_T );
1.374 JE_rel8( 5, nottaken );
1.375 load_imm32( R_EDI, disp + pc + 4 );
1.376 JMP_TARGET(nottaken);
1.377 sh4_x86.in_delay_slot = TRUE;
1.378 - INC_r32(R_ESI);
1.379 return 0;
1.380 }
1.381 :}
1.382 @@ -1234,7 +1340,6 @@
1.383 } else {
1.384 load_reg( R_EDI, Rn );
1.385 sh4_x86.in_delay_slot = TRUE;
1.386 - INC_r32(R_ESI);
1.387 return 0;
1.388 }
1.389 :}
1.390 @@ -1246,7 +1351,6 @@
1.391 store_spreg( R_EAX, R_PR );
1.392 load_reg( R_EDI, Rn );
1.393 sh4_x86.in_delay_slot = TRUE;
1.394 - INC_r32(R_ESI);
1.395 return 0;
1.396 }
1.397 :}
1.398 @@ -1255,13 +1359,12 @@
1.399 if( sh4_x86.in_delay_slot ) {
1.400 SLOTILLEGAL();
1.401 } else {
1.402 - load_spreg( R_EDI, R_PR );
1.403 + load_spreg( R_EDI, R_SPC );
1.404 load_spreg( R_EAX, R_SSR );
1.405 call_func1( sh4_write_sr, R_EAX );
1.406 sh4_x86.in_delay_slot = TRUE;
1.407 sh4_x86.priv_checked = FALSE;
1.408 sh4_x86.fpuen_checked = FALSE;
1.409 - INC_r32(R_ESI);
1.410 return 0;
1.411 }
1.412 :}
1.413 @@ -1271,7 +1374,6 @@
1.414 } else {
1.415 load_spreg( R_EDI, R_PR );
1.416 sh4_x86.in_delay_slot = TRUE;
1.417 - INC_r32(R_ESI);
1.418 return 0;
1.419 }
1.420 :}
1.421 @@ -1287,7 +1389,7 @@
1.422 if( sh4_x86.in_delay_slot ) {
1.423 SLOTILLEGAL();
1.424 } else {
1.425 - RAISE_EXCEPTION(EXC_ILLEGAL);
1.426 + JMP_exit(EXIT_ILLEGAL);
1.427 return 1;
1.428 }
1.429 :}
1.430 @@ -1331,7 +1433,7 @@
1.431 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
1.432 store_fr( R_EDX, R_EAX, FRn );
1.433 if( FRm&1 ) {
1.434 - JMP_rel8(22, end);
1.435 + JMP_rel8(24, end);
1.436 JMP_TARGET(doublesize);
1.437 load_xf_bank( R_ECX );
1.438 load_fr( R_ECX, R_EAX, FRm-1 );
1.439 @@ -1347,7 +1449,7 @@
1.440 JMP_TARGET(end);
1.441 } else /* FRm&1 == 0 */ {
1.442 if( FRn&1 ) {
1.443 - JMP_rel8(22, end);
1.444 + JMP_rel8(24, end);
1.445 load_xf_bank( R_ECX );
1.446 load_fr( R_EDX, R_EAX, FRm );
1.447 load_fr( R_EDX, R_EDX, FRm+1 );
1.448 @@ -1375,7 +1477,7 @@
1.449 load_fr( R_ECX, R_EAX, FRm );
1.450 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.451 if( FRm&1 ) {
1.452 - JMP_rel8( 46, end );
1.453 + JMP_rel8( 48, end );
1.454 JMP_TARGET(doublesize);
1.455 load_xf_bank( R_ECX );
1.456 load_fr( R_ECX, R_EAX, FRm&0x0E );
1.457 @@ -1403,7 +1505,7 @@
1.458 load_fr_bank( R_ECX );
1.459 store_fr( R_ECX, R_EAX, FRn );
1.460 if( FRn&1 ) {
1.461 - JMP_rel8(46, end);
1.462 + JMP_rel8(48, end);
1.463 JMP_TARGET(doublesize);
1.464 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.465 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.466 @@ -1434,7 +1536,7 @@
1.467 store_reg( R_EDX, Rn );
1.468 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.469 if( FRm&1 ) {
1.470 - JMP_rel8( 52, end );
1.471 + JMP_rel8( 54, end );
1.472 JMP_TARGET(doublesize);
1.473 load_xf_bank( R_ECX );
1.474 load_fr( R_ECX, R_EAX, FRm&0x0E );
1.475 @@ -1469,7 +1571,7 @@
1.476 load_fr_bank( R_ECX );
1.477 store_fr( R_ECX, R_EAX, FRn );
1.478 if( FRn&1 ) {
1.479 - JMP_rel8(52, end);
1.480 + JMP_rel8(54, end);
1.481 JMP_TARGET(doublesize);
1.482 ADD_imm8s_r32( 8, R_EAX );
1.483 store_reg(R_EAX, Rm);
1.484 @@ -1502,7 +1604,7 @@
1.485 load_fr( R_ECX, R_EAX, FRm );
1.486 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1.487 if( FRm&1 ) {
1.488 - JMP_rel8( 46, end );
1.489 + JMP_rel8( 48, end );
1.490 JMP_TARGET(doublesize);
1.491 load_xf_bank( R_ECX );
1.492 load_fr( R_ECX, R_EAX, FRm&0x0E );
1.493 @@ -1531,7 +1633,7 @@
1.494 load_fr_bank( R_ECX );
1.495 store_fr( R_ECX, R_EAX, FRn );
1.496 if( FRn&1 ) {
1.497 - JMP_rel8(46, end);
1.498 + JMP_rel8(48, end);
1.499 JMP_TARGET(doublesize);
1.500 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1.501 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1.502 @@ -1829,7 +1931,7 @@
1.503 load_spreg( R_ECX, R_FPSCR );
1.504 XOR_imm32_r32( FPSCR_FR, R_ECX );
1.505 store_spreg( R_ECX, R_FPSCR );
1.506 -
1.507 + update_fr_bank( R_ECX );
1.508 :}
1.509 FSCHG {:
1.510 check_fpuen();
1.511 @@ -1840,36 +1942,47 @@
1.512
1.513 /* Processor control instructions */
1.514 LDC Rm, SR {:
1.515 - load_reg( R_EAX, Rm );
1.516 - call_func1( sh4_write_sr, R_EAX );
1.517 - sh4_x86.priv_checked = FALSE;
1.518 - sh4_x86.fpuen_checked = FALSE;
1.519 + if( sh4_x86.in_delay_slot ) {
1.520 + SLOTILLEGAL();
1.521 + } else {
1.522 + check_priv();
1.523 + load_reg( R_EAX, Rm );
1.524 + call_func1( sh4_write_sr, R_EAX );
1.525 + sh4_x86.priv_checked = FALSE;
1.526 + sh4_x86.fpuen_checked = FALSE;
1.527 + }
1.528 :}
1.529 LDC Rm, GBR {:
1.530 load_reg( R_EAX, Rm );
1.531 store_spreg( R_EAX, R_GBR );
1.532 :}
1.533 LDC Rm, VBR {:
1.534 + check_priv();
1.535 load_reg( R_EAX, Rm );
1.536 store_spreg( R_EAX, R_VBR );
1.537 :}
1.538 LDC Rm, SSR {:
1.539 + check_priv();
1.540 load_reg( R_EAX, Rm );
1.541 store_spreg( R_EAX, R_SSR );
1.542 :}
1.543 LDC Rm, SGR {:
1.544 + check_priv();
1.545 load_reg( R_EAX, Rm );
1.546 store_spreg( R_EAX, R_SGR );
1.547 :}
1.548 LDC Rm, SPC {:
1.549 + check_priv();
1.550 load_reg( R_EAX, Rm );
1.551 store_spreg( R_EAX, R_SPC );
1.552 :}
1.553 LDC Rm, DBR {:
1.554 + check_priv();
1.555 load_reg( R_EAX, Rm );
1.556 store_spreg( R_EAX, R_DBR );
1.557 :}
1.558 LDC Rm, Rn_BANK {:
1.559 + check_priv();
1.560 load_reg( R_EAX, Rm );
1.561 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.562 :}
1.563 @@ -1882,16 +1995,22 @@
1.564 store_spreg( R_EAX, R_GBR );
1.565 :}
1.566 LDC.L @Rm+, SR {:
1.567 - load_reg( R_EAX, Rm );
1.568 - MOV_r32_r32( R_EAX, R_ECX );
1.569 - ADD_imm8s_r32( 4, R_EAX );
1.570 - store_reg( R_EAX, Rm );
1.571 - MEM_READ_LONG( R_ECX, R_EAX );
1.572 - call_func1( sh4_write_sr, R_EAX );
1.573 - sh4_x86.priv_checked = FALSE;
1.574 - sh4_x86.fpuen_checked = FALSE;
1.575 + if( sh4_x86.in_delay_slot ) {
1.576 + SLOTILLEGAL();
1.577 + } else {
1.578 + check_priv();
1.579 + load_reg( R_EAX, Rm );
1.580 + MOV_r32_r32( R_EAX, R_ECX );
1.581 + ADD_imm8s_r32( 4, R_EAX );
1.582 + store_reg( R_EAX, Rm );
1.583 + MEM_READ_LONG( R_ECX, R_EAX );
1.584 + call_func1( sh4_write_sr, R_EAX );
1.585 + sh4_x86.priv_checked = FALSE;
1.586 + sh4_x86.fpuen_checked = FALSE;
1.587 + }
1.588 :}
1.589 LDC.L @Rm+, VBR {:
1.590 + check_priv();
1.591 load_reg( R_EAX, Rm );
1.592 MOV_r32_r32( R_EAX, R_ECX );
1.593 ADD_imm8s_r32( 4, R_EAX );
1.594 @@ -1900,6 +2019,7 @@
1.595 store_spreg( R_EAX, R_VBR );
1.596 :}
1.597 LDC.L @Rm+, SSR {:
1.598 + check_priv();
1.599 load_reg( R_EAX, Rm );
1.600 MOV_r32_r32( R_EAX, R_ECX );
1.601 ADD_imm8s_r32( 4, R_EAX );
1.602 @@ -1908,6 +2028,7 @@
1.603 store_spreg( R_EAX, R_SSR );
1.604 :}
1.605 LDC.L @Rm+, SGR {:
1.606 + check_priv();
1.607 load_reg( R_EAX, Rm );
1.608 MOV_r32_r32( R_EAX, R_ECX );
1.609 ADD_imm8s_r32( 4, R_EAX );
1.610 @@ -1916,6 +2037,7 @@
1.611 store_spreg( R_EAX, R_SGR );
1.612 :}
1.613 LDC.L @Rm+, SPC {:
1.614 + check_priv();
1.615 load_reg( R_EAX, Rm );
1.616 MOV_r32_r32( R_EAX, R_ECX );
1.617 ADD_imm8s_r32( 4, R_EAX );
1.618 @@ -1924,6 +2046,7 @@
1.619 store_spreg( R_EAX, R_SPC );
1.620 :}
1.621 LDC.L @Rm+, DBR {:
1.622 + check_priv();
1.623 load_reg( R_EAX, Rm );
1.624 MOV_r32_r32( R_EAX, R_ECX );
1.625 ADD_imm8s_r32( 4, R_EAX );
1.626 @@ -1932,6 +2055,7 @@
1.627 store_spreg( R_EAX, R_DBR );
1.628 :}
1.629 LDC.L @Rm+, Rn_BANK {:
1.630 + check_priv();
1.631 load_reg( R_EAX, Rm );
1.632 MOV_r32_r32( R_EAX, R_ECX );
1.633 ADD_imm8s_r32( 4, R_EAX );
1.634 @@ -1942,6 +2066,7 @@
1.635 LDS Rm, FPSCR {:
1.636 load_reg( R_EAX, Rm );
1.637 store_spreg( R_EAX, R_FPSCR );
1.638 + update_fr_bank( R_EAX );
1.639 :}
1.640 LDS.L @Rm+, FPSCR {:
1.641 load_reg( R_EAX, Rm );
1.642 @@ -1950,6 +2075,7 @@
1.643 store_reg( R_EAX, Rm );
1.644 MEM_READ_LONG( R_ECX, R_EAX );
1.645 store_spreg( R_EAX, R_FPSCR );
1.646 + update_fr_bank( R_EAX );
1.647 :}
1.648 LDS Rm, FPUL {:
1.649 load_reg( R_EAX, Rm );
1.650 @@ -2013,40 +2139,48 @@
1.651 JMP_TARGET(end);
1.652 ADD_imm8s_r32( 4, R_ESP );
1.653 :}
1.654 - SLEEP {: /* TODO */ :}
1.655 - STC SR, Rn {:
1.656 - call_func0(sh4_read_sr);
1.657 - store_reg( R_EAX, Rn );
1.658 +SLEEP {: /* TODO */ :}
1.659 +STC SR, Rn {:
1.660 + check_priv();
1.661 + call_func0(sh4_read_sr);
1.662 + store_reg( R_EAX, Rn );
1.663 :}
1.664 STC GBR, Rn {:
1.665 load_spreg( R_EAX, R_GBR );
1.666 store_reg( R_EAX, Rn );
1.667 :}
1.668 STC VBR, Rn {:
1.669 + check_priv();
1.670 load_spreg( R_EAX, R_VBR );
1.671 store_reg( R_EAX, Rn );
1.672 :}
1.673 STC SSR, Rn {:
1.674 + check_priv();
1.675 load_spreg( R_EAX, R_SSR );
1.676 store_reg( R_EAX, Rn );
1.677 :}
1.678 STC SPC, Rn {:
1.679 + check_priv();
1.680 load_spreg( R_EAX, R_SPC );
1.681 store_reg( R_EAX, Rn );
1.682 :}
1.683 STC SGR, Rn {:
1.684 + check_priv();
1.685 load_spreg( R_EAX, R_SGR );
1.686 store_reg( R_EAX, Rn );
1.687 :}
1.688 STC DBR, Rn {:
1.689 + check_priv();
1.690 load_spreg( R_EAX, R_DBR );
1.691 store_reg( R_EAX, Rn );
1.692 :}
1.693 STC Rm_BANK, Rn {:
1.694 + check_priv();
1.695 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1.696 store_reg( R_EAX, Rn );
1.697 :}
1.698 STC.L SR, @-Rn {:
1.699 + check_priv();
1.700 load_reg( R_ECX, Rn );
1.701 ADD_imm8s_r32( -4, R_ECX );
1.702 store_reg( R_ECX, Rn );
1.703 @@ -2054,6 +2188,7 @@
1.704 MEM_WRITE_LONG( R_ECX, R_EAX );
1.705 :}
1.706 STC.L VBR, @-Rn {:
1.707 + check_priv();
1.708 load_reg( R_ECX, Rn );
1.709 ADD_imm8s_r32( -4, R_ECX );
1.710 store_reg( R_ECX, Rn );
1.711 @@ -2061,6 +2196,7 @@
1.712 MEM_WRITE_LONG( R_ECX, R_EAX );
1.713 :}
1.714 STC.L SSR, @-Rn {:
1.715 + check_priv();
1.716 load_reg( R_ECX, Rn );
1.717 ADD_imm8s_r32( -4, R_ECX );
1.718 store_reg( R_ECX, Rn );
1.719 @@ -2068,6 +2204,7 @@
1.720 MEM_WRITE_LONG( R_ECX, R_EAX );
1.721 :}
1.722 STC.L SPC, @-Rn {:
1.723 + check_priv();
1.724 load_reg( R_ECX, Rn );
1.725 ADD_imm8s_r32( -4, R_ECX );
1.726 store_reg( R_ECX, Rn );
1.727 @@ -2075,6 +2212,7 @@
1.728 MEM_WRITE_LONG( R_ECX, R_EAX );
1.729 :}
1.730 STC.L SGR, @-Rn {:
1.731 + check_priv();
1.732 load_reg( R_ECX, Rn );
1.733 ADD_imm8s_r32( -4, R_ECX );
1.734 store_reg( R_ECX, Rn );
1.735 @@ -2082,6 +2220,7 @@
1.736 MEM_WRITE_LONG( R_ECX, R_EAX );
1.737 :}
1.738 STC.L DBR, @-Rn {:
1.739 + check_priv();
1.740 load_reg( R_ECX, Rn );
1.741 ADD_imm8s_r32( -4, R_ECX );
1.742 store_reg( R_ECX, Rn );
1.743 @@ -2089,6 +2228,7 @@
1.744 MEM_WRITE_LONG( R_ECX, R_EAX );
1.745 :}
1.746 STC.L Rm_BANK, @-Rn {:
1.747 + check_priv();
1.748 load_reg( R_ECX, Rn );
1.749 ADD_imm8s_r32( -4, R_ECX );
1.750 store_reg( R_ECX, Rn );
1.751 @@ -2160,10 +2300,12 @@
1.752
1.753 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
1.754 %%
1.755 - INC_r32(R_ESI);
1.756 if( sh4_x86.in_delay_slot ) {
1.757 + ADD_imm8s_r32(2,R_ESI);
1.758 sh4_x86.in_delay_slot = FALSE;
1.759 return 1;
1.760 + } else {
1.761 + INC_r32(R_ESI);
1.762 }
1.763 return 0;
1.764 }
.