revision 386:6fb10951326a
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 386:6fb10951326a |
parent | 385:766eca01ef4d |
child | 387:38e9fddbf0e3 |
author | nkeynes |
date | Sun Sep 16 07:03:23 2007 +0000 (16 years ago) |
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
Correct SHAD/SHLD
Fix privilege and slot illegal checks on LDC/STC opcodes
Fix various other small bugs
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 Sun Sep 16 07:01:35 2007 +00001.2 +++ b/src/sh4/sh4x86.c Sun Sep 16 07:03:23 2007 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: sh4x86.c,v 1.8 2007-09-12 11:41:43 nkeynes Exp $1.6 + * $Id: sh4x86.c,v 1.9 2007-09-16 07:03:23 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 @@ -56,6 +56,15 @@1.12 static struct sh4_x86_state sh4_x86;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 size1.32 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction1.33 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg1.34 }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 size1.42 + AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction1.43 + OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg1.44 + store_spreg( fpscrreg, REG_OFFSET(fr_bank) );1.45 +}1.46 +/**1.47 * Push FPUL (as a 32-bit float) onto the FPU stack1.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.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.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.82 -#define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);1.83 -#define SLOTILLEGAL() RAISE_EXCEPTION(EXC_SLOT_ILLEGAL); return 11.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.89 @@ -415,6 +442,9 @@1.91 load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 61.92 CALL_r32( R_EAX ); // 21.93 + ADD_imm8s_r32( 4, R_ESP );1.94 + POP_r32(R_ESI);1.95 + POP_r32(R_EDI);1.96 POP_r32(R_EBP);1.97 RET();1.99 @@ -443,6 +473,7 @@1.100 case 0x0:1.101 { /* STC SR, Rn */1.102 uint32_t Rn = ((ir>>8)&0xF);1.103 + check_priv();1.104 call_func0(sh4_read_sr);1.105 store_reg( R_EAX, Rn );1.106 }1.107 @@ -457,6 +488,7 @@1.108 case 0x2:1.109 { /* STC VBR, Rn */1.110 uint32_t Rn = ((ir>>8)&0xF);1.111 + check_priv();1.112 load_spreg( R_EAX, R_VBR );1.113 store_reg( R_EAX, Rn );1.114 }1.115 @@ -464,6 +496,7 @@1.116 case 0x3:1.117 { /* STC SSR, Rn */1.118 uint32_t Rn = ((ir>>8)&0xF);1.119 + check_priv();1.120 load_spreg( R_EAX, R_SSR );1.121 store_reg( R_EAX, Rn );1.122 }1.123 @@ -471,6 +504,7 @@1.124 case 0x4:1.125 { /* STC SPC, Rn */1.126 uint32_t Rn = ((ir>>8)&0xF);1.127 + check_priv();1.128 load_spreg( R_EAX, R_SPC );1.129 store_reg( R_EAX, Rn );1.130 }1.131 @@ -483,6 +517,7 @@1.132 case 0x1:1.133 { /* STC Rm_BANK, Rn */1.134 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);1.135 + check_priv();1.136 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );1.137 store_reg( R_EAX, Rn );1.138 }1.139 @@ -502,7 +537,6 @@1.140 load_reg( R_EDI, Rn );1.141 ADD_r32_r32( R_EAX, R_EDI );1.142 sh4_x86.in_delay_slot = TRUE;1.143 - INC_r32(R_ESI);1.144 return 0;1.145 }1.146 }1.147 @@ -514,8 +548,8 @@1.148 SLOTILLEGAL();1.149 } else {1.150 load_reg( R_EDI, Rn );1.151 + ADD_imm32_r32( pc + 4, R_EDI );1.152 sh4_x86.in_delay_slot = TRUE;1.153 - INC_r32(R_ESI);1.154 return 0;1.155 }1.156 }1.157 @@ -698,6 +732,7 @@1.158 case 0x3:1.159 { /* STC SGR, Rn */1.160 uint32_t Rn = ((ir>>8)&0xF);1.161 + check_priv();1.162 load_spreg( R_EAX, R_SGR );1.163 store_reg( R_EAX, Rn );1.164 }1.165 @@ -719,6 +754,7 @@1.166 case 0xF:1.167 { /* STC DBR, Rn */1.168 uint32_t Rn = ((ir>>8)&0xF);1.169 + check_priv();1.170 load_spreg( R_EAX, R_DBR );1.171 store_reg( R_EAX, Rn );1.172 }1.173 @@ -737,7 +773,6 @@1.174 } else {1.175 load_spreg( R_EDI, R_PR );1.176 sh4_x86.in_delay_slot = TRUE;1.177 - INC_r32(R_ESI);1.178 return 0;1.179 }1.180 }1.181 @@ -753,13 +788,12 @@1.182 if( sh4_x86.in_delay_slot ) {1.183 SLOTILLEGAL();1.184 } else {1.185 - load_spreg( R_EDI, R_PR );1.186 + load_spreg( R_EDI, R_SPC );1.187 load_spreg( R_EAX, R_SSR );1.188 call_func1( sh4_write_sr, R_EAX );1.189 sh4_x86.in_delay_slot = TRUE;1.190 sh4_x86.priv_checked = FALSE;1.191 sh4_x86.fpuen_checked = FALSE;1.192 - INC_r32(R_ESI);1.193 return 0;1.194 }1.195 }1.196 @@ -804,6 +838,26 @@1.197 case 0xF:1.198 { /* MAC.L @Rm+, @Rn+ */1.199 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.200 + load_reg( R_ECX, Rm );1.201 + check_ralign32( R_ECX );1.202 + load_reg( R_ECX, Rn );1.203 + check_ralign32( R_ECX );1.204 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );1.205 + MEM_READ_LONG( R_ECX, R_EAX );1.206 + PUSH_r32( R_EAX );1.207 + load_reg( R_ECX, Rm );1.208 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );1.209 + MEM_READ_LONG( R_ECX, R_EAX );1.210 + POP_r32( R_ECX );1.211 + IMUL_r32( R_ECX );1.212 + ADD_r32_sh4r( R_EAX, R_MACL );1.213 + ADC_r32_sh4r( R_EDX, R_MACH );1.214 +1.215 + load_spreg( R_ECX, R_S );1.216 + TEST_r32_r32(R_ECX, R_ECX);1.217 + JE_rel8( 7, nosat );1.218 + call_func0( signsat48 );1.219 + JMP_TARGET( nosat );1.220 }1.221 break;1.222 default:1.223 @@ -836,8 +890,8 @@1.224 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.225 load_reg( R_ECX, Rn );1.226 check_walign16( R_ECX );1.227 - MEM_READ_WORD( R_ECX, R_EAX );1.228 - store_reg( R_EAX, Rn );1.229 + load_reg( R_EAX, Rm );1.230 + MEM_WRITE_WORD( R_ECX, R_EAX );1.231 }1.232 break;1.233 case 0x2:1.234 @@ -854,7 +908,7 @@1.235 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.236 load_reg( R_EAX, Rm );1.237 load_reg( R_ECX, Rn );1.238 - ADD_imm8s_r32( -1, Rn );1.239 + ADD_imm8s_r32( -1, R_ECX );1.240 store_reg( R_ECX, Rn );1.241 MEM_WRITE_BYTE( R_ECX, R_EAX );1.242 }1.243 @@ -866,6 +920,7 @@1.244 check_walign16( R_ECX );1.245 load_reg( R_EAX, Rm );1.246 ADD_imm8s_r32( -2, R_ECX );1.247 + store_reg( R_ECX, Rn );1.248 MEM_WRITE_WORD( R_ECX, R_EAX );1.249 }1.250 break;1.251 @@ -884,13 +939,13 @@1.252 { /* DIV0S Rm, Rn */1.253 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.254 load_reg( R_EAX, Rm );1.255 - load_reg( R_ECX, Rm );1.256 + load_reg( R_ECX, Rn );1.257 SHR_imm8_r32( 31, R_EAX );1.258 SHR_imm8_r32( 31, R_ECX );1.259 store_spreg( R_EAX, R_M );1.260 store_spreg( R_ECX, R_Q );1.261 CMP_r32_r32( R_EAX, R_ECX );1.262 - SETE_t();1.263 + SETNE_t();1.264 }1.265 break;1.266 case 0x8:1.267 @@ -1015,19 +1070,26 @@1.268 case 0x4:1.269 { /* DIV1 Rm, Rn */1.270 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.271 - load_reg( R_ECX, Rn );1.272 + load_spreg( R_ECX, R_M );1.273 + load_reg( R_EAX, Rn );1.274 LDC_t();1.275 - RCL1_r32( R_ECX ); // OP21.276 - SETC_r32( R_EDX ); // Q1.277 - load_spreg( R_EAX, R_Q );1.278 - CMP_sh4r_r32( R_M, R_EAX );1.279 - JE_rel8(8,mqequal);1.280 - ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );1.281 - JMP_rel8(3, mqnotequal);1.282 + RCL1_r32( R_EAX );1.283 + SETC_r8( R_DL ); // Q'1.284 + CMP_sh4r_r32( R_Q, R_ECX );1.285 + JE_rel8(5, mqequal);1.286 + ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );1.287 + JMP_rel8(3, end);1.288 JMP_TARGET(mqequal);1.289 - SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );1.290 - JMP_TARGET(mqnotequal);1.291 - // TODO1.292 + SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );1.293 + JMP_TARGET(end);1.294 + store_reg( R_EAX, Rn ); // Done with Rn now1.295 + SETC_r8(R_AL); // tmp11.296 + XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp11.297 + XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M1.298 + store_spreg( R_ECX, R_Q );1.299 + XOR_imm8s_r32( 1, R_AL ); // T = !Q'1.300 + MOVZX_r8_r32( R_AL, R_EAX );1.301 + store_spreg( R_EAX, R_T );1.302 }1.303 break;1.304 case 0x5:1.305 @@ -1148,7 +1210,7 @@1.306 { /* DT Rn */1.307 uint32_t Rn = ((ir>>8)&0xF);1.308 load_reg( R_EAX, Rn );1.309 - ADD_imm8s_r32( -1, Rn );1.310 + ADD_imm8s_r32( -1, R_EAX );1.311 store_reg( R_EAX, Rn );1.312 SETE_t();1.313 }1.314 @@ -1203,7 +1265,7 @@1.315 { /* STS.L MACH, @-Rn */1.316 uint32_t Rn = ((ir>>8)&0xF);1.317 load_reg( R_ECX, Rn );1.318 - ADD_imm8s_r32( -4, Rn );1.319 + ADD_imm8s_r32( -4, R_ECX );1.320 store_reg( R_ECX, Rn );1.321 load_spreg( R_EAX, R_MACH );1.322 MEM_WRITE_LONG( R_ECX, R_EAX );1.323 @@ -1213,7 +1275,7 @@1.324 { /* STS.L MACL, @-Rn */1.325 uint32_t Rn = ((ir>>8)&0xF);1.326 load_reg( R_ECX, Rn );1.327 - ADD_imm8s_r32( -4, Rn );1.328 + ADD_imm8s_r32( -4, R_ECX );1.329 store_reg( R_ECX, Rn );1.330 load_spreg( R_EAX, R_MACL );1.331 MEM_WRITE_LONG( R_ECX, R_EAX );1.332 @@ -1223,7 +1285,7 @@1.333 { /* STS.L PR, @-Rn */1.334 uint32_t Rn = ((ir>>8)&0xF);1.335 load_reg( R_ECX, Rn );1.336 - ADD_imm8s_r32( -4, Rn );1.337 + ADD_imm8s_r32( -4, R_ECX );1.338 store_reg( R_ECX, Rn );1.339 load_spreg( R_EAX, R_PR );1.340 MEM_WRITE_LONG( R_ECX, R_EAX );1.341 @@ -1232,8 +1294,9 @@1.342 case 0x3:1.343 { /* STC.L SGR, @-Rn */1.344 uint32_t Rn = ((ir>>8)&0xF);1.345 + check_priv();1.346 load_reg( R_ECX, Rn );1.347 - ADD_imm8s_r32( -4, Rn );1.348 + ADD_imm8s_r32( -4, R_ECX );1.349 store_reg( R_ECX, Rn );1.350 load_spreg( R_EAX, R_SGR );1.351 MEM_WRITE_LONG( R_ECX, R_EAX );1.352 @@ -1243,7 +1306,7 @@1.353 { /* STS.L FPUL, @-Rn */1.354 uint32_t Rn = ((ir>>8)&0xF);1.355 load_reg( R_ECX, Rn );1.356 - ADD_imm8s_r32( -4, Rn );1.357 + ADD_imm8s_r32( -4, R_ECX );1.358 store_reg( R_ECX, Rn );1.359 load_spreg( R_EAX, R_FPUL );1.360 MEM_WRITE_LONG( R_ECX, R_EAX );1.361 @@ -1253,7 +1316,7 @@1.362 { /* STS.L FPSCR, @-Rn */1.363 uint32_t Rn = ((ir>>8)&0xF);1.364 load_reg( R_ECX, Rn );1.365 - ADD_imm8s_r32( -4, Rn );1.366 + ADD_imm8s_r32( -4, R_ECX );1.367 store_reg( R_ECX, Rn );1.368 load_spreg( R_EAX, R_FPSCR );1.369 MEM_WRITE_LONG( R_ECX, R_EAX );1.370 @@ -1262,8 +1325,9 @@1.371 case 0xF:1.372 { /* STC.L DBR, @-Rn */1.373 uint32_t Rn = ((ir>>8)&0xF);1.374 + check_priv();1.375 load_reg( R_ECX, Rn );1.376 - ADD_imm8s_r32( -4, Rn );1.377 + ADD_imm8s_r32( -4, R_ECX );1.378 store_reg( R_ECX, Rn );1.379 load_spreg( R_EAX, R_DBR );1.380 MEM_WRITE_LONG( R_ECX, R_EAX );1.381 @@ -1281,8 +1345,9 @@1.382 case 0x0:1.383 { /* STC.L SR, @-Rn */1.384 uint32_t Rn = ((ir>>8)&0xF);1.385 + check_priv();1.386 load_reg( R_ECX, Rn );1.387 - ADD_imm8s_r32( -4, Rn );1.388 + ADD_imm8s_r32( -4, R_ECX );1.389 store_reg( R_ECX, Rn );1.390 call_func0( sh4_read_sr );1.391 MEM_WRITE_LONG( R_ECX, R_EAX );1.392 @@ -1292,7 +1357,7 @@1.393 { /* STC.L GBR, @-Rn */1.394 uint32_t Rn = ((ir>>8)&0xF);1.395 load_reg( R_ECX, Rn );1.396 - ADD_imm8s_r32( -4, Rn );1.397 + ADD_imm8s_r32( -4, R_ECX );1.398 store_reg( R_ECX, Rn );1.399 load_spreg( R_EAX, R_GBR );1.400 MEM_WRITE_LONG( R_ECX, R_EAX );1.401 @@ -1301,8 +1366,9 @@1.402 case 0x2:1.403 { /* STC.L VBR, @-Rn */1.404 uint32_t Rn = ((ir>>8)&0xF);1.405 + check_priv();1.406 load_reg( R_ECX, Rn );1.407 - ADD_imm8s_r32( -4, Rn );1.408 + ADD_imm8s_r32( -4, R_ECX );1.409 store_reg( R_ECX, Rn );1.410 load_spreg( R_EAX, R_VBR );1.411 MEM_WRITE_LONG( R_ECX, R_EAX );1.412 @@ -1311,8 +1377,9 @@1.413 case 0x3:1.414 { /* STC.L SSR, @-Rn */1.415 uint32_t Rn = ((ir>>8)&0xF);1.416 + check_priv();1.417 load_reg( R_ECX, Rn );1.418 - ADD_imm8s_r32( -4, Rn );1.419 + ADD_imm8s_r32( -4, R_ECX );1.420 store_reg( R_ECX, Rn );1.421 load_spreg( R_EAX, R_SSR );1.422 MEM_WRITE_LONG( R_ECX, R_EAX );1.423 @@ -1321,8 +1388,9 @@1.424 case 0x4:1.425 { /* STC.L SPC, @-Rn */1.426 uint32_t Rn = ((ir>>8)&0xF);1.427 + check_priv();1.428 load_reg( R_ECX, Rn );1.429 - ADD_imm8s_r32( -4, Rn );1.430 + ADD_imm8s_r32( -4, R_ECX );1.431 store_reg( R_ECX, Rn );1.432 load_spreg( R_EAX, R_SPC );1.433 MEM_WRITE_LONG( R_ECX, R_EAX );1.434 @@ -1336,8 +1404,9 @@1.435 case 0x1:1.436 { /* STC.L Rm_BANK, @-Rn */1.437 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);1.438 + check_priv();1.439 load_reg( R_ECX, Rn );1.440 - ADD_imm8s_r32( -4, Rn );1.441 + ADD_imm8s_r32( -4, R_ECX );1.442 store_reg( R_ECX, Rn );1.443 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );1.444 MEM_WRITE_LONG( R_ECX, R_EAX );1.445 @@ -1443,6 +1512,7 @@1.446 case 0x3:1.447 { /* LDC.L @Rm+, SGR */1.448 uint32_t Rm = ((ir>>8)&0xF);1.449 + check_priv();1.450 load_reg( R_EAX, Rm );1.451 MOV_r32_r32( R_EAX, R_ECX );1.452 ADD_imm8s_r32( 4, R_EAX );1.453 @@ -1471,11 +1541,13 @@1.454 store_reg( R_EAX, Rm );1.455 MEM_READ_LONG( R_ECX, R_EAX );1.456 store_spreg( R_EAX, R_FPSCR );1.457 + update_fr_bank( R_EAX );1.458 }1.459 break;1.460 case 0xF:1.461 { /* LDC.L @Rm+, DBR */1.462 uint32_t Rm = ((ir>>8)&0xF);1.463 + check_priv();1.464 load_reg( R_EAX, Rm );1.465 MOV_r32_r32( R_EAX, R_ECX );1.466 ADD_imm8s_r32( 4, R_EAX );1.467 @@ -1496,14 +1568,19 @@1.468 case 0x0:1.469 { /* LDC.L @Rm+, SR */1.470 uint32_t Rm = ((ir>>8)&0xF);1.471 - load_reg( R_EAX, Rm );1.472 - MOV_r32_r32( R_EAX, R_ECX );1.473 - ADD_imm8s_r32( 4, R_EAX );1.474 - store_reg( R_EAX, Rm );1.475 - MEM_READ_LONG( R_ECX, R_EAX );1.476 - call_func1( sh4_write_sr, R_EAX );1.477 - sh4_x86.priv_checked = FALSE;1.478 - sh4_x86.fpuen_checked = FALSE;1.479 + if( sh4_x86.in_delay_slot ) {1.480 + SLOTILLEGAL();1.481 + } else {1.482 + check_priv();1.483 + load_reg( R_EAX, Rm );1.484 + MOV_r32_r32( R_EAX, R_ECX );1.485 + ADD_imm8s_r32( 4, R_EAX );1.486 + store_reg( R_EAX, Rm );1.487 + MEM_READ_LONG( R_ECX, R_EAX );1.488 + call_func1( sh4_write_sr, R_EAX );1.489 + sh4_x86.priv_checked = FALSE;1.490 + sh4_x86.fpuen_checked = FALSE;1.491 + }1.492 }1.493 break;1.494 case 0x1:1.495 @@ -1520,6 +1597,7 @@1.496 case 0x2:1.497 { /* LDC.L @Rm+, VBR */1.498 uint32_t Rm = ((ir>>8)&0xF);1.499 + check_priv();1.500 load_reg( R_EAX, Rm );1.501 MOV_r32_r32( R_EAX, R_ECX );1.502 ADD_imm8s_r32( 4, R_EAX );1.503 @@ -1531,6 +1609,7 @@1.504 case 0x3:1.505 { /* LDC.L @Rm+, SSR */1.506 uint32_t Rm = ((ir>>8)&0xF);1.507 + check_priv();1.508 load_reg( R_EAX, Rm );1.509 MOV_r32_r32( R_EAX, R_ECX );1.510 ADD_imm8s_r32( 4, R_EAX );1.511 @@ -1542,6 +1621,7 @@1.512 case 0x4:1.513 { /* LDC.L @Rm+, SPC */1.514 uint32_t Rm = ((ir>>8)&0xF);1.515 + check_priv();1.516 load_reg( R_EAX, Rm );1.517 MOV_r32_r32( R_EAX, R_ECX );1.518 ADD_imm8s_r32( 4, R_EAX );1.519 @@ -1558,6 +1638,7 @@1.520 case 0x1:1.521 { /* LDC.L @Rm+, Rn_BANK */1.522 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);1.523 + check_priv();1.524 load_reg( R_EAX, Rm );1.525 MOV_r32_r32( R_EAX, R_ECX );1.526 ADD_imm8s_r32( 4, R_EAX );1.527 @@ -1656,6 +1737,7 @@1.528 case 0x3:1.529 { /* LDC Rm, SGR */1.530 uint32_t Rm = ((ir>>8)&0xF);1.531 + check_priv();1.532 load_reg( R_EAX, Rm );1.533 store_spreg( R_EAX, R_SGR );1.534 }1.535 @@ -1672,11 +1754,13 @@1.536 uint32_t Rm = ((ir>>8)&0xF);1.537 load_reg( R_EAX, Rm );1.538 store_spreg( R_EAX, R_FPSCR );1.539 + update_fr_bank( R_EAX );1.540 }1.541 break;1.542 case 0xF:1.543 { /* LDC Rm, DBR */1.544 uint32_t Rm = ((ir>>8)&0xF);1.545 + check_priv();1.546 load_reg( R_EAX, Rm );1.547 store_spreg( R_EAX, R_DBR );1.548 }1.549 @@ -1698,7 +1782,6 @@1.550 store_spreg( R_EAX, R_PR );1.551 load_reg( R_EDI, Rn );1.552 sh4_x86.in_delay_slot = TRUE;1.553 - INC_r32(R_ESI);1.554 return 0;1.555 }1.556 }1.557 @@ -1711,6 +1794,7 @@1.558 TEST_r8_r8( R_AL, R_AL );1.559 SETE_t();1.560 OR_imm8_r8( 0x80, R_AL );1.561 + load_reg( R_ECX, Rn );1.562 MEM_WRITE_BYTE( R_ECX, R_EAX );1.563 }1.564 break;1.565 @@ -1722,7 +1806,6 @@1.566 } else {1.567 load_reg( R_EDI, Rn );1.568 sh4_x86.in_delay_slot = TRUE;1.569 - INC_r32(R_ESI);1.570 return 0;1.571 }1.572 }1.573 @@ -1739,16 +1822,23 @@1.574 load_reg( R_EAX, Rn );1.575 load_reg( R_ECX, Rm );1.576 CMP_imm32_r32( 0, R_ECX );1.577 - JAE_rel8(9, doshl);1.578 + JGE_rel8(16, doshl);1.580 NEG_r32( R_ECX ); // 21.581 AND_imm8_r8( 0x1F, R_CL ); // 31.582 + JE_rel8( 4, emptysar); // 21.583 SAR_r32_CL( R_EAX ); // 21.584 - JMP_rel8(5, end); // 21.585 + JMP_rel8(10, end); // 21.586 +1.587 + JMP_TARGET(emptysar);1.588 + SAR_imm8_r32(31, R_EAX ); // 31.589 + JMP_rel8(5, end2);1.590 +1.591 JMP_TARGET(doshl);1.592 AND_imm8_r8( 0x1F, R_CL ); // 31.593 SHL_r32_CL( R_EAX ); // 21.594 JMP_TARGET(end);1.595 + JMP_TARGET(end2);1.596 store_reg( R_EAX, Rn );1.597 }1.598 break;1.599 @@ -1757,13 +1847,24 @@1.600 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.601 load_reg( R_EAX, Rn );1.602 load_reg( R_ECX, Rm );1.603 + CMP_imm32_r32( 0, R_ECX );1.604 + JGE_rel8(15, doshl);1.606 - MOV_r32_r32( R_EAX, R_EDX );1.607 - SHL_r32_CL( R_EAX );1.608 - NEG_r32( R_ECX );1.609 - SHR_r32_CL( R_EDX );1.610 - CMP_imm8s_r32( 0, R_ECX );1.611 - CMOVAE_r32_r32( R_EDX, R_EAX );1.612 + NEG_r32( R_ECX ); // 21.613 + AND_imm8_r8( 0x1F, R_CL ); // 31.614 + JE_rel8( 4, emptyshr );1.615 + SHR_r32_CL( R_EAX ); // 21.616 + JMP_rel8(9, end); // 21.617 +1.618 + JMP_TARGET(emptyshr);1.619 + XOR_r32_r32( R_EAX, R_EAX );1.620 + JMP_rel8(5, end2);1.621 +1.622 + JMP_TARGET(doshl);1.623 + AND_imm8_r8( 0x1F, R_CL ); // 31.624 + SHL_r32_CL( R_EAX ); // 21.625 + JMP_TARGET(end);1.626 + JMP_TARGET(end2);1.627 store_reg( R_EAX, Rn );1.628 }1.629 break;1.630 @@ -1774,10 +1875,15 @@1.631 case 0x0:1.632 { /* LDC Rm, SR */1.633 uint32_t Rm = ((ir>>8)&0xF);1.634 - load_reg( R_EAX, Rm );1.635 - call_func1( sh4_write_sr, R_EAX );1.636 - sh4_x86.priv_checked = FALSE;1.637 - sh4_x86.fpuen_checked = FALSE;1.638 + if( sh4_x86.in_delay_slot ) {1.639 + SLOTILLEGAL();1.640 + } else {1.641 + check_priv();1.642 + load_reg( R_EAX, Rm );1.643 + call_func1( sh4_write_sr, R_EAX );1.644 + sh4_x86.priv_checked = FALSE;1.645 + sh4_x86.fpuen_checked = FALSE;1.646 + }1.647 }1.648 break;1.649 case 0x1:1.650 @@ -1790,6 +1896,7 @@1.651 case 0x2:1.652 { /* LDC Rm, VBR */1.653 uint32_t Rm = ((ir>>8)&0xF);1.654 + check_priv();1.655 load_reg( R_EAX, Rm );1.656 store_spreg( R_EAX, R_VBR );1.657 }1.658 @@ -1797,6 +1904,7 @@1.659 case 0x3:1.660 { /* LDC Rm, SSR */1.661 uint32_t Rm = ((ir>>8)&0xF);1.662 + check_priv();1.663 load_reg( R_EAX, Rm );1.664 store_spreg( R_EAX, R_SSR );1.665 }1.666 @@ -1804,6 +1912,7 @@1.667 case 0x4:1.668 { /* LDC Rm, SPC */1.669 uint32_t Rm = ((ir>>8)&0xF);1.670 + check_priv();1.671 load_reg( R_EAX, Rm );1.672 store_spreg( R_EAX, R_SPC );1.673 }1.674 @@ -1816,6 +1925,7 @@1.675 case 0x1:1.676 { /* LDC Rm, Rn_BANK */1.677 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);1.678 + check_priv();1.679 load_reg( R_EAX, Rm );1.680 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );1.681 }1.682 @@ -1825,6 +1935,43 @@1.683 case 0xF:1.684 { /* MAC.W @Rm+, @Rn+ */1.685 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.686 + load_reg( R_ECX, Rm );1.687 + check_ralign16( R_ECX );1.688 + load_reg( R_ECX, Rn );1.689 + check_ralign16( R_ECX );1.690 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );1.691 + MEM_READ_WORD( R_ECX, R_EAX );1.692 + PUSH_r32( R_EAX );1.693 + load_reg( R_ECX, Rm );1.694 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );1.695 + MEM_READ_WORD( R_ECX, R_EAX );1.696 + POP_r32( R_ECX );1.697 + IMUL_r32( R_ECX );1.698 +1.699 + load_spreg( R_ECX, R_S );1.700 + TEST_r32_r32( R_ECX, R_ECX );1.701 + JE_rel8( 47, nosat );1.702 +1.703 + ADD_r32_sh4r( R_EAX, R_MACL ); // 61.704 + JNO_rel8( 51, end ); // 21.705 + load_imm32( R_EDX, 1 ); // 51.706 + store_spreg( R_EDX, R_MACH ); // 61.707 + JS_rel8( 13, positive ); // 21.708 + load_imm32( R_EAX, 0x80000000 );// 51.709 + store_spreg( R_EAX, R_MACL ); // 61.710 + JMP_rel8( 25, end2 ); // 21.711 +1.712 + JMP_TARGET(positive);1.713 + load_imm32( R_EAX, 0x7FFFFFFF );// 51.714 + store_spreg( R_EAX, R_MACL ); // 61.715 + JMP_rel8( 12, end3); // 21.716 +1.717 + JMP_TARGET(nosat);1.718 + ADD_r32_sh4r( R_EAX, R_MACL ); // 61.719 + ADC_r32_sh4r( R_EDX, R_MACH ); // 61.720 + JMP_TARGET(end);1.721 + JMP_TARGET(end2);1.722 + JMP_TARGET(end3);1.723 }1.724 break;1.725 }1.726 @@ -1846,7 +1993,7 @@1.727 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.728 load_reg( R_ECX, Rm );1.729 MEM_READ_BYTE( R_ECX, R_EAX );1.730 - store_reg( R_ECX, Rn );1.731 + store_reg( R_EAX, Rn );1.732 }1.733 break;1.734 case 0x1:1.735 @@ -1901,7 +2048,7 @@1.736 { /* MOV.L @Rm+, Rn */1.737 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);1.738 load_reg( R_EAX, Rm );1.739 - check_ralign32( R_ECX );1.740 + check_ralign32( R_EAX );1.741 MOV_r32_r32( R_EAX, R_ECX );1.742 ADD_imm8s_r32( 4, R_EAX );1.743 store_reg( R_EAX, Rm );1.744 @@ -2083,13 +2230,12 @@1.745 if( sh4_x86.in_delay_slot ) {1.746 SLOTILLEGAL();1.747 } else {1.748 - load_imm32( R_EDI, pc + 2 );1.749 + load_imm32( R_EDI, pc + 4 );1.750 CMP_imm8s_sh4r( 0, R_T );1.751 JE_rel8( 5, nottaken );1.752 load_imm32( R_EDI, disp + pc + 4 );1.753 JMP_TARGET(nottaken);1.754 sh4_x86.in_delay_slot = TRUE;1.755 - INC_r32(R_ESI);1.756 return 0;1.757 }1.758 }1.759 @@ -2100,13 +2246,12 @@1.760 if( sh4_x86.in_delay_slot ) {1.761 SLOTILLEGAL();1.762 } else {1.763 - load_imm32( R_EDI, pc + 2 );1.764 + load_imm32( R_EDI, pc + 4 );1.765 CMP_imm8s_sh4r( 0, R_T );1.766 JNE_rel8( 5, nottaken );1.767 load_imm32( R_EDI, disp + pc + 4 );1.768 JMP_TARGET(nottaken);1.769 sh4_x86.in_delay_slot = TRUE;1.770 - INC_r32(R_ESI);1.771 return 0;1.772 }1.773 }1.774 @@ -2136,7 +2281,6 @@1.775 } else {1.776 load_imm32( R_EDI, disp + pc + 4 );1.777 sh4_x86.in_delay_slot = TRUE;1.778 - INC_r32(R_ESI);1.779 return 0;1.780 }1.781 }1.782 @@ -2151,7 +2295,6 @@1.783 store_spreg( R_EAX, R_PR );1.784 load_imm32( R_EDI, disp + pc + 4 );1.785 sh4_x86.in_delay_slot = TRUE;1.786 - INC_r32(R_ESI);1.787 return 0;1.788 }1.789 }1.790 @@ -2287,8 +2430,10 @@1.791 load_reg( R_EAX, 0 );1.792 load_spreg( R_ECX, R_GBR );1.793 ADD_r32_r32( R_EAX, R_ECX );1.794 - MEM_READ_BYTE( R_ECX, R_EAX );1.795 - AND_imm32_r32(imm, R_ECX );1.796 + PUSH_r32(R_ECX);1.797 + call_func0(sh4_read_byte);1.798 + POP_r32(R_ECX);1.799 + AND_imm32_r32(imm, R_EAX );1.800 MEM_WRITE_BYTE( R_ECX, R_EAX );1.801 }1.802 break;1.803 @@ -2298,7 +2443,9 @@1.804 load_reg( R_EAX, 0 );1.805 load_spreg( R_ECX, R_GBR );1.806 ADD_r32_r32( R_EAX, R_ECX );1.807 - MEM_READ_BYTE( R_ECX, R_EAX );1.808 + PUSH_r32(R_ECX);1.809 + call_func0(sh4_read_byte);1.810 + POP_r32(R_ECX);1.811 XOR_imm32_r32( imm, R_EAX );1.812 MEM_WRITE_BYTE( R_ECX, R_EAX );1.813 }1.814 @@ -2309,8 +2456,10 @@1.815 load_reg( R_EAX, 0 );1.816 load_spreg( R_ECX, R_GBR );1.817 ADD_r32_r32( R_EAX, R_ECX );1.818 - MEM_READ_BYTE( R_ECX, R_EAX );1.819 - OR_imm32_r32(imm, R_ECX );1.820 + PUSH_r32(R_ECX);1.821 + call_func0(sh4_read_byte);1.822 + POP_r32(R_ECX);1.823 + OR_imm32_r32(imm, R_EAX );1.824 MEM_WRITE_BYTE( R_ECX, R_EAX );1.825 }1.826 break;1.827 @@ -2324,7 +2473,7 @@1.828 } else {1.829 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );1.830 MEM_READ_LONG( R_ECX, R_EAX );1.831 - store_reg( R_EAX, 0 );1.832 + store_reg( R_EAX, Rn );1.833 }1.834 }1.835 break;1.836 @@ -2435,10 +2584,10 @@1.837 JMP_TARGET(doubleprec);1.838 push_dr(R_EDX, FRm);1.839 push_dr(R_EDX, FRn);1.840 + JMP_TARGET(end);1.841 FCOMIP_st(1);1.842 SETE_t();1.843 FPOP_st();1.844 - JMP_TARGET(end);1.845 }1.846 break;1.847 case 0x5:1.848 @@ -2475,7 +2624,7 @@1.849 load_fr_bank( R_ECX );1.850 store_fr( R_ECX, R_EAX, FRn );1.851 if( FRn&1 ) {1.852 - JMP_rel8(46, end);1.853 + JMP_rel8(48, end);1.854 JMP_TARGET(doublesize);1.855 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );1.856 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it1.857 @@ -2508,7 +2657,7 @@1.858 load_fr( R_ECX, R_EAX, FRm );1.859 MEM_WRITE_LONG( R_EDX, R_EAX ); // 121.860 if( FRm&1 ) {1.861 - JMP_rel8( 46, end );1.862 + JMP_rel8( 48, end );1.863 JMP_TARGET(doublesize);1.864 load_xf_bank( R_ECX );1.865 load_fr( R_ECX, R_EAX, FRm&0x0E );1.866 @@ -2539,7 +2688,7 @@1.867 load_fr_bank( R_ECX );1.868 store_fr( R_ECX, R_EAX, FRn );1.869 if( FRn&1 ) {1.870 - JMP_rel8(46, end);1.871 + JMP_rel8(48, end);1.872 JMP_TARGET(doublesize);1.873 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );1.874 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it1.875 @@ -2574,7 +2723,7 @@1.876 load_fr_bank( R_ECX );1.877 store_fr( R_ECX, R_EAX, FRn );1.878 if( FRn&1 ) {1.879 - JMP_rel8(52, end);1.880 + JMP_rel8(54, end);1.881 JMP_TARGET(doublesize);1.882 ADD_imm8s_r32( 8, R_EAX );1.883 store_reg(R_EAX, Rm);1.884 @@ -2609,7 +2758,7 @@1.885 load_fr( R_ECX, R_EAX, FRm );1.886 MEM_WRITE_LONG( R_EDX, R_EAX ); // 121.887 if( FRm&1 ) {1.888 - JMP_rel8( 46, end );1.889 + JMP_rel8( 48, end );1.890 JMP_TARGET(doublesize);1.891 load_xf_bank( R_ECX );1.892 load_fr( R_ECX, R_EAX, FRm&0x0E );1.893 @@ -2635,14 +2784,14 @@1.894 check_walign32( R_EDX );1.895 load_spreg( R_ECX, R_FPSCR );1.896 TEST_imm32_r32( FPSCR_SZ, R_ECX );1.897 - JNE_rel8(20, doublesize);1.898 + JNE_rel8(26, doublesize);1.899 load_fr_bank( R_ECX );1.900 load_fr( R_ECX, R_EAX, FRm );1.901 ADD_imm8s_r32(-4,R_EDX);1.902 store_reg( R_EDX, Rn );1.903 MEM_WRITE_LONG( R_EDX, R_EAX ); // 121.904 if( FRm&1 ) {1.905 - JMP_rel8( 46, end );1.906 + JMP_rel8( 54, end );1.907 JMP_TARGET(doublesize);1.908 load_xf_bank( R_ECX );1.909 load_fr( R_ECX, R_EAX, FRm&0x0E );1.910 @@ -2652,7 +2801,7 @@1.911 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );1.912 JMP_TARGET(end);1.913 } else {1.914 - JMP_rel8( 39, end );1.915 + JMP_rel8( 45, end );1.916 JMP_TARGET(doublesize);1.917 load_fr_bank( R_ECX );1.918 load_fr( R_ECX, R_EAX, FRm&0x0E );1.919 @@ -2682,7 +2831,7 @@1.920 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch1.921 store_fr( R_EDX, R_EAX, FRn );1.922 if( FRm&1 ) {1.923 - JMP_rel8(22, end);1.924 + JMP_rel8(24, end);1.925 JMP_TARGET(doublesize);1.926 load_xf_bank( R_ECX );1.927 load_fr( R_ECX, R_EAX, FRm-1 );1.928 @@ -2698,7 +2847,7 @@1.929 JMP_TARGET(end);1.930 } else /* FRm&1 == 0 */ {1.931 if( FRn&1 ) {1.932 - JMP_rel8(22, end);1.933 + JMP_rel8(24, end);1.934 load_xf_bank( R_ECX );1.935 load_fr( R_EDX, R_EAX, FRm );1.936 load_fr( R_EDX, R_EDX, FRm+1 );1.937 @@ -2925,16 +3074,17 @@1.938 load_spreg( R_ECX, R_FPSCR );1.939 XOR_imm32_r32( FPSCR_FR, R_ECX );1.940 store_spreg( R_ECX, R_FPSCR );1.941 + update_fr_bank( R_ECX );1.942 }1.943 break;1.944 case 0x3:1.945 { /* UNDEF */1.946 if( sh4_x86.in_delay_slot ) {1.947 - RAISE_EXCEPTION(EXC_SLOT_ILLEGAL);1.948 + SLOTILLEGAL();1.949 } else {1.950 - RAISE_EXCEPTION(EXC_ILLEGAL);1.951 + JMP_exit(EXIT_ILLEGAL);1.952 + return 1;1.953 }1.954 - return 1;1.955 }1.956 break;1.957 default:1.958 @@ -2983,10 +3133,12 @@1.959 break;1.960 }1.962 - INC_r32(R_ESI);1.963 if( sh4_x86.in_delay_slot ) {1.964 + ADD_imm8s_r32(2,R_ESI);1.965 sh4_x86.in_delay_slot = FALSE;1.966 return 1;1.967 + } else {1.968 + INC_r32(R_ESI);1.969 }1.970 return 0;1.971 }
2.1 --- a/src/sh4/sh4x86.in Sun Sep 16 07:01:35 2007 +00002.2 +++ b/src/sh4/sh4x86.in Sun Sep 16 07:03:23 2007 +00002.3 @@ -1,5 +1,5 @@2.4 /**2.5 - * $Id: sh4x86.in,v 1.9 2007-09-13 08:28:01 nkeynes Exp $2.6 + * $Id: sh4x86.in,v 1.10 2007-09-16 07:03:23 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 @@ -56,6 +56,15 @@2.12 static struct sh4_x86_state sh4_x86;2.14 +void signsat48( void )2.15 +{2.16 + if( ((int64_t)sh4r.mac) < (int64_t)0xFFFF800000000000LL )2.17 + sh4r.mac = 0xFFFF800000000000LL;2.18 + else if( ((int64_t)sh4r.mac) > (int64_t)0x00007FFFFFFFFFFFLL )2.19 + sh4r.mac = 0x00007FFFFFFFFFFFLL;2.20 +}2.21 +2.22 +2.23 void sh4_x86_init()2.24 {2.25 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);2.26 @@ -156,12 +165,23 @@2.27 */2.28 static inline void load_xf_bank( int bankreg )2.29 {2.30 + NOT_r32( bankreg );2.31 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size2.32 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction2.33 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg2.34 }2.36 /**2.37 + * Update the fr_bank pointer based on the current fpscr value.2.38 + */2.39 +static inline void update_fr_bank( int fpscrreg )2.40 +{2.41 + SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size2.42 + AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction2.43 + OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg2.44 + store_spreg( fpscrreg, REG_OFFSET(fr_bank) );2.45 +}2.46 +/**2.47 * Push FPUL (as a 32-bit float) onto the FPU stack2.48 */2.49 static inline void push_fpul( )2.50 @@ -242,11 +262,11 @@2.51 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )2.52 {2.53 ADD_imm8s_r32( 4, addr );2.54 + PUSH_r32(arg2b);2.55 PUSH_r32(addr);2.56 - PUSH_r32(arg2b);2.57 ADD_imm8s_r32( -4, addr );2.58 + PUSH_r32(arg2a);2.59 PUSH_r32(addr);2.60 - PUSH_r32(arg2a);2.61 call_func0(sh4_write_long);2.62 ADD_imm8s_r32( 8, R_ESP );2.63 call_func0(sh4_write_long);2.64 @@ -324,6 +344,13 @@2.65 JNE_exit(EXIT_DATA_ADDR_WRITE);2.66 }2.68 +static inline void raise_exception( int exc )2.69 +{2.70 + PUSH_imm32(exc);2.71 + call_func0(sh4_raise_exception);2.72 + ADD_imm8s_r32( 4, R_ESP );2.73 + sh4_x86.in_delay_slot = FALSE;2.74 +}2.76 #define UNDEF()2.77 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }2.78 @@ -334,8 +361,8 @@2.79 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)2.80 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)2.82 -#define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);2.83 -#define SLOTILLEGAL() RAISE_EXCEPTION(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 12.84 +#define RAISE_EXCEPTION( exc ) raise_exception(exc); return 1;2.85 +#define SLOTILLEGAL() JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;2.89 @@ -479,8 +506,10 @@2.90 load_reg( R_EAX, 0 );2.91 load_spreg( R_ECX, R_GBR );2.92 ADD_r32_r32( R_EAX, R_ECX );2.93 - MEM_READ_BYTE( R_ECX, R_EAX );2.94 - AND_imm32_r32(imm, R_ECX );2.95 + PUSH_r32(R_ECX);2.96 + call_func0(sh4_read_byte);2.97 + POP_r32(R_ECX);2.98 + AND_imm32_r32(imm, R_EAX );2.99 MEM_WRITE_BYTE( R_ECX, R_EAX );2.100 :}2.101 CMP/EQ Rm, Rn {:2.102 @@ -547,13 +576,13 @@2.103 :}2.104 DIV0S Rm, Rn {:2.105 load_reg( R_EAX, Rm );2.106 - load_reg( R_ECX, Rm );2.107 + load_reg( R_ECX, Rn );2.108 SHR_imm8_r32( 31, R_EAX );2.109 SHR_imm8_r32( 31, R_ECX );2.110 store_spreg( R_EAX, R_M );2.111 store_spreg( R_ECX, R_Q );2.112 CMP_r32_r32( R_EAX, R_ECX );2.113 - SETE_t();2.114 + SETNE_t();2.115 :}2.116 DIV0U {:2.117 XOR_r32_r32( R_EAX, R_EAX );2.118 @@ -561,20 +590,27 @@2.119 store_spreg( R_EAX, R_M );2.120 store_spreg( R_EAX, R_T );2.121 :}2.122 -DIV1 Rm, Rn {:2.123 - load_reg( R_ECX, Rn );2.124 +DIV1 Rm, Rn {:2.125 + load_spreg( R_ECX, R_M );2.126 + load_reg( R_EAX, Rn );2.127 LDC_t();2.128 - RCL1_r32( R_ECX ); // OP22.129 - SETC_r32( R_EDX ); // Q2.130 - load_spreg( R_EAX, R_Q );2.131 - CMP_sh4r_r32( R_M, R_EAX );2.132 - JE_rel8(8,mqequal);2.133 - ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );2.134 - JMP_rel8(3, mqnotequal);2.135 + RCL1_r32( R_EAX );2.136 + SETC_r8( R_DL ); // Q'2.137 + CMP_sh4r_r32( R_Q, R_ECX );2.138 + JE_rel8(5, mqequal);2.139 + ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );2.140 + JMP_rel8(3, end);2.141 JMP_TARGET(mqequal);2.142 - SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );2.143 - JMP_TARGET(mqnotequal);2.144 - // TODO2.145 + SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );2.146 + JMP_TARGET(end);2.147 + store_reg( R_EAX, Rn ); // Done with Rn now2.148 + SETC_r8(R_AL); // tmp12.149 + XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp12.150 + XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M2.151 + store_spreg( R_ECX, R_Q );2.152 + XOR_imm8s_r32( 1, R_AL ); // T = !Q'2.153 + MOVZX_r8_r32( R_AL, R_EAX );2.154 + store_spreg( R_EAX, R_T );2.155 :}2.156 DMULS.L Rm, Rn {:2.157 load_reg( R_EAX, Rm );2.158 @@ -616,8 +652,67 @@2.159 MOVZX_r16_r32( R_EAX, R_EAX );2.160 store_reg( R_EAX, Rn );2.161 :}2.162 -MAC.L @Rm+, @Rn+ {: :}2.163 -MAC.W @Rm+, @Rn+ {: :}2.164 +MAC.L @Rm+, @Rn+ {:2.165 + load_reg( R_ECX, Rm );2.166 + check_ralign32( R_ECX );2.167 + load_reg( R_ECX, Rn );2.168 + check_ralign32( R_ECX );2.169 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );2.170 + MEM_READ_LONG( R_ECX, R_EAX );2.171 + PUSH_r32( R_EAX );2.172 + load_reg( R_ECX, Rm );2.173 + ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );2.174 + MEM_READ_LONG( R_ECX, R_EAX );2.175 + POP_r32( R_ECX );2.176 + IMUL_r32( R_ECX );2.177 + ADD_r32_sh4r( R_EAX, R_MACL );2.178 + ADC_r32_sh4r( R_EDX, R_MACH );2.179 +2.180 + load_spreg( R_ECX, R_S );2.181 + TEST_r32_r32(R_ECX, R_ECX);2.182 + JE_rel8( 7, nosat );2.183 + call_func0( signsat48 );2.184 + JMP_TARGET( nosat );2.185 +:}2.186 +MAC.W @Rm+, @Rn+ {:2.187 + load_reg( R_ECX, Rm );2.188 + check_ralign16( R_ECX );2.189 + load_reg( R_ECX, Rn );2.190 + check_ralign16( R_ECX );2.191 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );2.192 + MEM_READ_WORD( R_ECX, R_EAX );2.193 + PUSH_r32( R_EAX );2.194 + load_reg( R_ECX, Rm );2.195 + ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );2.196 + MEM_READ_WORD( R_ECX, R_EAX );2.197 + POP_r32( R_ECX );2.198 + IMUL_r32( R_ECX );2.199 +2.200 + load_spreg( R_ECX, R_S );2.201 + TEST_r32_r32( R_ECX, R_ECX );2.202 + JE_rel8( 47, nosat );2.203 +2.204 + ADD_r32_sh4r( R_EAX, R_MACL ); // 62.205 + JNO_rel8( 51, end ); // 22.206 + load_imm32( R_EDX, 1 ); // 52.207 + store_spreg( R_EDX, R_MACH ); // 62.208 + JS_rel8( 13, positive ); // 22.209 + load_imm32( R_EAX, 0x80000000 );// 52.210 + store_spreg( R_EAX, R_MACL ); // 62.211 + JMP_rel8( 25, end2 ); // 22.212 +2.213 + JMP_TARGET(positive);2.214 + load_imm32( R_EAX, 0x7FFFFFFF );// 52.215 + store_spreg( R_EAX, R_MACL ); // 62.216 + JMP_rel8( 12, end3); // 22.217 +2.218 + JMP_TARGET(nosat);2.219 + ADD_r32_sh4r( R_EAX, R_MACL ); // 62.220 + ADC_r32_sh4r( R_EDX, R_MACH ); // 62.221 + JMP_TARGET(end);2.222 + JMP_TARGET(end2);2.223 + JMP_TARGET(end3);2.224 +:}2.225 MOVT Rn {:2.226 load_spreg( R_EAX, R_T );2.227 store_reg( R_EAX, Rn );2.228 @@ -673,8 +768,10 @@2.229 load_reg( R_EAX, 0 );2.230 load_spreg( R_ECX, R_GBR );2.231 ADD_r32_r32( R_EAX, R_ECX );2.232 - MEM_READ_BYTE( R_ECX, R_EAX );2.233 - OR_imm32_r32(imm, R_ECX );2.234 + PUSH_r32(R_ECX);2.235 + call_func0(sh4_read_byte);2.236 + POP_r32(R_ECX);2.237 + OR_imm32_r32(imm, R_EAX );2.238 MEM_WRITE_BYTE( R_ECX, R_EAX );2.239 :}2.240 ROTCL Rn {:2.241 @@ -708,34 +805,46 @@2.242 load_reg( R_EAX, Rn );2.243 load_reg( R_ECX, Rm );2.244 CMP_imm32_r32( 0, R_ECX );2.245 - JGE_rel8(9, doshl);2.246 + JGE_rel8(16, doshl);2.248 NEG_r32( R_ECX ); // 22.249 AND_imm8_r8( 0x1F, R_CL ); // 32.250 + JE_rel8( 4, emptysar); // 22.251 SAR_r32_CL( R_EAX ); // 22.252 - JMP_rel8(5, end); // 22.253 + JMP_rel8(10, end); // 22.254 +2.255 + JMP_TARGET(emptysar);2.256 + SAR_imm8_r32(31, R_EAX ); // 32.257 + JMP_rel8(5, end2);2.259 JMP_TARGET(doshl);2.260 AND_imm8_r8( 0x1F, R_CL ); // 32.261 SHL_r32_CL( R_EAX ); // 22.262 JMP_TARGET(end);2.263 + JMP_TARGET(end2);2.264 store_reg( R_EAX, Rn );2.265 :}2.266 SHLD Rm, Rn {:2.267 load_reg( R_EAX, Rn );2.268 load_reg( R_ECX, Rm );2.269 CMP_imm32_r32( 0, R_ECX );2.270 - JGE_rel8(9, doshl);2.271 + JGE_rel8(15, doshl);2.273 NEG_r32( R_ECX ); // 22.274 AND_imm8_r8( 0x1F, R_CL ); // 32.275 + JE_rel8( 4, emptyshr );2.276 SHR_r32_CL( R_EAX ); // 22.277 - JMP_rel8(5, end); // 22.278 + JMP_rel8(9, end); // 22.279 +2.280 + JMP_TARGET(emptyshr);2.281 + XOR_r32_r32( R_EAX, R_EAX );2.282 + JMP_rel8(5, end2);2.284 JMP_TARGET(doshl);2.285 AND_imm8_r8( 0x1F, R_CL ); // 32.286 SHL_r32_CL( R_EAX ); // 22.287 JMP_TARGET(end);2.288 + JMP_TARGET(end2);2.289 store_reg( R_EAX, Rn );2.290 :}2.291 SHAL Rn {:2.292 @@ -827,6 +936,7 @@2.293 TEST_r8_r8( R_AL, R_AL );2.294 SETE_t();2.295 OR_imm8_r8( 0x80, R_AL );2.296 + load_reg( R_ECX, Rn );2.297 MEM_WRITE_BYTE( R_ECX, R_EAX );2.298 :}2.299 TST Rm, Rn {:2.300 @@ -863,7 +973,9 @@2.301 load_reg( R_EAX, 0 );2.302 load_spreg( R_ECX, R_GBR );2.303 ADD_r32_r32( R_EAX, R_ECX );2.304 - MEM_READ_BYTE( R_ECX, R_EAX );2.305 + PUSH_r32(R_ECX);2.306 + call_func0(sh4_read_byte);2.307 + POP_r32(R_ECX);2.308 XOR_imm32_r32( imm, R_EAX );2.309 MEM_WRITE_BYTE( R_ECX, R_EAX );2.310 :}2.311 @@ -919,7 +1031,7 @@2.312 MOV.B @Rm, Rn {:2.313 load_reg( R_ECX, Rm );2.314 MEM_READ_BYTE( R_ECX, R_EAX );2.315 - store_reg( R_ECX, Rn );2.316 + store_reg( R_EAX, Rn );2.317 :}2.318 MOV.B @Rm+, Rn {:2.319 load_reg( R_ECX, Rm );2.320 @@ -1145,13 +1257,12 @@2.321 if( sh4_x86.in_delay_slot ) {2.322 SLOTILLEGAL();2.323 } else {2.324 - load_imm32( R_EDI, pc + 2 );2.325 + load_imm32( R_EDI, pc + 4 );2.326 CMP_imm8s_sh4r( 0, R_T );2.327 JNE_rel8( 5, nottaken );2.328 load_imm32( R_EDI, disp + pc + 4 );2.329 JMP_TARGET(nottaken);2.330 sh4_x86.in_delay_slot = TRUE;2.331 - INC_r32(R_ESI);2.332 return 0;2.333 }2.334 :}2.335 @@ -1161,7 +1272,6 @@2.336 } else {2.337 load_imm32( R_EDI, disp + pc + 4 );2.338 sh4_x86.in_delay_slot = TRUE;2.339 - INC_r32(R_ESI);2.340 return 0;2.341 }2.342 :}2.343 @@ -1172,7 +1282,6 @@2.344 load_reg( R_EDI, Rn );2.345 ADD_imm32_r32( pc + 4, R_EDI );2.346 sh4_x86.in_delay_slot = TRUE;2.347 - INC_r32(R_ESI);2.348 return 0;2.349 }2.350 :}2.351 @@ -1184,7 +1293,6 @@2.352 store_spreg( R_EAX, R_PR );2.353 load_imm32( R_EDI, disp + pc + 4 );2.354 sh4_x86.in_delay_slot = TRUE;2.355 - INC_r32(R_ESI);2.356 return 0;2.357 }2.358 :}2.359 @@ -1197,7 +1305,6 @@2.360 load_reg( R_EDI, Rn );2.361 ADD_r32_r32( R_EAX, R_EDI );2.362 sh4_x86.in_delay_slot = TRUE;2.363 - INC_r32(R_ESI);2.364 return 0;2.365 }2.366 :}2.367 @@ -1218,13 +1325,12 @@2.368 if( sh4_x86.in_delay_slot ) {2.369 SLOTILLEGAL();2.370 } else {2.371 - load_imm32( R_EDI, pc + 2 );2.372 + load_imm32( R_EDI, pc + 4 );2.373 CMP_imm8s_sh4r( 0, R_T );2.374 JE_rel8( 5, nottaken );2.375 load_imm32( R_EDI, disp + pc + 4 );2.376 JMP_TARGET(nottaken);2.377 sh4_x86.in_delay_slot = TRUE;2.378 - INC_r32(R_ESI);2.379 return 0;2.380 }2.381 :}2.382 @@ -1234,7 +1340,6 @@2.383 } else {2.384 load_reg( R_EDI, Rn );2.385 sh4_x86.in_delay_slot = TRUE;2.386 - INC_r32(R_ESI);2.387 return 0;2.388 }2.389 :}2.390 @@ -1246,7 +1351,6 @@2.391 store_spreg( R_EAX, R_PR );2.392 load_reg( R_EDI, Rn );2.393 sh4_x86.in_delay_slot = TRUE;2.394 - INC_r32(R_ESI);2.395 return 0;2.396 }2.397 :}2.398 @@ -1255,13 +1359,12 @@2.399 if( sh4_x86.in_delay_slot ) {2.400 SLOTILLEGAL();2.401 } else {2.402 - load_spreg( R_EDI, R_PR );2.403 + load_spreg( R_EDI, R_SPC );2.404 load_spreg( R_EAX, R_SSR );2.405 call_func1( sh4_write_sr, R_EAX );2.406 sh4_x86.in_delay_slot = TRUE;2.407 sh4_x86.priv_checked = FALSE;2.408 sh4_x86.fpuen_checked = FALSE;2.409 - INC_r32(R_ESI);2.410 return 0;2.411 }2.412 :}2.413 @@ -1271,7 +1374,6 @@2.414 } else {2.415 load_spreg( R_EDI, R_PR );2.416 sh4_x86.in_delay_slot = TRUE;2.417 - INC_r32(R_ESI);2.418 return 0;2.419 }2.420 :}2.421 @@ -1287,7 +1389,7 @@2.422 if( sh4_x86.in_delay_slot ) {2.423 SLOTILLEGAL();2.424 } else {2.425 - RAISE_EXCEPTION(EXC_ILLEGAL);2.426 + JMP_exit(EXIT_ILLEGAL);2.427 return 1;2.428 }2.429 :}2.430 @@ -1331,7 +1433,7 @@2.431 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch2.432 store_fr( R_EDX, R_EAX, FRn );2.433 if( FRm&1 ) {2.434 - JMP_rel8(22, end);2.435 + JMP_rel8(24, end);2.436 JMP_TARGET(doublesize);2.437 load_xf_bank( R_ECX );2.438 load_fr( R_ECX, R_EAX, FRm-1 );2.439 @@ -1347,7 +1449,7 @@2.440 JMP_TARGET(end);2.441 } else /* FRm&1 == 0 */ {2.442 if( FRn&1 ) {2.443 - JMP_rel8(22, end);2.444 + JMP_rel8(24, end);2.445 load_xf_bank( R_ECX );2.446 load_fr( R_EDX, R_EAX, FRm );2.447 load_fr( R_EDX, R_EDX, FRm+1 );2.448 @@ -1375,7 +1477,7 @@2.449 load_fr( R_ECX, R_EAX, FRm );2.450 MEM_WRITE_LONG( R_EDX, R_EAX ); // 122.451 if( FRm&1 ) {2.452 - JMP_rel8( 46, end );2.453 + JMP_rel8( 48, end );2.454 JMP_TARGET(doublesize);2.455 load_xf_bank( R_ECX );2.456 load_fr( R_ECX, R_EAX, FRm&0x0E );2.457 @@ -1403,7 +1505,7 @@2.458 load_fr_bank( R_ECX );2.459 store_fr( R_ECX, R_EAX, FRn );2.460 if( FRn&1 ) {2.461 - JMP_rel8(46, end);2.462 + JMP_rel8(48, end);2.463 JMP_TARGET(doublesize);2.464 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.465 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it2.466 @@ -1434,7 +1536,7 @@2.467 store_reg( R_EDX, Rn );2.468 MEM_WRITE_LONG( R_EDX, R_EAX ); // 122.469 if( FRm&1 ) {2.470 - JMP_rel8( 52, end );2.471 + JMP_rel8( 54, end );2.472 JMP_TARGET(doublesize);2.473 load_xf_bank( R_ECX );2.474 load_fr( R_ECX, R_EAX, FRm&0x0E );2.475 @@ -1469,7 +1571,7 @@2.476 load_fr_bank( R_ECX );2.477 store_fr( R_ECX, R_EAX, FRn );2.478 if( FRn&1 ) {2.479 - JMP_rel8(52, end);2.480 + JMP_rel8(54, end);2.481 JMP_TARGET(doublesize);2.482 ADD_imm8s_r32( 8, R_EAX );2.483 store_reg(R_EAX, Rm);2.484 @@ -1502,7 +1604,7 @@2.485 load_fr( R_ECX, R_EAX, FRm );2.486 MEM_WRITE_LONG( R_EDX, R_EAX ); // 122.487 if( FRm&1 ) {2.488 - JMP_rel8( 46, end );2.489 + JMP_rel8( 48, end );2.490 JMP_TARGET(doublesize);2.491 load_xf_bank( R_ECX );2.492 load_fr( R_ECX, R_EAX, FRm&0x0E );2.493 @@ -1531,7 +1633,7 @@2.494 load_fr_bank( R_ECX );2.495 store_fr( R_ECX, R_EAX, FRn );2.496 if( FRn&1 ) {2.497 - JMP_rel8(46, end);2.498 + JMP_rel8(48, end);2.499 JMP_TARGET(doublesize);2.500 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );2.501 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it2.502 @@ -1829,7 +1931,7 @@2.503 load_spreg( R_ECX, R_FPSCR );2.504 XOR_imm32_r32( FPSCR_FR, R_ECX );2.505 store_spreg( R_ECX, R_FPSCR );2.506 -2.507 + update_fr_bank( R_ECX );2.508 :}2.509 FSCHG {:2.510 check_fpuen();2.511 @@ -1840,36 +1942,47 @@2.513 /* Processor control instructions */2.514 LDC Rm, SR {:2.515 - load_reg( R_EAX, Rm );2.516 - call_func1( sh4_write_sr, R_EAX );2.517 - sh4_x86.priv_checked = FALSE;2.518 - sh4_x86.fpuen_checked = FALSE;2.519 + if( sh4_x86.in_delay_slot ) {2.520 + SLOTILLEGAL();2.521 + } else {2.522 + check_priv();2.523 + load_reg( R_EAX, Rm );2.524 + call_func1( sh4_write_sr, R_EAX );2.525 + sh4_x86.priv_checked = FALSE;2.526 + sh4_x86.fpuen_checked = FALSE;2.527 + }2.528 :}2.529 LDC Rm, GBR {:2.530 load_reg( R_EAX, Rm );2.531 store_spreg( R_EAX, R_GBR );2.532 :}2.533 LDC Rm, VBR {:2.534 + check_priv();2.535 load_reg( R_EAX, Rm );2.536 store_spreg( R_EAX, R_VBR );2.537 :}2.538 LDC Rm, SSR {:2.539 + check_priv();2.540 load_reg( R_EAX, Rm );2.541 store_spreg( R_EAX, R_SSR );2.542 :}2.543 LDC Rm, SGR {:2.544 + check_priv();2.545 load_reg( R_EAX, Rm );2.546 store_spreg( R_EAX, R_SGR );2.547 :}2.548 LDC Rm, SPC {:2.549 + check_priv();2.550 load_reg( R_EAX, Rm );2.551 store_spreg( R_EAX, R_SPC );2.552 :}2.553 LDC Rm, DBR {:2.554 + check_priv();2.555 load_reg( R_EAX, Rm );2.556 store_spreg( R_EAX, R_DBR );2.557 :}2.558 LDC Rm, Rn_BANK {:2.559 + check_priv();2.560 load_reg( R_EAX, Rm );2.561 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );2.562 :}2.563 @@ -1882,16 +1995,22 @@2.564 store_spreg( R_EAX, R_GBR );2.565 :}2.566 LDC.L @Rm+, SR {:2.567 - load_reg( R_EAX, Rm );2.568 - MOV_r32_r32( R_EAX, R_ECX );2.569 - ADD_imm8s_r32( 4, R_EAX );2.570 - store_reg( R_EAX, Rm );2.571 - MEM_READ_LONG( R_ECX, R_EAX );2.572 - call_func1( sh4_write_sr, R_EAX );2.573 - sh4_x86.priv_checked = FALSE;2.574 - sh4_x86.fpuen_checked = FALSE;2.575 + if( sh4_x86.in_delay_slot ) {2.576 + SLOTILLEGAL();2.577 + } else {2.578 + check_priv();2.579 + load_reg( R_EAX, Rm );2.580 + MOV_r32_r32( R_EAX, R_ECX );2.581 + ADD_imm8s_r32( 4, R_EAX );2.582 + store_reg( R_EAX, Rm );2.583 + MEM_READ_LONG( R_ECX, R_EAX );2.584 + call_func1( sh4_write_sr, R_EAX );2.585 + sh4_x86.priv_checked = FALSE;2.586 + sh4_x86.fpuen_checked = FALSE;2.587 + }2.588 :}2.589 LDC.L @Rm+, VBR {:2.590 + check_priv();2.591 load_reg( R_EAX, Rm );2.592 MOV_r32_r32( R_EAX, R_ECX );2.593 ADD_imm8s_r32( 4, R_EAX );2.594 @@ -1900,6 +2019,7 @@2.595 store_spreg( R_EAX, R_VBR );2.596 :}2.597 LDC.L @Rm+, SSR {:2.598 + check_priv();2.599 load_reg( R_EAX, Rm );2.600 MOV_r32_r32( R_EAX, R_ECX );2.601 ADD_imm8s_r32( 4, R_EAX );2.602 @@ -1908,6 +2028,7 @@2.603 store_spreg( R_EAX, R_SSR );2.604 :}2.605 LDC.L @Rm+, SGR {:2.606 + check_priv();2.607 load_reg( R_EAX, Rm );2.608 MOV_r32_r32( R_EAX, R_ECX );2.609 ADD_imm8s_r32( 4, R_EAX );2.610 @@ -1916,6 +2037,7 @@2.611 store_spreg( R_EAX, R_SGR );2.612 :}2.613 LDC.L @Rm+, SPC {:2.614 + check_priv();2.615 load_reg( R_EAX, Rm );2.616 MOV_r32_r32( R_EAX, R_ECX );2.617 ADD_imm8s_r32( 4, R_EAX );2.618 @@ -1924,6 +2046,7 @@2.619 store_spreg( R_EAX, R_SPC );2.620 :}2.621 LDC.L @Rm+, DBR {:2.622 + check_priv();2.623 load_reg( R_EAX, Rm );2.624 MOV_r32_r32( R_EAX, R_ECX );2.625 ADD_imm8s_r32( 4, R_EAX );2.626 @@ -1932,6 +2055,7 @@2.627 store_spreg( R_EAX, R_DBR );2.628 :}2.629 LDC.L @Rm+, Rn_BANK {:2.630 + check_priv();2.631 load_reg( R_EAX, Rm );2.632 MOV_r32_r32( R_EAX, R_ECX );2.633 ADD_imm8s_r32( 4, R_EAX );2.634 @@ -1942,6 +2066,7 @@2.635 LDS Rm, FPSCR {:2.636 load_reg( R_EAX, Rm );2.637 store_spreg( R_EAX, R_FPSCR );2.638 + update_fr_bank( R_EAX );2.639 :}2.640 LDS.L @Rm+, FPSCR {:2.641 load_reg( R_EAX, Rm );2.642 @@ -1950,6 +2075,7 @@2.643 store_reg( R_EAX, Rm );2.644 MEM_READ_LONG( R_ECX, R_EAX );2.645 store_spreg( R_EAX, R_FPSCR );2.646 + update_fr_bank( R_EAX );2.647 :}2.648 LDS Rm, FPUL {:2.649 load_reg( R_EAX, Rm );2.650 @@ -2013,40 +2139,48 @@2.651 JMP_TARGET(end);2.652 ADD_imm8s_r32( 4, R_ESP );2.653 :}2.654 - SLEEP {: /* TODO */ :}2.655 - STC SR, Rn {:2.656 - call_func0(sh4_read_sr);2.657 - store_reg( R_EAX, Rn );2.658 +SLEEP {: /* TODO */ :}2.659 +STC SR, Rn {:2.660 + check_priv();2.661 + call_func0(sh4_read_sr);2.662 + store_reg( R_EAX, Rn );2.663 :}2.664 STC GBR, Rn {:2.665 load_spreg( R_EAX, R_GBR );2.666 store_reg( R_EAX, Rn );2.667 :}2.668 STC VBR, Rn {:2.669 + check_priv();2.670 load_spreg( R_EAX, R_VBR );2.671 store_reg( R_EAX, Rn );2.672 :}2.673 STC SSR, Rn {:2.674 + check_priv();2.675 load_spreg( R_EAX, R_SSR );2.676 store_reg( R_EAX, Rn );2.677 :}2.678 STC SPC, Rn {:2.679 + check_priv();2.680 load_spreg( R_EAX, R_SPC );2.681 store_reg( R_EAX, Rn );2.682 :}2.683 STC SGR, Rn {:2.684 + check_priv();2.685 load_spreg( R_EAX, R_SGR );2.686 store_reg( R_EAX, Rn );2.687 :}2.688 STC DBR, Rn {:2.689 + check_priv();2.690 load_spreg( R_EAX, R_DBR );2.691 store_reg( R_EAX, Rn );2.692 :}2.693 STC Rm_BANK, Rn {:2.694 + check_priv();2.695 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );2.696 store_reg( R_EAX, Rn );2.697 :}2.698 STC.L SR, @-Rn {:2.699 + check_priv();2.700 load_reg( R_ECX, Rn );2.701 ADD_imm8s_r32( -4, R_ECX );2.702 store_reg( R_ECX, Rn );2.703 @@ -2054,6 +2188,7 @@2.704 MEM_WRITE_LONG( R_ECX, R_EAX );2.705 :}2.706 STC.L VBR, @-Rn {:2.707 + check_priv();2.708 load_reg( R_ECX, Rn );2.709 ADD_imm8s_r32( -4, R_ECX );2.710 store_reg( R_ECX, Rn );2.711 @@ -2061,6 +2196,7 @@2.712 MEM_WRITE_LONG( R_ECX, R_EAX );2.713 :}2.714 STC.L SSR, @-Rn {:2.715 + check_priv();2.716 load_reg( R_ECX, Rn );2.717 ADD_imm8s_r32( -4, R_ECX );2.718 store_reg( R_ECX, Rn );2.719 @@ -2068,6 +2204,7 @@2.720 MEM_WRITE_LONG( R_ECX, R_EAX );2.721 :}2.722 STC.L SPC, @-Rn {:2.723 + check_priv();2.724 load_reg( R_ECX, Rn );2.725 ADD_imm8s_r32( -4, R_ECX );2.726 store_reg( R_ECX, Rn );2.727 @@ -2075,6 +2212,7 @@2.728 MEM_WRITE_LONG( R_ECX, R_EAX );2.729 :}2.730 STC.L SGR, @-Rn {:2.731 + check_priv();2.732 load_reg( R_ECX, Rn );2.733 ADD_imm8s_r32( -4, R_ECX );2.734 store_reg( R_ECX, Rn );2.735 @@ -2082,6 +2220,7 @@2.736 MEM_WRITE_LONG( R_ECX, R_EAX );2.737 :}2.738 STC.L DBR, @-Rn {:2.739 + check_priv();2.740 load_reg( R_ECX, Rn );2.741 ADD_imm8s_r32( -4, R_ECX );2.742 store_reg( R_ECX, Rn );2.743 @@ -2089,6 +2228,7 @@2.744 MEM_WRITE_LONG( R_ECX, R_EAX );2.745 :}2.746 STC.L Rm_BANK, @-Rn {:2.747 + check_priv();2.748 load_reg( R_ECX, Rn );2.749 ADD_imm8s_r32( -4, R_ECX );2.750 store_reg( R_ECX, Rn );2.751 @@ -2160,10 +2300,12 @@2.753 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}2.754 %%2.755 - INC_r32(R_ESI);2.756 if( sh4_x86.in_delay_slot ) {2.757 + ADD_imm8s_r32(2,R_ESI);2.758 sh4_x86.in_delay_slot = FALSE;2.759 return 1;2.760 + } else {2.761 + INC_r32(R_ESI);2.762 }2.763 return 0;2.764 }
3.1 --- a/src/sh4/x86op.h Sun Sep 16 07:01:35 2007 +00003.2 +++ b/src/sh4/x86op.h Sun Sep 16 07:03:23 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: x86op.h,v 1.7 2007-09-12 11:31:16 nkeynes Exp $3.6 + * $Id: x86op.h,v 1.8 2007-09-16 07:03:23 nkeynes Exp $3.7 *3.8 * Definitions of x86 opcodes for use by the translator.3.9 *3.10 @@ -92,10 +92,14 @@3.12 /* Major opcodes */3.13 #define ADD_sh4r_r32(disp,r1) OP(0x03); MODRM_r32_sh4r(r1,disp)3.14 +#define ADD_r32_sh4r(r1,disp) OP(0x01); MODRM_r32_sh4r(r1,disp)3.15 #define ADD_r32_r32(r1,r2) OP(0x03); MODRM_rm32_r32(r1,r2)3.16 #define ADD_imm8s_r32(imm,r1) OP(0x83); MODRM_rm32_r32(r1, 0); OP(imm)3.17 +#define ADD_imm8s_sh4r(imm,disp) OP(0x83); MODRM_r32_sh4r(0,disp); OP(imm)3.18 #define ADD_imm32_r32(imm32,r1) OP(0x81); MODRM_rm32_r32(r1,0); OP32(imm32)3.19 #define ADC_r32_r32(r1,r2) OP(0x13); MODRM_rm32_r32(r1,r2)3.20 +#define ADC_sh4r_r32(disp,r1) OP(0x13); MODRM_r32_sh4r(r1,disp)3.21 +#define ADC_r32_sh4r(r1,disp) OP(0x11); MODRM_r32_sh4r(r1,disp)3.22 #define AND_r32_r32(r1,r2) OP(0x23); MODRM_rm32_r32(r1,r2)3.23 #define AND_imm8_r8(imm8, r1) OP(0x80); MODRM_rm32_r32(r1,4); OP(imm8)3.24 #define AND_imm8s_r32(imm8,r1) OP(0x83); MODRM_rm32_r32(r1,4); OP(imm8)3.25 @@ -153,6 +157,8 @@3.26 #define TEST_imm8_r8(imm8,r1) OP(0xF6); MODRM_rm32_r32(r1,0); OP(imm8)3.27 #define TEST_imm32_r32(imm,r1) OP(0xF7); MODRM_rm32_r32(r1,0); OP32(imm)3.28 #define XCHG_r8_r8(r1,r2) OP(0x86); MODRM_rm32_r32(r1,r2)3.29 +#define XOR_r8_r8(r1,r2) OP(0x32); MODRM_rm32_r32(r1,r2)3.30 +#define XOR_imm8s_r32(imm,r1) OP(0x83); MODRM_rm32_r32(r1,6); OP(imm)3.31 #define XOR_r32_r32(r1,r2) OP(0x33); MODRM_rm32_r32(r1,r2)3.32 #define XOR_sh4r_r32(disp,r1) OP(0x33); MODRM_r32_sh4r(r1,disp)3.33 #define XOR_imm32_r32(imm,r1) OP(0x81); MODRM_rm32_r32(r1,6); OP32(imm)3.34 @@ -188,8 +194,12 @@3.35 #define JNGE_rel8(rel,label) OP(0x7C); OP(rel); MARK_JMP(rel,label)3.36 #define JNC_rel8(rel,label) OP(0x73); OP(rel); MARK_JMP(rel,label)3.37 #define JNO_rel8(rel,label) OP(0x71); OP(rel); MARK_JMP(rel,label)3.38 +#define JNS_rel8(rel,label) OP(0x79); OP(rel); MARK_JMP(rel,label)3.39 +#define JS_rel8(rel,label) OP(0x78); OP(rel); MARK_JMP(rel,label)3.40 +3.42 /* 32-bit long forms w/ backpatching to an exit routine */3.43 +#define JMP_exit(rel) OP(0xE9); sh4_x86_add_backpatch(xlat_output); OP32(rel)3.44 #define JE_exit(rel) OP(0x0F); OP(0x84); sh4_x86_add_backpatch(xlat_output); OP32(rel)3.45 #define JA_exit(rel) OP(0x0F); OP(0x87); sh4_x86_add_backpatch(xlat_output); OP32(rel)3.46 #define JAE_exit(rel) OP(0x0F); OP(0x83); sh4_x86_add_backpatch(xlat_output); OP32(rel)3.47 @@ -240,8 +250,9 @@3.48 #define SETGE_t() SETGE_sh4r(R_T)3.49 #define SETC_t() SETC_sh4r(R_T)3.50 #define SETO_t() SETO_sh4r(R_T)3.51 +#define SETNE_t() SETNE_sh4r(R_T)3.53 -#define SETC_r32(r1) OP(0x0F); OP(0x92); MODRM_rm32_r32(r1, 0)3.54 +#define SETC_r8(r1) OP(0x0F); OP(0x92); MODRM_rm32_r32(r1, 0)3.56 /* Pseudo-op Load carry from T: CMP [EBP+t], #01 ; CMC */3.57 #define LDC_t() OP(0x83); MODRM_r32_sh4r(7,R_T); OP(0x01); CMC()
.