filename | src/sh4/sh4x86.c |
changeset | 596:dfc0c93d882e |
prev | 593:6c710c7c6835 |
next | 601:d8d1af0d133c |
author | nkeynes |
date | Mon Jan 21 11:59:46 2008 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Fix MAC.L/MAC.W stack issues Fix various recovery-table issues |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * SH4 => x86 translation. This version does no real optimization, it just
5 * outputs straight-line x86 code - it mainly exists to provide a baseline
6 * to test the optimizing versions against.
7 *
8 * Copyright (c) 2007 Nathan Keynes.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
21 #include <assert.h>
22 #include <math.h>
24 #ifndef NDEBUG
25 #define DEBUG_JUMPS 1
26 #endif
28 #include "sh4/xltcache.h"
29 #include "sh4/sh4core.h"
30 #include "sh4/sh4trans.h"
31 #include "sh4/sh4mmio.h"
32 #include "sh4/x86op.h"
33 #include "clock.h"
35 #define DEFAULT_BACKPATCH_SIZE 4096
37 struct backpatch_record {
38 uint32_t *fixup_addr;
39 uint32_t fixup_icount;
40 int32_t exc_code;
41 };
43 #define MAX_RECOVERY_SIZE 2048
45 #define DELAY_NONE 0
46 #define DELAY_PC 1
47 #define DELAY_PC_PR 2
49 /**
50 * Struct to manage internal translation state. This state is not saved -
51 * it is only valid between calls to sh4_translate_begin_block() and
52 * sh4_translate_end_block()
53 */
54 struct sh4_x86_state {
55 int in_delay_slot;
56 gboolean priv_checked; /* true if we've already checked the cpu mode. */
57 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
58 gboolean branch_taken; /* true if we branched unconditionally */
59 uint32_t block_start_pc;
60 uint32_t stack_posn; /* Trace stack height for alignment purposes */
61 int tstate;
63 /* mode flags */
64 gboolean tlb_on; /* True if tlb translation is active */
66 /* Allocated memory for the (block-wide) back-patch list */
67 struct backpatch_record *backpatch_list;
68 uint32_t backpatch_posn;
69 uint32_t backpatch_size;
70 };
72 #define TSTATE_NONE -1
73 #define TSTATE_O 0
74 #define TSTATE_C 2
75 #define TSTATE_E 4
76 #define TSTATE_NE 5
77 #define TSTATE_G 0xF
78 #define TSTATE_GE 0xD
79 #define TSTATE_A 7
80 #define TSTATE_AE 3
82 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
83 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
84 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
85 OP(0x70+sh4_x86.tstate); OP(rel8); \
86 MARK_JMP(rel8,label)
87 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
88 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
89 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
90 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
91 MARK_JMP(rel8, label)
93 static struct sh4_x86_state sh4_x86;
95 static uint32_t max_int = 0x7FFFFFFF;
96 static uint32_t min_int = 0x80000000;
97 static uint32_t save_fcw; /* save value for fpu control word */
98 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
100 void sh4_x86_init()
101 {
102 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
103 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
104 }
107 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
108 {
109 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
110 sh4_x86.backpatch_size <<= 1;
111 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
112 sh4_x86.backpatch_size * sizeof(struct backpatch_record));
113 assert( sh4_x86.backpatch_list != NULL );
114 }
115 if( sh4_x86.in_delay_slot ) {
116 fixup_pc -= 2;
117 }
118 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;
119 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
120 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
121 sh4_x86.backpatch_posn++;
122 }
124 /**
125 * Emit an instruction to load an SH4 reg into a real register
126 */
127 static inline void load_reg( int x86reg, int sh4reg )
128 {
129 /* mov [bp+n], reg */
130 OP(0x8B);
131 OP(0x45 + (x86reg<<3));
132 OP(REG_OFFSET(r[sh4reg]));
133 }
135 static inline void load_reg16s( int x86reg, int sh4reg )
136 {
137 OP(0x0F);
138 OP(0xBF);
139 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
140 }
142 static inline void load_reg16u( int x86reg, int sh4reg )
143 {
144 OP(0x0F);
145 OP(0xB7);
146 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
148 }
150 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
151 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
152 /**
153 * Emit an instruction to load an immediate value into a register
154 */
155 static inline void load_imm32( int x86reg, uint32_t value ) {
156 /* mov #value, reg */
157 OP(0xB8 + x86reg);
158 OP32(value);
159 }
161 /**
162 * Load an immediate 64-bit quantity (note: x86-64 only)
163 */
164 static inline void load_imm64( int x86reg, uint32_t value ) {
165 /* mov #value, reg */
166 REXW();
167 OP(0xB8 + x86reg);
168 OP64(value);
169 }
172 /**
173 * Emit an instruction to store an SH4 reg (RN)
174 */
175 void static inline store_reg( int x86reg, int sh4reg ) {
176 /* mov reg, [bp+n] */
177 OP(0x89);
178 OP(0x45 + (x86reg<<3));
179 OP(REG_OFFSET(r[sh4reg]));
180 }
182 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
184 /**
185 * Load an FR register (single-precision floating point) into an integer x86
186 * register (eg for register-to-register moves)
187 */
188 void static inline load_fr( int bankreg, int x86reg, int frm )
189 {
190 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
191 }
193 /**
194 * Store an FR register (single-precision floating point) into an integer x86
195 * register (eg for register-to-register moves)
196 */
197 void static inline store_fr( int bankreg, int x86reg, int frn )
198 {
199 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
200 }
203 /**
204 * Load a pointer to the back fp back into the specified x86 register. The
205 * bankreg must have been previously loaded with FPSCR.
206 * NB: 12 bytes
207 */
208 static inline void load_xf_bank( int bankreg )
209 {
210 NOT_r32( bankreg );
211 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
212 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
213 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
214 }
216 /**
217 * Update the fr_bank pointer based on the current fpscr value.
218 */
219 static inline void update_fr_bank( int fpscrreg )
220 {
221 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
222 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
223 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
224 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
225 }
226 /**
227 * Push FPUL (as a 32-bit float) onto the FPU stack
228 */
229 static inline void push_fpul( )
230 {
231 OP(0xD9); OP(0x45); OP(R_FPUL);
232 }
234 /**
235 * Pop FPUL (as a 32-bit float) from the FPU stack
236 */
237 static inline void pop_fpul( )
238 {
239 OP(0xD9); OP(0x5D); OP(R_FPUL);
240 }
242 /**
243 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
244 * with the location of the current fp bank.
245 */
246 static inline void push_fr( int bankreg, int frm )
247 {
248 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
249 }
251 /**
252 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
253 * with bankreg previously loaded with the location of the current fp bank.
254 */
255 static inline void pop_fr( int bankreg, int frm )
256 {
257 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
258 }
260 /**
261 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
262 * with the location of the current fp bank.
263 */
264 static inline void push_dr( int bankreg, int frm )
265 {
266 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
267 }
269 static inline void pop_dr( int bankreg, int frm )
270 {
271 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
272 }
274 /* Exception checks - Note that all exception checks will clobber EAX */
276 #define check_priv( ) \
277 if( !sh4_x86.priv_checked ) { \
278 sh4_x86.priv_checked = TRUE;\
279 load_spreg( R_EAX, R_SR );\
280 AND_imm32_r32( SR_MD, R_EAX );\
281 if( sh4_x86.in_delay_slot ) {\
282 JE_exc( EXC_SLOT_ILLEGAL );\
283 } else {\
284 JE_exc( EXC_ILLEGAL );\
285 }\
286 }\
288 #define check_fpuen( ) \
289 if( !sh4_x86.fpuen_checked ) {\
290 sh4_x86.fpuen_checked = TRUE;\
291 load_spreg( R_EAX, R_SR );\
292 AND_imm32_r32( SR_FD, R_EAX );\
293 if( sh4_x86.in_delay_slot ) {\
294 JNE_exc(EXC_SLOT_FPU_DISABLED);\
295 } else {\
296 JNE_exc(EXC_FPU_DISABLED);\
297 }\
298 }
300 #define check_ralign16( x86reg ) \
301 TEST_imm32_r32( 0x00000001, x86reg ); \
302 JNE_exc(EXC_DATA_ADDR_READ)
304 #define check_walign16( x86reg ) \
305 TEST_imm32_r32( 0x00000001, x86reg ); \
306 JNE_exc(EXC_DATA_ADDR_WRITE);
308 #define check_ralign32( x86reg ) \
309 TEST_imm32_r32( 0x00000003, x86reg ); \
310 JNE_exc(EXC_DATA_ADDR_READ)
312 #define check_walign32( x86reg ) \
313 TEST_imm32_r32( 0x00000003, x86reg ); \
314 JNE_exc(EXC_DATA_ADDR_WRITE);
316 #define UNDEF()
317 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
318 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
319 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
320 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
321 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
322 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
323 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
325 /**
326 * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
327 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
328 */
329 #define MMU_TRANSLATE_READ( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }
331 #define MMU_TRANSLATE_READ_EXC( addr_reg, exc_code ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(exc_code); MEM_RESULT(addr_reg) }
332 /**
333 * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
334 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
335 */
336 #define MMU_TRANSLATE_WRITE( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }
338 #define MEM_READ_SIZE (CALL_FUNC1_SIZE)
339 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
340 #define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
342 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = DELAY_NONE; return 1;
344 /****** Import appropriate calling conventions ******/
345 #if SH4_TRANSLATOR == TARGET_X86_64
346 #include "sh4/ia64abi.h"
347 #else /* SH4_TRANSLATOR == TARGET_X86 */
348 #ifdef APPLE_BUILD
349 #include "sh4/ia32mac.h"
350 #else
351 #include "sh4/ia32abi.h"
352 #endif
353 #endif
355 uint32_t sh4_translate_end_block_size()
356 {
357 if( sh4_x86.backpatch_posn <= 3 ) {
358 return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
359 } else {
360 return EPILOGUE_SIZE + 48 + (sh4_x86.backpatch_posn-3)*15;
361 }
362 }
365 /**
366 * Embed a breakpoint into the generated code
367 */
368 void sh4_translate_emit_breakpoint( sh4vma_t pc )
369 {
370 load_imm32( R_EAX, pc );
371 call_func1( sh4_translate_breakpoint_hit, R_EAX );
372 }
374 /**
375 * Embed a call to sh4_execute_instruction for situations that we
376 * can't translate (mainly page-crossing delay slots at the moment).
377 * Caller is responsible for setting new_pc.
378 */
379 void sh4_emulator_exit( sh4vma_t endpc )
380 {
381 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 5
382 ADD_r32_sh4r( R_ECX, R_PC );
384 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
385 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
386 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );
387 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );
389 call_func0( sh4_execute_instruction );
390 load_imm32( R_EAX, R_PC );
391 if( sh4_x86.tlb_on ) {
392 call_func1(xlat_get_code_by_vma,R_EAX);
393 } else {
394 call_func1(xlat_get_code,R_EAX);
395 }
396 AND_imm8s_r32( 0xFC, R_EAX ); // 3
397 POP_r32(R_EBP);
398 RET();
399 }
401 /**
402 * Translate a single instruction. Delayed branches are handled specially
403 * by translating both branch and delayed instruction as a single unit (as
404 *
405 * The instruction MUST be in the icache (assert check)
406 *
407 * @return true if the instruction marks the end of a basic block
408 * (eg a branch or
409 */
410 uint32_t sh4_translate_instruction( sh4vma_t pc )
411 {
412 uint32_t ir;
413 /* Read instruction from icache */
414 assert( IS_IN_ICACHE(pc) );
415 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
417 /* PC is not in the current icache - this usually means we're running
418 * with MMU on, and we've gone past the end of the page. And since
419 * sh4_translate_block is pretty careful about this, it means we're
420 * almost certainly in a delay slot.
421 *
422 * Since we can't assume the page is present (and we can't fault it in
423 * at this point, inline a call to sh4_execute_instruction (with a few
424 * small repairs to cope with the different environment).
425 */
427 if( !sh4_x86.in_delay_slot ) {
428 sh4_translate_add_recovery( (pc - sh4_x86.block_start_pc)>>1 );
429 }
430 switch( (ir&0xF000) >> 12 ) {
431 case 0x0:
432 switch( ir&0xF ) {
433 case 0x2:
434 switch( (ir&0x80) >> 7 ) {
435 case 0x0:
436 switch( (ir&0x70) >> 4 ) {
437 case 0x0:
438 { /* STC SR, Rn */
439 uint32_t Rn = ((ir>>8)&0xF);
440 check_priv();
441 call_func0(sh4_read_sr);
442 store_reg( R_EAX, Rn );
443 sh4_x86.tstate = TSTATE_NONE;
444 }
445 break;
446 case 0x1:
447 { /* STC GBR, Rn */
448 uint32_t Rn = ((ir>>8)&0xF);
449 load_spreg( R_EAX, R_GBR );
450 store_reg( R_EAX, Rn );
451 }
452 break;
453 case 0x2:
454 { /* STC VBR, Rn */
455 uint32_t Rn = ((ir>>8)&0xF);
456 check_priv();
457 load_spreg( R_EAX, R_VBR );
458 store_reg( R_EAX, Rn );
459 sh4_x86.tstate = TSTATE_NONE;
460 }
461 break;
462 case 0x3:
463 { /* STC SSR, Rn */
464 uint32_t Rn = ((ir>>8)&0xF);
465 check_priv();
466 load_spreg( R_EAX, R_SSR );
467 store_reg( R_EAX, Rn );
468 sh4_x86.tstate = TSTATE_NONE;
469 }
470 break;
471 case 0x4:
472 { /* STC SPC, Rn */
473 uint32_t Rn = ((ir>>8)&0xF);
474 check_priv();
475 load_spreg( R_EAX, R_SPC );
476 store_reg( R_EAX, Rn );
477 sh4_x86.tstate = TSTATE_NONE;
478 }
479 break;
480 default:
481 UNDEF();
482 break;
483 }
484 break;
485 case 0x1:
486 { /* STC Rm_BANK, Rn */
487 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
488 check_priv();
489 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
490 store_reg( R_EAX, Rn );
491 sh4_x86.tstate = TSTATE_NONE;
492 }
493 break;
494 }
495 break;
496 case 0x3:
497 switch( (ir&0xF0) >> 4 ) {
498 case 0x0:
499 { /* BSRF Rn */
500 uint32_t Rn = ((ir>>8)&0xF);
501 if( sh4_x86.in_delay_slot ) {
502 SLOTILLEGAL();
503 } else {
504 load_spreg( R_EAX, R_PC );
505 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
506 store_spreg( R_EAX, R_PR );
507 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
508 store_spreg( R_EAX, R_NEW_PC );
510 sh4_x86.tstate = TSTATE_NONE;
511 sh4_translate_instruction( pc + 2 );
512 exit_block_newpcset(pc+2);
513 sh4_x86.branch_taken = TRUE;
514 return 4;
515 }
516 }
517 break;
518 case 0x2:
519 { /* BRAF Rn */
520 uint32_t Rn = ((ir>>8)&0xF);
521 if( sh4_x86.in_delay_slot ) {
522 SLOTILLEGAL();
523 } else {
524 load_spreg( R_EAX, R_PC );
525 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
526 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
527 store_spreg( R_EAX, R_NEW_PC );
528 sh4_x86.in_delay_slot = DELAY_PC;
529 sh4_x86.tstate = TSTATE_NONE;
530 sh4_translate_instruction( pc + 2 );
531 exit_block_newpcset(pc+2);
532 sh4_x86.branch_taken = TRUE;
533 return 4;
534 }
535 }
536 break;
537 case 0x8:
538 { /* PREF @Rn */
539 uint32_t Rn = ((ir>>8)&0xF);
540 load_reg( R_EAX, Rn );
541 MOV_r32_r32( R_EAX, R_ECX );
542 AND_imm32_r32( 0xFC000000, R_EAX );
543 CMP_imm32_r32( 0xE0000000, R_EAX );
544 JNE_rel8(8+CALL_FUNC1_SIZE, end);
545 call_func1( sh4_flush_store_queue, R_ECX );
546 TEST_r32_r32( R_EAX, R_EAX );
547 JE_exc(-1);
548 JMP_TARGET(end);
549 sh4_x86.tstate = TSTATE_NONE;
550 }
551 break;
552 case 0x9:
553 { /* OCBI @Rn */
554 uint32_t Rn = ((ir>>8)&0xF);
555 }
556 break;
557 case 0xA:
558 { /* OCBP @Rn */
559 uint32_t Rn = ((ir>>8)&0xF);
560 }
561 break;
562 case 0xB:
563 { /* OCBWB @Rn */
564 uint32_t Rn = ((ir>>8)&0xF);
565 }
566 break;
567 case 0xC:
568 { /* MOVCA.L R0, @Rn */
569 uint32_t Rn = ((ir>>8)&0xF);
570 load_reg( R_EAX, Rn );
571 check_walign32( R_EAX );
572 MMU_TRANSLATE_WRITE( R_EAX );
573 load_reg( R_EDX, 0 );
574 MEM_WRITE_LONG( R_EAX, R_EDX );
575 sh4_x86.tstate = TSTATE_NONE;
576 }
577 break;
578 default:
579 UNDEF();
580 break;
581 }
582 break;
583 case 0x4:
584 { /* MOV.B Rm, @(R0, Rn) */
585 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
586 load_reg( R_EAX, 0 );
587 load_reg( R_ECX, Rn );
588 ADD_r32_r32( R_ECX, R_EAX );
589 MMU_TRANSLATE_WRITE( R_EAX );
590 load_reg( R_EDX, Rm );
591 MEM_WRITE_BYTE( R_EAX, R_EDX );
592 sh4_x86.tstate = TSTATE_NONE;
593 }
594 break;
595 case 0x5:
596 { /* MOV.W Rm, @(R0, Rn) */
597 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
598 load_reg( R_EAX, 0 );
599 load_reg( R_ECX, Rn );
600 ADD_r32_r32( R_ECX, R_EAX );
601 check_walign16( R_EAX );
602 MMU_TRANSLATE_WRITE( R_EAX );
603 load_reg( R_EDX, Rm );
604 MEM_WRITE_WORD( R_EAX, R_EDX );
605 sh4_x86.tstate = TSTATE_NONE;
606 }
607 break;
608 case 0x6:
609 { /* MOV.L Rm, @(R0, Rn) */
610 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
611 load_reg( R_EAX, 0 );
612 load_reg( R_ECX, Rn );
613 ADD_r32_r32( R_ECX, R_EAX );
614 check_walign32( R_EAX );
615 MMU_TRANSLATE_WRITE( R_EAX );
616 load_reg( R_EDX, Rm );
617 MEM_WRITE_LONG( R_EAX, R_EDX );
618 sh4_x86.tstate = TSTATE_NONE;
619 }
620 break;
621 case 0x7:
622 { /* MUL.L Rm, Rn */
623 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
624 load_reg( R_EAX, Rm );
625 load_reg( R_ECX, Rn );
626 MUL_r32( R_ECX );
627 store_spreg( R_EAX, R_MACL );
628 sh4_x86.tstate = TSTATE_NONE;
629 }
630 break;
631 case 0x8:
632 switch( (ir&0xFF0) >> 4 ) {
633 case 0x0:
634 { /* CLRT */
635 CLC();
636 SETC_t();
637 sh4_x86.tstate = TSTATE_C;
638 }
639 break;
640 case 0x1:
641 { /* SETT */
642 STC();
643 SETC_t();
644 sh4_x86.tstate = TSTATE_C;
645 }
646 break;
647 case 0x2:
648 { /* CLRMAC */
649 XOR_r32_r32(R_EAX, R_EAX);
650 store_spreg( R_EAX, R_MACL );
651 store_spreg( R_EAX, R_MACH );
652 sh4_x86.tstate = TSTATE_NONE;
653 }
654 break;
655 case 0x3:
656 { /* LDTLB */
657 call_func0( MMU_ldtlb );
658 }
659 break;
660 case 0x4:
661 { /* CLRS */
662 CLC();
663 SETC_sh4r(R_S);
664 sh4_x86.tstate = TSTATE_C;
665 }
666 break;
667 case 0x5:
668 { /* SETS */
669 STC();
670 SETC_sh4r(R_S);
671 sh4_x86.tstate = TSTATE_C;
672 }
673 break;
674 default:
675 UNDEF();
676 break;
677 }
678 break;
679 case 0x9:
680 switch( (ir&0xF0) >> 4 ) {
681 case 0x0:
682 { /* NOP */
683 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
684 }
685 break;
686 case 0x1:
687 { /* DIV0U */
688 XOR_r32_r32( R_EAX, R_EAX );
689 store_spreg( R_EAX, R_Q );
690 store_spreg( R_EAX, R_M );
691 store_spreg( R_EAX, R_T );
692 sh4_x86.tstate = TSTATE_C; // works for DIV1
693 }
694 break;
695 case 0x2:
696 { /* MOVT Rn */
697 uint32_t Rn = ((ir>>8)&0xF);
698 load_spreg( R_EAX, R_T );
699 store_reg( R_EAX, Rn );
700 }
701 break;
702 default:
703 UNDEF();
704 break;
705 }
706 break;
707 case 0xA:
708 switch( (ir&0xF0) >> 4 ) {
709 case 0x0:
710 { /* STS MACH, Rn */
711 uint32_t Rn = ((ir>>8)&0xF);
712 load_spreg( R_EAX, R_MACH );
713 store_reg( R_EAX, Rn );
714 }
715 break;
716 case 0x1:
717 { /* STS MACL, Rn */
718 uint32_t Rn = ((ir>>8)&0xF);
719 load_spreg( R_EAX, R_MACL );
720 store_reg( R_EAX, Rn );
721 }
722 break;
723 case 0x2:
724 { /* STS PR, Rn */
725 uint32_t Rn = ((ir>>8)&0xF);
726 load_spreg( R_EAX, R_PR );
727 store_reg( R_EAX, Rn );
728 }
729 break;
730 case 0x3:
731 { /* STC SGR, Rn */
732 uint32_t Rn = ((ir>>8)&0xF);
733 check_priv();
734 load_spreg( R_EAX, R_SGR );
735 store_reg( R_EAX, Rn );
736 sh4_x86.tstate = TSTATE_NONE;
737 }
738 break;
739 case 0x5:
740 { /* STS FPUL, Rn */
741 uint32_t Rn = ((ir>>8)&0xF);
742 load_spreg( R_EAX, R_FPUL );
743 store_reg( R_EAX, Rn );
744 }
745 break;
746 case 0x6:
747 { /* STS FPSCR, Rn */
748 uint32_t Rn = ((ir>>8)&0xF);
749 load_spreg( R_EAX, R_FPSCR );
750 store_reg( R_EAX, Rn );
751 }
752 break;
753 case 0xF:
754 { /* STC DBR, Rn */
755 uint32_t Rn = ((ir>>8)&0xF);
756 check_priv();
757 load_spreg( R_EAX, R_DBR );
758 store_reg( R_EAX, Rn );
759 sh4_x86.tstate = TSTATE_NONE;
760 }
761 break;
762 default:
763 UNDEF();
764 break;
765 }
766 break;
767 case 0xB:
768 switch( (ir&0xFF0) >> 4 ) {
769 case 0x0:
770 { /* RTS */
771 if( sh4_x86.in_delay_slot ) {
772 SLOTILLEGAL();
773 } else {
774 load_spreg( R_ECX, R_PR );
775 store_spreg( R_ECX, R_NEW_PC );
776 sh4_x86.in_delay_slot = DELAY_PC;
777 sh4_translate_instruction(pc+2);
778 exit_block_newpcset(pc+2);
779 sh4_x86.branch_taken = TRUE;
780 return 4;
781 }
782 }
783 break;
784 case 0x1:
785 { /* SLEEP */
786 check_priv();
787 call_func0( sh4_sleep );
788 sh4_x86.tstate = TSTATE_NONE;
789 sh4_x86.in_delay_slot = DELAY_NONE;
790 return 2;
791 }
792 break;
793 case 0x2:
794 { /* RTE */
795 if( sh4_x86.in_delay_slot ) {
796 SLOTILLEGAL();
797 } else {
798 check_priv();
799 load_spreg( R_ECX, R_SPC );
800 store_spreg( R_ECX, R_NEW_PC );
801 load_spreg( R_EAX, R_SSR );
802 call_func1( sh4_write_sr, R_EAX );
803 sh4_x86.in_delay_slot = DELAY_PC;
804 sh4_x86.priv_checked = FALSE;
805 sh4_x86.fpuen_checked = FALSE;
806 sh4_x86.tstate = TSTATE_NONE;
807 sh4_translate_instruction(pc+2);
808 exit_block_newpcset(pc+2);
809 sh4_x86.branch_taken = TRUE;
810 return 4;
811 }
812 }
813 break;
814 default:
815 UNDEF();
816 break;
817 }
818 break;
819 case 0xC:
820 { /* MOV.B @(R0, Rm), Rn */
821 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
822 load_reg( R_EAX, 0 );
823 load_reg( R_ECX, Rm );
824 ADD_r32_r32( R_ECX, R_EAX );
825 MMU_TRANSLATE_READ( R_EAX )
826 MEM_READ_BYTE( R_EAX, R_EAX );
827 store_reg( R_EAX, Rn );
828 sh4_x86.tstate = TSTATE_NONE;
829 }
830 break;
831 case 0xD:
832 { /* MOV.W @(R0, Rm), Rn */
833 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
834 load_reg( R_EAX, 0 );
835 load_reg( R_ECX, Rm );
836 ADD_r32_r32( R_ECX, R_EAX );
837 check_ralign16( R_EAX );
838 MMU_TRANSLATE_READ( R_EAX );
839 MEM_READ_WORD( R_EAX, R_EAX );
840 store_reg( R_EAX, Rn );
841 sh4_x86.tstate = TSTATE_NONE;
842 }
843 break;
844 case 0xE:
845 { /* MOV.L @(R0, Rm), Rn */
846 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
847 load_reg( R_EAX, 0 );
848 load_reg( R_ECX, Rm );
849 ADD_r32_r32( R_ECX, R_EAX );
850 check_ralign32( R_EAX );
851 MMU_TRANSLATE_READ( R_EAX );
852 MEM_READ_LONG( R_EAX, R_EAX );
853 store_reg( R_EAX, Rn );
854 sh4_x86.tstate = TSTATE_NONE;
855 }
856 break;
857 case 0xF:
858 { /* MAC.L @Rm+, @Rn+ */
859 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
860 if( Rm == Rn ) {
861 load_reg( R_EAX, Rm );
862 check_ralign32( R_EAX );
863 MMU_TRANSLATE_READ( R_EAX );
864 PUSH_realigned_r32( R_EAX );
865 load_reg( R_EAX, Rn );
866 ADD_imm8s_r32( 4, R_EAX );
867 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
868 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
869 // Note translate twice in case of page boundaries. Maybe worth
870 // adding a page-boundary check to skip the second translation
871 } else {
872 load_reg( R_EAX, Rm );
873 check_ralign32( R_EAX );
874 MMU_TRANSLATE_READ( R_EAX );
875 load_reg( R_ECX, Rn );
876 check_ralign32( R_ECX );
877 PUSH_realigned_r32( R_EAX );
878 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
879 MOV_r32_r32( R_ECX, R_EAX );
880 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
881 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
882 }
883 MEM_READ_LONG( R_EAX, R_EAX );
884 POP_r32( R_ECX );
885 PUSH_r32( R_EAX );
886 MEM_READ_LONG( R_ECX, R_EAX );
887 POP_realigned_r32( R_ECX );
889 IMUL_r32( R_ECX );
890 ADD_r32_sh4r( R_EAX, R_MACL );
891 ADC_r32_sh4r( R_EDX, R_MACH );
893 load_spreg( R_ECX, R_S );
894 TEST_r32_r32(R_ECX, R_ECX);
895 JE_rel8( CALL_FUNC0_SIZE, nosat );
896 call_func0( signsat48 );
897 JMP_TARGET( nosat );
898 sh4_x86.tstate = TSTATE_NONE;
899 }
900 break;
901 default:
902 UNDEF();
903 break;
904 }
905 break;
906 case 0x1:
907 { /* MOV.L Rm, @(disp, Rn) */
908 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
909 load_reg( R_EAX, Rn );
910 ADD_imm32_r32( disp, R_EAX );
911 check_walign32( R_EAX );
912 MMU_TRANSLATE_WRITE( R_EAX );
913 load_reg( R_EDX, Rm );
914 MEM_WRITE_LONG( R_EAX, R_EDX );
915 sh4_x86.tstate = TSTATE_NONE;
916 }
917 break;
918 case 0x2:
919 switch( ir&0xF ) {
920 case 0x0:
921 { /* MOV.B Rm, @Rn */
922 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
923 load_reg( R_EAX, Rn );
924 MMU_TRANSLATE_WRITE( R_EAX );
925 load_reg( R_EDX, Rm );
926 MEM_WRITE_BYTE( R_EAX, R_EDX );
927 sh4_x86.tstate = TSTATE_NONE;
928 }
929 break;
930 case 0x1:
931 { /* MOV.W Rm, @Rn */
932 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
933 load_reg( R_EAX, Rn );
934 check_walign16( R_EAX );
935 MMU_TRANSLATE_WRITE( R_EAX )
936 load_reg( R_EDX, Rm );
937 MEM_WRITE_WORD( R_EAX, R_EDX );
938 sh4_x86.tstate = TSTATE_NONE;
939 }
940 break;
941 case 0x2:
942 { /* MOV.L Rm, @Rn */
943 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
944 load_reg( R_EAX, Rn );
945 check_walign32(R_EAX);
946 MMU_TRANSLATE_WRITE( R_EAX );
947 load_reg( R_EDX, Rm );
948 MEM_WRITE_LONG( R_EAX, R_EDX );
949 sh4_x86.tstate = TSTATE_NONE;
950 }
951 break;
952 case 0x4:
953 { /* MOV.B Rm, @-Rn */
954 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
955 load_reg( R_EAX, Rn );
956 ADD_imm8s_r32( -1, R_EAX );
957 MMU_TRANSLATE_WRITE( R_EAX );
958 load_reg( R_EDX, Rm );
959 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
960 MEM_WRITE_BYTE( R_EAX, R_EDX );
961 sh4_x86.tstate = TSTATE_NONE;
962 }
963 break;
964 case 0x5:
965 { /* MOV.W Rm, @-Rn */
966 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
967 load_reg( R_EAX, Rn );
968 ADD_imm8s_r32( -2, R_EAX );
969 check_walign16( R_EAX );
970 MMU_TRANSLATE_WRITE( R_EAX );
971 load_reg( R_EDX, Rm );
972 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
973 MEM_WRITE_WORD( R_EAX, R_EDX );
974 sh4_x86.tstate = TSTATE_NONE;
975 }
976 break;
977 case 0x6:
978 { /* MOV.L Rm, @-Rn */
979 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
980 load_reg( R_EAX, Rn );
981 ADD_imm8s_r32( -4, R_EAX );
982 check_walign32( R_EAX );
983 MMU_TRANSLATE_WRITE( R_EAX );
984 load_reg( R_EDX, Rm );
985 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
986 MEM_WRITE_LONG( R_EAX, R_EDX );
987 sh4_x86.tstate = TSTATE_NONE;
988 }
989 break;
990 case 0x7:
991 { /* DIV0S Rm, Rn */
992 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
993 load_reg( R_EAX, Rm );
994 load_reg( R_ECX, Rn );
995 SHR_imm8_r32( 31, R_EAX );
996 SHR_imm8_r32( 31, R_ECX );
997 store_spreg( R_EAX, R_M );
998 store_spreg( R_ECX, R_Q );
999 CMP_r32_r32( R_EAX, R_ECX );
1000 SETNE_t();
1001 sh4_x86.tstate = TSTATE_NE;
1002 }
1003 break;
1004 case 0x8:
1005 { /* TST Rm, Rn */
1006 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1007 load_reg( R_EAX, Rm );
1008 load_reg( R_ECX, Rn );
1009 TEST_r32_r32( R_EAX, R_ECX );
1010 SETE_t();
1011 sh4_x86.tstate = TSTATE_E;
1012 }
1013 break;
1014 case 0x9:
1015 { /* AND Rm, Rn */
1016 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1017 load_reg( R_EAX, Rm );
1018 load_reg( R_ECX, Rn );
1019 AND_r32_r32( R_EAX, R_ECX );
1020 store_reg( R_ECX, Rn );
1021 sh4_x86.tstate = TSTATE_NONE;
1022 }
1023 break;
1024 case 0xA:
1025 { /* XOR Rm, Rn */
1026 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1027 load_reg( R_EAX, Rm );
1028 load_reg( R_ECX, Rn );
1029 XOR_r32_r32( R_EAX, R_ECX );
1030 store_reg( R_ECX, Rn );
1031 sh4_x86.tstate = TSTATE_NONE;
1032 }
1033 break;
1034 case 0xB:
1035 { /* OR Rm, Rn */
1036 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1037 load_reg( R_EAX, Rm );
1038 load_reg( R_ECX, Rn );
1039 OR_r32_r32( R_EAX, R_ECX );
1040 store_reg( R_ECX, Rn );
1041 sh4_x86.tstate = TSTATE_NONE;
1042 }
1043 break;
1044 case 0xC:
1045 { /* CMP/STR Rm, Rn */
1046 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1047 load_reg( R_EAX, Rm );
1048 load_reg( R_ECX, Rn );
1049 XOR_r32_r32( R_ECX, R_EAX );
1050 TEST_r8_r8( R_AL, R_AL );
1051 JE_rel8(13, target1);
1052 TEST_r8_r8( R_AH, R_AH ); // 2
1053 JE_rel8(9, target2);
1054 SHR_imm8_r32( 16, R_EAX ); // 3
1055 TEST_r8_r8( R_AL, R_AL ); // 2
1056 JE_rel8(2, target3);
1057 TEST_r8_r8( R_AH, R_AH ); // 2
1058 JMP_TARGET(target1);
1059 JMP_TARGET(target2);
1060 JMP_TARGET(target3);
1061 SETE_t();
1062 sh4_x86.tstate = TSTATE_E;
1063 }
1064 break;
1065 case 0xD:
1066 { /* XTRCT Rm, Rn */
1067 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1068 load_reg( R_EAX, Rm );
1069 load_reg( R_ECX, Rn );
1070 SHL_imm8_r32( 16, R_EAX );
1071 SHR_imm8_r32( 16, R_ECX );
1072 OR_r32_r32( R_EAX, R_ECX );
1073 store_reg( R_ECX, Rn );
1074 sh4_x86.tstate = TSTATE_NONE;
1075 }
1076 break;
1077 case 0xE:
1078 { /* MULU.W Rm, Rn */
1079 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1080 load_reg16u( R_EAX, Rm );
1081 load_reg16u( R_ECX, Rn );
1082 MUL_r32( R_ECX );
1083 store_spreg( R_EAX, R_MACL );
1084 sh4_x86.tstate = TSTATE_NONE;
1085 }
1086 break;
1087 case 0xF:
1088 { /* MULS.W Rm, Rn */
1089 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1090 load_reg16s( R_EAX, Rm );
1091 load_reg16s( R_ECX, Rn );
1092 MUL_r32( R_ECX );
1093 store_spreg( R_EAX, R_MACL );
1094 sh4_x86.tstate = TSTATE_NONE;
1095 }
1096 break;
1097 default:
1098 UNDEF();
1099 break;
1100 }
1101 break;
1102 case 0x3:
1103 switch( ir&0xF ) {
1104 case 0x0:
1105 { /* CMP/EQ Rm, Rn */
1106 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1107 load_reg( R_EAX, Rm );
1108 load_reg( R_ECX, Rn );
1109 CMP_r32_r32( R_EAX, R_ECX );
1110 SETE_t();
1111 sh4_x86.tstate = TSTATE_E;
1112 }
1113 break;
1114 case 0x2:
1115 { /* CMP/HS Rm, Rn */
1116 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1117 load_reg( R_EAX, Rm );
1118 load_reg( R_ECX, Rn );
1119 CMP_r32_r32( R_EAX, R_ECX );
1120 SETAE_t();
1121 sh4_x86.tstate = TSTATE_AE;
1122 }
1123 break;
1124 case 0x3:
1125 { /* CMP/GE Rm, Rn */
1126 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1127 load_reg( R_EAX, Rm );
1128 load_reg( R_ECX, Rn );
1129 CMP_r32_r32( R_EAX, R_ECX );
1130 SETGE_t();
1131 sh4_x86.tstate = TSTATE_GE;
1132 }
1133 break;
1134 case 0x4:
1135 { /* DIV1 Rm, Rn */
1136 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1137 load_spreg( R_ECX, R_M );
1138 load_reg( R_EAX, Rn );
1139 if( sh4_x86.tstate != TSTATE_C ) {
1140 LDC_t();
1141 }
1142 RCL1_r32( R_EAX );
1143 SETC_r8( R_DL ); // Q'
1144 CMP_sh4r_r32( R_Q, R_ECX );
1145 JE_rel8(5, mqequal);
1146 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1147 JMP_rel8(3, end);
1148 JMP_TARGET(mqequal);
1149 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1150 JMP_TARGET(end);
1151 store_reg( R_EAX, Rn ); // Done with Rn now
1152 SETC_r8(R_AL); // tmp1
1153 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1154 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1155 store_spreg( R_ECX, R_Q );
1156 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1157 MOVZX_r8_r32( R_AL, R_EAX );
1158 store_spreg( R_EAX, R_T );
1159 sh4_x86.tstate = TSTATE_NONE;
1160 }
1161 break;
1162 case 0x5:
1163 { /* DMULU.L Rm, Rn */
1164 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1165 load_reg( R_EAX, Rm );
1166 load_reg( R_ECX, Rn );
1167 MUL_r32(R_ECX);
1168 store_spreg( R_EDX, R_MACH );
1169 store_spreg( R_EAX, R_MACL );
1170 sh4_x86.tstate = TSTATE_NONE;
1171 }
1172 break;
1173 case 0x6:
1174 { /* CMP/HI Rm, Rn */
1175 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1176 load_reg( R_EAX, Rm );
1177 load_reg( R_ECX, Rn );
1178 CMP_r32_r32( R_EAX, R_ECX );
1179 SETA_t();
1180 sh4_x86.tstate = TSTATE_A;
1181 }
1182 break;
1183 case 0x7:
1184 { /* CMP/GT Rm, Rn */
1185 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1186 load_reg( R_EAX, Rm );
1187 load_reg( R_ECX, Rn );
1188 CMP_r32_r32( R_EAX, R_ECX );
1189 SETG_t();
1190 sh4_x86.tstate = TSTATE_G;
1191 }
1192 break;
1193 case 0x8:
1194 { /* SUB Rm, Rn */
1195 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1196 load_reg( R_EAX, Rm );
1197 load_reg( R_ECX, Rn );
1198 SUB_r32_r32( R_EAX, R_ECX );
1199 store_reg( R_ECX, Rn );
1200 sh4_x86.tstate = TSTATE_NONE;
1201 }
1202 break;
1203 case 0xA:
1204 { /* SUBC Rm, Rn */
1205 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1206 load_reg( R_EAX, Rm );
1207 load_reg( R_ECX, Rn );
1208 if( sh4_x86.tstate != TSTATE_C ) {
1209 LDC_t();
1210 }
1211 SBB_r32_r32( R_EAX, R_ECX );
1212 store_reg( R_ECX, Rn );
1213 SETC_t();
1214 sh4_x86.tstate = TSTATE_C;
1215 }
1216 break;
1217 case 0xB:
1218 { /* SUBV Rm, Rn */
1219 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1220 load_reg( R_EAX, Rm );
1221 load_reg( R_ECX, Rn );
1222 SUB_r32_r32( R_EAX, R_ECX );
1223 store_reg( R_ECX, Rn );
1224 SETO_t();
1225 sh4_x86.tstate = TSTATE_O;
1226 }
1227 break;
1228 case 0xC:
1229 { /* ADD Rm, Rn */
1230 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1231 load_reg( R_EAX, Rm );
1232 load_reg( R_ECX, Rn );
1233 ADD_r32_r32( R_EAX, R_ECX );
1234 store_reg( R_ECX, Rn );
1235 sh4_x86.tstate = TSTATE_NONE;
1236 }
1237 break;
1238 case 0xD:
1239 { /* DMULS.L Rm, Rn */
1240 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1241 load_reg( R_EAX, Rm );
1242 load_reg( R_ECX, Rn );
1243 IMUL_r32(R_ECX);
1244 store_spreg( R_EDX, R_MACH );
1245 store_spreg( R_EAX, R_MACL );
1246 sh4_x86.tstate = TSTATE_NONE;
1247 }
1248 break;
1249 case 0xE:
1250 { /* ADDC Rm, Rn */
1251 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1252 if( sh4_x86.tstate != TSTATE_C ) {
1253 LDC_t();
1254 }
1255 load_reg( R_EAX, Rm );
1256 load_reg( R_ECX, Rn );
1257 ADC_r32_r32( R_EAX, R_ECX );
1258 store_reg( R_ECX, Rn );
1259 SETC_t();
1260 sh4_x86.tstate = TSTATE_C;
1261 }
1262 break;
1263 case 0xF:
1264 { /* ADDV Rm, Rn */
1265 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1266 load_reg( R_EAX, Rm );
1267 load_reg( R_ECX, Rn );
1268 ADD_r32_r32( R_EAX, R_ECX );
1269 store_reg( R_ECX, Rn );
1270 SETO_t();
1271 sh4_x86.tstate = TSTATE_O;
1272 }
1273 break;
1274 default:
1275 UNDEF();
1276 break;
1277 }
1278 break;
1279 case 0x4:
1280 switch( ir&0xF ) {
1281 case 0x0:
1282 switch( (ir&0xF0) >> 4 ) {
1283 case 0x0:
1284 { /* SHLL Rn */
1285 uint32_t Rn = ((ir>>8)&0xF);
1286 load_reg( R_EAX, Rn );
1287 SHL1_r32( R_EAX );
1288 SETC_t();
1289 store_reg( R_EAX, Rn );
1290 sh4_x86.tstate = TSTATE_C;
1291 }
1292 break;
1293 case 0x1:
1294 { /* DT Rn */
1295 uint32_t Rn = ((ir>>8)&0xF);
1296 load_reg( R_EAX, Rn );
1297 ADD_imm8s_r32( -1, R_EAX );
1298 store_reg( R_EAX, Rn );
1299 SETE_t();
1300 sh4_x86.tstate = TSTATE_E;
1301 }
1302 break;
1303 case 0x2:
1304 { /* SHAL Rn */
1305 uint32_t Rn = ((ir>>8)&0xF);
1306 load_reg( R_EAX, Rn );
1307 SHL1_r32( R_EAX );
1308 SETC_t();
1309 store_reg( R_EAX, Rn );
1310 sh4_x86.tstate = TSTATE_C;
1311 }
1312 break;
1313 default:
1314 UNDEF();
1315 break;
1316 }
1317 break;
1318 case 0x1:
1319 switch( (ir&0xF0) >> 4 ) {
1320 case 0x0:
1321 { /* SHLR Rn */
1322 uint32_t Rn = ((ir>>8)&0xF);
1323 load_reg( R_EAX, Rn );
1324 SHR1_r32( R_EAX );
1325 SETC_t();
1326 store_reg( R_EAX, Rn );
1327 sh4_x86.tstate = TSTATE_C;
1328 }
1329 break;
1330 case 0x1:
1331 { /* CMP/PZ Rn */
1332 uint32_t Rn = ((ir>>8)&0xF);
1333 load_reg( R_EAX, Rn );
1334 CMP_imm8s_r32( 0, R_EAX );
1335 SETGE_t();
1336 sh4_x86.tstate = TSTATE_GE;
1337 }
1338 break;
1339 case 0x2:
1340 { /* SHAR Rn */
1341 uint32_t Rn = ((ir>>8)&0xF);
1342 load_reg( R_EAX, Rn );
1343 SAR1_r32( R_EAX );
1344 SETC_t();
1345 store_reg( R_EAX, Rn );
1346 sh4_x86.tstate = TSTATE_C;
1347 }
1348 break;
1349 default:
1350 UNDEF();
1351 break;
1352 }
1353 break;
1354 case 0x2:
1355 switch( (ir&0xF0) >> 4 ) {
1356 case 0x0:
1357 { /* STS.L MACH, @-Rn */
1358 uint32_t Rn = ((ir>>8)&0xF);
1359 load_reg( R_EAX, Rn );
1360 check_walign32( R_EAX );
1361 ADD_imm8s_r32( -4, R_EAX );
1362 MMU_TRANSLATE_WRITE( R_EAX );
1363 load_spreg( R_EDX, R_MACH );
1364 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1365 MEM_WRITE_LONG( R_EAX, R_EDX );
1366 sh4_x86.tstate = TSTATE_NONE;
1367 }
1368 break;
1369 case 0x1:
1370 { /* STS.L MACL, @-Rn */
1371 uint32_t Rn = ((ir>>8)&0xF);
1372 load_reg( R_EAX, Rn );
1373 check_walign32( R_EAX );
1374 ADD_imm8s_r32( -4, R_EAX );
1375 MMU_TRANSLATE_WRITE( R_EAX );
1376 load_spreg( R_EDX, R_MACL );
1377 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1378 MEM_WRITE_LONG( R_EAX, R_EDX );
1379 sh4_x86.tstate = TSTATE_NONE;
1380 }
1381 break;
1382 case 0x2:
1383 { /* STS.L PR, @-Rn */
1384 uint32_t Rn = ((ir>>8)&0xF);
1385 load_reg( R_EAX, Rn );
1386 check_walign32( R_EAX );
1387 ADD_imm8s_r32( -4, R_EAX );
1388 MMU_TRANSLATE_WRITE( R_EAX );
1389 load_spreg( R_EDX, R_PR );
1390 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1391 MEM_WRITE_LONG( R_EAX, R_EDX );
1392 sh4_x86.tstate = TSTATE_NONE;
1393 }
1394 break;
1395 case 0x3:
1396 { /* STC.L SGR, @-Rn */
1397 uint32_t Rn = ((ir>>8)&0xF);
1398 check_priv();
1399 load_reg( R_EAX, Rn );
1400 check_walign32( R_EAX );
1401 ADD_imm8s_r32( -4, R_EAX );
1402 MMU_TRANSLATE_WRITE( R_EAX );
1403 load_spreg( R_EDX, R_SGR );
1404 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1405 MEM_WRITE_LONG( R_EAX, R_EDX );
1406 sh4_x86.tstate = TSTATE_NONE;
1407 }
1408 break;
1409 case 0x5:
1410 { /* STS.L FPUL, @-Rn */
1411 uint32_t Rn = ((ir>>8)&0xF);
1412 load_reg( R_EAX, Rn );
1413 check_walign32( R_EAX );
1414 ADD_imm8s_r32( -4, R_EAX );
1415 MMU_TRANSLATE_WRITE( R_EAX );
1416 load_spreg( R_EDX, R_FPUL );
1417 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1418 MEM_WRITE_LONG( R_EAX, R_EDX );
1419 sh4_x86.tstate = TSTATE_NONE;
1420 }
1421 break;
1422 case 0x6:
1423 { /* STS.L FPSCR, @-Rn */
1424 uint32_t Rn = ((ir>>8)&0xF);
1425 load_reg( R_EAX, Rn );
1426 check_walign32( R_EAX );
1427 ADD_imm8s_r32( -4, R_EAX );
1428 MMU_TRANSLATE_WRITE( R_EAX );
1429 load_spreg( R_EDX, R_FPSCR );
1430 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1431 MEM_WRITE_LONG( R_EAX, R_EDX );
1432 sh4_x86.tstate = TSTATE_NONE;
1433 }
1434 break;
1435 case 0xF:
1436 { /* STC.L DBR, @-Rn */
1437 uint32_t Rn = ((ir>>8)&0xF);
1438 check_priv();
1439 load_reg( R_EAX, Rn );
1440 check_walign32( R_EAX );
1441 ADD_imm8s_r32( -4, R_EAX );
1442 MMU_TRANSLATE_WRITE( R_EAX );
1443 load_spreg( R_EDX, R_DBR );
1444 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1445 MEM_WRITE_LONG( R_EAX, R_EDX );
1446 sh4_x86.tstate = TSTATE_NONE;
1447 }
1448 break;
1449 default:
1450 UNDEF();
1451 break;
1452 }
1453 break;
1454 case 0x3:
1455 switch( (ir&0x80) >> 7 ) {
1456 case 0x0:
1457 switch( (ir&0x70) >> 4 ) {
1458 case 0x0:
1459 { /* STC.L SR, @-Rn */
1460 uint32_t Rn = ((ir>>8)&0xF);
1461 check_priv();
1462 load_reg( R_EAX, Rn );
1463 check_walign32( R_EAX );
1464 ADD_imm8s_r32( -4, R_EAX );
1465 MMU_TRANSLATE_WRITE( R_EAX );
1466 PUSH_realigned_r32( R_EAX );
1467 call_func0( sh4_read_sr );
1468 POP_realigned_r32( R_ECX );
1469 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1470 MEM_WRITE_LONG( R_ECX, R_EAX );
1471 sh4_x86.tstate = TSTATE_NONE;
1472 }
1473 break;
1474 case 0x1:
1475 { /* STC.L GBR, @-Rn */
1476 uint32_t Rn = ((ir>>8)&0xF);
1477 load_reg( R_EAX, Rn );
1478 check_walign32( R_EAX );
1479 ADD_imm8s_r32( -4, R_EAX );
1480 MMU_TRANSLATE_WRITE( R_EAX );
1481 load_spreg( R_EDX, R_GBR );
1482 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1483 MEM_WRITE_LONG( R_EAX, R_EDX );
1484 sh4_x86.tstate = TSTATE_NONE;
1485 }
1486 break;
1487 case 0x2:
1488 { /* STC.L VBR, @-Rn */
1489 uint32_t Rn = ((ir>>8)&0xF);
1490 check_priv();
1491 load_reg( R_EAX, Rn );
1492 check_walign32( R_EAX );
1493 ADD_imm8s_r32( -4, R_EAX );
1494 MMU_TRANSLATE_WRITE( R_EAX );
1495 load_spreg( R_EDX, R_VBR );
1496 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1497 MEM_WRITE_LONG( R_EAX, R_EDX );
1498 sh4_x86.tstate = TSTATE_NONE;
1499 }
1500 break;
1501 case 0x3:
1502 { /* STC.L SSR, @-Rn */
1503 uint32_t Rn = ((ir>>8)&0xF);
1504 check_priv();
1505 load_reg( R_EAX, Rn );
1506 check_walign32( R_EAX );
1507 ADD_imm8s_r32( -4, R_EAX );
1508 MMU_TRANSLATE_WRITE( R_EAX );
1509 load_spreg( R_EDX, R_SSR );
1510 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1511 MEM_WRITE_LONG( R_EAX, R_EDX );
1512 sh4_x86.tstate = TSTATE_NONE;
1513 }
1514 break;
1515 case 0x4:
1516 { /* STC.L SPC, @-Rn */
1517 uint32_t Rn = ((ir>>8)&0xF);
1518 check_priv();
1519 load_reg( R_EAX, Rn );
1520 check_walign32( R_EAX );
1521 ADD_imm8s_r32( -4, R_EAX );
1522 MMU_TRANSLATE_WRITE( R_EAX );
1523 load_spreg( R_EDX, R_SPC );
1524 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1525 MEM_WRITE_LONG( R_EAX, R_EDX );
1526 sh4_x86.tstate = TSTATE_NONE;
1527 }
1528 break;
1529 default:
1530 UNDEF();
1531 break;
1532 }
1533 break;
1534 case 0x1:
1535 { /* STC.L Rm_BANK, @-Rn */
1536 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1537 check_priv();
1538 load_reg( R_EAX, Rn );
1539 check_walign32( R_EAX );
1540 ADD_imm8s_r32( -4, R_EAX );
1541 MMU_TRANSLATE_WRITE( R_EAX );
1542 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1543 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1544 MEM_WRITE_LONG( R_EAX, R_EDX );
1545 sh4_x86.tstate = TSTATE_NONE;
1546 }
1547 break;
1548 }
1549 break;
1550 case 0x4:
1551 switch( (ir&0xF0) >> 4 ) {
1552 case 0x0:
1553 { /* ROTL Rn */
1554 uint32_t Rn = ((ir>>8)&0xF);
1555 load_reg( R_EAX, Rn );
1556 ROL1_r32( R_EAX );
1557 store_reg( R_EAX, Rn );
1558 SETC_t();
1559 sh4_x86.tstate = TSTATE_C;
1560 }
1561 break;
1562 case 0x2:
1563 { /* ROTCL Rn */
1564 uint32_t Rn = ((ir>>8)&0xF);
1565 load_reg( R_EAX, Rn );
1566 if( sh4_x86.tstate != TSTATE_C ) {
1567 LDC_t();
1568 }
1569 RCL1_r32( R_EAX );
1570 store_reg( R_EAX, Rn );
1571 SETC_t();
1572 sh4_x86.tstate = TSTATE_C;
1573 }
1574 break;
1575 default:
1576 UNDEF();
1577 break;
1578 }
1579 break;
1580 case 0x5:
1581 switch( (ir&0xF0) >> 4 ) {
1582 case 0x0:
1583 { /* ROTR Rn */
1584 uint32_t Rn = ((ir>>8)&0xF);
1585 load_reg( R_EAX, Rn );
1586 ROR1_r32( R_EAX );
1587 store_reg( R_EAX, Rn );
1588 SETC_t();
1589 sh4_x86.tstate = TSTATE_C;
1590 }
1591 break;
1592 case 0x1:
1593 { /* CMP/PL Rn */
1594 uint32_t Rn = ((ir>>8)&0xF);
1595 load_reg( R_EAX, Rn );
1596 CMP_imm8s_r32( 0, R_EAX );
1597 SETG_t();
1598 sh4_x86.tstate = TSTATE_G;
1599 }
1600 break;
1601 case 0x2:
1602 { /* ROTCR Rn */
1603 uint32_t Rn = ((ir>>8)&0xF);
1604 load_reg( R_EAX, Rn );
1605 if( sh4_x86.tstate != TSTATE_C ) {
1606 LDC_t();
1607 }
1608 RCR1_r32( R_EAX );
1609 store_reg( R_EAX, Rn );
1610 SETC_t();
1611 sh4_x86.tstate = TSTATE_C;
1612 }
1613 break;
1614 default:
1615 UNDEF();
1616 break;
1617 }
1618 break;
1619 case 0x6:
1620 switch( (ir&0xF0) >> 4 ) {
1621 case 0x0:
1622 { /* LDS.L @Rm+, MACH */
1623 uint32_t Rm = ((ir>>8)&0xF);
1624 load_reg( R_EAX, Rm );
1625 check_ralign32( R_EAX );
1626 MMU_TRANSLATE_READ( R_EAX );
1627 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1628 MEM_READ_LONG( R_EAX, R_EAX );
1629 store_spreg( R_EAX, R_MACH );
1630 sh4_x86.tstate = TSTATE_NONE;
1631 }
1632 break;
1633 case 0x1:
1634 { /* LDS.L @Rm+, MACL */
1635 uint32_t Rm = ((ir>>8)&0xF);
1636 load_reg( R_EAX, Rm );
1637 check_ralign32( R_EAX );
1638 MMU_TRANSLATE_READ( R_EAX );
1639 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1640 MEM_READ_LONG( R_EAX, R_EAX );
1641 store_spreg( R_EAX, R_MACL );
1642 sh4_x86.tstate = TSTATE_NONE;
1643 }
1644 break;
1645 case 0x2:
1646 { /* LDS.L @Rm+, PR */
1647 uint32_t Rm = ((ir>>8)&0xF);
1648 load_reg( R_EAX, Rm );
1649 check_ralign32( R_EAX );
1650 MMU_TRANSLATE_READ( R_EAX );
1651 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1652 MEM_READ_LONG( R_EAX, R_EAX );
1653 store_spreg( R_EAX, R_PR );
1654 sh4_x86.tstate = TSTATE_NONE;
1655 }
1656 break;
1657 case 0x3:
1658 { /* LDC.L @Rm+, SGR */
1659 uint32_t Rm = ((ir>>8)&0xF);
1660 check_priv();
1661 load_reg( R_EAX, Rm );
1662 check_ralign32( R_EAX );
1663 MMU_TRANSLATE_READ( R_EAX );
1664 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1665 MEM_READ_LONG( R_EAX, R_EAX );
1666 store_spreg( R_EAX, R_SGR );
1667 sh4_x86.tstate = TSTATE_NONE;
1668 }
1669 break;
1670 case 0x5:
1671 { /* LDS.L @Rm+, FPUL */
1672 uint32_t Rm = ((ir>>8)&0xF);
1673 load_reg( R_EAX, Rm );
1674 check_ralign32( R_EAX );
1675 MMU_TRANSLATE_READ( R_EAX );
1676 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1677 MEM_READ_LONG( R_EAX, R_EAX );
1678 store_spreg( R_EAX, R_FPUL );
1679 sh4_x86.tstate = TSTATE_NONE;
1680 }
1681 break;
1682 case 0x6:
1683 { /* LDS.L @Rm+, FPSCR */
1684 uint32_t Rm = ((ir>>8)&0xF);
1685 load_reg( R_EAX, Rm );
1686 check_ralign32( R_EAX );
1687 MMU_TRANSLATE_READ( R_EAX );
1688 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1689 MEM_READ_LONG( R_EAX, R_EAX );
1690 store_spreg( R_EAX, R_FPSCR );
1691 update_fr_bank( R_EAX );
1692 sh4_x86.tstate = TSTATE_NONE;
1693 }
1694 break;
1695 case 0xF:
1696 { /* LDC.L @Rm+, DBR */
1697 uint32_t Rm = ((ir>>8)&0xF);
1698 check_priv();
1699 load_reg( R_EAX, Rm );
1700 check_ralign32( R_EAX );
1701 MMU_TRANSLATE_READ( R_EAX );
1702 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1703 MEM_READ_LONG( R_EAX, R_EAX );
1704 store_spreg( R_EAX, R_DBR );
1705 sh4_x86.tstate = TSTATE_NONE;
1706 }
1707 break;
1708 default:
1709 UNDEF();
1710 break;
1711 }
1712 break;
1713 case 0x7:
1714 switch( (ir&0x80) >> 7 ) {
1715 case 0x0:
1716 switch( (ir&0x70) >> 4 ) {
1717 case 0x0:
1718 { /* LDC.L @Rm+, SR */
1719 uint32_t Rm = ((ir>>8)&0xF);
1720 if( sh4_x86.in_delay_slot ) {
1721 SLOTILLEGAL();
1722 } else {
1723 check_priv();
1724 load_reg( R_EAX, Rm );
1725 check_ralign32( R_EAX );
1726 MMU_TRANSLATE_READ( R_EAX );
1727 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1728 MEM_READ_LONG( R_EAX, R_EAX );
1729 call_func1( sh4_write_sr, R_EAX );
1730 sh4_x86.priv_checked = FALSE;
1731 sh4_x86.fpuen_checked = FALSE;
1732 sh4_x86.tstate = TSTATE_NONE;
1733 }
1734 }
1735 break;
1736 case 0x1:
1737 { /* LDC.L @Rm+, GBR */
1738 uint32_t Rm = ((ir>>8)&0xF);
1739 load_reg( R_EAX, Rm );
1740 check_ralign32( R_EAX );
1741 MMU_TRANSLATE_READ( R_EAX );
1742 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1743 MEM_READ_LONG( R_EAX, R_EAX );
1744 store_spreg( R_EAX, R_GBR );
1745 sh4_x86.tstate = TSTATE_NONE;
1746 }
1747 break;
1748 case 0x2:
1749 { /* LDC.L @Rm+, VBR */
1750 uint32_t Rm = ((ir>>8)&0xF);
1751 check_priv();
1752 load_reg( R_EAX, Rm );
1753 check_ralign32( R_EAX );
1754 MMU_TRANSLATE_READ( R_EAX );
1755 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1756 MEM_READ_LONG( R_EAX, R_EAX );
1757 store_spreg( R_EAX, R_VBR );
1758 sh4_x86.tstate = TSTATE_NONE;
1759 }
1760 break;
1761 case 0x3:
1762 { /* LDC.L @Rm+, SSR */
1763 uint32_t Rm = ((ir>>8)&0xF);
1764 check_priv();
1765 load_reg( R_EAX, Rm );
1766 check_ralign32( R_EAX );
1767 MMU_TRANSLATE_READ( R_EAX );
1768 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1769 MEM_READ_LONG( R_EAX, R_EAX );
1770 store_spreg( R_EAX, R_SSR );
1771 sh4_x86.tstate = TSTATE_NONE;
1772 }
1773 break;
1774 case 0x4:
1775 { /* LDC.L @Rm+, SPC */
1776 uint32_t Rm = ((ir>>8)&0xF);
1777 check_priv();
1778 load_reg( R_EAX, Rm );
1779 check_ralign32( R_EAX );
1780 MMU_TRANSLATE_READ( R_EAX );
1781 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1782 MEM_READ_LONG( R_EAX, R_EAX );
1783 store_spreg( R_EAX, R_SPC );
1784 sh4_x86.tstate = TSTATE_NONE;
1785 }
1786 break;
1787 default:
1788 UNDEF();
1789 break;
1790 }
1791 break;
1792 case 0x1:
1793 { /* LDC.L @Rm+, Rn_BANK */
1794 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1795 check_priv();
1796 load_reg( R_EAX, Rm );
1797 check_ralign32( R_EAX );
1798 MMU_TRANSLATE_READ( R_EAX );
1799 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1800 MEM_READ_LONG( R_EAX, R_EAX );
1801 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1802 sh4_x86.tstate = TSTATE_NONE;
1803 }
1804 break;
1805 }
1806 break;
1807 case 0x8:
1808 switch( (ir&0xF0) >> 4 ) {
1809 case 0x0:
1810 { /* SHLL2 Rn */
1811 uint32_t Rn = ((ir>>8)&0xF);
1812 load_reg( R_EAX, Rn );
1813 SHL_imm8_r32( 2, R_EAX );
1814 store_reg( R_EAX, Rn );
1815 sh4_x86.tstate = TSTATE_NONE;
1816 }
1817 break;
1818 case 0x1:
1819 { /* SHLL8 Rn */
1820 uint32_t Rn = ((ir>>8)&0xF);
1821 load_reg( R_EAX, Rn );
1822 SHL_imm8_r32( 8, R_EAX );
1823 store_reg( R_EAX, Rn );
1824 sh4_x86.tstate = TSTATE_NONE;
1825 }
1826 break;
1827 case 0x2:
1828 { /* SHLL16 Rn */
1829 uint32_t Rn = ((ir>>8)&0xF);
1830 load_reg( R_EAX, Rn );
1831 SHL_imm8_r32( 16, R_EAX );
1832 store_reg( R_EAX, Rn );
1833 sh4_x86.tstate = TSTATE_NONE;
1834 }
1835 break;
1836 default:
1837 UNDEF();
1838 break;
1839 }
1840 break;
1841 case 0x9:
1842 switch( (ir&0xF0) >> 4 ) {
1843 case 0x0:
1844 { /* SHLR2 Rn */
1845 uint32_t Rn = ((ir>>8)&0xF);
1846 load_reg( R_EAX, Rn );
1847 SHR_imm8_r32( 2, R_EAX );
1848 store_reg( R_EAX, Rn );
1849 sh4_x86.tstate = TSTATE_NONE;
1850 }
1851 break;
1852 case 0x1:
1853 { /* SHLR8 Rn */
1854 uint32_t Rn = ((ir>>8)&0xF);
1855 load_reg( R_EAX, Rn );
1856 SHR_imm8_r32( 8, R_EAX );
1857 store_reg( R_EAX, Rn );
1858 sh4_x86.tstate = TSTATE_NONE;
1859 }
1860 break;
1861 case 0x2:
1862 { /* SHLR16 Rn */
1863 uint32_t Rn = ((ir>>8)&0xF);
1864 load_reg( R_EAX, Rn );
1865 SHR_imm8_r32( 16, R_EAX );
1866 store_reg( R_EAX, Rn );
1867 sh4_x86.tstate = TSTATE_NONE;
1868 }
1869 break;
1870 default:
1871 UNDEF();
1872 break;
1873 }
1874 break;
1875 case 0xA:
1876 switch( (ir&0xF0) >> 4 ) {
1877 case 0x0:
1878 { /* LDS Rm, MACH */
1879 uint32_t Rm = ((ir>>8)&0xF);
1880 load_reg( R_EAX, Rm );
1881 store_spreg( R_EAX, R_MACH );
1882 }
1883 break;
1884 case 0x1:
1885 { /* LDS Rm, MACL */
1886 uint32_t Rm = ((ir>>8)&0xF);
1887 load_reg( R_EAX, Rm );
1888 store_spreg( R_EAX, R_MACL );
1889 }
1890 break;
1891 case 0x2:
1892 { /* LDS Rm, PR */
1893 uint32_t Rm = ((ir>>8)&0xF);
1894 load_reg( R_EAX, Rm );
1895 store_spreg( R_EAX, R_PR );
1896 }
1897 break;
1898 case 0x3:
1899 { /* LDC Rm, SGR */
1900 uint32_t Rm = ((ir>>8)&0xF);
1901 check_priv();
1902 load_reg( R_EAX, Rm );
1903 store_spreg( R_EAX, R_SGR );
1904 sh4_x86.tstate = TSTATE_NONE;
1905 }
1906 break;
1907 case 0x5:
1908 { /* LDS Rm, FPUL */
1909 uint32_t Rm = ((ir>>8)&0xF);
1910 load_reg( R_EAX, Rm );
1911 store_spreg( R_EAX, R_FPUL );
1912 }
1913 break;
1914 case 0x6:
1915 { /* LDS Rm, FPSCR */
1916 uint32_t Rm = ((ir>>8)&0xF);
1917 load_reg( R_EAX, Rm );
1918 store_spreg( R_EAX, R_FPSCR );
1919 update_fr_bank( R_EAX );
1920 sh4_x86.tstate = TSTATE_NONE;
1921 }
1922 break;
1923 case 0xF:
1924 { /* LDC Rm, DBR */
1925 uint32_t Rm = ((ir>>8)&0xF);
1926 check_priv();
1927 load_reg( R_EAX, Rm );
1928 store_spreg( R_EAX, R_DBR );
1929 sh4_x86.tstate = TSTATE_NONE;
1930 }
1931 break;
1932 default:
1933 UNDEF();
1934 break;
1935 }
1936 break;
1937 case 0xB:
1938 switch( (ir&0xF0) >> 4 ) {
1939 case 0x0:
1940 { /* JSR @Rn */
1941 uint32_t Rn = ((ir>>8)&0xF);
1942 if( sh4_x86.in_delay_slot ) {
1943 SLOTILLEGAL();
1944 } else {
1945 load_spreg( R_EAX, R_PC );
1946 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1947 store_spreg( R_EAX, R_PR );
1948 load_reg( R_ECX, Rn );
1949 store_spreg( R_ECX, R_NEW_PC );
1950 sh4_translate_instruction(pc+2);
1951 exit_block_newpcset(pc+2);
1952 sh4_x86.branch_taken = TRUE;
1953 return 4;
1954 }
1955 }
1956 break;
1957 case 0x1:
1958 { /* TAS.B @Rn */
1959 uint32_t Rn = ((ir>>8)&0xF);
1960 load_reg( R_EAX, Rn );
1961 MMU_TRANSLATE_WRITE( R_EAX );
1962 PUSH_realigned_r32( R_EAX );
1963 MEM_READ_BYTE( R_EAX, R_EAX );
1964 TEST_r8_r8( R_AL, R_AL );
1965 SETE_t();
1966 OR_imm8_r8( 0x80, R_AL );
1967 POP_realigned_r32( R_ECX );
1968 MEM_WRITE_BYTE( R_ECX, R_EAX );
1969 sh4_x86.tstate = TSTATE_NONE;
1970 }
1971 break;
1972 case 0x2:
1973 { /* JMP @Rn */
1974 uint32_t Rn = ((ir>>8)&0xF);
1975 if( sh4_x86.in_delay_slot ) {
1976 SLOTILLEGAL();
1977 } else {
1978 load_reg( R_ECX, Rn );
1979 store_spreg( R_ECX, R_NEW_PC );
1980 sh4_x86.in_delay_slot = DELAY_PC;
1981 sh4_translate_instruction(pc+2);
1982 exit_block_newpcset(pc+2);
1983 sh4_x86.branch_taken = TRUE;
1984 return 4;
1985 }
1986 }
1987 break;
1988 default:
1989 UNDEF();
1990 break;
1991 }
1992 break;
1993 case 0xC:
1994 { /* SHAD Rm, Rn */
1995 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1996 /* Annoyingly enough, not directly convertible */
1997 load_reg( R_EAX, Rn );
1998 load_reg( R_ECX, Rm );
1999 CMP_imm32_r32( 0, R_ECX );
2000 JGE_rel8(16, doshl);
2002 NEG_r32( R_ECX ); // 2
2003 AND_imm8_r8( 0x1F, R_CL ); // 3
2004 JE_rel8( 4, emptysar); // 2
2005 SAR_r32_CL( R_EAX ); // 2
2006 JMP_rel8(10, end); // 2
2008 JMP_TARGET(emptysar);
2009 SAR_imm8_r32(31, R_EAX ); // 3
2010 JMP_rel8(5, end2);
2012 JMP_TARGET(doshl);
2013 AND_imm8_r8( 0x1F, R_CL ); // 3
2014 SHL_r32_CL( R_EAX ); // 2
2015 JMP_TARGET(end);
2016 JMP_TARGET(end2);
2017 store_reg( R_EAX, Rn );
2018 sh4_x86.tstate = TSTATE_NONE;
2019 }
2020 break;
2021 case 0xD:
2022 { /* SHLD Rm, Rn */
2023 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2024 load_reg( R_EAX, Rn );
2025 load_reg( R_ECX, Rm );
2026 CMP_imm32_r32( 0, R_ECX );
2027 JGE_rel8(15, doshl);
2029 NEG_r32( R_ECX ); // 2
2030 AND_imm8_r8( 0x1F, R_CL ); // 3
2031 JE_rel8( 4, emptyshr );
2032 SHR_r32_CL( R_EAX ); // 2
2033 JMP_rel8(9, end); // 2
2035 JMP_TARGET(emptyshr);
2036 XOR_r32_r32( R_EAX, R_EAX );
2037 JMP_rel8(5, end2);
2039 JMP_TARGET(doshl);
2040 AND_imm8_r8( 0x1F, R_CL ); // 3
2041 SHL_r32_CL( R_EAX ); // 2
2042 JMP_TARGET(end);
2043 JMP_TARGET(end2);
2044 store_reg( R_EAX, Rn );
2045 sh4_x86.tstate = TSTATE_NONE;
2046 }
2047 break;
2048 case 0xE:
2049 switch( (ir&0x80) >> 7 ) {
2050 case 0x0:
2051 switch( (ir&0x70) >> 4 ) {
2052 case 0x0:
2053 { /* LDC Rm, SR */
2054 uint32_t Rm = ((ir>>8)&0xF);
2055 if( sh4_x86.in_delay_slot ) {
2056 SLOTILLEGAL();
2057 } else {
2058 check_priv();
2059 load_reg( R_EAX, Rm );
2060 call_func1( sh4_write_sr, R_EAX );
2061 sh4_x86.priv_checked = FALSE;
2062 sh4_x86.fpuen_checked = FALSE;
2063 sh4_x86.tstate = TSTATE_NONE;
2064 }
2065 }
2066 break;
2067 case 0x1:
2068 { /* LDC Rm, GBR */
2069 uint32_t Rm = ((ir>>8)&0xF);
2070 load_reg( R_EAX, Rm );
2071 store_spreg( R_EAX, R_GBR );
2072 }
2073 break;
2074 case 0x2:
2075 { /* LDC Rm, VBR */
2076 uint32_t Rm = ((ir>>8)&0xF);
2077 check_priv();
2078 load_reg( R_EAX, Rm );
2079 store_spreg( R_EAX, R_VBR );
2080 sh4_x86.tstate = TSTATE_NONE;
2081 }
2082 break;
2083 case 0x3:
2084 { /* LDC Rm, SSR */
2085 uint32_t Rm = ((ir>>8)&0xF);
2086 check_priv();
2087 load_reg( R_EAX, Rm );
2088 store_spreg( R_EAX, R_SSR );
2089 sh4_x86.tstate = TSTATE_NONE;
2090 }
2091 break;
2092 case 0x4:
2093 { /* LDC Rm, SPC */
2094 uint32_t Rm = ((ir>>8)&0xF);
2095 check_priv();
2096 load_reg( R_EAX, Rm );
2097 store_spreg( R_EAX, R_SPC );
2098 sh4_x86.tstate = TSTATE_NONE;
2099 }
2100 break;
2101 default:
2102 UNDEF();
2103 break;
2104 }
2105 break;
2106 case 0x1:
2107 { /* LDC Rm, Rn_BANK */
2108 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2109 check_priv();
2110 load_reg( R_EAX, Rm );
2111 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2112 sh4_x86.tstate = TSTATE_NONE;
2113 }
2114 break;
2115 }
2116 break;
2117 case 0xF:
2118 { /* MAC.W @Rm+, @Rn+ */
2119 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2120 if( Rm == Rn ) {
2121 load_reg( R_EAX, Rm );
2122 check_ralign16( R_EAX );
2123 MMU_TRANSLATE_READ( R_EAX );
2124 PUSH_realigned_r32( R_EAX );
2125 load_reg( R_EAX, Rn );
2126 ADD_imm8s_r32( 2, R_EAX );
2127 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
2128 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
2129 // Note translate twice in case of page boundaries. Maybe worth
2130 // adding a page-boundary check to skip the second translation
2131 } else {
2132 load_reg( R_EAX, Rm );
2133 check_ralign16( R_EAX );
2134 MMU_TRANSLATE_READ( R_EAX );
2135 load_reg( R_ECX, Rn );
2136 check_ralign16( R_ECX );
2137 PUSH_realigned_r32( R_EAX );
2138 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
2139 MOV_r32_r32( R_ECX, R_EAX );
2140 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2141 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2142 }
2143 MEM_READ_WORD( R_EAX, R_EAX );
2144 POP_r32( R_ECX );
2145 PUSH_r32( R_EAX );
2146 MEM_READ_WORD( R_ECX, R_EAX );
2147 POP_realigned_r32( R_ECX );
2148 IMUL_r32( R_ECX );
2150 load_spreg( R_ECX, R_S );
2151 TEST_r32_r32( R_ECX, R_ECX );
2152 JE_rel8( 47, nosat );
2154 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2155 JNO_rel8( 51, end ); // 2
2156 load_imm32( R_EDX, 1 ); // 5
2157 store_spreg( R_EDX, R_MACH ); // 6
2158 JS_rel8( 13, positive ); // 2
2159 load_imm32( R_EAX, 0x80000000 );// 5
2160 store_spreg( R_EAX, R_MACL ); // 6
2161 JMP_rel8( 25, end2 ); // 2
2163 JMP_TARGET(positive);
2164 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2165 store_spreg( R_EAX, R_MACL ); // 6
2166 JMP_rel8( 12, end3); // 2
2168 JMP_TARGET(nosat);
2169 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2170 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2171 JMP_TARGET(end);
2172 JMP_TARGET(end2);
2173 JMP_TARGET(end3);
2174 sh4_x86.tstate = TSTATE_NONE;
2175 }
2176 break;
2177 }
2178 break;
2179 case 0x5:
2180 { /* MOV.L @(disp, Rm), Rn */
2181 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2182 load_reg( R_EAX, Rm );
2183 ADD_imm8s_r32( disp, R_EAX );
2184 check_ralign32( R_EAX );
2185 MMU_TRANSLATE_READ( R_EAX );
2186 MEM_READ_LONG( R_EAX, R_EAX );
2187 store_reg( R_EAX, Rn );
2188 sh4_x86.tstate = TSTATE_NONE;
2189 }
2190 break;
2191 case 0x6:
2192 switch( ir&0xF ) {
2193 case 0x0:
2194 { /* MOV.B @Rm, Rn */
2195 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2196 load_reg( R_EAX, Rm );
2197 MMU_TRANSLATE_READ( R_EAX );
2198 MEM_READ_BYTE( R_EAX, R_EAX );
2199 store_reg( R_EAX, Rn );
2200 sh4_x86.tstate = TSTATE_NONE;
2201 }
2202 break;
2203 case 0x1:
2204 { /* MOV.W @Rm, Rn */
2205 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2206 load_reg( R_EAX, Rm );
2207 check_ralign16( R_EAX );
2208 MMU_TRANSLATE_READ( R_EAX );
2209 MEM_READ_WORD( R_EAX, R_EAX );
2210 store_reg( R_EAX, Rn );
2211 sh4_x86.tstate = TSTATE_NONE;
2212 }
2213 break;
2214 case 0x2:
2215 { /* MOV.L @Rm, Rn */
2216 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2217 load_reg( R_EAX, Rm );
2218 check_ralign32( R_EAX );
2219 MMU_TRANSLATE_READ( R_EAX );
2220 MEM_READ_LONG( R_EAX, R_EAX );
2221 store_reg( R_EAX, Rn );
2222 sh4_x86.tstate = TSTATE_NONE;
2223 }
2224 break;
2225 case 0x3:
2226 { /* MOV Rm, Rn */
2227 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2228 load_reg( R_EAX, Rm );
2229 store_reg( R_EAX, Rn );
2230 }
2231 break;
2232 case 0x4:
2233 { /* MOV.B @Rm+, Rn */
2234 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2235 load_reg( R_EAX, Rm );
2236 MMU_TRANSLATE_READ( R_EAX );
2237 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
2238 MEM_READ_BYTE( R_EAX, R_EAX );
2239 store_reg( R_EAX, Rn );
2240 sh4_x86.tstate = TSTATE_NONE;
2241 }
2242 break;
2243 case 0x5:
2244 { /* MOV.W @Rm+, Rn */
2245 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2246 load_reg( R_EAX, Rm );
2247 check_ralign16( R_EAX );
2248 MMU_TRANSLATE_READ( R_EAX );
2249 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2250 MEM_READ_WORD( R_EAX, R_EAX );
2251 store_reg( R_EAX, Rn );
2252 sh4_x86.tstate = TSTATE_NONE;
2253 }
2254 break;
2255 case 0x6:
2256 { /* MOV.L @Rm+, Rn */
2257 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2258 load_reg( R_EAX, Rm );
2259 check_ralign32( R_EAX );
2260 MMU_TRANSLATE_READ( R_EAX );
2261 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2262 MEM_READ_LONG( R_EAX, R_EAX );
2263 store_reg( R_EAX, Rn );
2264 sh4_x86.tstate = TSTATE_NONE;
2265 }
2266 break;
2267 case 0x7:
2268 { /* NOT Rm, Rn */
2269 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2270 load_reg( R_EAX, Rm );
2271 NOT_r32( R_EAX );
2272 store_reg( R_EAX, Rn );
2273 sh4_x86.tstate = TSTATE_NONE;
2274 }
2275 break;
2276 case 0x8:
2277 { /* SWAP.B Rm, Rn */
2278 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2279 load_reg( R_EAX, Rm );
2280 XCHG_r8_r8( R_AL, R_AH );
2281 store_reg( R_EAX, Rn );
2282 }
2283 break;
2284 case 0x9:
2285 { /* SWAP.W Rm, Rn */
2286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2287 load_reg( R_EAX, Rm );
2288 MOV_r32_r32( R_EAX, R_ECX );
2289 SHL_imm8_r32( 16, R_ECX );
2290 SHR_imm8_r32( 16, R_EAX );
2291 OR_r32_r32( R_EAX, R_ECX );
2292 store_reg( R_ECX, Rn );
2293 sh4_x86.tstate = TSTATE_NONE;
2294 }
2295 break;
2296 case 0xA:
2297 { /* NEGC Rm, Rn */
2298 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2299 load_reg( R_EAX, Rm );
2300 XOR_r32_r32( R_ECX, R_ECX );
2301 LDC_t();
2302 SBB_r32_r32( R_EAX, R_ECX );
2303 store_reg( R_ECX, Rn );
2304 SETC_t();
2305 sh4_x86.tstate = TSTATE_C;
2306 }
2307 break;
2308 case 0xB:
2309 { /* NEG Rm, Rn */
2310 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2311 load_reg( R_EAX, Rm );
2312 NEG_r32( R_EAX );
2313 store_reg( R_EAX, Rn );
2314 sh4_x86.tstate = TSTATE_NONE;
2315 }
2316 break;
2317 case 0xC:
2318 { /* EXTU.B Rm, Rn */
2319 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2320 load_reg( R_EAX, Rm );
2321 MOVZX_r8_r32( R_EAX, R_EAX );
2322 store_reg( R_EAX, Rn );
2323 }
2324 break;
2325 case 0xD:
2326 { /* EXTU.W Rm, Rn */
2327 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2328 load_reg( R_EAX, Rm );
2329 MOVZX_r16_r32( R_EAX, R_EAX );
2330 store_reg( R_EAX, Rn );
2331 }
2332 break;
2333 case 0xE:
2334 { /* EXTS.B Rm, Rn */
2335 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2336 load_reg( R_EAX, Rm );
2337 MOVSX_r8_r32( R_EAX, R_EAX );
2338 store_reg( R_EAX, Rn );
2339 }
2340 break;
2341 case 0xF:
2342 { /* EXTS.W Rm, Rn */
2343 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2344 load_reg( R_EAX, Rm );
2345 MOVSX_r16_r32( R_EAX, R_EAX );
2346 store_reg( R_EAX, Rn );
2347 }
2348 break;
2349 }
2350 break;
2351 case 0x7:
2352 { /* ADD #imm, Rn */
2353 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2354 load_reg( R_EAX, Rn );
2355 ADD_imm8s_r32( imm, R_EAX );
2356 store_reg( R_EAX, Rn );
2357 sh4_x86.tstate = TSTATE_NONE;
2358 }
2359 break;
2360 case 0x8:
2361 switch( (ir&0xF00) >> 8 ) {
2362 case 0x0:
2363 { /* MOV.B R0, @(disp, Rn) */
2364 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2365 load_reg( R_EAX, Rn );
2366 ADD_imm32_r32( disp, R_EAX );
2367 MMU_TRANSLATE_WRITE( R_EAX );
2368 load_reg( R_EDX, 0 );
2369 MEM_WRITE_BYTE( R_EAX, R_EDX );
2370 sh4_x86.tstate = TSTATE_NONE;
2371 }
2372 break;
2373 case 0x1:
2374 { /* MOV.W R0, @(disp, Rn) */
2375 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2376 load_reg( R_EAX, Rn );
2377 ADD_imm32_r32( disp, R_EAX );
2378 check_walign16( R_EAX );
2379 MMU_TRANSLATE_WRITE( R_EAX );
2380 load_reg( R_EDX, 0 );
2381 MEM_WRITE_WORD( R_EAX, R_EDX );
2382 sh4_x86.tstate = TSTATE_NONE;
2383 }
2384 break;
2385 case 0x4:
2386 { /* MOV.B @(disp, Rm), R0 */
2387 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2388 load_reg( R_EAX, Rm );
2389 ADD_imm32_r32( disp, R_EAX );
2390 MMU_TRANSLATE_READ( R_EAX );
2391 MEM_READ_BYTE( R_EAX, R_EAX );
2392 store_reg( R_EAX, 0 );
2393 sh4_x86.tstate = TSTATE_NONE;
2394 }
2395 break;
2396 case 0x5:
2397 { /* MOV.W @(disp, Rm), R0 */
2398 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2399 load_reg( R_EAX, Rm );
2400 ADD_imm32_r32( disp, R_EAX );
2401 check_ralign16( R_EAX );
2402 MMU_TRANSLATE_READ( R_EAX );
2403 MEM_READ_WORD( R_EAX, R_EAX );
2404 store_reg( R_EAX, 0 );
2405 sh4_x86.tstate = TSTATE_NONE;
2406 }
2407 break;
2408 case 0x8:
2409 { /* CMP/EQ #imm, R0 */
2410 int32_t imm = SIGNEXT8(ir&0xFF);
2411 load_reg( R_EAX, 0 );
2412 CMP_imm8s_r32(imm, R_EAX);
2413 SETE_t();
2414 sh4_x86.tstate = TSTATE_E;
2415 }
2416 break;
2417 case 0x9:
2418 { /* BT disp */
2419 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2420 if( sh4_x86.in_delay_slot ) {
2421 SLOTILLEGAL();
2422 } else {
2423 sh4vma_t target = disp + pc + 4;
2424 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2425 exit_block_rel(target, pc+2 );
2426 JMP_TARGET(nottaken);
2427 return 2;
2428 }
2429 }
2430 break;
2431 case 0xB:
2432 { /* BF disp */
2433 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2434 if( sh4_x86.in_delay_slot ) {
2435 SLOTILLEGAL();
2436 } else {
2437 sh4vma_t target = disp + pc + 4;
2438 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2439 exit_block_rel(target, pc+2 );
2440 JMP_TARGET(nottaken);
2441 return 2;
2442 }
2443 }
2444 break;
2445 case 0xD:
2446 { /* BT/S disp */
2447 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2448 if( sh4_x86.in_delay_slot ) {
2449 SLOTILLEGAL();
2450 } else {
2451 sh4_x86.in_delay_slot = DELAY_PC;
2452 if( sh4_x86.tstate == TSTATE_NONE ) {
2453 CMP_imm8s_sh4r( 1, R_T );
2454 sh4_x86.tstate = TSTATE_E;
2455 }
2456 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2457 sh4_translate_instruction(pc+2);
2458 exit_block_rel( disp + pc + 4, pc+4 );
2459 // not taken
2460 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2461 sh4_translate_instruction(pc+2);
2462 return 4;
2463 }
2464 }
2465 break;
2466 case 0xF:
2467 { /* BF/S disp */
2468 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2469 if( sh4_x86.in_delay_slot ) {
2470 SLOTILLEGAL();
2471 } else {
2472 sh4vma_t target = disp + pc + 4;
2473 sh4_x86.in_delay_slot = DELAY_PC;
2474 if( sh4_x86.tstate == TSTATE_NONE ) {
2475 CMP_imm8s_sh4r( 1, R_T );
2476 sh4_x86.tstate = TSTATE_E;
2477 }
2478 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2479 sh4_translate_instruction(pc+2);
2480 exit_block_rel( target, pc+4 );
2481 // not taken
2482 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2483 sh4_translate_instruction(pc+2);
2484 return 4;
2485 }
2486 }
2487 break;
2488 default:
2489 UNDEF();
2490 break;
2491 }
2492 break;
2493 case 0x9:
2494 { /* MOV.W @(disp, PC), Rn */
2495 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2496 if( sh4_x86.in_delay_slot ) {
2497 SLOTILLEGAL();
2498 } else {
2499 // See comments for MOV.L @(disp, PC), Rn
2500 uint32_t target = pc + disp + 4;
2501 if( IS_IN_ICACHE(target) ) {
2502 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2503 MOV_moff32_EAX( ptr );
2504 MOVSX_r16_r32( R_EAX, R_EAX );
2505 } else {
2506 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
2507 ADD_sh4r_r32( R_PC, R_EAX );
2508 MMU_TRANSLATE_READ( R_EAX );
2509 MEM_READ_WORD( R_EAX, R_EAX );
2510 sh4_x86.tstate = TSTATE_NONE;
2511 }
2512 store_reg( R_EAX, Rn );
2513 }
2514 }
2515 break;
2516 case 0xA:
2517 { /* BRA disp */
2518 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2519 if( sh4_x86.in_delay_slot ) {
2520 SLOTILLEGAL();
2521 } else {
2522 sh4_x86.in_delay_slot = DELAY_PC;
2523 sh4_translate_instruction( pc + 2 );
2524 exit_block_rel( disp + pc + 4, pc+4 );
2525 sh4_x86.branch_taken = TRUE;
2526 return 4;
2527 }
2528 }
2529 break;
2530 case 0xB:
2531 { /* BSR disp */
2532 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2533 if( sh4_x86.in_delay_slot ) {
2534 SLOTILLEGAL();
2535 } else {
2536 load_spreg( R_EAX, R_PC );
2537 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
2538 store_spreg( R_EAX, R_PR );
2539 sh4_x86.in_delay_slot = DELAY_PC;
2540 sh4_translate_instruction( pc + 2 );
2541 exit_block_rel( disp + pc + 4, pc+4 );
2542 sh4_x86.branch_taken = TRUE;
2543 return 4;
2544 }
2545 }
2546 break;
2547 case 0xC:
2548 switch( (ir&0xF00) >> 8 ) {
2549 case 0x0:
2550 { /* MOV.B R0, @(disp, GBR) */
2551 uint32_t disp = (ir&0xFF);
2552 load_spreg( R_EAX, R_GBR );
2553 ADD_imm32_r32( disp, R_EAX );
2554 MMU_TRANSLATE_WRITE( R_EAX );
2555 load_reg( R_EDX, 0 );
2556 MEM_WRITE_BYTE( R_EAX, R_EDX );
2557 sh4_x86.tstate = TSTATE_NONE;
2558 }
2559 break;
2560 case 0x1:
2561 { /* MOV.W R0, @(disp, GBR) */
2562 uint32_t disp = (ir&0xFF)<<1;
2563 load_spreg( R_EAX, R_GBR );
2564 ADD_imm32_r32( disp, R_EAX );
2565 check_walign16( R_EAX );
2566 MMU_TRANSLATE_WRITE( R_EAX );
2567 load_reg( R_EDX, 0 );
2568 MEM_WRITE_WORD( R_EAX, R_EDX );
2569 sh4_x86.tstate = TSTATE_NONE;
2570 }
2571 break;
2572 case 0x2:
2573 { /* MOV.L R0, @(disp, GBR) */
2574 uint32_t disp = (ir&0xFF)<<2;
2575 load_spreg( R_EAX, R_GBR );
2576 ADD_imm32_r32( disp, R_EAX );
2577 check_walign32( R_EAX );
2578 MMU_TRANSLATE_WRITE( R_EAX );
2579 load_reg( R_EDX, 0 );
2580 MEM_WRITE_LONG( R_EAX, R_EDX );
2581 sh4_x86.tstate = TSTATE_NONE;
2582 }
2583 break;
2584 case 0x3:
2585 { /* TRAPA #imm */
2586 uint32_t imm = (ir&0xFF);
2587 if( sh4_x86.in_delay_slot ) {
2588 SLOTILLEGAL();
2589 } else {
2590 load_imm32( R_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
2591 ADD_r32_sh4r( R_ECX, R_PC );
2592 load_imm32( R_EAX, imm );
2593 call_func1( sh4_raise_trap, R_EAX );
2594 sh4_x86.tstate = TSTATE_NONE;
2595 exit_block_pcset(pc);
2596 sh4_x86.branch_taken = TRUE;
2597 return 2;
2598 }
2599 }
2600 break;
2601 case 0x4:
2602 { /* MOV.B @(disp, GBR), R0 */
2603 uint32_t disp = (ir&0xFF);
2604 load_spreg( R_EAX, R_GBR );
2605 ADD_imm32_r32( disp, R_EAX );
2606 MMU_TRANSLATE_READ( R_EAX );
2607 MEM_READ_BYTE( R_EAX, R_EAX );
2608 store_reg( R_EAX, 0 );
2609 sh4_x86.tstate = TSTATE_NONE;
2610 }
2611 break;
2612 case 0x5:
2613 { /* MOV.W @(disp, GBR), R0 */
2614 uint32_t disp = (ir&0xFF)<<1;
2615 load_spreg( R_EAX, R_GBR );
2616 ADD_imm32_r32( disp, R_EAX );
2617 check_ralign16( R_EAX );
2618 MMU_TRANSLATE_READ( R_EAX );
2619 MEM_READ_WORD( R_EAX, R_EAX );
2620 store_reg( R_EAX, 0 );
2621 sh4_x86.tstate = TSTATE_NONE;
2622 }
2623 break;
2624 case 0x6:
2625 { /* MOV.L @(disp, GBR), R0 */
2626 uint32_t disp = (ir&0xFF)<<2;
2627 load_spreg( R_EAX, R_GBR );
2628 ADD_imm32_r32( disp, R_EAX );
2629 check_ralign32( R_EAX );
2630 MMU_TRANSLATE_READ( R_EAX );
2631 MEM_READ_LONG( R_EAX, R_EAX );
2632 store_reg( R_EAX, 0 );
2633 sh4_x86.tstate = TSTATE_NONE;
2634 }
2635 break;
2636 case 0x7:
2637 { /* MOVA @(disp, PC), R0 */
2638 uint32_t disp = (ir&0xFF)<<2;
2639 if( sh4_x86.in_delay_slot ) {
2640 SLOTILLEGAL();
2641 } else {
2642 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2643 ADD_sh4r_r32( R_PC, R_ECX );
2644 store_reg( R_ECX, 0 );
2645 sh4_x86.tstate = TSTATE_NONE;
2646 }
2647 }
2648 break;
2649 case 0x8:
2650 { /* TST #imm, R0 */
2651 uint32_t imm = (ir&0xFF);
2652 load_reg( R_EAX, 0 );
2653 TEST_imm32_r32( imm, R_EAX );
2654 SETE_t();
2655 sh4_x86.tstate = TSTATE_E;
2656 }
2657 break;
2658 case 0x9:
2659 { /* AND #imm, R0 */
2660 uint32_t imm = (ir&0xFF);
2661 load_reg( R_EAX, 0 );
2662 AND_imm32_r32(imm, R_EAX);
2663 store_reg( R_EAX, 0 );
2664 sh4_x86.tstate = TSTATE_NONE;
2665 }
2666 break;
2667 case 0xA:
2668 { /* XOR #imm, R0 */
2669 uint32_t imm = (ir&0xFF);
2670 load_reg( R_EAX, 0 );
2671 XOR_imm32_r32( imm, R_EAX );
2672 store_reg( R_EAX, 0 );
2673 sh4_x86.tstate = TSTATE_NONE;
2674 }
2675 break;
2676 case 0xB:
2677 { /* OR #imm, R0 */
2678 uint32_t imm = (ir&0xFF);
2679 load_reg( R_EAX, 0 );
2680 OR_imm32_r32(imm, R_EAX);
2681 store_reg( R_EAX, 0 );
2682 sh4_x86.tstate = TSTATE_NONE;
2683 }
2684 break;
2685 case 0xC:
2686 { /* TST.B #imm, @(R0, GBR) */
2687 uint32_t imm = (ir&0xFF);
2688 load_reg( R_EAX, 0);
2689 load_reg( R_ECX, R_GBR);
2690 ADD_r32_r32( R_ECX, R_EAX );
2691 MMU_TRANSLATE_READ( R_EAX );
2692 MEM_READ_BYTE( R_EAX, R_EAX );
2693 TEST_imm8_r8( imm, R_AL );
2694 SETE_t();
2695 sh4_x86.tstate = TSTATE_E;
2696 }
2697 break;
2698 case 0xD:
2699 { /* AND.B #imm, @(R0, GBR) */
2700 uint32_t imm = (ir&0xFF);
2701 load_reg( R_EAX, 0 );
2702 load_spreg( R_ECX, R_GBR );
2703 ADD_r32_r32( R_ECX, R_EAX );
2704 MMU_TRANSLATE_WRITE( R_EAX );
2705 PUSH_realigned_r32(R_EAX);
2706 MEM_READ_BYTE( R_EAX, R_EAX );
2707 POP_realigned_r32(R_ECX);
2708 AND_imm32_r32(imm, R_EAX );
2709 MEM_WRITE_BYTE( R_ECX, R_EAX );
2710 sh4_x86.tstate = TSTATE_NONE;
2711 }
2712 break;
2713 case 0xE:
2714 { /* XOR.B #imm, @(R0, GBR) */
2715 uint32_t imm = (ir&0xFF);
2716 load_reg( R_EAX, 0 );
2717 load_spreg( R_ECX, R_GBR );
2718 ADD_r32_r32( R_ECX, R_EAX );
2719 MMU_TRANSLATE_WRITE( R_EAX );
2720 PUSH_realigned_r32(R_EAX);
2721 MEM_READ_BYTE(R_EAX, R_EAX);
2722 POP_realigned_r32(R_ECX);
2723 XOR_imm32_r32( imm, R_EAX );
2724 MEM_WRITE_BYTE( R_ECX, R_EAX );
2725 sh4_x86.tstate = TSTATE_NONE;
2726 }
2727 break;
2728 case 0xF:
2729 { /* OR.B #imm, @(R0, GBR) */
2730 uint32_t imm = (ir&0xFF);
2731 load_reg( R_EAX, 0 );
2732 load_spreg( R_ECX, R_GBR );
2733 ADD_r32_r32( R_ECX, R_EAX );
2734 MMU_TRANSLATE_WRITE( R_EAX );
2735 PUSH_realigned_r32(R_EAX);
2736 MEM_READ_BYTE( R_EAX, R_EAX );
2737 POP_realigned_r32(R_ECX);
2738 OR_imm32_r32(imm, R_EAX );
2739 MEM_WRITE_BYTE( R_ECX, R_EAX );
2740 sh4_x86.tstate = TSTATE_NONE;
2741 }
2742 break;
2743 }
2744 break;
2745 case 0xD:
2746 { /* MOV.L @(disp, PC), Rn */
2747 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2748 if( sh4_x86.in_delay_slot ) {
2749 SLOTILLEGAL();
2750 } else {
2751 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2752 if( IS_IN_ICACHE(target) ) {
2753 // If the target address is in the same page as the code, it's
2754 // pretty safe to just ref it directly and circumvent the whole
2755 // memory subsystem. (this is a big performance win)
2757 // FIXME: There's a corner-case that's not handled here when
2758 // the current code-page is in the ITLB but not in the UTLB.
2759 // (should generate a TLB miss although need to test SH4
2760 // behaviour to confirm) Unlikely to be anyone depending on this
2761 // behaviour though.
2762 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2763 MOV_moff32_EAX( ptr );
2764 } else {
2765 // Note: we use sh4r.pc for the calc as we could be running at a
2766 // different virtual address than the translation was done with,
2767 // but we can safely assume that the low bits are the same.
2768 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2769 ADD_sh4r_r32( R_PC, R_EAX );
2770 MMU_TRANSLATE_READ( R_EAX );
2771 MEM_READ_LONG( R_EAX, R_EAX );
2772 sh4_x86.tstate = TSTATE_NONE;
2773 }
2774 store_reg( R_EAX, Rn );
2775 }
2776 }
2777 break;
2778 case 0xE:
2779 { /* MOV #imm, Rn */
2780 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2781 load_imm32( R_EAX, imm );
2782 store_reg( R_EAX, Rn );
2783 }
2784 break;
2785 case 0xF:
2786 switch( ir&0xF ) {
2787 case 0x0:
2788 { /* FADD FRm, FRn */
2789 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2790 check_fpuen();
2791 load_spreg( R_ECX, R_FPSCR );
2792 TEST_imm32_r32( FPSCR_PR, R_ECX );
2793 load_fr_bank( R_EDX );
2794 JNE_rel8(13,doubleprec);
2795 push_fr(R_EDX, FRm);
2796 push_fr(R_EDX, FRn);
2797 FADDP_st(1);
2798 pop_fr(R_EDX, FRn);
2799 JMP_rel8(11,end);
2800 JMP_TARGET(doubleprec);
2801 push_dr(R_EDX, FRm);
2802 push_dr(R_EDX, FRn);
2803 FADDP_st(1);
2804 pop_dr(R_EDX, FRn);
2805 JMP_TARGET(end);
2806 sh4_x86.tstate = TSTATE_NONE;
2807 }
2808 break;
2809 case 0x1:
2810 { /* FSUB FRm, FRn */
2811 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2812 check_fpuen();
2813 load_spreg( R_ECX, R_FPSCR );
2814 TEST_imm32_r32( FPSCR_PR, R_ECX );
2815 load_fr_bank( R_EDX );
2816 JNE_rel8(13, doubleprec);
2817 push_fr(R_EDX, FRn);
2818 push_fr(R_EDX, FRm);
2819 FSUBP_st(1);
2820 pop_fr(R_EDX, FRn);
2821 JMP_rel8(11, end);
2822 JMP_TARGET(doubleprec);
2823 push_dr(R_EDX, FRn);
2824 push_dr(R_EDX, FRm);
2825 FSUBP_st(1);
2826 pop_dr(R_EDX, FRn);
2827 JMP_TARGET(end);
2828 sh4_x86.tstate = TSTATE_NONE;
2829 }
2830 break;
2831 case 0x2:
2832 { /* FMUL FRm, FRn */
2833 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2834 check_fpuen();
2835 load_spreg( R_ECX, R_FPSCR );
2836 TEST_imm32_r32( FPSCR_PR, R_ECX );
2837 load_fr_bank( R_EDX );
2838 JNE_rel8(13, doubleprec);
2839 push_fr(R_EDX, FRm);
2840 push_fr(R_EDX, FRn);
2841 FMULP_st(1);
2842 pop_fr(R_EDX, FRn);
2843 JMP_rel8(11, end);
2844 JMP_TARGET(doubleprec);
2845 push_dr(R_EDX, FRm);
2846 push_dr(R_EDX, FRn);
2847 FMULP_st(1);
2848 pop_dr(R_EDX, FRn);
2849 JMP_TARGET(end);
2850 sh4_x86.tstate = TSTATE_NONE;
2851 }
2852 break;
2853 case 0x3:
2854 { /* FDIV FRm, FRn */
2855 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2856 check_fpuen();
2857 load_spreg( R_ECX, R_FPSCR );
2858 TEST_imm32_r32( FPSCR_PR, R_ECX );
2859 load_fr_bank( R_EDX );
2860 JNE_rel8(13, doubleprec);
2861 push_fr(R_EDX, FRn);
2862 push_fr(R_EDX, FRm);
2863 FDIVP_st(1);
2864 pop_fr(R_EDX, FRn);
2865 JMP_rel8(11, end);
2866 JMP_TARGET(doubleprec);
2867 push_dr(R_EDX, FRn);
2868 push_dr(R_EDX, FRm);
2869 FDIVP_st(1);
2870 pop_dr(R_EDX, FRn);
2871 JMP_TARGET(end);
2872 sh4_x86.tstate = TSTATE_NONE;
2873 }
2874 break;
2875 case 0x4:
2876 { /* FCMP/EQ FRm, FRn */
2877 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2878 check_fpuen();
2879 load_spreg( R_ECX, R_FPSCR );
2880 TEST_imm32_r32( FPSCR_PR, R_ECX );
2881 load_fr_bank( R_EDX );
2882 JNE_rel8(8, doubleprec);
2883 push_fr(R_EDX, FRm);
2884 push_fr(R_EDX, FRn);
2885 JMP_rel8(6, end);
2886 JMP_TARGET(doubleprec);
2887 push_dr(R_EDX, FRm);
2888 push_dr(R_EDX, FRn);
2889 JMP_TARGET(end);
2890 FCOMIP_st(1);
2891 SETE_t();
2892 FPOP_st();
2893 sh4_x86.tstate = TSTATE_NONE;
2894 }
2895 break;
2896 case 0x5:
2897 { /* FCMP/GT FRm, FRn */
2898 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2899 check_fpuen();
2900 load_spreg( R_ECX, R_FPSCR );
2901 TEST_imm32_r32( FPSCR_PR, R_ECX );
2902 load_fr_bank( R_EDX );
2903 JNE_rel8(8, doubleprec);
2904 push_fr(R_EDX, FRm);
2905 push_fr(R_EDX, FRn);
2906 JMP_rel8(6, end);
2907 JMP_TARGET(doubleprec);
2908 push_dr(R_EDX, FRm);
2909 push_dr(R_EDX, FRn);
2910 JMP_TARGET(end);
2911 FCOMIP_st(1);
2912 SETA_t();
2913 FPOP_st();
2914 sh4_x86.tstate = TSTATE_NONE;
2915 }
2916 break;
2917 case 0x6:
2918 { /* FMOV @(R0, Rm), FRn */
2919 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2920 check_fpuen();
2921 load_reg( R_EAX, Rm );
2922 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2923 check_ralign32( R_EAX );
2924 MMU_TRANSLATE_READ( R_EAX );
2925 load_spreg( R_EDX, R_FPSCR );
2926 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2927 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2928 MEM_READ_LONG( R_EAX, R_EAX );
2929 load_fr_bank( R_EDX );
2930 store_fr( R_EDX, R_EAX, FRn );
2931 if( FRn&1 ) {
2932 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2933 JMP_TARGET(doublesize);
2934 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2935 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2936 load_xf_bank( R_EDX );
2937 store_fr( R_EDX, R_ECX, FRn&0x0E );
2938 store_fr( R_EDX, R_EAX, FRn|0x01 );
2939 JMP_TARGET(end);
2940 } else {
2941 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2942 JMP_TARGET(doublesize);
2943 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2944 load_fr_bank( R_EDX );
2945 store_fr( R_EDX, R_ECX, FRn&0x0E );
2946 store_fr( R_EDX, R_EAX, FRn|0x01 );
2947 JMP_TARGET(end);
2948 }
2949 sh4_x86.tstate = TSTATE_NONE;
2950 }
2951 break;
2952 case 0x7:
2953 { /* FMOV FRm, @(R0, Rn) */
2954 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2955 check_fpuen();
2956 load_reg( R_EAX, Rn );
2957 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2958 check_walign32( R_EAX );
2959 MMU_TRANSLATE_WRITE( R_EAX );
2960 load_spreg( R_EDX, R_FPSCR );
2961 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2962 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
2963 load_fr_bank( R_EDX );
2964 load_fr( R_EDX, R_ECX, FRm );
2965 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
2966 if( FRm&1 ) {
2967 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
2968 JMP_TARGET(doublesize);
2969 load_xf_bank( R_EDX );
2970 load_fr( R_EDX, R_ECX, FRm&0x0E );
2971 load_fr( R_EDX, R_EDX, FRm|0x01 );
2972 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2973 JMP_TARGET(end);
2974 } else {
2975 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
2976 JMP_TARGET(doublesize);
2977 load_fr_bank( R_EDX );
2978 load_fr( R_EDX, R_ECX, FRm&0x0E );
2979 load_fr( R_EDX, R_EDX, FRm|0x01 );
2980 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2981 JMP_TARGET(end);
2982 }
2983 sh4_x86.tstate = TSTATE_NONE;
2984 }
2985 break;
2986 case 0x8:
2987 { /* FMOV @Rm, FRn */
2988 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2989 check_fpuen();
2990 load_reg( R_EAX, Rm );
2991 check_ralign32( R_EAX );
2992 MMU_TRANSLATE_READ( R_EAX );
2993 load_spreg( R_EDX, R_FPSCR );
2994 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2995 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2996 MEM_READ_LONG( R_EAX, R_EAX );
2997 load_fr_bank( R_EDX );
2998 store_fr( R_EDX, R_EAX, FRn );
2999 if( FRn&1 ) {
3000 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
3001 JMP_TARGET(doublesize);
3002 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3003 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3004 load_xf_bank( R_EDX );
3005 store_fr( R_EDX, R_ECX, FRn&0x0E );
3006 store_fr( R_EDX, R_EAX, FRn|0x01 );
3007 JMP_TARGET(end);
3008 } else {
3009 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
3010 JMP_TARGET(doublesize);
3011 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3012 load_fr_bank( R_EDX );
3013 store_fr( R_EDX, R_ECX, FRn&0x0E );
3014 store_fr( R_EDX, R_EAX, FRn|0x01 );
3015 JMP_TARGET(end);
3016 }
3017 sh4_x86.tstate = TSTATE_NONE;
3018 }
3019 break;
3020 case 0x9:
3021 { /* FMOV @Rm+, FRn */
3022 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3023 check_fpuen();
3024 load_reg( R_EAX, Rm );
3025 check_ralign32( R_EAX );
3026 MMU_TRANSLATE_READ( R_EAX );
3027 load_spreg( R_EDX, R_FPSCR );
3028 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3029 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
3030 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
3031 MEM_READ_LONG( R_EAX, R_EAX );
3032 load_fr_bank( R_EDX );
3033 store_fr( R_EDX, R_EAX, FRn );
3034 if( FRn&1 ) {
3035 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
3036 JMP_TARGET(doublesize);
3037 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3038 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3039 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3040 load_xf_bank( R_EDX );
3041 store_fr( R_EDX, R_ECX, FRn&0x0E );
3042 store_fr( R_EDX, R_EAX, FRn|0x01 );
3043 JMP_TARGET(end);
3044 } else {
3045 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
3046 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3047 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3048 load_fr_bank( R_EDX );
3049 store_fr( R_EDX, R_ECX, FRn&0x0E );
3050 store_fr( R_EDX, R_EAX, FRn|0x01 );
3051 JMP_TARGET(end);
3052 }
3053 sh4_x86.tstate = TSTATE_NONE;
3054 }
3055 break;
3056 case 0xA:
3057 { /* FMOV FRm, @Rn */
3058 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3059 check_fpuen();
3060 load_reg( R_EAX, Rn );
3061 check_walign32( R_EAX );
3062 MMU_TRANSLATE_WRITE( R_EAX );
3063 load_spreg( R_EDX, R_FPSCR );
3064 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3065 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
3066 load_fr_bank( R_EDX );
3067 load_fr( R_EDX, R_ECX, FRm );
3068 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3069 if( FRm&1 ) {
3070 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3071 JMP_TARGET(doublesize);
3072 load_xf_bank( R_EDX );
3073 load_fr( R_EDX, R_ECX, FRm&0x0E );
3074 load_fr( R_EDX, R_EDX, FRm|0x01 );
3075 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3076 JMP_TARGET(end);
3077 } else {
3078 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3079 JMP_TARGET(doublesize);
3080 load_fr_bank( R_EDX );
3081 load_fr( R_EDX, R_ECX, FRm&0x0E );
3082 load_fr( R_EDX, R_EDX, FRm|0x01 );
3083 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3084 JMP_TARGET(end);
3085 }
3086 sh4_x86.tstate = TSTATE_NONE;
3087 }
3088 break;
3089 case 0xB:
3090 { /* FMOV FRm, @-Rn */
3091 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3092 check_fpuen();
3093 load_reg( R_EAX, Rn );
3094 check_walign32( R_EAX );
3095 load_spreg( R_EDX, R_FPSCR );
3096 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3097 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
3098 ADD_imm8s_r32( -4, R_EAX );
3099 MMU_TRANSLATE_WRITE( R_EAX );
3100 load_fr_bank( R_EDX );
3101 load_fr( R_EDX, R_ECX, FRm );
3102 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
3103 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3104 if( FRm&1 ) {
3105 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3106 JMP_TARGET(doublesize);
3107 ADD_imm8s_r32(-8,R_EAX);
3108 MMU_TRANSLATE_WRITE( R_EAX );
3109 load_xf_bank( R_EDX );
3110 load_fr( R_EDX, R_ECX, FRm&0x0E );
3111 load_fr( R_EDX, R_EDX, FRm|0x01 );
3112 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3113 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3114 JMP_TARGET(end);
3115 } else {
3116 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3117 JMP_TARGET(doublesize);
3118 ADD_imm8s_r32(-8,R_EAX);
3119 MMU_TRANSLATE_WRITE( R_EAX );
3120 load_fr_bank( R_EDX );
3121 load_fr( R_EDX, R_ECX, FRm&0x0E );
3122 load_fr( R_EDX, R_EDX, FRm|0x01 );
3123 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3124 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3125 JMP_TARGET(end);
3126 }
3127 sh4_x86.tstate = TSTATE_NONE;
3128 }
3129 break;
3130 case 0xC:
3131 { /* FMOV FRm, FRn */
3132 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3133 /* As horrible as this looks, it's actually covering 5 separate cases:
3134 * 1. 32-bit fr-to-fr (PR=0)
3135 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3136 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3137 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3138 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3139 */
3140 check_fpuen();
3141 load_spreg( R_ECX, R_FPSCR );
3142 load_fr_bank( R_EDX );
3143 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3144 JNE_rel8(8, doublesize);
3145 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3146 store_fr( R_EDX, R_EAX, FRn );
3147 if( FRm&1 ) {
3148 JMP_rel8(24, end);
3149 JMP_TARGET(doublesize);
3150 load_xf_bank( R_ECX );
3151 load_fr( R_ECX, R_EAX, FRm-1 );
3152 if( FRn&1 ) {
3153 load_fr( R_ECX, R_EDX, FRm );
3154 store_fr( R_ECX, R_EAX, FRn-1 );
3155 store_fr( R_ECX, R_EDX, FRn );
3156 } else /* FRn&1 == 0 */ {
3157 load_fr( R_ECX, R_ECX, FRm );
3158 store_fr( R_EDX, R_EAX, FRn );
3159 store_fr( R_EDX, R_ECX, FRn+1 );
3160 }
3161 JMP_TARGET(end);
3162 } else /* FRm&1 == 0 */ {
3163 if( FRn&1 ) {
3164 JMP_rel8(24, end);
3165 load_xf_bank( R_ECX );
3166 load_fr( R_EDX, R_EAX, FRm );
3167 load_fr( R_EDX, R_EDX, FRm+1 );
3168 store_fr( R_ECX, R_EAX, FRn-1 );
3169 store_fr( R_ECX, R_EDX, FRn );
3170 JMP_TARGET(end);
3171 } else /* FRn&1 == 0 */ {
3172 JMP_rel8(12, end);
3173 load_fr( R_EDX, R_EAX, FRm );
3174 load_fr( R_EDX, R_ECX, FRm+1 );
3175 store_fr( R_EDX, R_EAX, FRn );
3176 store_fr( R_EDX, R_ECX, FRn+1 );
3177 JMP_TARGET(end);
3178 }
3179 }
3180 sh4_x86.tstate = TSTATE_NONE;
3181 }
3182 break;
3183 case 0xD:
3184 switch( (ir&0xF0) >> 4 ) {
3185 case 0x0:
3186 { /* FSTS FPUL, FRn */
3187 uint32_t FRn = ((ir>>8)&0xF);
3188 check_fpuen();
3189 load_fr_bank( R_ECX );
3190 load_spreg( R_EAX, R_FPUL );
3191 store_fr( R_ECX, R_EAX, FRn );
3192 sh4_x86.tstate = TSTATE_NONE;
3193 }
3194 break;
3195 case 0x1:
3196 { /* FLDS FRm, FPUL */
3197 uint32_t FRm = ((ir>>8)&0xF);
3198 check_fpuen();
3199 load_fr_bank( R_ECX );
3200 load_fr( R_ECX, R_EAX, FRm );
3201 store_spreg( R_EAX, R_FPUL );
3202 sh4_x86.tstate = TSTATE_NONE;
3203 }
3204 break;
3205 case 0x2:
3206 { /* FLOAT FPUL, FRn */
3207 uint32_t FRn = ((ir>>8)&0xF);
3208 check_fpuen();
3209 load_spreg( R_ECX, R_FPSCR );
3210 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3211 FILD_sh4r(R_FPUL);
3212 TEST_imm32_r32( FPSCR_PR, R_ECX );
3213 JNE_rel8(5, doubleprec);
3214 pop_fr( R_EDX, FRn );
3215 JMP_rel8(3, end);
3216 JMP_TARGET(doubleprec);
3217 pop_dr( R_EDX, FRn );
3218 JMP_TARGET(end);
3219 sh4_x86.tstate = TSTATE_NONE;
3220 }
3221 break;
3222 case 0x3:
3223 { /* FTRC FRm, FPUL */
3224 uint32_t FRm = ((ir>>8)&0xF);
3225 check_fpuen();
3226 load_spreg( R_ECX, R_FPSCR );
3227 load_fr_bank( R_EDX );
3228 TEST_imm32_r32( FPSCR_PR, R_ECX );
3229 JNE_rel8(5, doubleprec);
3230 push_fr( R_EDX, FRm );
3231 JMP_rel8(3, doop);
3232 JMP_TARGET(doubleprec);
3233 push_dr( R_EDX, FRm );
3234 JMP_TARGET( doop );
3235 load_imm32( R_ECX, (uint32_t)&max_int );
3236 FILD_r32ind( R_ECX );
3237 FCOMIP_st(1);
3238 JNA_rel8( 32, sat );
3239 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3240 FILD_r32ind( R_ECX ); // 2
3241 FCOMIP_st(1); // 2
3242 JAE_rel8( 21, sat2 ); // 2
3243 load_imm32( R_EAX, (uint32_t)&save_fcw );
3244 FNSTCW_r32ind( R_EAX );
3245 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3246 FLDCW_r32ind( R_EDX );
3247 FISTP_sh4r(R_FPUL); // 3
3248 FLDCW_r32ind( R_EAX );
3249 JMP_rel8( 9, end ); // 2
3251 JMP_TARGET(sat);
3252 JMP_TARGET(sat2);
3253 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3254 store_spreg( R_ECX, R_FPUL );
3255 FPOP_st();
3256 JMP_TARGET(end);
3257 sh4_x86.tstate = TSTATE_NONE;
3258 }
3259 break;
3260 case 0x4:
3261 { /* FNEG FRn */
3262 uint32_t FRn = ((ir>>8)&0xF);
3263 check_fpuen();
3264 load_spreg( R_ECX, R_FPSCR );
3265 TEST_imm32_r32( FPSCR_PR, R_ECX );
3266 load_fr_bank( R_EDX );
3267 JNE_rel8(10, doubleprec);
3268 push_fr(R_EDX, FRn);
3269 FCHS_st0();
3270 pop_fr(R_EDX, FRn);
3271 JMP_rel8(8, end);
3272 JMP_TARGET(doubleprec);
3273 push_dr(R_EDX, FRn);
3274 FCHS_st0();
3275 pop_dr(R_EDX, FRn);
3276 JMP_TARGET(end);
3277 sh4_x86.tstate = TSTATE_NONE;
3278 }
3279 break;
3280 case 0x5:
3281 { /* FABS FRn */
3282 uint32_t FRn = ((ir>>8)&0xF);
3283 check_fpuen();
3284 load_spreg( R_ECX, R_FPSCR );
3285 load_fr_bank( R_EDX );
3286 TEST_imm32_r32( FPSCR_PR, R_ECX );
3287 JNE_rel8(10, doubleprec);
3288 push_fr(R_EDX, FRn); // 3
3289 FABS_st0(); // 2
3290 pop_fr( R_EDX, FRn); //3
3291 JMP_rel8(8,end); // 2
3292 JMP_TARGET(doubleprec);
3293 push_dr(R_EDX, FRn);
3294 FABS_st0();
3295 pop_dr(R_EDX, FRn);
3296 JMP_TARGET(end);
3297 sh4_x86.tstate = TSTATE_NONE;
3298 }
3299 break;
3300 case 0x6:
3301 { /* FSQRT FRn */
3302 uint32_t FRn = ((ir>>8)&0xF);
3303 check_fpuen();
3304 load_spreg( R_ECX, R_FPSCR );
3305 TEST_imm32_r32( FPSCR_PR, R_ECX );
3306 load_fr_bank( R_EDX );
3307 JNE_rel8(10, doubleprec);
3308 push_fr(R_EDX, FRn);
3309 FSQRT_st0();
3310 pop_fr(R_EDX, FRn);
3311 JMP_rel8(8, end);
3312 JMP_TARGET(doubleprec);
3313 push_dr(R_EDX, FRn);
3314 FSQRT_st0();
3315 pop_dr(R_EDX, FRn);
3316 JMP_TARGET(end);
3317 sh4_x86.tstate = TSTATE_NONE;
3318 }
3319 break;
3320 case 0x7:
3321 { /* FSRRA FRn */
3322 uint32_t FRn = ((ir>>8)&0xF);
3323 check_fpuen();
3324 load_spreg( R_ECX, R_FPSCR );
3325 TEST_imm32_r32( FPSCR_PR, R_ECX );
3326 load_fr_bank( R_EDX );
3327 JNE_rel8(12, end); // PR=0 only
3328 FLD1_st0();
3329 push_fr(R_EDX, FRn);
3330 FSQRT_st0();
3331 FDIVP_st(1);
3332 pop_fr(R_EDX, FRn);
3333 JMP_TARGET(end);
3334 sh4_x86.tstate = TSTATE_NONE;
3335 }
3336 break;
3337 case 0x8:
3338 { /* FLDI0 FRn */
3339 uint32_t FRn = ((ir>>8)&0xF);
3340 /* IFF PR=0 */
3341 check_fpuen();
3342 load_spreg( R_ECX, R_FPSCR );
3343 TEST_imm32_r32( FPSCR_PR, R_ECX );
3344 JNE_rel8(8, end);
3345 XOR_r32_r32( R_EAX, R_EAX );
3346 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3347 store_fr( R_ECX, R_EAX, FRn );
3348 JMP_TARGET(end);
3349 sh4_x86.tstate = TSTATE_NONE;
3350 }
3351 break;
3352 case 0x9:
3353 { /* FLDI1 FRn */
3354 uint32_t FRn = ((ir>>8)&0xF);
3355 /* IFF PR=0 */
3356 check_fpuen();
3357 load_spreg( R_ECX, R_FPSCR );
3358 TEST_imm32_r32( FPSCR_PR, R_ECX );
3359 JNE_rel8(11, end);
3360 load_imm32(R_EAX, 0x3F800000);
3361 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3362 store_fr( R_ECX, R_EAX, FRn );
3363 JMP_TARGET(end);
3364 sh4_x86.tstate = TSTATE_NONE;
3365 }
3366 break;
3367 case 0xA:
3368 { /* FCNVSD FPUL, FRn */
3369 uint32_t FRn = ((ir>>8)&0xF);
3370 check_fpuen();
3371 load_spreg( R_ECX, R_FPSCR );
3372 TEST_imm32_r32( FPSCR_PR, R_ECX );
3373 JE_rel8(9, end); // only when PR=1
3374 load_fr_bank( R_ECX );
3375 push_fpul();
3376 pop_dr( R_ECX, FRn );
3377 JMP_TARGET(end);
3378 sh4_x86.tstate = TSTATE_NONE;
3379 }
3380 break;
3381 case 0xB:
3382 { /* FCNVDS FRm, FPUL */
3383 uint32_t FRm = ((ir>>8)&0xF);
3384 check_fpuen();
3385 load_spreg( R_ECX, R_FPSCR );
3386 TEST_imm32_r32( FPSCR_PR, R_ECX );
3387 JE_rel8(9, end); // only when PR=1
3388 load_fr_bank( R_ECX );
3389 push_dr( R_ECX, FRm );
3390 pop_fpul();
3391 JMP_TARGET(end);
3392 sh4_x86.tstate = TSTATE_NONE;
3393 }
3394 break;
3395 case 0xE:
3396 { /* FIPR FVm, FVn */
3397 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3398 check_fpuen();
3399 load_spreg( R_ECX, R_FPSCR );
3400 TEST_imm32_r32( FPSCR_PR, R_ECX );
3401 JNE_rel8(44, doubleprec);
3403 load_fr_bank( R_ECX );
3404 push_fr( R_ECX, FVm<<2 );
3405 push_fr( R_ECX, FVn<<2 );
3406 FMULP_st(1);
3407 push_fr( R_ECX, (FVm<<2)+1);
3408 push_fr( R_ECX, (FVn<<2)+1);
3409 FMULP_st(1);
3410 FADDP_st(1);
3411 push_fr( R_ECX, (FVm<<2)+2);
3412 push_fr( R_ECX, (FVn<<2)+2);
3413 FMULP_st(1);
3414 FADDP_st(1);
3415 push_fr( R_ECX, (FVm<<2)+3);
3416 push_fr( R_ECX, (FVn<<2)+3);
3417 FMULP_st(1);
3418 FADDP_st(1);
3419 pop_fr( R_ECX, (FVn<<2)+3);
3420 JMP_TARGET(doubleprec);
3421 sh4_x86.tstate = TSTATE_NONE;
3422 }
3423 break;
3424 case 0xF:
3425 switch( (ir&0x100) >> 8 ) {
3426 case 0x0:
3427 { /* FSCA FPUL, FRn */
3428 uint32_t FRn = ((ir>>9)&0x7)<<1;
3429 check_fpuen();
3430 load_spreg( R_ECX, R_FPSCR );
3431 TEST_imm32_r32( FPSCR_PR, R_ECX );
3432 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3433 load_fr_bank( R_ECX );
3434 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3435 load_spreg( R_EDX, R_FPUL );
3436 call_func2( sh4_fsca, R_EDX, R_ECX );
3437 JMP_TARGET(doubleprec);
3438 sh4_x86.tstate = TSTATE_NONE;
3439 }
3440 break;
3441 case 0x1:
3442 switch( (ir&0x200) >> 9 ) {
3443 case 0x0:
3444 { /* FTRV XMTRX, FVn */
3445 uint32_t FVn = ((ir>>10)&0x3);
3446 check_fpuen();
3447 load_spreg( R_ECX, R_FPSCR );
3448 TEST_imm32_r32( FPSCR_PR, R_ECX );
3449 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3450 load_fr_bank( R_EDX ); // 3
3451 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3452 load_xf_bank( R_ECX ); // 12
3453 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3454 JMP_TARGET(doubleprec);
3455 sh4_x86.tstate = TSTATE_NONE;
3456 }
3457 break;
3458 case 0x1:
3459 switch( (ir&0xC00) >> 10 ) {
3460 case 0x0:
3461 { /* FSCHG */
3462 check_fpuen();
3463 load_spreg( R_ECX, R_FPSCR );
3464 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3465 store_spreg( R_ECX, R_FPSCR );
3466 sh4_x86.tstate = TSTATE_NONE;
3467 }
3468 break;
3469 case 0x2:
3470 { /* FRCHG */
3471 check_fpuen();
3472 load_spreg( R_ECX, R_FPSCR );
3473 XOR_imm32_r32( FPSCR_FR, R_ECX );
3474 store_spreg( R_ECX, R_FPSCR );
3475 update_fr_bank( R_ECX );
3476 sh4_x86.tstate = TSTATE_NONE;
3477 }
3478 break;
3479 case 0x3:
3480 { /* UNDEF */
3481 if( sh4_x86.in_delay_slot ) {
3482 SLOTILLEGAL();
3483 } else {
3484 JMP_exc(EXC_ILLEGAL);
3485 return 2;
3486 }
3487 }
3488 break;
3489 default:
3490 UNDEF();
3491 break;
3492 }
3493 break;
3494 }
3495 break;
3496 }
3497 break;
3498 default:
3499 UNDEF();
3500 break;
3501 }
3502 break;
3503 case 0xE:
3504 { /* FMAC FR0, FRm, FRn */
3505 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3506 check_fpuen();
3507 load_spreg( R_ECX, R_FPSCR );
3508 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3509 TEST_imm32_r32( FPSCR_PR, R_ECX );
3510 JNE_rel8(18, doubleprec);
3511 push_fr( R_EDX, 0 );
3512 push_fr( R_EDX, FRm );
3513 FMULP_st(1);
3514 push_fr( R_EDX, FRn );
3515 FADDP_st(1);
3516 pop_fr( R_EDX, FRn );
3517 JMP_rel8(16, end);
3518 JMP_TARGET(doubleprec);
3519 push_dr( R_EDX, 0 );
3520 push_dr( R_EDX, FRm );
3521 FMULP_st(1);
3522 push_dr( R_EDX, FRn );
3523 FADDP_st(1);
3524 pop_dr( R_EDX, FRn );
3525 JMP_TARGET(end);
3526 sh4_x86.tstate = TSTATE_NONE;
3527 }
3528 break;
3529 default:
3530 UNDEF();
3531 break;
3532 }
3533 break;
3534 }
3536 sh4_x86.in_delay_slot = DELAY_NONE;
3537 return 0;
3538 }
.