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.
8 * Copyright (c) 2007 Nathan Keynes.
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.
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.
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"
35 #define DEFAULT_BACKPATCH_SIZE 4096
37 struct backpatch_record {
39 uint32_t fixup_icount;
43 #define MAX_RECOVERY_SIZE 2048
46 * Struct to manage internal translation state. This state is not saved -
47 * it is only valid between calls to sh4_translate_begin_block() and
48 * sh4_translate_end_block()
50 struct sh4_x86_state {
51 gboolean in_delay_slot;
52 gboolean priv_checked; /* true if we've already checked the cpu mode. */
53 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
54 gboolean branch_taken; /* true if we branched unconditionally */
55 uint32_t block_start_pc;
56 uint32_t stack_posn; /* Trace stack height for alignment purposes */
60 gboolean tlb_on; /* True if tlb translation is active */
62 /* Allocated memory for the (block-wide) back-patch list */
63 struct backpatch_record *backpatch_list;
64 uint32_t backpatch_posn;
65 uint32_t backpatch_size;
66 struct xlat_recovery_record recovery_list[MAX_RECOVERY_SIZE];
67 uint32_t recovery_posn;
70 #define TSTATE_NONE -1
80 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
81 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
82 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
83 OP(0x70+sh4_x86.tstate); OP(rel8); \
85 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
86 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
87 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
88 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
91 static struct sh4_x86_state sh4_x86;
93 static uint32_t max_int = 0x7FFFFFFF;
94 static uint32_t min_int = 0x80000000;
95 static uint32_t save_fcw; /* save value for fpu control word */
96 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
100 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
101 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
105 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
107 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
108 sh4_x86.backpatch_size <<= 1;
109 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
110 sh4_x86.backpatch_size * sizeof(struct backpatch_record));
111 assert( sh4_x86.backpatch_list != NULL );
113 if( sh4_x86.in_delay_slot ) {
116 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;
117 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
118 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
119 sh4_x86.backpatch_posn++;
122 void sh4_x86_add_recovery( uint32_t pc )
124 xlat_recovery[xlat_recovery_posn].xlat_pc = (uintptr_t)xlat_output;
125 xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;
126 xlat_recovery_posn++;
130 * Emit an instruction to load an SH4 reg into a real register
132 static inline void load_reg( int x86reg, int sh4reg )
134 /* mov [bp+n], reg */
136 OP(0x45 + (x86reg<<3));
137 OP(REG_OFFSET(r[sh4reg]));
140 static inline void load_reg16s( int x86reg, int sh4reg )
144 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
147 static inline void load_reg16u( int x86reg, int sh4reg )
151 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
155 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
156 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
158 * Emit an instruction to load an immediate value into a register
160 static inline void load_imm32( int x86reg, uint32_t value ) {
161 /* mov #value, reg */
167 * Load an immediate 64-bit quantity (note: x86-64 only)
169 static inline void load_imm64( int x86reg, uint32_t value ) {
170 /* mov #value, reg */
178 * Emit an instruction to store an SH4 reg (RN)
180 void static inline store_reg( int x86reg, int sh4reg ) {
181 /* mov reg, [bp+n] */
183 OP(0x45 + (x86reg<<3));
184 OP(REG_OFFSET(r[sh4reg]));
187 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
190 * Load an FR register (single-precision floating point) into an integer x86
191 * register (eg for register-to-register moves)
193 void static inline load_fr( int bankreg, int x86reg, int frm )
195 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
199 * Store an FR register (single-precision floating point) into an integer x86
200 * register (eg for register-to-register moves)
202 void static inline store_fr( int bankreg, int x86reg, int frn )
204 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
209 * Load a pointer to the back fp back into the specified x86 register. The
210 * bankreg must have been previously loaded with FPSCR.
213 static inline void load_xf_bank( int bankreg )
216 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
217 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
218 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
222 * Update the fr_bank pointer based on the current fpscr value.
224 static inline void update_fr_bank( int fpscrreg )
226 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
227 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
228 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
229 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
232 * Push FPUL (as a 32-bit float) onto the FPU stack
234 static inline void push_fpul( )
236 OP(0xD9); OP(0x45); OP(R_FPUL);
240 * Pop FPUL (as a 32-bit float) from the FPU stack
242 static inline void pop_fpul( )
244 OP(0xD9); OP(0x5D); OP(R_FPUL);
248 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
249 * with the location of the current fp bank.
251 static inline void push_fr( int bankreg, int frm )
253 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
257 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
258 * with bankreg previously loaded with the location of the current fp bank.
260 static inline void pop_fr( int bankreg, int frm )
262 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
266 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
267 * with the location of the current fp bank.
269 static inline void push_dr( int bankreg, int frm )
271 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
274 static inline void pop_dr( int bankreg, int frm )
276 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
279 /* Exception checks - Note that all exception checks will clobber EAX */
281 #define check_priv( ) \
282 if( !sh4_x86.priv_checked ) { \
283 sh4_x86.priv_checked = TRUE;\
284 load_spreg( R_EAX, R_SR );\
285 AND_imm32_r32( SR_MD, R_EAX );\
286 if( sh4_x86.in_delay_slot ) {\
287 JE_exc( EXC_SLOT_ILLEGAL );\
289 JE_exc( EXC_ILLEGAL );\
293 #define check_fpuen( ) \
294 if( !sh4_x86.fpuen_checked ) {\
295 sh4_x86.fpuen_checked = TRUE;\
296 load_spreg( R_EAX, R_SR );\
297 AND_imm32_r32( SR_FD, R_EAX );\
298 if( sh4_x86.in_delay_slot ) {\
299 JNE_exc(EXC_SLOT_FPU_DISABLED);\
301 JNE_exc(EXC_FPU_DISABLED);\
305 #define check_ralign16( x86reg ) \
306 TEST_imm32_r32( 0x00000001, x86reg ); \
307 JNE_exc(EXC_DATA_ADDR_READ)
309 #define check_walign16( x86reg ) \
310 TEST_imm32_r32( 0x00000001, x86reg ); \
311 JNE_exc(EXC_DATA_ADDR_WRITE);
313 #define check_ralign32( x86reg ) \
314 TEST_imm32_r32( 0x00000003, x86reg ); \
315 JNE_exc(EXC_DATA_ADDR_READ)
317 #define check_walign32( x86reg ) \
318 TEST_imm32_r32( 0x00000003, x86reg ); \
319 JNE_exc(EXC_DATA_ADDR_WRITE);
322 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
323 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
324 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
325 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
326 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
327 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
328 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
331 * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
332 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
334 #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); }
336 * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
337 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
339 #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); }
341 #define MEM_READ_SIZE (CALL_FUNC1_SIZE)
342 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
343 #define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
345 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
347 /****** Import appropriate calling conventions ******/
348 #if SH4_TRANSLATOR == TARGET_X86_64
349 #include "sh4/ia64abi.h"
350 #else /* SH4_TRANSLATOR == TARGET_X86 */
352 #include "sh4/ia32mac.h"
354 #include "sh4/ia32abi.h"
360 * Translate a single instruction. Delayed branches are handled specially
361 * by translating both branch and delayed instruction as a single unit (as
364 * @return true if the instruction marks the end of a basic block
367 uint32_t sh4_translate_instruction( sh4addr_t pc )
370 /* Read instruction */
371 if( IS_IN_ICACHE(pc) ) {
372 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
374 ir = sh4_read_word(pc);
376 if( !sh4_x86.in_delay_slot ) {
377 sh4_x86_add_recovery(pc);
379 switch( (ir&0xF000) >> 12 ) {
383 switch( (ir&0x80) >> 7 ) {
385 switch( (ir&0x70) >> 4 ) {
388 uint32_t Rn = ((ir>>8)&0xF);
390 call_func0(sh4_read_sr);
391 store_reg( R_EAX, Rn );
392 sh4_x86.tstate = TSTATE_NONE;
397 uint32_t Rn = ((ir>>8)&0xF);
398 load_spreg( R_EAX, R_GBR );
399 store_reg( R_EAX, Rn );
404 uint32_t Rn = ((ir>>8)&0xF);
406 load_spreg( R_EAX, R_VBR );
407 store_reg( R_EAX, Rn );
408 sh4_x86.tstate = TSTATE_NONE;
413 uint32_t Rn = ((ir>>8)&0xF);
415 load_spreg( R_EAX, R_SSR );
416 store_reg( R_EAX, Rn );
417 sh4_x86.tstate = TSTATE_NONE;
422 uint32_t Rn = ((ir>>8)&0xF);
424 load_spreg( R_EAX, R_SPC );
425 store_reg( R_EAX, Rn );
426 sh4_x86.tstate = TSTATE_NONE;
435 { /* STC Rm_BANK, Rn */
436 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
438 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
439 store_reg( R_EAX, Rn );
440 sh4_x86.tstate = TSTATE_NONE;
446 switch( (ir&0xF0) >> 4 ) {
449 uint32_t Rn = ((ir>>8)&0xF);
450 if( sh4_x86.in_delay_slot ) {
453 load_imm32( R_ECX, pc + 4 );
454 store_spreg( R_ECX, R_PR );
455 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_ECX );
456 store_spreg( R_ECX, REG_OFFSET(pc) );
457 sh4_x86.in_delay_slot = TRUE;
458 sh4_x86.tstate = TSTATE_NONE;
459 sh4_translate_instruction( pc + 2 );
460 exit_block_pcset(pc+2);
461 sh4_x86.branch_taken = TRUE;
468 uint32_t Rn = ((ir>>8)&0xF);
469 if( sh4_x86.in_delay_slot ) {
472 load_reg( R_EAX, Rn );
473 ADD_imm32_r32( pc + 4, R_EAX );
474 store_spreg( R_EAX, REG_OFFSET(pc) );
475 sh4_x86.in_delay_slot = TRUE;
476 sh4_x86.tstate = TSTATE_NONE;
477 sh4_translate_instruction( pc + 2 );
478 exit_block_pcset(pc+2);
479 sh4_x86.branch_taken = TRUE;
486 uint32_t Rn = ((ir>>8)&0xF);
487 load_reg( R_EAX, Rn );
488 MOV_r32_r32( R_EAX, R_ECX );
489 AND_imm32_r32( 0xFC000000, R_EAX );
490 CMP_imm32_r32( 0xE0000000, R_EAX );
491 JNE_rel8(CALL_FUNC1_SIZE, end);
492 call_func1( sh4_flush_store_queue, R_ECX );
494 sh4_x86.tstate = TSTATE_NONE;
499 uint32_t Rn = ((ir>>8)&0xF);
504 uint32_t Rn = ((ir>>8)&0xF);
509 uint32_t Rn = ((ir>>8)&0xF);
513 { /* MOVCA.L R0, @Rn */
514 uint32_t Rn = ((ir>>8)&0xF);
515 load_reg( R_EAX, Rn );
516 check_walign32( R_EAX );
517 MMU_TRANSLATE_WRITE( R_EAX );
518 load_reg( R_EDX, 0 );
519 MEM_WRITE_LONG( R_EAX, R_EDX );
520 sh4_x86.tstate = TSTATE_NONE;
529 { /* MOV.B Rm, @(R0, Rn) */
530 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
531 load_reg( R_EAX, 0 );
532 load_reg( R_ECX, Rn );
533 ADD_r32_r32( R_ECX, R_EAX );
534 MMU_TRANSLATE_WRITE( R_EAX );
535 load_reg( R_EDX, Rm );
536 MEM_WRITE_BYTE( R_EAX, R_EDX );
537 sh4_x86.tstate = TSTATE_NONE;
541 { /* MOV.W Rm, @(R0, Rn) */
542 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
543 load_reg( R_EAX, 0 );
544 load_reg( R_ECX, Rn );
545 ADD_r32_r32( R_ECX, R_EAX );
546 check_walign16( R_EAX );
547 MMU_TRANSLATE_WRITE( R_EAX );
548 load_reg( R_EDX, Rm );
549 MEM_WRITE_WORD( R_EAX, R_EDX );
550 sh4_x86.tstate = TSTATE_NONE;
554 { /* MOV.L Rm, @(R0, Rn) */
555 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
556 load_reg( R_EAX, 0 );
557 load_reg( R_ECX, Rn );
558 ADD_r32_r32( R_ECX, R_EAX );
559 check_walign32( R_EAX );
560 MMU_TRANSLATE_WRITE( R_EAX );
561 load_reg( R_EDX, Rm );
562 MEM_WRITE_LONG( R_EAX, R_EDX );
563 sh4_x86.tstate = TSTATE_NONE;
568 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
569 load_reg( R_EAX, Rm );
570 load_reg( R_ECX, Rn );
572 store_spreg( R_EAX, R_MACL );
573 sh4_x86.tstate = TSTATE_NONE;
577 switch( (ir&0xFF0) >> 4 ) {
582 sh4_x86.tstate = TSTATE_C;
589 sh4_x86.tstate = TSTATE_C;
594 XOR_r32_r32(R_EAX, R_EAX);
595 store_spreg( R_EAX, R_MACL );
596 store_spreg( R_EAX, R_MACH );
597 sh4_x86.tstate = TSTATE_NONE;
602 call_func0( MMU_ldtlb );
609 sh4_x86.tstate = TSTATE_C;
616 sh4_x86.tstate = TSTATE_C;
625 switch( (ir&0xF0) >> 4 ) {
628 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
633 XOR_r32_r32( R_EAX, R_EAX );
634 store_spreg( R_EAX, R_Q );
635 store_spreg( R_EAX, R_M );
636 store_spreg( R_EAX, R_T );
637 sh4_x86.tstate = TSTATE_C; // works for DIV1
642 uint32_t Rn = ((ir>>8)&0xF);
643 load_spreg( R_EAX, R_T );
644 store_reg( R_EAX, Rn );
653 switch( (ir&0xF0) >> 4 ) {
656 uint32_t Rn = ((ir>>8)&0xF);
657 load_spreg( R_EAX, R_MACH );
658 store_reg( R_EAX, Rn );
663 uint32_t Rn = ((ir>>8)&0xF);
664 load_spreg( R_EAX, R_MACL );
665 store_reg( R_EAX, Rn );
670 uint32_t Rn = ((ir>>8)&0xF);
671 load_spreg( R_EAX, R_PR );
672 store_reg( R_EAX, Rn );
677 uint32_t Rn = ((ir>>8)&0xF);
679 load_spreg( R_EAX, R_SGR );
680 store_reg( R_EAX, Rn );
681 sh4_x86.tstate = TSTATE_NONE;
686 uint32_t Rn = ((ir>>8)&0xF);
687 load_spreg( R_EAX, R_FPUL );
688 store_reg( R_EAX, Rn );
692 { /* STS FPSCR, Rn */
693 uint32_t Rn = ((ir>>8)&0xF);
694 load_spreg( R_EAX, R_FPSCR );
695 store_reg( R_EAX, Rn );
700 uint32_t Rn = ((ir>>8)&0xF);
702 load_spreg( R_EAX, R_DBR );
703 store_reg( R_EAX, Rn );
704 sh4_x86.tstate = TSTATE_NONE;
713 switch( (ir&0xFF0) >> 4 ) {
716 if( sh4_x86.in_delay_slot ) {
719 load_spreg( R_ECX, R_PR );
720 store_spreg( R_ECX, REG_OFFSET(pc) );
721 sh4_x86.in_delay_slot = TRUE;
722 sh4_translate_instruction(pc+2);
723 exit_block_pcset(pc+2);
724 sh4_x86.branch_taken = TRUE;
732 call_func0( sh4_sleep );
733 sh4_x86.tstate = TSTATE_NONE;
734 sh4_x86.in_delay_slot = FALSE;
740 if( sh4_x86.in_delay_slot ) {
744 load_spreg( R_ECX, R_SPC );
745 store_spreg( R_ECX, REG_OFFSET(pc) );
746 load_spreg( R_EAX, R_SSR );
747 call_func1( sh4_write_sr, R_EAX );
748 sh4_x86.in_delay_slot = TRUE;
749 sh4_x86.priv_checked = FALSE;
750 sh4_x86.fpuen_checked = FALSE;
751 sh4_x86.tstate = TSTATE_NONE;
752 sh4_translate_instruction(pc+2);
753 exit_block_pcset(pc+2);
754 sh4_x86.branch_taken = TRUE;
765 { /* MOV.B @(R0, Rm), Rn */
766 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
767 load_reg( R_EAX, 0 );
768 load_reg( R_ECX, Rm );
769 ADD_r32_r32( R_ECX, R_EAX );
770 MMU_TRANSLATE_READ( R_EAX )
771 MEM_READ_BYTE( R_EAX, R_EAX );
772 store_reg( R_EAX, Rn );
773 sh4_x86.tstate = TSTATE_NONE;
777 { /* MOV.W @(R0, Rm), Rn */
778 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
779 load_reg( R_EAX, 0 );
780 load_reg( R_ECX, Rm );
781 ADD_r32_r32( R_ECX, R_EAX );
782 check_ralign16( R_EAX );
783 MMU_TRANSLATE_READ( R_EAX );
784 MEM_READ_WORD( R_EAX, R_EAX );
785 store_reg( R_EAX, Rn );
786 sh4_x86.tstate = TSTATE_NONE;
790 { /* MOV.L @(R0, Rm), Rn */
791 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
792 load_reg( R_EAX, 0 );
793 load_reg( R_ECX, Rm );
794 ADD_r32_r32( R_ECX, R_EAX );
795 check_ralign32( R_EAX );
796 MMU_TRANSLATE_READ( R_EAX );
797 MEM_READ_LONG( R_EAX, R_EAX );
798 store_reg( R_EAX, Rn );
799 sh4_x86.tstate = TSTATE_NONE;
803 { /* MAC.L @Rm+, @Rn+ */
804 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
806 load_reg( R_EAX, Rm );
807 check_ralign32( R_EAX );
808 MMU_TRANSLATE_READ( R_EAX );
809 PUSH_realigned_r32( R_EAX );
810 load_reg( R_EAX, Rn );
811 ADD_imm8s_r32( 4, R_EAX );
812 MMU_TRANSLATE_READ( R_EAX );
813 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
814 // Note translate twice in case of page boundaries. Maybe worth
815 // adding a page-boundary check to skip the second translation
817 load_reg( R_EAX, Rm );
818 check_ralign32( R_EAX );
819 MMU_TRANSLATE_READ( R_EAX );
820 PUSH_realigned_r32( R_EAX );
821 load_reg( R_EAX, Rn );
822 check_ralign32( R_EAX );
823 MMU_TRANSLATE_READ( R_EAX );
824 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
825 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
827 MEM_READ_LONG( R_EAX, R_EAX );
830 MEM_READ_LONG( R_ECX, R_EAX );
831 POP_realigned_r32( R_ECX );
834 ADD_r32_sh4r( R_EAX, R_MACL );
835 ADC_r32_sh4r( R_EDX, R_MACH );
837 load_spreg( R_ECX, R_S );
838 TEST_r32_r32(R_ECX, R_ECX);
839 JE_rel8( CALL_FUNC0_SIZE, nosat );
840 call_func0( signsat48 );
842 sh4_x86.tstate = TSTATE_NONE;
851 { /* MOV.L Rm, @(disp, Rn) */
852 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
853 load_reg( R_EAX, Rn );
854 ADD_imm32_r32( disp, R_EAX );
855 check_walign32( R_EAX );
856 MMU_TRANSLATE_WRITE( R_EAX );
857 load_reg( R_EDX, Rm );
858 MEM_WRITE_LONG( R_EAX, R_EDX );
859 sh4_x86.tstate = TSTATE_NONE;
865 { /* MOV.B Rm, @Rn */
866 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
867 load_reg( R_EAX, Rn );
868 MMU_TRANSLATE_WRITE( R_EAX );
869 load_reg( R_EDX, Rm );
870 MEM_WRITE_BYTE( R_EAX, R_EDX );
871 sh4_x86.tstate = TSTATE_NONE;
875 { /* MOV.W Rm, @Rn */
876 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
877 load_reg( R_EAX, Rn );
878 check_walign16( R_EAX );
879 MMU_TRANSLATE_WRITE( R_EAX )
880 load_reg( R_EDX, Rm );
881 MEM_WRITE_WORD( R_EAX, R_EDX );
882 sh4_x86.tstate = TSTATE_NONE;
886 { /* MOV.L Rm, @Rn */
887 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
888 load_reg( R_EAX, Rn );
889 check_walign32(R_EAX);
890 MMU_TRANSLATE_WRITE( R_EAX );
891 load_reg( R_EDX, Rm );
892 MEM_WRITE_LONG( R_EAX, R_EDX );
893 sh4_x86.tstate = TSTATE_NONE;
897 { /* MOV.B Rm, @-Rn */
898 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
899 load_reg( R_EAX, Rn );
900 ADD_imm8s_r32( -1, R_EAX );
901 MMU_TRANSLATE_WRITE( R_EAX );
902 load_reg( R_EDX, Rm );
903 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
904 MEM_WRITE_BYTE( R_EAX, R_EDX );
905 sh4_x86.tstate = TSTATE_NONE;
909 { /* MOV.W Rm, @-Rn */
910 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
911 load_reg( R_EAX, Rn );
912 ADD_imm8s_r32( -2, R_EAX );
913 check_walign16( R_EAX );
914 MMU_TRANSLATE_WRITE( R_EAX );
915 load_reg( R_EDX, Rm );
916 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
917 MEM_WRITE_WORD( R_EAX, R_EDX );
918 sh4_x86.tstate = TSTATE_NONE;
922 { /* MOV.L Rm, @-Rn */
923 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
924 load_reg( R_EAX, Rn );
925 ADD_imm8s_r32( -4, R_EAX );
926 check_walign32( R_EAX );
927 MMU_TRANSLATE_WRITE( R_EAX );
928 load_reg( R_EDX, Rm );
929 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
930 MEM_WRITE_LONG( R_EAX, R_EDX );
931 sh4_x86.tstate = TSTATE_NONE;
936 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
937 load_reg( R_EAX, Rm );
938 load_reg( R_ECX, Rn );
939 SHR_imm8_r32( 31, R_EAX );
940 SHR_imm8_r32( 31, R_ECX );
941 store_spreg( R_EAX, R_M );
942 store_spreg( R_ECX, R_Q );
943 CMP_r32_r32( R_EAX, R_ECX );
945 sh4_x86.tstate = TSTATE_NE;
950 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
951 load_reg( R_EAX, Rm );
952 load_reg( R_ECX, Rn );
953 TEST_r32_r32( R_EAX, R_ECX );
955 sh4_x86.tstate = TSTATE_E;
960 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
961 load_reg( R_EAX, Rm );
962 load_reg( R_ECX, Rn );
963 AND_r32_r32( R_EAX, R_ECX );
964 store_reg( R_ECX, Rn );
965 sh4_x86.tstate = TSTATE_NONE;
970 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
971 load_reg( R_EAX, Rm );
972 load_reg( R_ECX, Rn );
973 XOR_r32_r32( R_EAX, R_ECX );
974 store_reg( R_ECX, Rn );
975 sh4_x86.tstate = TSTATE_NONE;
980 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
981 load_reg( R_EAX, Rm );
982 load_reg( R_ECX, Rn );
983 OR_r32_r32( R_EAX, R_ECX );
984 store_reg( R_ECX, Rn );
985 sh4_x86.tstate = TSTATE_NONE;
989 { /* CMP/STR Rm, Rn */
990 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
991 load_reg( R_EAX, Rm );
992 load_reg( R_ECX, Rn );
993 XOR_r32_r32( R_ECX, R_EAX );
994 TEST_r8_r8( R_AL, R_AL );
995 JE_rel8(13, target1);
996 TEST_r8_r8( R_AH, R_AH ); // 2
998 SHR_imm8_r32( 16, R_EAX ); // 3
999 TEST_r8_r8( R_AL, R_AL ); // 2
1000 JE_rel8(2, target3);
1001 TEST_r8_r8( R_AH, R_AH ); // 2
1002 JMP_TARGET(target1);
1003 JMP_TARGET(target2);
1004 JMP_TARGET(target3);
1006 sh4_x86.tstate = TSTATE_E;
1010 { /* XTRCT Rm, Rn */
1011 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1012 load_reg( R_EAX, Rm );
1013 load_reg( R_ECX, Rn );
1014 SHL_imm8_r32( 16, R_EAX );
1015 SHR_imm8_r32( 16, R_ECX );
1016 OR_r32_r32( R_EAX, R_ECX );
1017 store_reg( R_ECX, Rn );
1018 sh4_x86.tstate = TSTATE_NONE;
1022 { /* MULU.W Rm, Rn */
1023 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1024 load_reg16u( R_EAX, Rm );
1025 load_reg16u( R_ECX, Rn );
1027 store_spreg( R_EAX, R_MACL );
1028 sh4_x86.tstate = TSTATE_NONE;
1032 { /* MULS.W Rm, Rn */
1033 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1034 load_reg16s( R_EAX, Rm );
1035 load_reg16s( R_ECX, Rn );
1037 store_spreg( R_EAX, R_MACL );
1038 sh4_x86.tstate = TSTATE_NONE;
1049 { /* CMP/EQ Rm, Rn */
1050 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1051 load_reg( R_EAX, Rm );
1052 load_reg( R_ECX, Rn );
1053 CMP_r32_r32( R_EAX, R_ECX );
1055 sh4_x86.tstate = TSTATE_E;
1059 { /* CMP/HS Rm, Rn */
1060 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1061 load_reg( R_EAX, Rm );
1062 load_reg( R_ECX, Rn );
1063 CMP_r32_r32( R_EAX, R_ECX );
1065 sh4_x86.tstate = TSTATE_AE;
1069 { /* CMP/GE Rm, Rn */
1070 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1071 load_reg( R_EAX, Rm );
1072 load_reg( R_ECX, Rn );
1073 CMP_r32_r32( R_EAX, R_ECX );
1075 sh4_x86.tstate = TSTATE_GE;
1080 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1081 load_spreg( R_ECX, R_M );
1082 load_reg( R_EAX, Rn );
1083 if( sh4_x86.tstate != TSTATE_C ) {
1087 SETC_r8( R_DL ); // Q'
1088 CMP_sh4r_r32( R_Q, R_ECX );
1089 JE_rel8(5, mqequal);
1090 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1092 JMP_TARGET(mqequal);
1093 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1095 store_reg( R_EAX, Rn ); // Done with Rn now
1096 SETC_r8(R_AL); // tmp1
1097 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1098 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1099 store_spreg( R_ECX, R_Q );
1100 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1101 MOVZX_r8_r32( R_AL, R_EAX );
1102 store_spreg( R_EAX, R_T );
1103 sh4_x86.tstate = TSTATE_NONE;
1107 { /* DMULU.L Rm, Rn */
1108 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1109 load_reg( R_EAX, Rm );
1110 load_reg( R_ECX, Rn );
1112 store_spreg( R_EDX, R_MACH );
1113 store_spreg( R_EAX, R_MACL );
1114 sh4_x86.tstate = TSTATE_NONE;
1118 { /* CMP/HI Rm, Rn */
1119 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1120 load_reg( R_EAX, Rm );
1121 load_reg( R_ECX, Rn );
1122 CMP_r32_r32( R_EAX, R_ECX );
1124 sh4_x86.tstate = TSTATE_A;
1128 { /* CMP/GT Rm, Rn */
1129 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1130 load_reg( R_EAX, Rm );
1131 load_reg( R_ECX, Rn );
1132 CMP_r32_r32( R_EAX, R_ECX );
1134 sh4_x86.tstate = TSTATE_G;
1139 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1140 load_reg( R_EAX, Rm );
1141 load_reg( R_ECX, Rn );
1142 SUB_r32_r32( R_EAX, R_ECX );
1143 store_reg( R_ECX, Rn );
1144 sh4_x86.tstate = TSTATE_NONE;
1149 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1150 load_reg( R_EAX, Rm );
1151 load_reg( R_ECX, Rn );
1152 if( sh4_x86.tstate != TSTATE_C ) {
1155 SBB_r32_r32( R_EAX, R_ECX );
1156 store_reg( R_ECX, Rn );
1158 sh4_x86.tstate = TSTATE_C;
1163 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1164 load_reg( R_EAX, Rm );
1165 load_reg( R_ECX, Rn );
1166 SUB_r32_r32( R_EAX, R_ECX );
1167 store_reg( R_ECX, Rn );
1169 sh4_x86.tstate = TSTATE_O;
1174 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1175 load_reg( R_EAX, Rm );
1176 load_reg( R_ECX, Rn );
1177 ADD_r32_r32( R_EAX, R_ECX );
1178 store_reg( R_ECX, Rn );
1179 sh4_x86.tstate = TSTATE_NONE;
1183 { /* DMULS.L Rm, Rn */
1184 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1185 load_reg( R_EAX, Rm );
1186 load_reg( R_ECX, Rn );
1188 store_spreg( R_EDX, R_MACH );
1189 store_spreg( R_EAX, R_MACL );
1190 sh4_x86.tstate = TSTATE_NONE;
1195 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1196 if( sh4_x86.tstate != TSTATE_C ) {
1199 load_reg( R_EAX, Rm );
1200 load_reg( R_ECX, Rn );
1201 ADC_r32_r32( R_EAX, R_ECX );
1202 store_reg( R_ECX, Rn );
1204 sh4_x86.tstate = TSTATE_C;
1209 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1210 load_reg( R_EAX, Rm );
1211 load_reg( R_ECX, Rn );
1212 ADD_r32_r32( R_EAX, R_ECX );
1213 store_reg( R_ECX, Rn );
1215 sh4_x86.tstate = TSTATE_O;
1226 switch( (ir&0xF0) >> 4 ) {
1229 uint32_t Rn = ((ir>>8)&0xF);
1230 load_reg( R_EAX, Rn );
1233 store_reg( R_EAX, Rn );
1234 sh4_x86.tstate = TSTATE_C;
1239 uint32_t Rn = ((ir>>8)&0xF);
1240 load_reg( R_EAX, Rn );
1241 ADD_imm8s_r32( -1, R_EAX );
1242 store_reg( R_EAX, Rn );
1244 sh4_x86.tstate = TSTATE_E;
1249 uint32_t Rn = ((ir>>8)&0xF);
1250 load_reg( R_EAX, Rn );
1253 store_reg( R_EAX, Rn );
1254 sh4_x86.tstate = TSTATE_C;
1263 switch( (ir&0xF0) >> 4 ) {
1266 uint32_t Rn = ((ir>>8)&0xF);
1267 load_reg( R_EAX, Rn );
1270 store_reg( R_EAX, Rn );
1271 sh4_x86.tstate = TSTATE_C;
1276 uint32_t Rn = ((ir>>8)&0xF);
1277 load_reg( R_EAX, Rn );
1278 CMP_imm8s_r32( 0, R_EAX );
1280 sh4_x86.tstate = TSTATE_GE;
1285 uint32_t Rn = ((ir>>8)&0xF);
1286 load_reg( R_EAX, Rn );
1289 store_reg( R_EAX, Rn );
1290 sh4_x86.tstate = TSTATE_C;
1299 switch( (ir&0xF0) >> 4 ) {
1301 { /* STS.L MACH, @-Rn */
1302 uint32_t Rn = ((ir>>8)&0xF);
1303 load_reg( R_EAX, Rn );
1304 check_walign32( R_EAX );
1305 ADD_imm8s_r32( -4, R_EAX );
1306 MMU_TRANSLATE_WRITE( R_EAX );
1307 load_spreg( R_EDX, R_MACH );
1308 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1309 MEM_WRITE_LONG( R_EAX, R_EDX );
1310 sh4_x86.tstate = TSTATE_NONE;
1314 { /* STS.L MACL, @-Rn */
1315 uint32_t Rn = ((ir>>8)&0xF);
1316 load_reg( R_EAX, Rn );
1317 check_walign32( R_EAX );
1318 ADD_imm8s_r32( -4, R_EAX );
1319 MMU_TRANSLATE_WRITE( R_EAX );
1320 load_spreg( R_EDX, R_MACL );
1321 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1322 MEM_WRITE_LONG( R_EAX, R_EDX );
1323 sh4_x86.tstate = TSTATE_NONE;
1327 { /* STS.L PR, @-Rn */
1328 uint32_t Rn = ((ir>>8)&0xF);
1329 load_reg( R_EAX, Rn );
1330 check_walign32( R_EAX );
1331 ADD_imm8s_r32( -4, R_EAX );
1332 MMU_TRANSLATE_WRITE( R_EAX );
1333 load_spreg( R_EDX, R_PR );
1334 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1335 MEM_WRITE_LONG( R_EAX, R_EDX );
1336 sh4_x86.tstate = TSTATE_NONE;
1340 { /* STC.L SGR, @-Rn */
1341 uint32_t Rn = ((ir>>8)&0xF);
1343 load_reg( R_EAX, Rn );
1344 check_walign32( R_EAX );
1345 ADD_imm8s_r32( -4, R_EAX );
1346 MMU_TRANSLATE_WRITE( R_EAX );
1347 load_spreg( R_EDX, R_SGR );
1348 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1349 MEM_WRITE_LONG( R_EAX, R_EDX );
1350 sh4_x86.tstate = TSTATE_NONE;
1354 { /* STS.L FPUL, @-Rn */
1355 uint32_t Rn = ((ir>>8)&0xF);
1356 load_reg( R_EAX, Rn );
1357 check_walign32( R_EAX );
1358 ADD_imm8s_r32( -4, R_EAX );
1359 MMU_TRANSLATE_WRITE( R_EAX );
1360 load_spreg( R_EDX, R_FPUL );
1361 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1362 MEM_WRITE_LONG( R_EAX, R_EDX );
1363 sh4_x86.tstate = TSTATE_NONE;
1367 { /* STS.L FPSCR, @-Rn */
1368 uint32_t Rn = ((ir>>8)&0xF);
1369 load_reg( R_EAX, Rn );
1370 check_walign32( R_EAX );
1371 ADD_imm8s_r32( -4, R_EAX );
1372 MMU_TRANSLATE_WRITE( R_EAX );
1373 load_spreg( R_EDX, R_FPSCR );
1374 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1375 MEM_WRITE_LONG( R_EAX, R_EDX );
1376 sh4_x86.tstate = TSTATE_NONE;
1380 { /* STC.L DBR, @-Rn */
1381 uint32_t Rn = ((ir>>8)&0xF);
1383 load_reg( R_EAX, Rn );
1384 check_walign32( R_EAX );
1385 ADD_imm8s_r32( -4, R_EAX );
1386 MMU_TRANSLATE_WRITE( R_EAX );
1387 load_spreg( R_EDX, R_DBR );
1388 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1389 MEM_WRITE_LONG( R_EAX, R_EDX );
1390 sh4_x86.tstate = TSTATE_NONE;
1399 switch( (ir&0x80) >> 7 ) {
1401 switch( (ir&0x70) >> 4 ) {
1403 { /* STC.L SR, @-Rn */
1404 uint32_t Rn = ((ir>>8)&0xF);
1406 load_reg( R_EAX, Rn );
1407 check_walign32( R_EAX );
1408 ADD_imm8s_r32( -4, R_EAX );
1409 MMU_TRANSLATE_WRITE( R_EAX );
1410 PUSH_realigned_r32( R_EAX );
1411 call_func0( sh4_read_sr );
1412 POP_realigned_r32( R_ECX );
1413 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1414 MEM_WRITE_LONG( R_ECX, R_EAX );
1415 sh4_x86.tstate = TSTATE_NONE;
1419 { /* STC.L GBR, @-Rn */
1420 uint32_t Rn = ((ir>>8)&0xF);
1421 load_reg( R_EAX, Rn );
1422 check_walign32( R_EAX );
1423 ADD_imm8s_r32( -4, R_EAX );
1424 MMU_TRANSLATE_WRITE( R_EAX );
1425 load_spreg( R_EDX, R_GBR );
1426 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1427 MEM_WRITE_LONG( R_EAX, R_EDX );
1428 sh4_x86.tstate = TSTATE_NONE;
1432 { /* STC.L VBR, @-Rn */
1433 uint32_t Rn = ((ir>>8)&0xF);
1435 load_reg( R_EAX, Rn );
1436 check_walign32( R_EAX );
1437 ADD_imm8s_r32( -4, R_EAX );
1438 MMU_TRANSLATE_WRITE( R_EAX );
1439 load_spreg( R_EDX, R_VBR );
1440 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1441 MEM_WRITE_LONG( R_EAX, R_EDX );
1442 sh4_x86.tstate = TSTATE_NONE;
1446 { /* STC.L SSR, @-Rn */
1447 uint32_t Rn = ((ir>>8)&0xF);
1449 load_reg( R_EAX, Rn );
1450 check_walign32( R_EAX );
1451 ADD_imm8s_r32( -4, R_EAX );
1452 MMU_TRANSLATE_WRITE( R_EAX );
1453 load_spreg( R_EDX, R_SSR );
1454 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1455 MEM_WRITE_LONG( R_EAX, R_EDX );
1456 sh4_x86.tstate = TSTATE_NONE;
1460 { /* STC.L SPC, @-Rn */
1461 uint32_t Rn = ((ir>>8)&0xF);
1463 load_reg( R_EAX, Rn );
1464 check_walign32( R_EAX );
1465 ADD_imm8s_r32( -4, R_EAX );
1466 MMU_TRANSLATE_WRITE( R_EAX );
1467 load_spreg( R_EDX, R_SPC );
1468 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1469 MEM_WRITE_LONG( R_EAX, R_EDX );
1470 sh4_x86.tstate = TSTATE_NONE;
1479 { /* STC.L Rm_BANK, @-Rn */
1480 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1482 load_reg( R_EAX, Rn );
1483 check_walign32( R_EAX );
1484 ADD_imm8s_r32( -4, R_EAX );
1485 MMU_TRANSLATE_WRITE( R_EAX );
1486 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1487 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1488 MEM_WRITE_LONG( R_EAX, R_EDX );
1489 sh4_x86.tstate = TSTATE_NONE;
1495 switch( (ir&0xF0) >> 4 ) {
1498 uint32_t Rn = ((ir>>8)&0xF);
1499 load_reg( R_EAX, Rn );
1501 store_reg( R_EAX, Rn );
1503 sh4_x86.tstate = TSTATE_C;
1508 uint32_t Rn = ((ir>>8)&0xF);
1509 load_reg( R_EAX, Rn );
1510 if( sh4_x86.tstate != TSTATE_C ) {
1514 store_reg( R_EAX, Rn );
1516 sh4_x86.tstate = TSTATE_C;
1525 switch( (ir&0xF0) >> 4 ) {
1528 uint32_t Rn = ((ir>>8)&0xF);
1529 load_reg( R_EAX, Rn );
1531 store_reg( R_EAX, Rn );
1533 sh4_x86.tstate = TSTATE_C;
1538 uint32_t Rn = ((ir>>8)&0xF);
1539 load_reg( R_EAX, Rn );
1540 CMP_imm8s_r32( 0, R_EAX );
1542 sh4_x86.tstate = TSTATE_G;
1547 uint32_t Rn = ((ir>>8)&0xF);
1548 load_reg( R_EAX, Rn );
1549 if( sh4_x86.tstate != TSTATE_C ) {
1553 store_reg( R_EAX, Rn );
1555 sh4_x86.tstate = TSTATE_C;
1564 switch( (ir&0xF0) >> 4 ) {
1566 { /* LDS.L @Rm+, MACH */
1567 uint32_t Rm = ((ir>>8)&0xF);
1568 load_reg( R_EAX, Rm );
1569 check_ralign32( R_EAX );
1570 MMU_TRANSLATE_READ( R_EAX );
1571 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1572 MEM_READ_LONG( R_EAX, R_EAX );
1573 store_spreg( R_EAX, R_MACH );
1574 sh4_x86.tstate = TSTATE_NONE;
1578 { /* LDS.L @Rm+, MACL */
1579 uint32_t Rm = ((ir>>8)&0xF);
1580 load_reg( R_EAX, Rm );
1581 check_ralign32( R_EAX );
1582 MMU_TRANSLATE_READ( R_EAX );
1583 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1584 MEM_READ_LONG( R_EAX, R_EAX );
1585 store_spreg( R_EAX, R_MACL );
1586 sh4_x86.tstate = TSTATE_NONE;
1590 { /* LDS.L @Rm+, PR */
1591 uint32_t Rm = ((ir>>8)&0xF);
1592 load_reg( R_EAX, Rm );
1593 check_ralign32( R_EAX );
1594 MMU_TRANSLATE_READ( R_EAX );
1595 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1596 MEM_READ_LONG( R_EAX, R_EAX );
1597 store_spreg( R_EAX, R_PR );
1598 sh4_x86.tstate = TSTATE_NONE;
1602 { /* LDC.L @Rm+, SGR */
1603 uint32_t Rm = ((ir>>8)&0xF);
1605 load_reg( R_EAX, Rm );
1606 check_ralign32( R_EAX );
1607 MMU_TRANSLATE_READ( R_EAX );
1608 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1609 MEM_READ_LONG( R_EAX, R_EAX );
1610 store_spreg( R_EAX, R_SGR );
1611 sh4_x86.tstate = TSTATE_NONE;
1615 { /* LDS.L @Rm+, FPUL */
1616 uint32_t Rm = ((ir>>8)&0xF);
1617 load_reg( R_EAX, Rm );
1618 check_ralign32( R_EAX );
1619 MMU_TRANSLATE_READ( R_EAX );
1620 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1621 MEM_READ_LONG( R_EAX, R_EAX );
1622 store_spreg( R_EAX, R_FPUL );
1623 sh4_x86.tstate = TSTATE_NONE;
1627 { /* LDS.L @Rm+, FPSCR */
1628 uint32_t Rm = ((ir>>8)&0xF);
1629 load_reg( R_EAX, Rm );
1630 check_ralign32( R_EAX );
1631 MMU_TRANSLATE_READ( R_EAX );
1632 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1633 MEM_READ_LONG( R_EAX, R_EAX );
1634 store_spreg( R_EAX, R_FPSCR );
1635 update_fr_bank( R_EAX );
1636 sh4_x86.tstate = TSTATE_NONE;
1640 { /* LDC.L @Rm+, DBR */
1641 uint32_t Rm = ((ir>>8)&0xF);
1643 load_reg( R_EAX, Rm );
1644 check_ralign32( R_EAX );
1645 MMU_TRANSLATE_READ( R_EAX );
1646 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1647 MEM_READ_LONG( R_EAX, R_EAX );
1648 store_spreg( R_EAX, R_DBR );
1649 sh4_x86.tstate = TSTATE_NONE;
1658 switch( (ir&0x80) >> 7 ) {
1660 switch( (ir&0x70) >> 4 ) {
1662 { /* LDC.L @Rm+, SR */
1663 uint32_t Rm = ((ir>>8)&0xF);
1664 if( sh4_x86.in_delay_slot ) {
1668 load_reg( R_EAX, Rm );
1669 check_ralign32( R_EAX );
1670 MMU_TRANSLATE_READ( R_EAX );
1671 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1672 MEM_READ_LONG( R_EAX, R_EAX );
1673 call_func1( sh4_write_sr, R_EAX );
1674 sh4_x86.priv_checked = FALSE;
1675 sh4_x86.fpuen_checked = FALSE;
1676 sh4_x86.tstate = TSTATE_NONE;
1681 { /* LDC.L @Rm+, GBR */
1682 uint32_t Rm = ((ir>>8)&0xF);
1683 load_reg( R_EAX, Rm );
1684 check_ralign32( R_EAX );
1685 MMU_TRANSLATE_READ( R_EAX );
1686 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1687 MEM_READ_LONG( R_EAX, R_EAX );
1688 store_spreg( R_EAX, R_GBR );
1689 sh4_x86.tstate = TSTATE_NONE;
1693 { /* LDC.L @Rm+, VBR */
1694 uint32_t Rm = ((ir>>8)&0xF);
1696 load_reg( R_EAX, Rm );
1697 check_ralign32( R_EAX );
1698 MMU_TRANSLATE_READ( R_EAX );
1699 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1700 MEM_READ_LONG( R_EAX, R_EAX );
1701 store_spreg( R_EAX, R_VBR );
1702 sh4_x86.tstate = TSTATE_NONE;
1706 { /* LDC.L @Rm+, SSR */
1707 uint32_t Rm = ((ir>>8)&0xF);
1709 load_reg( R_EAX, Rm );
1710 check_ralign32( R_EAX );
1711 MMU_TRANSLATE_READ( R_EAX );
1712 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1713 MEM_READ_LONG( R_EAX, R_EAX );
1714 store_spreg( R_EAX, R_SSR );
1715 sh4_x86.tstate = TSTATE_NONE;
1719 { /* LDC.L @Rm+, SPC */
1720 uint32_t Rm = ((ir>>8)&0xF);
1722 load_reg( R_EAX, Rm );
1723 check_ralign32( R_EAX );
1724 MMU_TRANSLATE_READ( R_EAX );
1725 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1726 MEM_READ_LONG( R_EAX, R_EAX );
1727 store_spreg( R_EAX, R_SPC );
1728 sh4_x86.tstate = TSTATE_NONE;
1737 { /* LDC.L @Rm+, Rn_BANK */
1738 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1740 load_reg( R_EAX, Rm );
1741 check_ralign32( R_EAX );
1742 MMU_TRANSLATE_READ( R_EAX );
1743 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1744 MEM_READ_LONG( R_EAX, R_EAX );
1745 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1746 sh4_x86.tstate = TSTATE_NONE;
1752 switch( (ir&0xF0) >> 4 ) {
1755 uint32_t Rn = ((ir>>8)&0xF);
1756 load_reg( R_EAX, Rn );
1757 SHL_imm8_r32( 2, R_EAX );
1758 store_reg( R_EAX, Rn );
1759 sh4_x86.tstate = TSTATE_NONE;
1764 uint32_t Rn = ((ir>>8)&0xF);
1765 load_reg( R_EAX, Rn );
1766 SHL_imm8_r32( 8, R_EAX );
1767 store_reg( R_EAX, Rn );
1768 sh4_x86.tstate = TSTATE_NONE;
1773 uint32_t Rn = ((ir>>8)&0xF);
1774 load_reg( R_EAX, Rn );
1775 SHL_imm8_r32( 16, R_EAX );
1776 store_reg( R_EAX, Rn );
1777 sh4_x86.tstate = TSTATE_NONE;
1786 switch( (ir&0xF0) >> 4 ) {
1789 uint32_t Rn = ((ir>>8)&0xF);
1790 load_reg( R_EAX, Rn );
1791 SHR_imm8_r32( 2, R_EAX );
1792 store_reg( R_EAX, Rn );
1793 sh4_x86.tstate = TSTATE_NONE;
1798 uint32_t Rn = ((ir>>8)&0xF);
1799 load_reg( R_EAX, Rn );
1800 SHR_imm8_r32( 8, R_EAX );
1801 store_reg( R_EAX, Rn );
1802 sh4_x86.tstate = TSTATE_NONE;
1807 uint32_t Rn = ((ir>>8)&0xF);
1808 load_reg( R_EAX, Rn );
1809 SHR_imm8_r32( 16, R_EAX );
1810 store_reg( R_EAX, Rn );
1811 sh4_x86.tstate = TSTATE_NONE;
1820 switch( (ir&0xF0) >> 4 ) {
1822 { /* LDS Rm, MACH */
1823 uint32_t Rm = ((ir>>8)&0xF);
1824 load_reg( R_EAX, Rm );
1825 store_spreg( R_EAX, R_MACH );
1829 { /* LDS Rm, MACL */
1830 uint32_t Rm = ((ir>>8)&0xF);
1831 load_reg( R_EAX, Rm );
1832 store_spreg( R_EAX, R_MACL );
1837 uint32_t Rm = ((ir>>8)&0xF);
1838 load_reg( R_EAX, Rm );
1839 store_spreg( R_EAX, R_PR );
1844 uint32_t Rm = ((ir>>8)&0xF);
1846 load_reg( R_EAX, Rm );
1847 store_spreg( R_EAX, R_SGR );
1848 sh4_x86.tstate = TSTATE_NONE;
1852 { /* LDS Rm, FPUL */
1853 uint32_t Rm = ((ir>>8)&0xF);
1854 load_reg( R_EAX, Rm );
1855 store_spreg( R_EAX, R_FPUL );
1859 { /* LDS Rm, FPSCR */
1860 uint32_t Rm = ((ir>>8)&0xF);
1861 load_reg( R_EAX, Rm );
1862 store_spreg( R_EAX, R_FPSCR );
1863 update_fr_bank( R_EAX );
1864 sh4_x86.tstate = TSTATE_NONE;
1869 uint32_t Rm = ((ir>>8)&0xF);
1871 load_reg( R_EAX, Rm );
1872 store_spreg( R_EAX, R_DBR );
1873 sh4_x86.tstate = TSTATE_NONE;
1882 switch( (ir&0xF0) >> 4 ) {
1885 uint32_t Rn = ((ir>>8)&0xF);
1886 if( sh4_x86.in_delay_slot ) {
1889 load_imm32( R_EAX, pc + 4 );
1890 store_spreg( R_EAX, R_PR );
1891 load_reg( R_ECX, Rn );
1892 store_spreg( R_ECX, REG_OFFSET(pc) );
1893 sh4_x86.in_delay_slot = TRUE;
1894 sh4_translate_instruction(pc+2);
1895 exit_block_pcset(pc+2);
1896 sh4_x86.branch_taken = TRUE;
1903 uint32_t Rn = ((ir>>8)&0xF);
1904 load_reg( R_EAX, Rn );
1905 MMU_TRANSLATE_WRITE( R_EAX );
1906 PUSH_realigned_r32( R_EAX );
1907 MEM_READ_BYTE( R_EAX, R_EAX );
1908 TEST_r8_r8( R_AL, R_AL );
1910 OR_imm8_r8( 0x80, R_AL );
1911 POP_realigned_r32( R_ECX );
1912 MEM_WRITE_BYTE( R_ECX, R_EAX );
1913 sh4_x86.tstate = TSTATE_NONE;
1918 uint32_t Rn = ((ir>>8)&0xF);
1919 if( sh4_x86.in_delay_slot ) {
1922 load_reg( R_ECX, Rn );
1923 store_spreg( R_ECX, REG_OFFSET(pc) );
1924 sh4_x86.in_delay_slot = TRUE;
1925 sh4_translate_instruction(pc+2);
1926 exit_block_pcset(pc+2);
1927 sh4_x86.branch_taken = TRUE;
1939 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1940 /* Annoyingly enough, not directly convertible */
1941 load_reg( R_EAX, Rn );
1942 load_reg( R_ECX, Rm );
1943 CMP_imm32_r32( 0, R_ECX );
1944 JGE_rel8(16, doshl);
1946 NEG_r32( R_ECX ); // 2
1947 AND_imm8_r8( 0x1F, R_CL ); // 3
1948 JE_rel8( 4, emptysar); // 2
1949 SAR_r32_CL( R_EAX ); // 2
1950 JMP_rel8(10, end); // 2
1952 JMP_TARGET(emptysar);
1953 SAR_imm8_r32(31, R_EAX ); // 3
1957 AND_imm8_r8( 0x1F, R_CL ); // 3
1958 SHL_r32_CL( R_EAX ); // 2
1961 store_reg( R_EAX, Rn );
1962 sh4_x86.tstate = TSTATE_NONE;
1967 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1968 load_reg( R_EAX, Rn );
1969 load_reg( R_ECX, Rm );
1970 CMP_imm32_r32( 0, R_ECX );
1971 JGE_rel8(15, doshl);
1973 NEG_r32( R_ECX ); // 2
1974 AND_imm8_r8( 0x1F, R_CL ); // 3
1975 JE_rel8( 4, emptyshr );
1976 SHR_r32_CL( R_EAX ); // 2
1977 JMP_rel8(9, end); // 2
1979 JMP_TARGET(emptyshr);
1980 XOR_r32_r32( R_EAX, R_EAX );
1984 AND_imm8_r8( 0x1F, R_CL ); // 3
1985 SHL_r32_CL( R_EAX ); // 2
1988 store_reg( R_EAX, Rn );
1989 sh4_x86.tstate = TSTATE_NONE;
1993 switch( (ir&0x80) >> 7 ) {
1995 switch( (ir&0x70) >> 4 ) {
1998 uint32_t Rm = ((ir>>8)&0xF);
1999 if( sh4_x86.in_delay_slot ) {
2003 load_reg( R_EAX, Rm );
2004 call_func1( sh4_write_sr, R_EAX );
2005 sh4_x86.priv_checked = FALSE;
2006 sh4_x86.fpuen_checked = FALSE;
2007 sh4_x86.tstate = TSTATE_NONE;
2013 uint32_t Rm = ((ir>>8)&0xF);
2014 load_reg( R_EAX, Rm );
2015 store_spreg( R_EAX, R_GBR );
2020 uint32_t Rm = ((ir>>8)&0xF);
2022 load_reg( R_EAX, Rm );
2023 store_spreg( R_EAX, R_VBR );
2024 sh4_x86.tstate = TSTATE_NONE;
2029 uint32_t Rm = ((ir>>8)&0xF);
2031 load_reg( R_EAX, Rm );
2032 store_spreg( R_EAX, R_SSR );
2033 sh4_x86.tstate = TSTATE_NONE;
2038 uint32_t Rm = ((ir>>8)&0xF);
2040 load_reg( R_EAX, Rm );
2041 store_spreg( R_EAX, R_SPC );
2042 sh4_x86.tstate = TSTATE_NONE;
2051 { /* LDC Rm, Rn_BANK */
2052 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2054 load_reg( R_EAX, Rm );
2055 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2056 sh4_x86.tstate = TSTATE_NONE;
2062 { /* MAC.W @Rm+, @Rn+ */
2063 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2065 load_reg( R_EAX, Rm );
2066 check_ralign16( R_EAX );
2067 MMU_TRANSLATE_READ( R_EAX );
2068 PUSH_realigned_r32( R_EAX );
2069 load_reg( R_EAX, Rn );
2070 ADD_imm8s_r32( 2, R_EAX );
2071 MMU_TRANSLATE_READ( R_EAX );
2072 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
2073 // Note translate twice in case of page boundaries. Maybe worth
2074 // adding a page-boundary check to skip the second translation
2076 load_reg( R_EAX, Rm );
2077 check_ralign16( R_EAX );
2078 MMU_TRANSLATE_READ( R_EAX );
2079 PUSH_realigned_r32( R_EAX );
2080 load_reg( R_EAX, Rn );
2081 check_ralign16( R_EAX );
2082 MMU_TRANSLATE_READ( R_EAX );
2083 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2084 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2086 MEM_READ_WORD( R_EAX, R_EAX );
2089 MEM_READ_WORD( R_ECX, R_EAX );
2090 POP_realigned_r32( R_ECX );
2093 load_spreg( R_ECX, R_S );
2094 TEST_r32_r32( R_ECX, R_ECX );
2095 JE_rel8( 47, nosat );
2097 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2098 JNO_rel8( 51, end ); // 2
2099 load_imm32( R_EDX, 1 ); // 5
2100 store_spreg( R_EDX, R_MACH ); // 6
2101 JS_rel8( 13, positive ); // 2
2102 load_imm32( R_EAX, 0x80000000 );// 5
2103 store_spreg( R_EAX, R_MACL ); // 6
2104 JMP_rel8( 25, end2 ); // 2
2106 JMP_TARGET(positive);
2107 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2108 store_spreg( R_EAX, R_MACL ); // 6
2109 JMP_rel8( 12, end3); // 2
2112 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2113 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2117 sh4_x86.tstate = TSTATE_NONE;
2123 { /* MOV.L @(disp, Rm), Rn */
2124 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2125 load_reg( R_EAX, Rm );
2126 ADD_imm8s_r32( disp, R_EAX );
2127 check_ralign32( R_EAX );
2128 MMU_TRANSLATE_READ( R_EAX );
2129 MEM_READ_LONG( R_EAX, R_EAX );
2130 store_reg( R_EAX, Rn );
2131 sh4_x86.tstate = TSTATE_NONE;
2137 { /* MOV.B @Rm, Rn */
2138 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2139 load_reg( R_EAX, Rm );
2140 MMU_TRANSLATE_READ( R_EAX );
2141 MEM_READ_BYTE( R_EAX, R_EAX );
2142 store_reg( R_EAX, Rn );
2143 sh4_x86.tstate = TSTATE_NONE;
2147 { /* MOV.W @Rm, Rn */
2148 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2149 load_reg( R_EAX, Rm );
2150 check_ralign16( R_EAX );
2151 MMU_TRANSLATE_READ( R_EAX );
2152 MEM_READ_WORD( R_EAX, R_EAX );
2153 store_reg( R_EAX, Rn );
2154 sh4_x86.tstate = TSTATE_NONE;
2158 { /* MOV.L @Rm, Rn */
2159 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2160 load_reg( R_EAX, Rm );
2161 check_ralign32( R_EAX );
2162 MMU_TRANSLATE_READ( R_EAX );
2163 MEM_READ_LONG( R_EAX, R_EAX );
2164 store_reg( R_EAX, Rn );
2165 sh4_x86.tstate = TSTATE_NONE;
2170 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2171 load_reg( R_EAX, Rm );
2172 store_reg( R_EAX, Rn );
2176 { /* MOV.B @Rm+, Rn */
2177 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2178 load_reg( R_EAX, Rm );
2179 MMU_TRANSLATE_READ( R_EAX );
2180 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
2181 MEM_READ_BYTE( R_EAX, R_EAX );
2182 store_reg( R_EAX, Rn );
2183 sh4_x86.tstate = TSTATE_NONE;
2187 { /* MOV.W @Rm+, Rn */
2188 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2189 load_reg( R_EAX, Rm );
2190 check_ralign16( R_EAX );
2191 MMU_TRANSLATE_READ( R_EAX );
2192 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2193 MEM_READ_WORD( R_EAX, R_EAX );
2194 store_reg( R_EAX, Rn );
2195 sh4_x86.tstate = TSTATE_NONE;
2199 { /* MOV.L @Rm+, Rn */
2200 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2201 load_reg( R_EAX, Rm );
2202 check_ralign32( R_EAX );
2203 MMU_TRANSLATE_READ( R_EAX );
2204 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2205 MEM_READ_LONG( R_EAX, R_EAX );
2206 store_reg( R_EAX, Rn );
2207 sh4_x86.tstate = TSTATE_NONE;
2212 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2213 load_reg( R_EAX, Rm );
2215 store_reg( R_EAX, Rn );
2216 sh4_x86.tstate = TSTATE_NONE;
2220 { /* SWAP.B Rm, Rn */
2221 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2222 load_reg( R_EAX, Rm );
2223 XCHG_r8_r8( R_AL, R_AH );
2224 store_reg( R_EAX, Rn );
2228 { /* SWAP.W Rm, Rn */
2229 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2230 load_reg( R_EAX, Rm );
2231 MOV_r32_r32( R_EAX, R_ECX );
2232 SHL_imm8_r32( 16, R_ECX );
2233 SHR_imm8_r32( 16, R_EAX );
2234 OR_r32_r32( R_EAX, R_ECX );
2235 store_reg( R_ECX, Rn );
2236 sh4_x86.tstate = TSTATE_NONE;
2241 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2242 load_reg( R_EAX, Rm );
2243 XOR_r32_r32( R_ECX, R_ECX );
2245 SBB_r32_r32( R_EAX, R_ECX );
2246 store_reg( R_ECX, Rn );
2248 sh4_x86.tstate = TSTATE_C;
2253 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2254 load_reg( R_EAX, Rm );
2256 store_reg( R_EAX, Rn );
2257 sh4_x86.tstate = TSTATE_NONE;
2261 { /* EXTU.B Rm, Rn */
2262 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2263 load_reg( R_EAX, Rm );
2264 MOVZX_r8_r32( R_EAX, R_EAX );
2265 store_reg( R_EAX, Rn );
2269 { /* EXTU.W Rm, Rn */
2270 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2271 load_reg( R_EAX, Rm );
2272 MOVZX_r16_r32( R_EAX, R_EAX );
2273 store_reg( R_EAX, Rn );
2277 { /* EXTS.B Rm, Rn */
2278 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2279 load_reg( R_EAX, Rm );
2280 MOVSX_r8_r32( R_EAX, R_EAX );
2281 store_reg( R_EAX, Rn );
2285 { /* EXTS.W Rm, Rn */
2286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2287 load_reg( R_EAX, Rm );
2288 MOVSX_r16_r32( R_EAX, R_EAX );
2289 store_reg( R_EAX, Rn );
2295 { /* ADD #imm, Rn */
2296 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2297 load_reg( R_EAX, Rn );
2298 ADD_imm8s_r32( imm, R_EAX );
2299 store_reg( R_EAX, Rn );
2300 sh4_x86.tstate = TSTATE_NONE;
2304 switch( (ir&0xF00) >> 8 ) {
2306 { /* MOV.B R0, @(disp, Rn) */
2307 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2308 load_reg( R_EAX, Rn );
2309 ADD_imm32_r32( disp, R_EAX );
2310 MMU_TRANSLATE_WRITE( R_EAX );
2311 load_reg( R_EDX, 0 );
2312 MEM_WRITE_BYTE( R_EAX, R_EDX );
2313 sh4_x86.tstate = TSTATE_NONE;
2317 { /* MOV.W R0, @(disp, Rn) */
2318 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2319 load_reg( R_EAX, Rn );
2320 ADD_imm32_r32( disp, R_EAX );
2321 check_walign16( R_EAX );
2322 MMU_TRANSLATE_WRITE( R_EAX );
2323 load_reg( R_EDX, 0 );
2324 MEM_WRITE_WORD( R_EAX, R_EDX );
2325 sh4_x86.tstate = TSTATE_NONE;
2329 { /* MOV.B @(disp, Rm), R0 */
2330 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2331 load_reg( R_EAX, Rm );
2332 ADD_imm32_r32( disp, R_EAX );
2333 MMU_TRANSLATE_READ( R_EAX );
2334 MEM_READ_BYTE( R_EAX, R_EAX );
2335 store_reg( R_EAX, 0 );
2336 sh4_x86.tstate = TSTATE_NONE;
2340 { /* MOV.W @(disp, Rm), R0 */
2341 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2342 load_reg( R_EAX, Rm );
2343 ADD_imm32_r32( disp, R_EAX );
2344 check_ralign16( R_EAX );
2345 MMU_TRANSLATE_READ( R_EAX );
2346 MEM_READ_WORD( R_EAX, R_EAX );
2347 store_reg( R_EAX, 0 );
2348 sh4_x86.tstate = TSTATE_NONE;
2352 { /* CMP/EQ #imm, R0 */
2353 int32_t imm = SIGNEXT8(ir&0xFF);
2354 load_reg( R_EAX, 0 );
2355 CMP_imm8s_r32(imm, R_EAX);
2357 sh4_x86.tstate = TSTATE_E;
2362 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2363 if( sh4_x86.in_delay_slot ) {
2366 sh4vma_t target = disp + pc + 4;
2367 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2368 exit_block_rel(target, pc+2 );
2369 JMP_TARGET(nottaken);
2376 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2377 if( sh4_x86.in_delay_slot ) {
2380 sh4vma_t target = disp + pc + 4;
2381 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2382 exit_block_rel(target, pc+2 );
2383 JMP_TARGET(nottaken);
2390 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2391 if( sh4_x86.in_delay_slot ) {
2394 sh4_x86.in_delay_slot = TRUE;
2395 if( sh4_x86.tstate == TSTATE_NONE ) {
2396 CMP_imm8s_sh4r( 1, R_T );
2397 sh4_x86.tstate = TSTATE_E;
2399 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2400 sh4_translate_instruction(pc+2);
2401 exit_block_rel( disp + pc + 4, pc+4 );
2403 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2404 sh4_translate_instruction(pc+2);
2411 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2412 if( sh4_x86.in_delay_slot ) {
2415 sh4vma_t target = disp + pc + 4;
2416 sh4_x86.in_delay_slot = TRUE;
2417 if( sh4_x86.tstate == TSTATE_NONE ) {
2418 CMP_imm8s_sh4r( 1, R_T );
2419 sh4_x86.tstate = TSTATE_E;
2421 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2422 sh4_translate_instruction(pc+2);
2423 exit_block_rel( target, pc+4 );
2425 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2426 sh4_translate_instruction(pc+2);
2437 { /* MOV.W @(disp, PC), Rn */
2438 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2439 if( sh4_x86.in_delay_slot ) {
2442 // See comments for MOV.L @(disp, PC), Rn
2443 uint32_t target = pc + disp + 4;
2444 if( IS_IN_ICACHE(target) ) {
2445 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2446 MOV_moff32_EAX( ptr );
2447 MOVSX_r16_r32( R_EAX, R_EAX );
2449 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
2450 ADD_sh4r_r32( R_PC, R_EAX );
2451 MMU_TRANSLATE_READ( R_EAX );
2452 MEM_READ_WORD( R_EAX, R_EAX );
2453 sh4_x86.tstate = TSTATE_NONE;
2455 store_reg( R_EAX, Rn );
2461 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2462 if( sh4_x86.in_delay_slot ) {
2465 sh4_x86.in_delay_slot = TRUE;
2466 sh4_translate_instruction( pc + 2 );
2467 exit_block_rel( disp + pc + 4, pc+4 );
2468 sh4_x86.branch_taken = TRUE;
2475 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2476 if( sh4_x86.in_delay_slot ) {
2479 load_imm32( R_EAX, pc + 4 );
2480 store_spreg( R_EAX, R_PR );
2481 sh4_x86.in_delay_slot = TRUE;
2482 sh4_translate_instruction( pc + 2 );
2483 exit_block_rel( disp + pc + 4, pc+4 );
2484 sh4_x86.branch_taken = TRUE;
2490 switch( (ir&0xF00) >> 8 ) {
2492 { /* MOV.B R0, @(disp, GBR) */
2493 uint32_t disp = (ir&0xFF);
2494 load_spreg( R_EAX, R_GBR );
2495 ADD_imm32_r32( disp, R_EAX );
2496 MMU_TRANSLATE_WRITE( R_EAX );
2497 load_reg( R_EDX, 0 );
2498 MEM_WRITE_BYTE( R_EAX, R_EDX );
2499 sh4_x86.tstate = TSTATE_NONE;
2503 { /* MOV.W R0, @(disp, GBR) */
2504 uint32_t disp = (ir&0xFF)<<1;
2505 load_spreg( R_EAX, R_GBR );
2506 ADD_imm32_r32( disp, R_EAX );
2507 check_walign16( R_EAX );
2508 MMU_TRANSLATE_WRITE( R_EAX );
2509 load_reg( R_EDX, 0 );
2510 MEM_WRITE_WORD( R_EAX, R_EDX );
2511 sh4_x86.tstate = TSTATE_NONE;
2515 { /* MOV.L R0, @(disp, GBR) */
2516 uint32_t disp = (ir&0xFF)<<2;
2517 load_spreg( R_EAX, R_GBR );
2518 ADD_imm32_r32( disp, R_EAX );
2519 check_walign32( R_EAX );
2520 MMU_TRANSLATE_WRITE( R_EAX );
2521 load_reg( R_EDX, 0 );
2522 MEM_WRITE_LONG( R_EAX, R_EDX );
2523 sh4_x86.tstate = TSTATE_NONE;
2528 uint32_t imm = (ir&0xFF);
2529 if( sh4_x86.in_delay_slot ) {
2532 load_imm32( R_ECX, pc+2 );
2533 store_spreg( R_ECX, REG_OFFSET(pc) );
2534 load_imm32( R_EAX, imm );
2535 call_func1( sh4_raise_trap, R_EAX );
2536 sh4_x86.tstate = TSTATE_NONE;
2537 exit_block_pcset(pc);
2538 sh4_x86.branch_taken = TRUE;
2544 { /* MOV.B @(disp, GBR), R0 */
2545 uint32_t disp = (ir&0xFF);
2546 load_spreg( R_EAX, R_GBR );
2547 ADD_imm32_r32( disp, R_EAX );
2548 MMU_TRANSLATE_READ( R_EAX );
2549 MEM_READ_BYTE( R_EAX, R_EAX );
2550 store_reg( R_EAX, 0 );
2551 sh4_x86.tstate = TSTATE_NONE;
2555 { /* MOV.W @(disp, GBR), R0 */
2556 uint32_t disp = (ir&0xFF)<<1;
2557 load_spreg( R_EAX, R_GBR );
2558 ADD_imm32_r32( disp, R_EAX );
2559 check_ralign16( R_EAX );
2560 MMU_TRANSLATE_READ( R_EAX );
2561 MEM_READ_WORD( R_EAX, R_EAX );
2562 store_reg( R_EAX, 0 );
2563 sh4_x86.tstate = TSTATE_NONE;
2567 { /* MOV.L @(disp, GBR), R0 */
2568 uint32_t disp = (ir&0xFF)<<2;
2569 load_spreg( R_EAX, R_GBR );
2570 ADD_imm32_r32( disp, R_EAX );
2571 check_ralign32( R_EAX );
2572 MMU_TRANSLATE_READ( R_EAX );
2573 MEM_READ_LONG( R_EAX, R_EAX );
2574 store_reg( R_EAX, 0 );
2575 sh4_x86.tstate = TSTATE_NONE;
2579 { /* MOVA @(disp, PC), R0 */
2580 uint32_t disp = (ir&0xFF)<<2;
2581 if( sh4_x86.in_delay_slot ) {
2584 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2585 ADD_sh4r_r32( R_PC, R_ECX );
2586 store_reg( R_ECX, 0 );
2587 sh4_x86.tstate = TSTATE_NONE;
2592 { /* TST #imm, R0 */
2593 uint32_t imm = (ir&0xFF);
2594 load_reg( R_EAX, 0 );
2595 TEST_imm32_r32( imm, R_EAX );
2597 sh4_x86.tstate = TSTATE_E;
2601 { /* AND #imm, R0 */
2602 uint32_t imm = (ir&0xFF);
2603 load_reg( R_EAX, 0 );
2604 AND_imm32_r32(imm, R_EAX);
2605 store_reg( R_EAX, 0 );
2606 sh4_x86.tstate = TSTATE_NONE;
2610 { /* XOR #imm, R0 */
2611 uint32_t imm = (ir&0xFF);
2612 load_reg( R_EAX, 0 );
2613 XOR_imm32_r32( imm, R_EAX );
2614 store_reg( R_EAX, 0 );
2615 sh4_x86.tstate = TSTATE_NONE;
2620 uint32_t imm = (ir&0xFF);
2621 load_reg( R_EAX, 0 );
2622 OR_imm32_r32(imm, R_EAX);
2623 store_reg( R_EAX, 0 );
2624 sh4_x86.tstate = TSTATE_NONE;
2628 { /* TST.B #imm, @(R0, GBR) */
2629 uint32_t imm = (ir&0xFF);
2630 load_reg( R_EAX, 0);
2631 load_reg( R_ECX, R_GBR);
2632 ADD_r32_r32( R_ECX, R_EAX );
2633 MMU_TRANSLATE_READ( R_EAX );
2634 MEM_READ_BYTE( R_EAX, R_EAX );
2635 TEST_imm8_r8( imm, R_AL );
2637 sh4_x86.tstate = TSTATE_E;
2641 { /* AND.B #imm, @(R0, GBR) */
2642 uint32_t imm = (ir&0xFF);
2643 load_reg( R_EAX, 0 );
2644 load_spreg( R_ECX, R_GBR );
2645 ADD_r32_r32( R_ECX, R_EAX );
2646 MMU_TRANSLATE_WRITE( R_EAX );
2647 PUSH_realigned_r32(R_EAX);
2648 MEM_READ_BYTE( R_EAX, R_EAX );
2649 POP_realigned_r32(R_ECX);
2650 AND_imm32_r32(imm, R_EAX );
2651 MEM_WRITE_BYTE( R_ECX, R_EAX );
2652 sh4_x86.tstate = TSTATE_NONE;
2656 { /* XOR.B #imm, @(R0, GBR) */
2657 uint32_t imm = (ir&0xFF);
2658 load_reg( R_EAX, 0 );
2659 load_spreg( R_ECX, R_GBR );
2660 ADD_r32_r32( R_ECX, R_EAX );
2661 MMU_TRANSLATE_WRITE( R_EAX );
2662 PUSH_realigned_r32(R_EAX);
2663 MEM_READ_BYTE(R_EAX, R_EAX);
2664 POP_realigned_r32(R_ECX);
2665 XOR_imm32_r32( imm, R_EAX );
2666 MEM_WRITE_BYTE( R_ECX, R_EAX );
2667 sh4_x86.tstate = TSTATE_NONE;
2671 { /* OR.B #imm, @(R0, GBR) */
2672 uint32_t imm = (ir&0xFF);
2673 load_reg( R_EAX, 0 );
2674 load_spreg( R_ECX, R_GBR );
2675 ADD_r32_r32( R_ECX, R_EAX );
2676 MMU_TRANSLATE_WRITE( R_EAX );
2677 PUSH_realigned_r32(R_EAX);
2678 MEM_READ_BYTE( R_EAX, R_EAX );
2679 POP_realigned_r32(R_ECX);
2680 OR_imm32_r32(imm, R_EAX );
2681 MEM_WRITE_BYTE( R_ECX, R_EAX );
2682 sh4_x86.tstate = TSTATE_NONE;
2688 { /* MOV.L @(disp, PC), Rn */
2689 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2690 if( sh4_x86.in_delay_slot ) {
2693 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2694 if( IS_IN_ICACHE(target) ) {
2695 // If the target address is in the same page as the code, it's
2696 // pretty safe to just ref it directly and circumvent the whole
2697 // memory subsystem. (this is a big performance win)
2699 // FIXME: There's a corner-case that's not handled here when
2700 // the current code-page is in the ITLB but not in the UTLB.
2701 // (should generate a TLB miss although need to test SH4
2702 // behaviour to confirm) Unlikely to be anyone depending on this
2703 // behaviour though.
2704 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2705 MOV_moff32_EAX( ptr );
2707 // Note: we use sh4r.pc for the calc as we could be running at a
2708 // different virtual address than the translation was done with,
2709 // but we can safely assume that the low bits are the same.
2710 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2711 ADD_sh4r_r32( R_PC, R_EAX );
2712 MMU_TRANSLATE_READ( R_EAX );
2713 MEM_READ_LONG( R_EAX, R_EAX );
2714 sh4_x86.tstate = TSTATE_NONE;
2716 store_reg( R_EAX, Rn );
2721 { /* MOV #imm, Rn */
2722 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2723 load_imm32( R_EAX, imm );
2724 store_reg( R_EAX, Rn );
2730 { /* FADD FRm, FRn */
2731 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2733 load_spreg( R_ECX, R_FPSCR );
2734 TEST_imm32_r32( FPSCR_PR, R_ECX );
2735 load_fr_bank( R_EDX );
2736 JNE_rel8(13,doubleprec);
2737 push_fr(R_EDX, FRm);
2738 push_fr(R_EDX, FRn);
2742 JMP_TARGET(doubleprec);
2743 push_dr(R_EDX, FRm);
2744 push_dr(R_EDX, FRn);
2748 sh4_x86.tstate = TSTATE_NONE;
2752 { /* FSUB FRm, FRn */
2753 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2755 load_spreg( R_ECX, R_FPSCR );
2756 TEST_imm32_r32( FPSCR_PR, R_ECX );
2757 load_fr_bank( R_EDX );
2758 JNE_rel8(13, doubleprec);
2759 push_fr(R_EDX, FRn);
2760 push_fr(R_EDX, FRm);
2764 JMP_TARGET(doubleprec);
2765 push_dr(R_EDX, FRn);
2766 push_dr(R_EDX, FRm);
2770 sh4_x86.tstate = TSTATE_NONE;
2774 { /* FMUL FRm, FRn */
2775 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2777 load_spreg( R_ECX, R_FPSCR );
2778 TEST_imm32_r32( FPSCR_PR, R_ECX );
2779 load_fr_bank( R_EDX );
2780 JNE_rel8(13, doubleprec);
2781 push_fr(R_EDX, FRm);
2782 push_fr(R_EDX, FRn);
2786 JMP_TARGET(doubleprec);
2787 push_dr(R_EDX, FRm);
2788 push_dr(R_EDX, FRn);
2792 sh4_x86.tstate = TSTATE_NONE;
2796 { /* FDIV FRm, FRn */
2797 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2799 load_spreg( R_ECX, R_FPSCR );
2800 TEST_imm32_r32( FPSCR_PR, R_ECX );
2801 load_fr_bank( R_EDX );
2802 JNE_rel8(13, doubleprec);
2803 push_fr(R_EDX, FRn);
2804 push_fr(R_EDX, FRm);
2808 JMP_TARGET(doubleprec);
2809 push_dr(R_EDX, FRn);
2810 push_dr(R_EDX, FRm);
2814 sh4_x86.tstate = TSTATE_NONE;
2818 { /* FCMP/EQ FRm, FRn */
2819 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2821 load_spreg( R_ECX, R_FPSCR );
2822 TEST_imm32_r32( FPSCR_PR, R_ECX );
2823 load_fr_bank( R_EDX );
2824 JNE_rel8(8, doubleprec);
2825 push_fr(R_EDX, FRm);
2826 push_fr(R_EDX, FRn);
2828 JMP_TARGET(doubleprec);
2829 push_dr(R_EDX, FRm);
2830 push_dr(R_EDX, FRn);
2835 sh4_x86.tstate = TSTATE_NONE;
2839 { /* FCMP/GT FRm, FRn */
2840 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2842 load_spreg( R_ECX, R_FPSCR );
2843 TEST_imm32_r32( FPSCR_PR, R_ECX );
2844 load_fr_bank( R_EDX );
2845 JNE_rel8(8, doubleprec);
2846 push_fr(R_EDX, FRm);
2847 push_fr(R_EDX, FRn);
2849 JMP_TARGET(doubleprec);
2850 push_dr(R_EDX, FRm);
2851 push_dr(R_EDX, FRn);
2856 sh4_x86.tstate = TSTATE_NONE;
2860 { /* FMOV @(R0, Rm), FRn */
2861 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2863 load_reg( R_EAX, Rm );
2864 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2865 check_ralign32( R_EAX );
2866 MMU_TRANSLATE_READ( R_EAX );
2867 load_spreg( R_EDX, R_FPSCR );
2868 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2869 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2870 MEM_READ_LONG( R_EAX, R_EAX );
2871 load_fr_bank( R_EDX );
2872 store_fr( R_EDX, R_EAX, FRn );
2874 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2875 JMP_TARGET(doublesize);
2876 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2877 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2878 load_xf_bank( R_EDX );
2879 store_fr( R_EDX, R_ECX, FRn&0x0E );
2880 store_fr( R_EDX, R_EAX, FRn|0x01 );
2883 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2884 JMP_TARGET(doublesize);
2885 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2886 load_fr_bank( R_EDX );
2887 store_fr( R_EDX, R_ECX, FRn&0x0E );
2888 store_fr( R_EDX, R_EAX, FRn|0x01 );
2891 sh4_x86.tstate = TSTATE_NONE;
2895 { /* FMOV FRm, @(R0, Rn) */
2896 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2898 load_reg( R_EAX, Rn );
2899 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2900 check_walign32( R_EAX );
2901 MMU_TRANSLATE_WRITE( R_EAX );
2902 load_spreg( R_EDX, R_FPSCR );
2903 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2904 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
2905 load_fr_bank( R_EDX );
2906 load_fr( R_EDX, R_ECX, FRm );
2907 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
2909 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
2910 JMP_TARGET(doublesize);
2911 load_xf_bank( R_EDX );
2912 load_fr( R_EDX, R_ECX, FRm&0x0E );
2913 load_fr( R_EDX, R_EDX, FRm|0x01 );
2914 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2917 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
2918 JMP_TARGET(doublesize);
2919 load_fr_bank( R_EDX );
2920 load_fr( R_EDX, R_ECX, FRm&0x0E );
2921 load_fr( R_EDX, R_EDX, FRm|0x01 );
2922 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2925 sh4_x86.tstate = TSTATE_NONE;
2929 { /* FMOV @Rm, FRn */
2930 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2932 load_reg( R_EAX, Rm );
2933 check_ralign32( R_EAX );
2934 MMU_TRANSLATE_READ( R_EAX );
2935 load_spreg( R_EDX, R_FPSCR );
2936 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2937 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2938 MEM_READ_LONG( R_EAX, R_EAX );
2939 load_fr_bank( R_EDX );
2940 store_fr( R_EDX, R_EAX, FRn );
2942 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2943 JMP_TARGET(doublesize);
2944 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2945 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2946 load_xf_bank( R_EDX );
2947 store_fr( R_EDX, R_ECX, FRn&0x0E );
2948 store_fr( R_EDX, R_EAX, FRn|0x01 );
2951 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2952 JMP_TARGET(doublesize);
2953 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2954 load_fr_bank( R_EDX );
2955 store_fr( R_EDX, R_ECX, FRn&0x0E );
2956 store_fr( R_EDX, R_EAX, FRn|0x01 );
2959 sh4_x86.tstate = TSTATE_NONE;
2963 { /* FMOV @Rm+, FRn */
2964 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2966 load_reg( R_EAX, Rm );
2967 check_ralign32( R_EAX );
2968 MMU_TRANSLATE_READ( R_EAX );
2969 load_spreg( R_EDX, R_FPSCR );
2970 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2971 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
2972 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2973 MEM_READ_LONG( R_EAX, R_EAX );
2974 load_fr_bank( R_EDX );
2975 store_fr( R_EDX, R_EAX, FRn );
2977 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
2978 JMP_TARGET(doublesize);
2979 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
2980 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2981 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2982 load_xf_bank( R_EDX );
2983 store_fr( R_EDX, R_ECX, FRn&0x0E );
2984 store_fr( R_EDX, R_EAX, FRn|0x01 );
2987 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
2988 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
2989 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2990 load_fr_bank( R_EDX );
2991 store_fr( R_EDX, R_ECX, FRn&0x0E );
2992 store_fr( R_EDX, R_EAX, FRn|0x01 );
2995 sh4_x86.tstate = TSTATE_NONE;
2999 { /* FMOV FRm, @Rn */
3000 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3002 load_reg( R_EAX, Rn );
3003 check_walign32( R_EAX );
3004 MMU_TRANSLATE_WRITE( R_EAX );
3005 load_spreg( R_EDX, R_FPSCR );
3006 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3007 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
3008 load_fr_bank( R_EDX );
3009 load_fr( R_EDX, R_ECX, FRm );
3010 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3012 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3013 JMP_TARGET(doublesize);
3014 load_xf_bank( R_EDX );
3015 load_fr( R_EDX, R_ECX, FRm&0x0E );
3016 load_fr( R_EDX, R_EDX, FRm|0x01 );
3017 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3020 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3021 JMP_TARGET(doublesize);
3022 load_fr_bank( R_EDX );
3023 load_fr( R_EDX, R_ECX, FRm&0x0E );
3024 load_fr( R_EDX, R_EDX, FRm|0x01 );
3025 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3028 sh4_x86.tstate = TSTATE_NONE;
3032 { /* FMOV FRm, @-Rn */
3033 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3035 load_reg( R_EAX, Rn );
3036 check_walign32( R_EAX );
3037 load_spreg( R_EDX, R_FPSCR );
3038 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3039 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
3040 ADD_imm8s_r32( -4, R_EAX );
3041 MMU_TRANSLATE_WRITE( R_EAX );
3042 load_fr_bank( R_EDX );
3043 load_fr( R_EDX, R_ECX, FRm );
3044 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
3045 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3047 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3048 JMP_TARGET(doublesize);
3049 ADD_imm8s_r32(-8,R_EAX);
3050 MMU_TRANSLATE_WRITE( R_EAX );
3051 load_xf_bank( R_EDX );
3052 load_fr( R_EDX, R_ECX, FRm&0x0E );
3053 load_fr( R_EDX, R_EDX, FRm|0x01 );
3054 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3055 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3058 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3059 JMP_TARGET(doublesize);
3060 ADD_imm8s_r32(-8,R_EAX);
3061 MMU_TRANSLATE_WRITE( R_EAX );
3062 load_fr_bank( R_EDX );
3063 load_fr( R_EDX, R_ECX, FRm&0x0E );
3064 load_fr( R_EDX, R_EDX, FRm|0x01 );
3065 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3066 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3069 sh4_x86.tstate = TSTATE_NONE;
3073 { /* FMOV FRm, FRn */
3074 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3075 /* As horrible as this looks, it's actually covering 5 separate cases:
3076 * 1. 32-bit fr-to-fr (PR=0)
3077 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3078 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3079 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3080 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3083 load_spreg( R_ECX, R_FPSCR );
3084 load_fr_bank( R_EDX );
3085 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3086 JNE_rel8(8, doublesize);
3087 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3088 store_fr( R_EDX, R_EAX, FRn );
3091 JMP_TARGET(doublesize);
3092 load_xf_bank( R_ECX );
3093 load_fr( R_ECX, R_EAX, FRm-1 );
3095 load_fr( R_ECX, R_EDX, FRm );
3096 store_fr( R_ECX, R_EAX, FRn-1 );
3097 store_fr( R_ECX, R_EDX, FRn );
3098 } else /* FRn&1 == 0 */ {
3099 load_fr( R_ECX, R_ECX, FRm );
3100 store_fr( R_EDX, R_EAX, FRn );
3101 store_fr( R_EDX, R_ECX, FRn+1 );
3104 } else /* FRm&1 == 0 */ {
3107 load_xf_bank( R_ECX );
3108 load_fr( R_EDX, R_EAX, FRm );
3109 load_fr( R_EDX, R_EDX, FRm+1 );
3110 store_fr( R_ECX, R_EAX, FRn-1 );
3111 store_fr( R_ECX, R_EDX, FRn );
3113 } else /* FRn&1 == 0 */ {
3115 load_fr( R_EDX, R_EAX, FRm );
3116 load_fr( R_EDX, R_ECX, FRm+1 );
3117 store_fr( R_EDX, R_EAX, FRn );
3118 store_fr( R_EDX, R_ECX, FRn+1 );
3122 sh4_x86.tstate = TSTATE_NONE;
3126 switch( (ir&0xF0) >> 4 ) {
3128 { /* FSTS FPUL, FRn */
3129 uint32_t FRn = ((ir>>8)&0xF);
3131 load_fr_bank( R_ECX );
3132 load_spreg( R_EAX, R_FPUL );
3133 store_fr( R_ECX, R_EAX, FRn );
3134 sh4_x86.tstate = TSTATE_NONE;
3138 { /* FLDS FRm, FPUL */
3139 uint32_t FRm = ((ir>>8)&0xF);
3141 load_fr_bank( R_ECX );
3142 load_fr( R_ECX, R_EAX, FRm );
3143 store_spreg( R_EAX, R_FPUL );
3144 sh4_x86.tstate = TSTATE_NONE;
3148 { /* FLOAT FPUL, FRn */
3149 uint32_t FRn = ((ir>>8)&0xF);
3151 load_spreg( R_ECX, R_FPSCR );
3152 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3154 TEST_imm32_r32( FPSCR_PR, R_ECX );
3155 JNE_rel8(5, doubleprec);
3156 pop_fr( R_EDX, FRn );
3158 JMP_TARGET(doubleprec);
3159 pop_dr( R_EDX, FRn );
3161 sh4_x86.tstate = TSTATE_NONE;
3165 { /* FTRC FRm, FPUL */
3166 uint32_t FRm = ((ir>>8)&0xF);
3168 load_spreg( R_ECX, R_FPSCR );
3169 load_fr_bank( R_EDX );
3170 TEST_imm32_r32( FPSCR_PR, R_ECX );
3171 JNE_rel8(5, doubleprec);
3172 push_fr( R_EDX, FRm );
3174 JMP_TARGET(doubleprec);
3175 push_dr( R_EDX, FRm );
3177 load_imm32( R_ECX, (uint32_t)&max_int );
3178 FILD_r32ind( R_ECX );
3180 JNA_rel8( 32, sat );
3181 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3182 FILD_r32ind( R_ECX ); // 2
3184 JAE_rel8( 21, sat2 ); // 2
3185 load_imm32( R_EAX, (uint32_t)&save_fcw );
3186 FNSTCW_r32ind( R_EAX );
3187 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3188 FLDCW_r32ind( R_EDX );
3189 FISTP_sh4r(R_FPUL); // 3
3190 FLDCW_r32ind( R_EAX );
3191 JMP_rel8( 9, end ); // 2
3195 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3196 store_spreg( R_ECX, R_FPUL );
3199 sh4_x86.tstate = TSTATE_NONE;
3204 uint32_t FRn = ((ir>>8)&0xF);
3206 load_spreg( R_ECX, R_FPSCR );
3207 TEST_imm32_r32( FPSCR_PR, R_ECX );
3208 load_fr_bank( R_EDX );
3209 JNE_rel8(10, doubleprec);
3210 push_fr(R_EDX, FRn);
3214 JMP_TARGET(doubleprec);
3215 push_dr(R_EDX, FRn);
3219 sh4_x86.tstate = TSTATE_NONE;
3224 uint32_t FRn = ((ir>>8)&0xF);
3226 load_spreg( R_ECX, R_FPSCR );
3227 load_fr_bank( R_EDX );
3228 TEST_imm32_r32( FPSCR_PR, R_ECX );
3229 JNE_rel8(10, doubleprec);
3230 push_fr(R_EDX, FRn); // 3
3232 pop_fr( R_EDX, FRn); //3
3233 JMP_rel8(8,end); // 2
3234 JMP_TARGET(doubleprec);
3235 push_dr(R_EDX, FRn);
3239 sh4_x86.tstate = TSTATE_NONE;
3244 uint32_t FRn = ((ir>>8)&0xF);
3246 load_spreg( R_ECX, R_FPSCR );
3247 TEST_imm32_r32( FPSCR_PR, R_ECX );
3248 load_fr_bank( R_EDX );
3249 JNE_rel8(10, doubleprec);
3250 push_fr(R_EDX, FRn);
3254 JMP_TARGET(doubleprec);
3255 push_dr(R_EDX, FRn);
3259 sh4_x86.tstate = TSTATE_NONE;
3264 uint32_t FRn = ((ir>>8)&0xF);
3266 load_spreg( R_ECX, R_FPSCR );
3267 TEST_imm32_r32( FPSCR_PR, R_ECX );
3268 load_fr_bank( R_EDX );
3269 JNE_rel8(12, end); // PR=0 only
3271 push_fr(R_EDX, FRn);
3276 sh4_x86.tstate = TSTATE_NONE;
3281 uint32_t FRn = ((ir>>8)&0xF);
3284 load_spreg( R_ECX, R_FPSCR );
3285 TEST_imm32_r32( FPSCR_PR, R_ECX );
3287 XOR_r32_r32( R_EAX, R_EAX );
3288 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3289 store_fr( R_ECX, R_EAX, FRn );
3291 sh4_x86.tstate = TSTATE_NONE;
3296 uint32_t FRn = ((ir>>8)&0xF);
3299 load_spreg( R_ECX, R_FPSCR );
3300 TEST_imm32_r32( FPSCR_PR, R_ECX );
3302 load_imm32(R_EAX, 0x3F800000);
3303 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3304 store_fr( R_ECX, R_EAX, FRn );
3306 sh4_x86.tstate = TSTATE_NONE;
3310 { /* FCNVSD FPUL, FRn */
3311 uint32_t FRn = ((ir>>8)&0xF);
3313 load_spreg( R_ECX, R_FPSCR );
3314 TEST_imm32_r32( FPSCR_PR, R_ECX );
3315 JE_rel8(9, end); // only when PR=1
3316 load_fr_bank( R_ECX );
3318 pop_dr( R_ECX, FRn );
3320 sh4_x86.tstate = TSTATE_NONE;
3324 { /* FCNVDS FRm, FPUL */
3325 uint32_t FRm = ((ir>>8)&0xF);
3327 load_spreg( R_ECX, R_FPSCR );
3328 TEST_imm32_r32( FPSCR_PR, R_ECX );
3329 JE_rel8(9, end); // only when PR=1
3330 load_fr_bank( R_ECX );
3331 push_dr( R_ECX, FRm );
3334 sh4_x86.tstate = TSTATE_NONE;
3338 { /* FIPR FVm, FVn */
3339 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3341 load_spreg( R_ECX, R_FPSCR );
3342 TEST_imm32_r32( FPSCR_PR, R_ECX );
3343 JNE_rel8(44, doubleprec);
3345 load_fr_bank( R_ECX );
3346 push_fr( R_ECX, FVm<<2 );
3347 push_fr( R_ECX, FVn<<2 );
3349 push_fr( R_ECX, (FVm<<2)+1);
3350 push_fr( R_ECX, (FVn<<2)+1);
3353 push_fr( R_ECX, (FVm<<2)+2);
3354 push_fr( R_ECX, (FVn<<2)+2);
3357 push_fr( R_ECX, (FVm<<2)+3);
3358 push_fr( R_ECX, (FVn<<2)+3);
3361 pop_fr( R_ECX, (FVn<<2)+3);
3362 JMP_TARGET(doubleprec);
3363 sh4_x86.tstate = TSTATE_NONE;
3367 switch( (ir&0x100) >> 8 ) {
3369 { /* FSCA FPUL, FRn */
3370 uint32_t FRn = ((ir>>9)&0x7)<<1;
3372 load_spreg( R_ECX, R_FPSCR );
3373 TEST_imm32_r32( FPSCR_PR, R_ECX );
3374 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3375 load_fr_bank( R_ECX );
3376 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3377 load_spreg( R_EDX, R_FPUL );
3378 call_func2( sh4_fsca, R_EDX, R_ECX );
3379 JMP_TARGET(doubleprec);
3380 sh4_x86.tstate = TSTATE_NONE;
3384 switch( (ir&0x200) >> 9 ) {
3386 { /* FTRV XMTRX, FVn */
3387 uint32_t FVn = ((ir>>10)&0x3);
3389 load_spreg( R_ECX, R_FPSCR );
3390 TEST_imm32_r32( FPSCR_PR, R_ECX );
3391 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3392 load_fr_bank( R_EDX ); // 3
3393 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3394 load_xf_bank( R_ECX ); // 12
3395 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3396 JMP_TARGET(doubleprec);
3397 sh4_x86.tstate = TSTATE_NONE;
3401 switch( (ir&0xC00) >> 10 ) {
3405 load_spreg( R_ECX, R_FPSCR );
3406 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3407 store_spreg( R_ECX, R_FPSCR );
3408 sh4_x86.tstate = TSTATE_NONE;
3414 load_spreg( R_ECX, R_FPSCR );
3415 XOR_imm32_r32( FPSCR_FR, R_ECX );
3416 store_spreg( R_ECX, R_FPSCR );
3417 update_fr_bank( R_ECX );
3418 sh4_x86.tstate = TSTATE_NONE;
3423 if( sh4_x86.in_delay_slot ) {
3426 JMP_exc(EXC_ILLEGAL);
3446 { /* FMAC FR0, FRm, FRn */
3447 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3449 load_spreg( R_ECX, R_FPSCR );
3450 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3451 TEST_imm32_r32( FPSCR_PR, R_ECX );
3452 JNE_rel8(18, doubleprec);
3453 push_fr( R_EDX, 0 );
3454 push_fr( R_EDX, FRm );
3456 push_fr( R_EDX, FRn );
3458 pop_fr( R_EDX, FRn );
3460 JMP_TARGET(doubleprec);
3461 push_dr( R_EDX, 0 );
3462 push_dr( R_EDX, FRm );
3464 push_dr( R_EDX, FRn );
3466 pop_dr( R_EDX, FRn );
3468 sh4_x86.tstate = TSTATE_NONE;
3478 sh4_x86.in_delay_slot = FALSE;
.