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"
358 void sh4_translate_emit_breakpoint( sh4vma_t pc )
360 load_imm32( R_EAX, XLAT_EXIT_BREAKPOINT );
361 call_func1( sh4_translate_exit, R_EAX );
366 * Translate a single instruction. Delayed branches are handled specially
367 * by translating both branch and delayed instruction as a single unit (as
369 * The instruction MUST be in the icache (assert check)
371 * @return true if the instruction marks the end of a basic block
374 uint32_t sh4_translate_instruction( sh4addr_t pc )
377 /* Read instruction from icache */
378 assert( IS_IN_ICACHE(pc) );
379 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
381 /* PC is not in the current icache - this usually means we're running
382 * with MMU on, and we've gone past the end of the page. And since
383 * sh4_translate_block is pretty careful about this, it means we're
384 * almost certainly in a delay slot.
386 * Since we can't assume the page is present (and we can't fault it in
387 * at this point, inline a call to sh4_execute_instruction (with a few
388 * small repairs to cope with the different environment).
391 if( !sh4_x86.in_delay_slot ) {
392 sh4_x86_add_recovery(pc);
394 switch( (ir&0xF000) >> 12 ) {
398 switch( (ir&0x80) >> 7 ) {
400 switch( (ir&0x70) >> 4 ) {
403 uint32_t Rn = ((ir>>8)&0xF);
405 call_func0(sh4_read_sr);
406 store_reg( R_EAX, Rn );
407 sh4_x86.tstate = TSTATE_NONE;
412 uint32_t Rn = ((ir>>8)&0xF);
413 load_spreg( R_EAX, R_GBR );
414 store_reg( R_EAX, Rn );
419 uint32_t Rn = ((ir>>8)&0xF);
421 load_spreg( R_EAX, R_VBR );
422 store_reg( R_EAX, Rn );
423 sh4_x86.tstate = TSTATE_NONE;
428 uint32_t Rn = ((ir>>8)&0xF);
430 load_spreg( R_EAX, R_SSR );
431 store_reg( R_EAX, Rn );
432 sh4_x86.tstate = TSTATE_NONE;
437 uint32_t Rn = ((ir>>8)&0xF);
439 load_spreg( R_EAX, R_SPC );
440 store_reg( R_EAX, Rn );
441 sh4_x86.tstate = TSTATE_NONE;
450 { /* STC Rm_BANK, Rn */
451 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
453 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
454 store_reg( R_EAX, Rn );
455 sh4_x86.tstate = TSTATE_NONE;
461 switch( (ir&0xF0) >> 4 ) {
464 uint32_t Rn = ((ir>>8)&0xF);
465 if( sh4_x86.in_delay_slot ) {
468 load_imm32( R_ECX, pc + 4 );
469 store_spreg( R_ECX, R_PR );
470 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_ECX );
471 store_spreg( R_ECX, REG_OFFSET(pc) );
472 sh4_x86.in_delay_slot = TRUE;
473 sh4_x86.tstate = TSTATE_NONE;
474 sh4_translate_instruction( pc + 2 );
475 exit_block_pcset(pc+2);
476 sh4_x86.branch_taken = TRUE;
483 uint32_t Rn = ((ir>>8)&0xF);
484 if( sh4_x86.in_delay_slot ) {
487 load_reg( R_EAX, Rn );
488 ADD_imm32_r32( pc + 4, R_EAX );
489 store_spreg( R_EAX, REG_OFFSET(pc) );
490 sh4_x86.in_delay_slot = TRUE;
491 sh4_x86.tstate = TSTATE_NONE;
492 sh4_translate_instruction( pc + 2 );
493 exit_block_pcset(pc+2);
494 sh4_x86.branch_taken = TRUE;
501 uint32_t Rn = ((ir>>8)&0xF);
502 load_reg( R_EAX, Rn );
503 MOV_r32_r32( R_EAX, R_ECX );
504 AND_imm32_r32( 0xFC000000, R_EAX );
505 CMP_imm32_r32( 0xE0000000, R_EAX );
506 JNE_rel8(8+CALL_FUNC1_SIZE, end);
507 call_func1( sh4_flush_store_queue, R_ECX );
508 TEST_r32_r32( R_EAX, R_EAX );
511 sh4_x86.tstate = TSTATE_NONE;
516 uint32_t Rn = ((ir>>8)&0xF);
521 uint32_t Rn = ((ir>>8)&0xF);
526 uint32_t Rn = ((ir>>8)&0xF);
530 { /* MOVCA.L R0, @Rn */
531 uint32_t Rn = ((ir>>8)&0xF);
532 load_reg( R_EAX, Rn );
533 check_walign32( R_EAX );
534 MMU_TRANSLATE_WRITE( R_EAX );
535 load_reg( R_EDX, 0 );
536 MEM_WRITE_LONG( R_EAX, R_EDX );
537 sh4_x86.tstate = TSTATE_NONE;
546 { /* MOV.B Rm, @(R0, Rn) */
547 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
548 load_reg( R_EAX, 0 );
549 load_reg( R_ECX, Rn );
550 ADD_r32_r32( R_ECX, R_EAX );
551 MMU_TRANSLATE_WRITE( R_EAX );
552 load_reg( R_EDX, Rm );
553 MEM_WRITE_BYTE( R_EAX, R_EDX );
554 sh4_x86.tstate = TSTATE_NONE;
558 { /* MOV.W Rm, @(R0, Rn) */
559 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
560 load_reg( R_EAX, 0 );
561 load_reg( R_ECX, Rn );
562 ADD_r32_r32( R_ECX, R_EAX );
563 check_walign16( R_EAX );
564 MMU_TRANSLATE_WRITE( R_EAX );
565 load_reg( R_EDX, Rm );
566 MEM_WRITE_WORD( R_EAX, R_EDX );
567 sh4_x86.tstate = TSTATE_NONE;
571 { /* MOV.L Rm, @(R0, Rn) */
572 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
573 load_reg( R_EAX, 0 );
574 load_reg( R_ECX, Rn );
575 ADD_r32_r32( R_ECX, R_EAX );
576 check_walign32( R_EAX );
577 MMU_TRANSLATE_WRITE( R_EAX );
578 load_reg( R_EDX, Rm );
579 MEM_WRITE_LONG( R_EAX, R_EDX );
580 sh4_x86.tstate = TSTATE_NONE;
585 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
586 load_reg( R_EAX, Rm );
587 load_reg( R_ECX, Rn );
589 store_spreg( R_EAX, R_MACL );
590 sh4_x86.tstate = TSTATE_NONE;
594 switch( (ir&0xFF0) >> 4 ) {
599 sh4_x86.tstate = TSTATE_C;
606 sh4_x86.tstate = TSTATE_C;
611 XOR_r32_r32(R_EAX, R_EAX);
612 store_spreg( R_EAX, R_MACL );
613 store_spreg( R_EAX, R_MACH );
614 sh4_x86.tstate = TSTATE_NONE;
619 call_func0( MMU_ldtlb );
626 sh4_x86.tstate = TSTATE_C;
633 sh4_x86.tstate = TSTATE_C;
642 switch( (ir&0xF0) >> 4 ) {
645 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
650 XOR_r32_r32( R_EAX, R_EAX );
651 store_spreg( R_EAX, R_Q );
652 store_spreg( R_EAX, R_M );
653 store_spreg( R_EAX, R_T );
654 sh4_x86.tstate = TSTATE_C; // works for DIV1
659 uint32_t Rn = ((ir>>8)&0xF);
660 load_spreg( R_EAX, R_T );
661 store_reg( R_EAX, Rn );
670 switch( (ir&0xF0) >> 4 ) {
673 uint32_t Rn = ((ir>>8)&0xF);
674 load_spreg( R_EAX, R_MACH );
675 store_reg( R_EAX, Rn );
680 uint32_t Rn = ((ir>>8)&0xF);
681 load_spreg( R_EAX, R_MACL );
682 store_reg( R_EAX, Rn );
687 uint32_t Rn = ((ir>>8)&0xF);
688 load_spreg( R_EAX, R_PR );
689 store_reg( R_EAX, Rn );
694 uint32_t Rn = ((ir>>8)&0xF);
696 load_spreg( R_EAX, R_SGR );
697 store_reg( R_EAX, Rn );
698 sh4_x86.tstate = TSTATE_NONE;
703 uint32_t Rn = ((ir>>8)&0xF);
704 load_spreg( R_EAX, R_FPUL );
705 store_reg( R_EAX, Rn );
709 { /* STS FPSCR, Rn */
710 uint32_t Rn = ((ir>>8)&0xF);
711 load_spreg( R_EAX, R_FPSCR );
712 store_reg( R_EAX, Rn );
717 uint32_t Rn = ((ir>>8)&0xF);
719 load_spreg( R_EAX, R_DBR );
720 store_reg( R_EAX, Rn );
721 sh4_x86.tstate = TSTATE_NONE;
730 switch( (ir&0xFF0) >> 4 ) {
733 if( sh4_x86.in_delay_slot ) {
736 load_spreg( R_ECX, R_PR );
737 store_spreg( R_ECX, REG_OFFSET(pc) );
738 sh4_x86.in_delay_slot = TRUE;
739 sh4_translate_instruction(pc+2);
740 exit_block_pcset(pc+2);
741 sh4_x86.branch_taken = TRUE;
749 call_func0( sh4_sleep );
750 sh4_x86.tstate = TSTATE_NONE;
751 sh4_x86.in_delay_slot = FALSE;
757 if( sh4_x86.in_delay_slot ) {
761 load_spreg( R_ECX, R_SPC );
762 store_spreg( R_ECX, REG_OFFSET(pc) );
763 load_spreg( R_EAX, R_SSR );
764 call_func1( sh4_write_sr, R_EAX );
765 sh4_x86.in_delay_slot = TRUE;
766 sh4_x86.priv_checked = FALSE;
767 sh4_x86.fpuen_checked = FALSE;
768 sh4_x86.tstate = TSTATE_NONE;
769 sh4_translate_instruction(pc+2);
770 exit_block_pcset(pc+2);
771 sh4_x86.branch_taken = TRUE;
782 { /* MOV.B @(R0, Rm), Rn */
783 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
784 load_reg( R_EAX, 0 );
785 load_reg( R_ECX, Rm );
786 ADD_r32_r32( R_ECX, R_EAX );
787 MMU_TRANSLATE_READ( R_EAX )
788 MEM_READ_BYTE( R_EAX, R_EAX );
789 store_reg( R_EAX, Rn );
790 sh4_x86.tstate = TSTATE_NONE;
794 { /* MOV.W @(R0, Rm), Rn */
795 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
796 load_reg( R_EAX, 0 );
797 load_reg( R_ECX, Rm );
798 ADD_r32_r32( R_ECX, R_EAX );
799 check_ralign16( R_EAX );
800 MMU_TRANSLATE_READ( R_EAX );
801 MEM_READ_WORD( R_EAX, R_EAX );
802 store_reg( R_EAX, Rn );
803 sh4_x86.tstate = TSTATE_NONE;
807 { /* MOV.L @(R0, Rm), Rn */
808 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
809 load_reg( R_EAX, 0 );
810 load_reg( R_ECX, Rm );
811 ADD_r32_r32( R_ECX, R_EAX );
812 check_ralign32( R_EAX );
813 MMU_TRANSLATE_READ( R_EAX );
814 MEM_READ_LONG( R_EAX, R_EAX );
815 store_reg( R_EAX, Rn );
816 sh4_x86.tstate = TSTATE_NONE;
820 { /* MAC.L @Rm+, @Rn+ */
821 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
823 load_reg( R_EAX, Rm );
824 check_ralign32( R_EAX );
825 MMU_TRANSLATE_READ( R_EAX );
826 PUSH_realigned_r32( R_EAX );
827 load_reg( R_EAX, Rn );
828 ADD_imm8s_r32( 4, R_EAX );
829 MMU_TRANSLATE_READ( R_EAX );
830 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
831 // Note translate twice in case of page boundaries. Maybe worth
832 // adding a page-boundary check to skip the second translation
834 load_reg( R_EAX, Rm );
835 check_ralign32( R_EAX );
836 MMU_TRANSLATE_READ( R_EAX );
837 PUSH_realigned_r32( R_EAX );
838 load_reg( R_EAX, Rn );
839 check_ralign32( R_EAX );
840 MMU_TRANSLATE_READ( R_EAX );
841 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
842 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
844 MEM_READ_LONG( R_EAX, R_EAX );
847 MEM_READ_LONG( R_ECX, R_EAX );
848 POP_realigned_r32( R_ECX );
851 ADD_r32_sh4r( R_EAX, R_MACL );
852 ADC_r32_sh4r( R_EDX, R_MACH );
854 load_spreg( R_ECX, R_S );
855 TEST_r32_r32(R_ECX, R_ECX);
856 JE_rel8( CALL_FUNC0_SIZE, nosat );
857 call_func0( signsat48 );
859 sh4_x86.tstate = TSTATE_NONE;
868 { /* MOV.L Rm, @(disp, Rn) */
869 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
870 load_reg( R_EAX, Rn );
871 ADD_imm32_r32( disp, R_EAX );
872 check_walign32( R_EAX );
873 MMU_TRANSLATE_WRITE( R_EAX );
874 load_reg( R_EDX, Rm );
875 MEM_WRITE_LONG( R_EAX, R_EDX );
876 sh4_x86.tstate = TSTATE_NONE;
882 { /* MOV.B Rm, @Rn */
883 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
884 load_reg( R_EAX, Rn );
885 MMU_TRANSLATE_WRITE( R_EAX );
886 load_reg( R_EDX, Rm );
887 MEM_WRITE_BYTE( R_EAX, R_EDX );
888 sh4_x86.tstate = TSTATE_NONE;
892 { /* MOV.W Rm, @Rn */
893 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
894 load_reg( R_EAX, Rn );
895 check_walign16( R_EAX );
896 MMU_TRANSLATE_WRITE( R_EAX )
897 load_reg( R_EDX, Rm );
898 MEM_WRITE_WORD( R_EAX, R_EDX );
899 sh4_x86.tstate = TSTATE_NONE;
903 { /* MOV.L Rm, @Rn */
904 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
905 load_reg( R_EAX, Rn );
906 check_walign32(R_EAX);
907 MMU_TRANSLATE_WRITE( R_EAX );
908 load_reg( R_EDX, Rm );
909 MEM_WRITE_LONG( R_EAX, R_EDX );
910 sh4_x86.tstate = TSTATE_NONE;
914 { /* MOV.B Rm, @-Rn */
915 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
916 load_reg( R_EAX, Rn );
917 ADD_imm8s_r32( -1, R_EAX );
918 MMU_TRANSLATE_WRITE( R_EAX );
919 load_reg( R_EDX, Rm );
920 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
921 MEM_WRITE_BYTE( R_EAX, R_EDX );
922 sh4_x86.tstate = TSTATE_NONE;
926 { /* MOV.W Rm, @-Rn */
927 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
928 load_reg( R_EAX, Rn );
929 ADD_imm8s_r32( -2, R_EAX );
930 check_walign16( R_EAX );
931 MMU_TRANSLATE_WRITE( R_EAX );
932 load_reg( R_EDX, Rm );
933 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
934 MEM_WRITE_WORD( R_EAX, R_EDX );
935 sh4_x86.tstate = TSTATE_NONE;
939 { /* MOV.L Rm, @-Rn */
940 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
941 load_reg( R_EAX, Rn );
942 ADD_imm8s_r32( -4, R_EAX );
943 check_walign32( R_EAX );
944 MMU_TRANSLATE_WRITE( R_EAX );
945 load_reg( R_EDX, Rm );
946 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
947 MEM_WRITE_LONG( R_EAX, R_EDX );
948 sh4_x86.tstate = TSTATE_NONE;
953 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
954 load_reg( R_EAX, Rm );
955 load_reg( R_ECX, Rn );
956 SHR_imm8_r32( 31, R_EAX );
957 SHR_imm8_r32( 31, R_ECX );
958 store_spreg( R_EAX, R_M );
959 store_spreg( R_ECX, R_Q );
960 CMP_r32_r32( R_EAX, R_ECX );
962 sh4_x86.tstate = TSTATE_NE;
967 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
968 load_reg( R_EAX, Rm );
969 load_reg( R_ECX, Rn );
970 TEST_r32_r32( R_EAX, R_ECX );
972 sh4_x86.tstate = TSTATE_E;
977 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
978 load_reg( R_EAX, Rm );
979 load_reg( R_ECX, Rn );
980 AND_r32_r32( R_EAX, R_ECX );
981 store_reg( R_ECX, Rn );
982 sh4_x86.tstate = TSTATE_NONE;
987 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
988 load_reg( R_EAX, Rm );
989 load_reg( R_ECX, Rn );
990 XOR_r32_r32( R_EAX, R_ECX );
991 store_reg( R_ECX, Rn );
992 sh4_x86.tstate = TSTATE_NONE;
997 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
998 load_reg( R_EAX, Rm );
999 load_reg( R_ECX, Rn );
1000 OR_r32_r32( R_EAX, R_ECX );
1001 store_reg( R_ECX, Rn );
1002 sh4_x86.tstate = TSTATE_NONE;
1006 { /* CMP/STR Rm, Rn */
1007 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1008 load_reg( R_EAX, Rm );
1009 load_reg( R_ECX, Rn );
1010 XOR_r32_r32( R_ECX, R_EAX );
1011 TEST_r8_r8( R_AL, R_AL );
1012 JE_rel8(13, target1);
1013 TEST_r8_r8( R_AH, R_AH ); // 2
1014 JE_rel8(9, target2);
1015 SHR_imm8_r32( 16, R_EAX ); // 3
1016 TEST_r8_r8( R_AL, R_AL ); // 2
1017 JE_rel8(2, target3);
1018 TEST_r8_r8( R_AH, R_AH ); // 2
1019 JMP_TARGET(target1);
1020 JMP_TARGET(target2);
1021 JMP_TARGET(target3);
1023 sh4_x86.tstate = TSTATE_E;
1027 { /* XTRCT Rm, Rn */
1028 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1029 load_reg( R_EAX, Rm );
1030 load_reg( R_ECX, Rn );
1031 SHL_imm8_r32( 16, R_EAX );
1032 SHR_imm8_r32( 16, R_ECX );
1033 OR_r32_r32( R_EAX, R_ECX );
1034 store_reg( R_ECX, Rn );
1035 sh4_x86.tstate = TSTATE_NONE;
1039 { /* MULU.W Rm, Rn */
1040 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1041 load_reg16u( R_EAX, Rm );
1042 load_reg16u( R_ECX, Rn );
1044 store_spreg( R_EAX, R_MACL );
1045 sh4_x86.tstate = TSTATE_NONE;
1049 { /* MULS.W Rm, Rn */
1050 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1051 load_reg16s( R_EAX, Rm );
1052 load_reg16s( R_ECX, Rn );
1054 store_spreg( R_EAX, R_MACL );
1055 sh4_x86.tstate = TSTATE_NONE;
1066 { /* CMP/EQ 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 CMP_r32_r32( R_EAX, R_ECX );
1072 sh4_x86.tstate = TSTATE_E;
1076 { /* CMP/HS Rm, Rn */
1077 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1078 load_reg( R_EAX, Rm );
1079 load_reg( R_ECX, Rn );
1080 CMP_r32_r32( R_EAX, R_ECX );
1082 sh4_x86.tstate = TSTATE_AE;
1086 { /* CMP/GE Rm, Rn */
1087 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1088 load_reg( R_EAX, Rm );
1089 load_reg( R_ECX, Rn );
1090 CMP_r32_r32( R_EAX, R_ECX );
1092 sh4_x86.tstate = TSTATE_GE;
1097 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1098 load_spreg( R_ECX, R_M );
1099 load_reg( R_EAX, Rn );
1100 if( sh4_x86.tstate != TSTATE_C ) {
1104 SETC_r8( R_DL ); // Q'
1105 CMP_sh4r_r32( R_Q, R_ECX );
1106 JE_rel8(5, mqequal);
1107 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1109 JMP_TARGET(mqequal);
1110 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1112 store_reg( R_EAX, Rn ); // Done with Rn now
1113 SETC_r8(R_AL); // tmp1
1114 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1115 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1116 store_spreg( R_ECX, R_Q );
1117 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1118 MOVZX_r8_r32( R_AL, R_EAX );
1119 store_spreg( R_EAX, R_T );
1120 sh4_x86.tstate = TSTATE_NONE;
1124 { /* DMULU.L Rm, Rn */
1125 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1126 load_reg( R_EAX, Rm );
1127 load_reg( R_ECX, Rn );
1129 store_spreg( R_EDX, R_MACH );
1130 store_spreg( R_EAX, R_MACL );
1131 sh4_x86.tstate = TSTATE_NONE;
1135 { /* CMP/HI Rm, Rn */
1136 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1137 load_reg( R_EAX, Rm );
1138 load_reg( R_ECX, Rn );
1139 CMP_r32_r32( R_EAX, R_ECX );
1141 sh4_x86.tstate = TSTATE_A;
1145 { /* CMP/GT Rm, Rn */
1146 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1147 load_reg( R_EAX, Rm );
1148 load_reg( R_ECX, Rn );
1149 CMP_r32_r32( R_EAX, R_ECX );
1151 sh4_x86.tstate = TSTATE_G;
1156 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1157 load_reg( R_EAX, Rm );
1158 load_reg( R_ECX, Rn );
1159 SUB_r32_r32( R_EAX, R_ECX );
1160 store_reg( R_ECX, Rn );
1161 sh4_x86.tstate = TSTATE_NONE;
1166 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1167 load_reg( R_EAX, Rm );
1168 load_reg( R_ECX, Rn );
1169 if( sh4_x86.tstate != TSTATE_C ) {
1172 SBB_r32_r32( R_EAX, R_ECX );
1173 store_reg( R_ECX, Rn );
1175 sh4_x86.tstate = TSTATE_C;
1180 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1181 load_reg( R_EAX, Rm );
1182 load_reg( R_ECX, Rn );
1183 SUB_r32_r32( R_EAX, R_ECX );
1184 store_reg( R_ECX, Rn );
1186 sh4_x86.tstate = TSTATE_O;
1191 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1192 load_reg( R_EAX, Rm );
1193 load_reg( R_ECX, Rn );
1194 ADD_r32_r32( R_EAX, R_ECX );
1195 store_reg( R_ECX, Rn );
1196 sh4_x86.tstate = TSTATE_NONE;
1200 { /* DMULS.L Rm, Rn */
1201 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1202 load_reg( R_EAX, Rm );
1203 load_reg( R_ECX, Rn );
1205 store_spreg( R_EDX, R_MACH );
1206 store_spreg( R_EAX, R_MACL );
1207 sh4_x86.tstate = TSTATE_NONE;
1212 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1213 if( sh4_x86.tstate != TSTATE_C ) {
1216 load_reg( R_EAX, Rm );
1217 load_reg( R_ECX, Rn );
1218 ADC_r32_r32( R_EAX, R_ECX );
1219 store_reg( R_ECX, Rn );
1221 sh4_x86.tstate = TSTATE_C;
1226 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1227 load_reg( R_EAX, Rm );
1228 load_reg( R_ECX, Rn );
1229 ADD_r32_r32( R_EAX, R_ECX );
1230 store_reg( R_ECX, Rn );
1232 sh4_x86.tstate = TSTATE_O;
1243 switch( (ir&0xF0) >> 4 ) {
1246 uint32_t Rn = ((ir>>8)&0xF);
1247 load_reg( R_EAX, Rn );
1250 store_reg( R_EAX, Rn );
1251 sh4_x86.tstate = TSTATE_C;
1256 uint32_t Rn = ((ir>>8)&0xF);
1257 load_reg( R_EAX, Rn );
1258 ADD_imm8s_r32( -1, R_EAX );
1259 store_reg( R_EAX, Rn );
1261 sh4_x86.tstate = TSTATE_E;
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;
1280 switch( (ir&0xF0) >> 4 ) {
1283 uint32_t Rn = ((ir>>8)&0xF);
1284 load_reg( R_EAX, Rn );
1287 store_reg( R_EAX, Rn );
1288 sh4_x86.tstate = TSTATE_C;
1293 uint32_t Rn = ((ir>>8)&0xF);
1294 load_reg( R_EAX, Rn );
1295 CMP_imm8s_r32( 0, R_EAX );
1297 sh4_x86.tstate = TSTATE_GE;
1302 uint32_t Rn = ((ir>>8)&0xF);
1303 load_reg( R_EAX, Rn );
1306 store_reg( R_EAX, Rn );
1307 sh4_x86.tstate = TSTATE_C;
1316 switch( (ir&0xF0) >> 4 ) {
1318 { /* STS.L MACH, @-Rn */
1319 uint32_t Rn = ((ir>>8)&0xF);
1320 load_reg( R_EAX, Rn );
1321 check_walign32( R_EAX );
1322 ADD_imm8s_r32( -4, R_EAX );
1323 MMU_TRANSLATE_WRITE( R_EAX );
1324 load_spreg( R_EDX, R_MACH );
1325 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1326 MEM_WRITE_LONG( R_EAX, R_EDX );
1327 sh4_x86.tstate = TSTATE_NONE;
1331 { /* STS.L MACL, @-Rn */
1332 uint32_t Rn = ((ir>>8)&0xF);
1333 load_reg( R_EAX, Rn );
1334 check_walign32( R_EAX );
1335 ADD_imm8s_r32( -4, R_EAX );
1336 MMU_TRANSLATE_WRITE( R_EAX );
1337 load_spreg( R_EDX, R_MACL );
1338 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1339 MEM_WRITE_LONG( R_EAX, R_EDX );
1340 sh4_x86.tstate = TSTATE_NONE;
1344 { /* STS.L PR, @-Rn */
1345 uint32_t Rn = ((ir>>8)&0xF);
1346 load_reg( R_EAX, Rn );
1347 check_walign32( R_EAX );
1348 ADD_imm8s_r32( -4, R_EAX );
1349 MMU_TRANSLATE_WRITE( R_EAX );
1350 load_spreg( R_EDX, R_PR );
1351 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1352 MEM_WRITE_LONG( R_EAX, R_EDX );
1353 sh4_x86.tstate = TSTATE_NONE;
1357 { /* STC.L SGR, @-Rn */
1358 uint32_t Rn = ((ir>>8)&0xF);
1360 load_reg( R_EAX, Rn );
1361 check_walign32( R_EAX );
1362 ADD_imm8s_r32( -4, R_EAX );
1363 MMU_TRANSLATE_WRITE( R_EAX );
1364 load_spreg( R_EDX, R_SGR );
1365 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1366 MEM_WRITE_LONG( R_EAX, R_EDX );
1367 sh4_x86.tstate = TSTATE_NONE;
1371 { /* STS.L FPUL, @-Rn */
1372 uint32_t Rn = ((ir>>8)&0xF);
1373 load_reg( R_EAX, Rn );
1374 check_walign32( R_EAX );
1375 ADD_imm8s_r32( -4, R_EAX );
1376 MMU_TRANSLATE_WRITE( R_EAX );
1377 load_spreg( R_EDX, R_FPUL );
1378 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1379 MEM_WRITE_LONG( R_EAX, R_EDX );
1380 sh4_x86.tstate = TSTATE_NONE;
1384 { /* STS.L FPSCR, @-Rn */
1385 uint32_t Rn = ((ir>>8)&0xF);
1386 load_reg( R_EAX, Rn );
1387 check_walign32( R_EAX );
1388 ADD_imm8s_r32( -4, R_EAX );
1389 MMU_TRANSLATE_WRITE( R_EAX );
1390 load_spreg( R_EDX, R_FPSCR );
1391 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1392 MEM_WRITE_LONG( R_EAX, R_EDX );
1393 sh4_x86.tstate = TSTATE_NONE;
1397 { /* STC.L DBR, @-Rn */
1398 uint32_t Rn = ((ir>>8)&0xF);
1400 load_reg( R_EAX, Rn );
1401 check_walign32( R_EAX );
1402 ADD_imm8s_r32( -4, R_EAX );
1403 MMU_TRANSLATE_WRITE( R_EAX );
1404 load_spreg( R_EDX, R_DBR );
1405 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1406 MEM_WRITE_LONG( R_EAX, R_EDX );
1407 sh4_x86.tstate = TSTATE_NONE;
1416 switch( (ir&0x80) >> 7 ) {
1418 switch( (ir&0x70) >> 4 ) {
1420 { /* STC.L SR, @-Rn */
1421 uint32_t Rn = ((ir>>8)&0xF);
1423 load_reg( R_EAX, Rn );
1424 check_walign32( R_EAX );
1425 ADD_imm8s_r32( -4, R_EAX );
1426 MMU_TRANSLATE_WRITE( R_EAX );
1427 PUSH_realigned_r32( R_EAX );
1428 call_func0( sh4_read_sr );
1429 POP_realigned_r32( R_ECX );
1430 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1431 MEM_WRITE_LONG( R_ECX, R_EAX );
1432 sh4_x86.tstate = TSTATE_NONE;
1436 { /* STC.L GBR, @-Rn */
1437 uint32_t Rn = ((ir>>8)&0xF);
1438 load_reg( R_EAX, Rn );
1439 check_walign32( R_EAX );
1440 ADD_imm8s_r32( -4, R_EAX );
1441 MMU_TRANSLATE_WRITE( R_EAX );
1442 load_spreg( R_EDX, R_GBR );
1443 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1444 MEM_WRITE_LONG( R_EAX, R_EDX );
1445 sh4_x86.tstate = TSTATE_NONE;
1449 { /* STC.L VBR, @-Rn */
1450 uint32_t Rn = ((ir>>8)&0xF);
1452 load_reg( R_EAX, Rn );
1453 check_walign32( R_EAX );
1454 ADD_imm8s_r32( -4, R_EAX );
1455 MMU_TRANSLATE_WRITE( R_EAX );
1456 load_spreg( R_EDX, R_VBR );
1457 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1458 MEM_WRITE_LONG( R_EAX, R_EDX );
1459 sh4_x86.tstate = TSTATE_NONE;
1463 { /* STC.L SSR, @-Rn */
1464 uint32_t Rn = ((ir>>8)&0xF);
1466 load_reg( R_EAX, Rn );
1467 check_walign32( R_EAX );
1468 ADD_imm8s_r32( -4, R_EAX );
1469 MMU_TRANSLATE_WRITE( R_EAX );
1470 load_spreg( R_EDX, R_SSR );
1471 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1472 MEM_WRITE_LONG( R_EAX, R_EDX );
1473 sh4_x86.tstate = TSTATE_NONE;
1477 { /* STC.L SPC, @-Rn */
1478 uint32_t Rn = ((ir>>8)&0xF);
1480 load_reg( R_EAX, Rn );
1481 check_walign32( R_EAX );
1482 ADD_imm8s_r32( -4, R_EAX );
1483 MMU_TRANSLATE_WRITE( R_EAX );
1484 load_spreg( R_EDX, R_SPC );
1485 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1486 MEM_WRITE_LONG( R_EAX, R_EDX );
1487 sh4_x86.tstate = TSTATE_NONE;
1496 { /* STC.L Rm_BANK, @-Rn */
1497 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1499 load_reg( R_EAX, Rn );
1500 check_walign32( R_EAX );
1501 ADD_imm8s_r32( -4, R_EAX );
1502 MMU_TRANSLATE_WRITE( R_EAX );
1503 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1504 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1505 MEM_WRITE_LONG( R_EAX, R_EDX );
1506 sh4_x86.tstate = TSTATE_NONE;
1512 switch( (ir&0xF0) >> 4 ) {
1515 uint32_t Rn = ((ir>>8)&0xF);
1516 load_reg( R_EAX, Rn );
1518 store_reg( R_EAX, Rn );
1520 sh4_x86.tstate = TSTATE_C;
1525 uint32_t Rn = ((ir>>8)&0xF);
1526 load_reg( R_EAX, Rn );
1527 if( sh4_x86.tstate != TSTATE_C ) {
1531 store_reg( R_EAX, Rn );
1533 sh4_x86.tstate = TSTATE_C;
1542 switch( (ir&0xF0) >> 4 ) {
1545 uint32_t Rn = ((ir>>8)&0xF);
1546 load_reg( R_EAX, Rn );
1548 store_reg( R_EAX, Rn );
1550 sh4_x86.tstate = TSTATE_C;
1555 uint32_t Rn = ((ir>>8)&0xF);
1556 load_reg( R_EAX, Rn );
1557 CMP_imm8s_r32( 0, R_EAX );
1559 sh4_x86.tstate = TSTATE_G;
1564 uint32_t Rn = ((ir>>8)&0xF);
1565 load_reg( R_EAX, Rn );
1566 if( sh4_x86.tstate != TSTATE_C ) {
1570 store_reg( R_EAX, Rn );
1572 sh4_x86.tstate = TSTATE_C;
1581 switch( (ir&0xF0) >> 4 ) {
1583 { /* LDS.L @Rm+, MACH */
1584 uint32_t Rm = ((ir>>8)&0xF);
1585 load_reg( R_EAX, Rm );
1586 check_ralign32( R_EAX );
1587 MMU_TRANSLATE_READ( R_EAX );
1588 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1589 MEM_READ_LONG( R_EAX, R_EAX );
1590 store_spreg( R_EAX, R_MACH );
1591 sh4_x86.tstate = TSTATE_NONE;
1595 { /* LDS.L @Rm+, MACL */
1596 uint32_t Rm = ((ir>>8)&0xF);
1597 load_reg( R_EAX, Rm );
1598 check_ralign32( R_EAX );
1599 MMU_TRANSLATE_READ( R_EAX );
1600 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1601 MEM_READ_LONG( R_EAX, R_EAX );
1602 store_spreg( R_EAX, R_MACL );
1603 sh4_x86.tstate = TSTATE_NONE;
1607 { /* LDS.L @Rm+, PR */
1608 uint32_t Rm = ((ir>>8)&0xF);
1609 load_reg( R_EAX, Rm );
1610 check_ralign32( R_EAX );
1611 MMU_TRANSLATE_READ( R_EAX );
1612 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1613 MEM_READ_LONG( R_EAX, R_EAX );
1614 store_spreg( R_EAX, R_PR );
1615 sh4_x86.tstate = TSTATE_NONE;
1619 { /* LDC.L @Rm+, SGR */
1620 uint32_t Rm = ((ir>>8)&0xF);
1622 load_reg( R_EAX, Rm );
1623 check_ralign32( R_EAX );
1624 MMU_TRANSLATE_READ( R_EAX );
1625 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1626 MEM_READ_LONG( R_EAX, R_EAX );
1627 store_spreg( R_EAX, R_SGR );
1628 sh4_x86.tstate = TSTATE_NONE;
1632 { /* LDS.L @Rm+, FPUL */
1633 uint32_t Rm = ((ir>>8)&0xF);
1634 load_reg( R_EAX, Rm );
1635 check_ralign32( R_EAX );
1636 MMU_TRANSLATE_READ( R_EAX );
1637 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1638 MEM_READ_LONG( R_EAX, R_EAX );
1639 store_spreg( R_EAX, R_FPUL );
1640 sh4_x86.tstate = TSTATE_NONE;
1644 { /* LDS.L @Rm+, FPSCR */
1645 uint32_t Rm = ((ir>>8)&0xF);
1646 load_reg( R_EAX, Rm );
1647 check_ralign32( R_EAX );
1648 MMU_TRANSLATE_READ( R_EAX );
1649 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1650 MEM_READ_LONG( R_EAX, R_EAX );
1651 store_spreg( R_EAX, R_FPSCR );
1652 update_fr_bank( R_EAX );
1653 sh4_x86.tstate = TSTATE_NONE;
1657 { /* LDC.L @Rm+, DBR */
1658 uint32_t Rm = ((ir>>8)&0xF);
1660 load_reg( R_EAX, Rm );
1661 check_ralign32( R_EAX );
1662 MMU_TRANSLATE_READ( R_EAX );
1663 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1664 MEM_READ_LONG( R_EAX, R_EAX );
1665 store_spreg( R_EAX, R_DBR );
1666 sh4_x86.tstate = TSTATE_NONE;
1675 switch( (ir&0x80) >> 7 ) {
1677 switch( (ir&0x70) >> 4 ) {
1679 { /* LDC.L @Rm+, SR */
1680 uint32_t Rm = ((ir>>8)&0xF);
1681 if( sh4_x86.in_delay_slot ) {
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 call_func1( sh4_write_sr, R_EAX );
1691 sh4_x86.priv_checked = FALSE;
1692 sh4_x86.fpuen_checked = FALSE;
1693 sh4_x86.tstate = TSTATE_NONE;
1698 { /* LDC.L @Rm+, GBR */
1699 uint32_t Rm = ((ir>>8)&0xF);
1700 load_reg( R_EAX, Rm );
1701 check_ralign32( R_EAX );
1702 MMU_TRANSLATE_READ( R_EAX );
1703 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1704 MEM_READ_LONG( R_EAX, R_EAX );
1705 store_spreg( R_EAX, R_GBR );
1706 sh4_x86.tstate = TSTATE_NONE;
1710 { /* LDC.L @Rm+, VBR */
1711 uint32_t Rm = ((ir>>8)&0xF);
1713 load_reg( R_EAX, Rm );
1714 check_ralign32( R_EAX );
1715 MMU_TRANSLATE_READ( R_EAX );
1716 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1717 MEM_READ_LONG( R_EAX, R_EAX );
1718 store_spreg( R_EAX, R_VBR );
1719 sh4_x86.tstate = TSTATE_NONE;
1723 { /* LDC.L @Rm+, SSR */
1724 uint32_t Rm = ((ir>>8)&0xF);
1726 load_reg( R_EAX, Rm );
1727 check_ralign32( R_EAX );
1728 MMU_TRANSLATE_READ( R_EAX );
1729 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1730 MEM_READ_LONG( R_EAX, R_EAX );
1731 store_spreg( R_EAX, R_SSR );
1732 sh4_x86.tstate = TSTATE_NONE;
1736 { /* LDC.L @Rm+, SPC */
1737 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_SPC );
1745 sh4_x86.tstate = TSTATE_NONE;
1754 { /* LDC.L @Rm+, Rn_BANK */
1755 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1757 load_reg( R_EAX, Rm );
1758 check_ralign32( R_EAX );
1759 MMU_TRANSLATE_READ( R_EAX );
1760 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1761 MEM_READ_LONG( R_EAX, R_EAX );
1762 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1763 sh4_x86.tstate = TSTATE_NONE;
1769 switch( (ir&0xF0) >> 4 ) {
1772 uint32_t Rn = ((ir>>8)&0xF);
1773 load_reg( R_EAX, Rn );
1774 SHL_imm8_r32( 2, R_EAX );
1775 store_reg( R_EAX, Rn );
1776 sh4_x86.tstate = TSTATE_NONE;
1781 uint32_t Rn = ((ir>>8)&0xF);
1782 load_reg( R_EAX, Rn );
1783 SHL_imm8_r32( 8, R_EAX );
1784 store_reg( R_EAX, Rn );
1785 sh4_x86.tstate = TSTATE_NONE;
1790 uint32_t Rn = ((ir>>8)&0xF);
1791 load_reg( R_EAX, Rn );
1792 SHL_imm8_r32( 16, R_EAX );
1793 store_reg( R_EAX, Rn );
1794 sh4_x86.tstate = TSTATE_NONE;
1803 switch( (ir&0xF0) >> 4 ) {
1806 uint32_t Rn = ((ir>>8)&0xF);
1807 load_reg( R_EAX, Rn );
1808 SHR_imm8_r32( 2, R_EAX );
1809 store_reg( R_EAX, Rn );
1810 sh4_x86.tstate = TSTATE_NONE;
1815 uint32_t Rn = ((ir>>8)&0xF);
1816 load_reg( R_EAX, Rn );
1817 SHR_imm8_r32( 8, R_EAX );
1818 store_reg( R_EAX, Rn );
1819 sh4_x86.tstate = TSTATE_NONE;
1824 uint32_t Rn = ((ir>>8)&0xF);
1825 load_reg( R_EAX, Rn );
1826 SHR_imm8_r32( 16, R_EAX );
1827 store_reg( R_EAX, Rn );
1828 sh4_x86.tstate = TSTATE_NONE;
1837 switch( (ir&0xF0) >> 4 ) {
1839 { /* LDS Rm, MACH */
1840 uint32_t Rm = ((ir>>8)&0xF);
1841 load_reg( R_EAX, Rm );
1842 store_spreg( R_EAX, R_MACH );
1846 { /* LDS Rm, MACL */
1847 uint32_t Rm = ((ir>>8)&0xF);
1848 load_reg( R_EAX, Rm );
1849 store_spreg( R_EAX, R_MACL );
1854 uint32_t Rm = ((ir>>8)&0xF);
1855 load_reg( R_EAX, Rm );
1856 store_spreg( R_EAX, R_PR );
1861 uint32_t Rm = ((ir>>8)&0xF);
1863 load_reg( R_EAX, Rm );
1864 store_spreg( R_EAX, R_SGR );
1865 sh4_x86.tstate = TSTATE_NONE;
1869 { /* LDS Rm, FPUL */
1870 uint32_t Rm = ((ir>>8)&0xF);
1871 load_reg( R_EAX, Rm );
1872 store_spreg( R_EAX, R_FPUL );
1876 { /* LDS Rm, FPSCR */
1877 uint32_t Rm = ((ir>>8)&0xF);
1878 load_reg( R_EAX, Rm );
1879 store_spreg( R_EAX, R_FPSCR );
1880 update_fr_bank( R_EAX );
1881 sh4_x86.tstate = TSTATE_NONE;
1886 uint32_t Rm = ((ir>>8)&0xF);
1888 load_reg( R_EAX, Rm );
1889 store_spreg( R_EAX, R_DBR );
1890 sh4_x86.tstate = TSTATE_NONE;
1899 switch( (ir&0xF0) >> 4 ) {
1902 uint32_t Rn = ((ir>>8)&0xF);
1903 if( sh4_x86.in_delay_slot ) {
1906 load_imm32( R_EAX, pc + 4 );
1907 store_spreg( R_EAX, R_PR );
1908 load_reg( R_ECX, Rn );
1909 store_spreg( R_ECX, REG_OFFSET(pc) );
1910 sh4_x86.in_delay_slot = TRUE;
1911 sh4_translate_instruction(pc+2);
1912 exit_block_pcset(pc+2);
1913 sh4_x86.branch_taken = TRUE;
1920 uint32_t Rn = ((ir>>8)&0xF);
1921 load_reg( R_EAX, Rn );
1922 MMU_TRANSLATE_WRITE( R_EAX );
1923 PUSH_realigned_r32( R_EAX );
1924 MEM_READ_BYTE( R_EAX, R_EAX );
1925 TEST_r8_r8( R_AL, R_AL );
1927 OR_imm8_r8( 0x80, R_AL );
1928 POP_realigned_r32( R_ECX );
1929 MEM_WRITE_BYTE( R_ECX, R_EAX );
1930 sh4_x86.tstate = TSTATE_NONE;
1935 uint32_t Rn = ((ir>>8)&0xF);
1936 if( sh4_x86.in_delay_slot ) {
1939 load_reg( R_ECX, Rn );
1940 store_spreg( R_ECX, REG_OFFSET(pc) );
1941 sh4_x86.in_delay_slot = TRUE;
1942 sh4_translate_instruction(pc+2);
1943 exit_block_pcset(pc+2);
1944 sh4_x86.branch_taken = TRUE;
1956 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1957 /* Annoyingly enough, not directly convertible */
1958 load_reg( R_EAX, Rn );
1959 load_reg( R_ECX, Rm );
1960 CMP_imm32_r32( 0, R_ECX );
1961 JGE_rel8(16, doshl);
1963 NEG_r32( R_ECX ); // 2
1964 AND_imm8_r8( 0x1F, R_CL ); // 3
1965 JE_rel8( 4, emptysar); // 2
1966 SAR_r32_CL( R_EAX ); // 2
1967 JMP_rel8(10, end); // 2
1969 JMP_TARGET(emptysar);
1970 SAR_imm8_r32(31, R_EAX ); // 3
1974 AND_imm8_r8( 0x1F, R_CL ); // 3
1975 SHL_r32_CL( R_EAX ); // 2
1978 store_reg( R_EAX, Rn );
1979 sh4_x86.tstate = TSTATE_NONE;
1984 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1985 load_reg( R_EAX, Rn );
1986 load_reg( R_ECX, Rm );
1987 CMP_imm32_r32( 0, R_ECX );
1988 JGE_rel8(15, doshl);
1990 NEG_r32( R_ECX ); // 2
1991 AND_imm8_r8( 0x1F, R_CL ); // 3
1992 JE_rel8( 4, emptyshr );
1993 SHR_r32_CL( R_EAX ); // 2
1994 JMP_rel8(9, end); // 2
1996 JMP_TARGET(emptyshr);
1997 XOR_r32_r32( R_EAX, R_EAX );
2001 AND_imm8_r8( 0x1F, R_CL ); // 3
2002 SHL_r32_CL( R_EAX ); // 2
2005 store_reg( R_EAX, Rn );
2006 sh4_x86.tstate = TSTATE_NONE;
2010 switch( (ir&0x80) >> 7 ) {
2012 switch( (ir&0x70) >> 4 ) {
2015 uint32_t Rm = ((ir>>8)&0xF);
2016 if( sh4_x86.in_delay_slot ) {
2020 load_reg( R_EAX, Rm );
2021 call_func1( sh4_write_sr, R_EAX );
2022 sh4_x86.priv_checked = FALSE;
2023 sh4_x86.fpuen_checked = FALSE;
2024 sh4_x86.tstate = TSTATE_NONE;
2030 uint32_t Rm = ((ir>>8)&0xF);
2031 load_reg( R_EAX, Rm );
2032 store_spreg( R_EAX, R_GBR );
2037 uint32_t Rm = ((ir>>8)&0xF);
2039 load_reg( R_EAX, Rm );
2040 store_spreg( R_EAX, R_VBR );
2041 sh4_x86.tstate = TSTATE_NONE;
2046 uint32_t Rm = ((ir>>8)&0xF);
2048 load_reg( R_EAX, Rm );
2049 store_spreg( R_EAX, R_SSR );
2050 sh4_x86.tstate = TSTATE_NONE;
2055 uint32_t Rm = ((ir>>8)&0xF);
2057 load_reg( R_EAX, Rm );
2058 store_spreg( R_EAX, R_SPC );
2059 sh4_x86.tstate = TSTATE_NONE;
2068 { /* LDC Rm, Rn_BANK */
2069 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2071 load_reg( R_EAX, Rm );
2072 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2073 sh4_x86.tstate = TSTATE_NONE;
2079 { /* MAC.W @Rm+, @Rn+ */
2080 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2082 load_reg( R_EAX, Rm );
2083 check_ralign16( R_EAX );
2084 MMU_TRANSLATE_READ( R_EAX );
2085 PUSH_realigned_r32( R_EAX );
2086 load_reg( R_EAX, Rn );
2087 ADD_imm8s_r32( 2, R_EAX );
2088 MMU_TRANSLATE_READ( R_EAX );
2089 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
2090 // Note translate twice in case of page boundaries. Maybe worth
2091 // adding a page-boundary check to skip the second translation
2093 load_reg( R_EAX, Rm );
2094 check_ralign16( R_EAX );
2095 MMU_TRANSLATE_READ( R_EAX );
2096 PUSH_realigned_r32( R_EAX );
2097 load_reg( R_EAX, Rn );
2098 check_ralign16( R_EAX );
2099 MMU_TRANSLATE_READ( R_EAX );
2100 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2101 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2103 MEM_READ_WORD( R_EAX, R_EAX );
2106 MEM_READ_WORD( R_ECX, R_EAX );
2107 POP_realigned_r32( R_ECX );
2110 load_spreg( R_ECX, R_S );
2111 TEST_r32_r32( R_ECX, R_ECX );
2112 JE_rel8( 47, nosat );
2114 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2115 JNO_rel8( 51, end ); // 2
2116 load_imm32( R_EDX, 1 ); // 5
2117 store_spreg( R_EDX, R_MACH ); // 6
2118 JS_rel8( 13, positive ); // 2
2119 load_imm32( R_EAX, 0x80000000 );// 5
2120 store_spreg( R_EAX, R_MACL ); // 6
2121 JMP_rel8( 25, end2 ); // 2
2123 JMP_TARGET(positive);
2124 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2125 store_spreg( R_EAX, R_MACL ); // 6
2126 JMP_rel8( 12, end3); // 2
2129 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2130 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2134 sh4_x86.tstate = TSTATE_NONE;
2140 { /* MOV.L @(disp, Rm), Rn */
2141 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2142 load_reg( R_EAX, Rm );
2143 ADD_imm8s_r32( disp, R_EAX );
2144 check_ralign32( R_EAX );
2145 MMU_TRANSLATE_READ( R_EAX );
2146 MEM_READ_LONG( R_EAX, R_EAX );
2147 store_reg( R_EAX, Rn );
2148 sh4_x86.tstate = TSTATE_NONE;
2154 { /* MOV.B @Rm, Rn */
2155 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2156 load_reg( R_EAX, Rm );
2157 MMU_TRANSLATE_READ( R_EAX );
2158 MEM_READ_BYTE( R_EAX, R_EAX );
2159 store_reg( R_EAX, Rn );
2160 sh4_x86.tstate = TSTATE_NONE;
2164 { /* MOV.W @Rm, Rn */
2165 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2166 load_reg( R_EAX, Rm );
2167 check_ralign16( R_EAX );
2168 MMU_TRANSLATE_READ( R_EAX );
2169 MEM_READ_WORD( R_EAX, R_EAX );
2170 store_reg( R_EAX, Rn );
2171 sh4_x86.tstate = TSTATE_NONE;
2175 { /* MOV.L @Rm, Rn */
2176 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2177 load_reg( R_EAX, Rm );
2178 check_ralign32( R_EAX );
2179 MMU_TRANSLATE_READ( R_EAX );
2180 MEM_READ_LONG( R_EAX, R_EAX );
2181 store_reg( R_EAX, Rn );
2182 sh4_x86.tstate = TSTATE_NONE;
2187 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2188 load_reg( R_EAX, Rm );
2189 store_reg( R_EAX, Rn );
2193 { /* MOV.B @Rm+, Rn */
2194 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2195 load_reg( R_EAX, Rm );
2196 MMU_TRANSLATE_READ( R_EAX );
2197 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
2198 MEM_READ_BYTE( R_EAX, R_EAX );
2199 store_reg( R_EAX, Rn );
2200 sh4_x86.tstate = TSTATE_NONE;
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 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2210 MEM_READ_WORD( R_EAX, R_EAX );
2211 store_reg( R_EAX, Rn );
2212 sh4_x86.tstate = TSTATE_NONE;
2216 { /* MOV.L @Rm+, Rn */
2217 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2218 load_reg( R_EAX, Rm );
2219 check_ralign32( R_EAX );
2220 MMU_TRANSLATE_READ( R_EAX );
2221 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2222 MEM_READ_LONG( R_EAX, R_EAX );
2223 store_reg( R_EAX, Rn );
2224 sh4_x86.tstate = TSTATE_NONE;
2229 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2230 load_reg( R_EAX, Rm );
2232 store_reg( R_EAX, Rn );
2233 sh4_x86.tstate = TSTATE_NONE;
2237 { /* SWAP.B Rm, Rn */
2238 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2239 load_reg( R_EAX, Rm );
2240 XCHG_r8_r8( R_AL, R_AH );
2241 store_reg( R_EAX, Rn );
2245 { /* SWAP.W Rm, Rn */
2246 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2247 load_reg( R_EAX, Rm );
2248 MOV_r32_r32( R_EAX, R_ECX );
2249 SHL_imm8_r32( 16, R_ECX );
2250 SHR_imm8_r32( 16, R_EAX );
2251 OR_r32_r32( R_EAX, R_ECX );
2252 store_reg( R_ECX, Rn );
2253 sh4_x86.tstate = TSTATE_NONE;
2258 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2259 load_reg( R_EAX, Rm );
2260 XOR_r32_r32( R_ECX, R_ECX );
2262 SBB_r32_r32( R_EAX, R_ECX );
2263 store_reg( R_ECX, Rn );
2265 sh4_x86.tstate = TSTATE_C;
2270 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2271 load_reg( R_EAX, Rm );
2273 store_reg( R_EAX, Rn );
2274 sh4_x86.tstate = TSTATE_NONE;
2278 { /* EXTU.B Rm, Rn */
2279 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2280 load_reg( R_EAX, Rm );
2281 MOVZX_r8_r32( R_EAX, R_EAX );
2282 store_reg( R_EAX, Rn );
2286 { /* EXTU.W Rm, Rn */
2287 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2288 load_reg( R_EAX, Rm );
2289 MOVZX_r16_r32( R_EAX, R_EAX );
2290 store_reg( R_EAX, Rn );
2294 { /* EXTS.B Rm, Rn */
2295 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2296 load_reg( R_EAX, Rm );
2297 MOVSX_r8_r32( R_EAX, R_EAX );
2298 store_reg( R_EAX, Rn );
2302 { /* EXTS.W Rm, Rn */
2303 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2304 load_reg( R_EAX, Rm );
2305 MOVSX_r16_r32( R_EAX, R_EAX );
2306 store_reg( R_EAX, Rn );
2312 { /* ADD #imm, Rn */
2313 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2314 load_reg( R_EAX, Rn );
2315 ADD_imm8s_r32( imm, R_EAX );
2316 store_reg( R_EAX, Rn );
2317 sh4_x86.tstate = TSTATE_NONE;
2321 switch( (ir&0xF00) >> 8 ) {
2323 { /* MOV.B R0, @(disp, Rn) */
2324 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2325 load_reg( R_EAX, Rn );
2326 ADD_imm32_r32( disp, R_EAX );
2327 MMU_TRANSLATE_WRITE( R_EAX );
2328 load_reg( R_EDX, 0 );
2329 MEM_WRITE_BYTE( R_EAX, R_EDX );
2330 sh4_x86.tstate = TSTATE_NONE;
2334 { /* MOV.W R0, @(disp, Rn) */
2335 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2336 load_reg( R_EAX, Rn );
2337 ADD_imm32_r32( disp, R_EAX );
2338 check_walign16( R_EAX );
2339 MMU_TRANSLATE_WRITE( R_EAX );
2340 load_reg( R_EDX, 0 );
2341 MEM_WRITE_WORD( R_EAX, R_EDX );
2342 sh4_x86.tstate = TSTATE_NONE;
2346 { /* MOV.B @(disp, Rm), R0 */
2347 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2348 load_reg( R_EAX, Rm );
2349 ADD_imm32_r32( disp, R_EAX );
2350 MMU_TRANSLATE_READ( R_EAX );
2351 MEM_READ_BYTE( R_EAX, R_EAX );
2352 store_reg( R_EAX, 0 );
2353 sh4_x86.tstate = TSTATE_NONE;
2357 { /* MOV.W @(disp, Rm), R0 */
2358 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2359 load_reg( R_EAX, Rm );
2360 ADD_imm32_r32( disp, R_EAX );
2361 check_ralign16( R_EAX );
2362 MMU_TRANSLATE_READ( R_EAX );
2363 MEM_READ_WORD( R_EAX, R_EAX );
2364 store_reg( R_EAX, 0 );
2365 sh4_x86.tstate = TSTATE_NONE;
2369 { /* CMP/EQ #imm, R0 */
2370 int32_t imm = SIGNEXT8(ir&0xFF);
2371 load_reg( R_EAX, 0 );
2372 CMP_imm8s_r32(imm, R_EAX);
2374 sh4_x86.tstate = TSTATE_E;
2379 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2380 if( sh4_x86.in_delay_slot ) {
2383 sh4vma_t target = disp + pc + 4;
2384 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2385 exit_block_rel(target, pc+2 );
2386 JMP_TARGET(nottaken);
2393 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2394 if( sh4_x86.in_delay_slot ) {
2397 sh4vma_t target = disp + pc + 4;
2398 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2399 exit_block_rel(target, pc+2 );
2400 JMP_TARGET(nottaken);
2407 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2408 if( sh4_x86.in_delay_slot ) {
2411 sh4_x86.in_delay_slot = TRUE;
2412 if( sh4_x86.tstate == TSTATE_NONE ) {
2413 CMP_imm8s_sh4r( 1, R_T );
2414 sh4_x86.tstate = TSTATE_E;
2416 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2417 sh4_translate_instruction(pc+2);
2418 exit_block_rel( disp + pc + 4, pc+4 );
2420 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2421 sh4_translate_instruction(pc+2);
2428 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2429 if( sh4_x86.in_delay_slot ) {
2432 sh4vma_t target = disp + pc + 4;
2433 sh4_x86.in_delay_slot = TRUE;
2434 if( sh4_x86.tstate == TSTATE_NONE ) {
2435 CMP_imm8s_sh4r( 1, R_T );
2436 sh4_x86.tstate = TSTATE_E;
2438 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2439 sh4_translate_instruction(pc+2);
2440 exit_block_rel( target, pc+4 );
2442 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2443 sh4_translate_instruction(pc+2);
2454 { /* MOV.W @(disp, PC), Rn */
2455 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2456 if( sh4_x86.in_delay_slot ) {
2459 // See comments for MOV.L @(disp, PC), Rn
2460 uint32_t target = pc + disp + 4;
2461 if( IS_IN_ICACHE(target) ) {
2462 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2463 MOV_moff32_EAX( ptr );
2464 MOVSX_r16_r32( R_EAX, R_EAX );
2466 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
2467 ADD_sh4r_r32( R_PC, R_EAX );
2468 MMU_TRANSLATE_READ( R_EAX );
2469 MEM_READ_WORD( R_EAX, R_EAX );
2470 sh4_x86.tstate = TSTATE_NONE;
2472 store_reg( R_EAX, Rn );
2478 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2479 if( sh4_x86.in_delay_slot ) {
2482 sh4_x86.in_delay_slot = TRUE;
2483 sh4_translate_instruction( pc + 2 );
2484 exit_block_rel( disp + pc + 4, pc+4 );
2485 sh4_x86.branch_taken = TRUE;
2492 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2493 if( sh4_x86.in_delay_slot ) {
2496 load_imm32( R_EAX, pc + 4 );
2497 store_spreg( R_EAX, R_PR );
2498 sh4_x86.in_delay_slot = TRUE;
2499 sh4_translate_instruction( pc + 2 );
2500 exit_block_rel( disp + pc + 4, pc+4 );
2501 sh4_x86.branch_taken = TRUE;
2507 switch( (ir&0xF00) >> 8 ) {
2509 { /* MOV.B R0, @(disp, GBR) */
2510 uint32_t disp = (ir&0xFF);
2511 load_spreg( R_EAX, R_GBR );
2512 ADD_imm32_r32( disp, R_EAX );
2513 MMU_TRANSLATE_WRITE( R_EAX );
2514 load_reg( R_EDX, 0 );
2515 MEM_WRITE_BYTE( R_EAX, R_EDX );
2516 sh4_x86.tstate = TSTATE_NONE;
2520 { /* MOV.W R0, @(disp, GBR) */
2521 uint32_t disp = (ir&0xFF)<<1;
2522 load_spreg( R_EAX, R_GBR );
2523 ADD_imm32_r32( disp, R_EAX );
2524 check_walign16( R_EAX );
2525 MMU_TRANSLATE_WRITE( R_EAX );
2526 load_reg( R_EDX, 0 );
2527 MEM_WRITE_WORD( R_EAX, R_EDX );
2528 sh4_x86.tstate = TSTATE_NONE;
2532 { /* MOV.L R0, @(disp, GBR) */
2533 uint32_t disp = (ir&0xFF)<<2;
2534 load_spreg( R_EAX, R_GBR );
2535 ADD_imm32_r32( disp, R_EAX );
2536 check_walign32( R_EAX );
2537 MMU_TRANSLATE_WRITE( R_EAX );
2538 load_reg( R_EDX, 0 );
2539 MEM_WRITE_LONG( R_EAX, R_EDX );
2540 sh4_x86.tstate = TSTATE_NONE;
2545 uint32_t imm = (ir&0xFF);
2546 if( sh4_x86.in_delay_slot ) {
2549 load_imm32( R_ECX, pc+2 );
2550 store_spreg( R_ECX, REG_OFFSET(pc) );
2551 load_imm32( R_EAX, imm );
2552 call_func1( sh4_raise_trap, R_EAX );
2553 sh4_x86.tstate = TSTATE_NONE;
2554 exit_block_pcset(pc);
2555 sh4_x86.branch_taken = TRUE;
2561 { /* MOV.B @(disp, GBR), R0 */
2562 uint32_t disp = (ir&0xFF);
2563 load_spreg( R_EAX, R_GBR );
2564 ADD_imm32_r32( disp, R_EAX );
2565 MMU_TRANSLATE_READ( R_EAX );
2566 MEM_READ_BYTE( R_EAX, R_EAX );
2567 store_reg( R_EAX, 0 );
2568 sh4_x86.tstate = TSTATE_NONE;
2572 { /* MOV.W @(disp, GBR), R0 */
2573 uint32_t disp = (ir&0xFF)<<1;
2574 load_spreg( R_EAX, R_GBR );
2575 ADD_imm32_r32( disp, R_EAX );
2576 check_ralign16( R_EAX );
2577 MMU_TRANSLATE_READ( R_EAX );
2578 MEM_READ_WORD( R_EAX, R_EAX );
2579 store_reg( R_EAX, 0 );
2580 sh4_x86.tstate = TSTATE_NONE;
2584 { /* MOV.L @(disp, GBR), R0 */
2585 uint32_t disp = (ir&0xFF)<<2;
2586 load_spreg( R_EAX, R_GBR );
2587 ADD_imm32_r32( disp, R_EAX );
2588 check_ralign32( R_EAX );
2589 MMU_TRANSLATE_READ( R_EAX );
2590 MEM_READ_LONG( R_EAX, R_EAX );
2591 store_reg( R_EAX, 0 );
2592 sh4_x86.tstate = TSTATE_NONE;
2596 { /* MOVA @(disp, PC), R0 */
2597 uint32_t disp = (ir&0xFF)<<2;
2598 if( sh4_x86.in_delay_slot ) {
2601 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2602 ADD_sh4r_r32( R_PC, R_ECX );
2603 store_reg( R_ECX, 0 );
2604 sh4_x86.tstate = TSTATE_NONE;
2609 { /* TST #imm, R0 */
2610 uint32_t imm = (ir&0xFF);
2611 load_reg( R_EAX, 0 );
2612 TEST_imm32_r32( imm, R_EAX );
2614 sh4_x86.tstate = TSTATE_E;
2618 { /* AND #imm, R0 */
2619 uint32_t imm = (ir&0xFF);
2620 load_reg( R_EAX, 0 );
2621 AND_imm32_r32(imm, R_EAX);
2622 store_reg( R_EAX, 0 );
2623 sh4_x86.tstate = TSTATE_NONE;
2627 { /* XOR #imm, R0 */
2628 uint32_t imm = (ir&0xFF);
2629 load_reg( R_EAX, 0 );
2630 XOR_imm32_r32( imm, R_EAX );
2631 store_reg( R_EAX, 0 );
2632 sh4_x86.tstate = TSTATE_NONE;
2637 uint32_t imm = (ir&0xFF);
2638 load_reg( R_EAX, 0 );
2639 OR_imm32_r32(imm, R_EAX);
2640 store_reg( R_EAX, 0 );
2641 sh4_x86.tstate = TSTATE_NONE;
2645 { /* TST.B #imm, @(R0, GBR) */
2646 uint32_t imm = (ir&0xFF);
2647 load_reg( R_EAX, 0);
2648 load_reg( R_ECX, R_GBR);
2649 ADD_r32_r32( R_ECX, R_EAX );
2650 MMU_TRANSLATE_READ( R_EAX );
2651 MEM_READ_BYTE( R_EAX, R_EAX );
2652 TEST_imm8_r8( imm, R_AL );
2654 sh4_x86.tstate = TSTATE_E;
2658 { /* AND.B #imm, @(R0, GBR) */
2659 uint32_t imm = (ir&0xFF);
2660 load_reg( R_EAX, 0 );
2661 load_spreg( R_ECX, R_GBR );
2662 ADD_r32_r32( R_ECX, R_EAX );
2663 MMU_TRANSLATE_WRITE( R_EAX );
2664 PUSH_realigned_r32(R_EAX);
2665 MEM_READ_BYTE( R_EAX, R_EAX );
2666 POP_realigned_r32(R_ECX);
2667 AND_imm32_r32(imm, R_EAX );
2668 MEM_WRITE_BYTE( R_ECX, R_EAX );
2669 sh4_x86.tstate = TSTATE_NONE;
2673 { /* XOR.B #imm, @(R0, GBR) */
2674 uint32_t imm = (ir&0xFF);
2675 load_reg( R_EAX, 0 );
2676 load_spreg( R_ECX, R_GBR );
2677 ADD_r32_r32( R_ECX, R_EAX );
2678 MMU_TRANSLATE_WRITE( R_EAX );
2679 PUSH_realigned_r32(R_EAX);
2680 MEM_READ_BYTE(R_EAX, R_EAX);
2681 POP_realigned_r32(R_ECX);
2682 XOR_imm32_r32( imm, R_EAX );
2683 MEM_WRITE_BYTE( R_ECX, R_EAX );
2684 sh4_x86.tstate = TSTATE_NONE;
2688 { /* OR.B #imm, @(R0, GBR) */
2689 uint32_t imm = (ir&0xFF);
2690 load_reg( R_EAX, 0 );
2691 load_spreg( R_ECX, R_GBR );
2692 ADD_r32_r32( R_ECX, R_EAX );
2693 MMU_TRANSLATE_WRITE( R_EAX );
2694 PUSH_realigned_r32(R_EAX);
2695 MEM_READ_BYTE( R_EAX, R_EAX );
2696 POP_realigned_r32(R_ECX);
2697 OR_imm32_r32(imm, R_EAX );
2698 MEM_WRITE_BYTE( R_ECX, R_EAX );
2699 sh4_x86.tstate = TSTATE_NONE;
2705 { /* MOV.L @(disp, PC), Rn */
2706 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2707 if( sh4_x86.in_delay_slot ) {
2710 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2711 if( IS_IN_ICACHE(target) ) {
2712 // If the target address is in the same page as the code, it's
2713 // pretty safe to just ref it directly and circumvent the whole
2714 // memory subsystem. (this is a big performance win)
2716 // FIXME: There's a corner-case that's not handled here when
2717 // the current code-page is in the ITLB but not in the UTLB.
2718 // (should generate a TLB miss although need to test SH4
2719 // behaviour to confirm) Unlikely to be anyone depending on this
2720 // behaviour though.
2721 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2722 MOV_moff32_EAX( ptr );
2724 // Note: we use sh4r.pc for the calc as we could be running at a
2725 // different virtual address than the translation was done with,
2726 // but we can safely assume that the low bits are the same.
2727 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2728 ADD_sh4r_r32( R_PC, R_EAX );
2729 MMU_TRANSLATE_READ( R_EAX );
2730 MEM_READ_LONG( R_EAX, R_EAX );
2731 sh4_x86.tstate = TSTATE_NONE;
2733 store_reg( R_EAX, Rn );
2738 { /* MOV #imm, Rn */
2739 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2740 load_imm32( R_EAX, imm );
2741 store_reg( R_EAX, Rn );
2747 { /* FADD FRm, FRn */
2748 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2750 load_spreg( R_ECX, R_FPSCR );
2751 TEST_imm32_r32( FPSCR_PR, R_ECX );
2752 load_fr_bank( R_EDX );
2753 JNE_rel8(13,doubleprec);
2754 push_fr(R_EDX, FRm);
2755 push_fr(R_EDX, FRn);
2759 JMP_TARGET(doubleprec);
2760 push_dr(R_EDX, FRm);
2761 push_dr(R_EDX, FRn);
2765 sh4_x86.tstate = TSTATE_NONE;
2769 { /* FSUB FRm, FRn */
2770 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2772 load_spreg( R_ECX, R_FPSCR );
2773 TEST_imm32_r32( FPSCR_PR, R_ECX );
2774 load_fr_bank( R_EDX );
2775 JNE_rel8(13, doubleprec);
2776 push_fr(R_EDX, FRn);
2777 push_fr(R_EDX, FRm);
2781 JMP_TARGET(doubleprec);
2782 push_dr(R_EDX, FRn);
2783 push_dr(R_EDX, FRm);
2787 sh4_x86.tstate = TSTATE_NONE;
2791 { /* FMUL FRm, FRn */
2792 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2794 load_spreg( R_ECX, R_FPSCR );
2795 TEST_imm32_r32( FPSCR_PR, R_ECX );
2796 load_fr_bank( R_EDX );
2797 JNE_rel8(13, doubleprec);
2798 push_fr(R_EDX, FRm);
2799 push_fr(R_EDX, FRn);
2803 JMP_TARGET(doubleprec);
2804 push_dr(R_EDX, FRm);
2805 push_dr(R_EDX, FRn);
2809 sh4_x86.tstate = TSTATE_NONE;
2813 { /* FDIV FRm, FRn */
2814 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2816 load_spreg( R_ECX, R_FPSCR );
2817 TEST_imm32_r32( FPSCR_PR, R_ECX );
2818 load_fr_bank( R_EDX );
2819 JNE_rel8(13, doubleprec);
2820 push_fr(R_EDX, FRn);
2821 push_fr(R_EDX, FRm);
2825 JMP_TARGET(doubleprec);
2826 push_dr(R_EDX, FRn);
2827 push_dr(R_EDX, FRm);
2831 sh4_x86.tstate = TSTATE_NONE;
2835 { /* FCMP/EQ FRm, FRn */
2836 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2838 load_spreg( R_ECX, R_FPSCR );
2839 TEST_imm32_r32( FPSCR_PR, R_ECX );
2840 load_fr_bank( R_EDX );
2841 JNE_rel8(8, doubleprec);
2842 push_fr(R_EDX, FRm);
2843 push_fr(R_EDX, FRn);
2845 JMP_TARGET(doubleprec);
2846 push_dr(R_EDX, FRm);
2847 push_dr(R_EDX, FRn);
2852 sh4_x86.tstate = TSTATE_NONE;
2856 { /* FCMP/GT FRm, FRn */
2857 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2859 load_spreg( R_ECX, R_FPSCR );
2860 TEST_imm32_r32( FPSCR_PR, R_ECX );
2861 load_fr_bank( R_EDX );
2862 JNE_rel8(8, doubleprec);
2863 push_fr(R_EDX, FRm);
2864 push_fr(R_EDX, FRn);
2866 JMP_TARGET(doubleprec);
2867 push_dr(R_EDX, FRm);
2868 push_dr(R_EDX, FRn);
2873 sh4_x86.tstate = TSTATE_NONE;
2877 { /* FMOV @(R0, Rm), FRn */
2878 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2880 load_reg( R_EAX, Rm );
2881 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2882 check_ralign32( R_EAX );
2883 MMU_TRANSLATE_READ( R_EAX );
2884 load_spreg( R_EDX, R_FPSCR );
2885 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2886 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2887 MEM_READ_LONG( R_EAX, R_EAX );
2888 load_fr_bank( R_EDX );
2889 store_fr( R_EDX, R_EAX, FRn );
2891 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2892 JMP_TARGET(doublesize);
2893 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2894 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2895 load_xf_bank( R_EDX );
2896 store_fr( R_EDX, R_ECX, FRn&0x0E );
2897 store_fr( R_EDX, R_EAX, FRn|0x01 );
2900 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2901 JMP_TARGET(doublesize);
2902 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2903 load_fr_bank( R_EDX );
2904 store_fr( R_EDX, R_ECX, FRn&0x0E );
2905 store_fr( R_EDX, R_EAX, FRn|0x01 );
2908 sh4_x86.tstate = TSTATE_NONE;
2912 { /* FMOV FRm, @(R0, Rn) */
2913 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2915 load_reg( R_EAX, Rn );
2916 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2917 check_walign32( R_EAX );
2918 MMU_TRANSLATE_WRITE( R_EAX );
2919 load_spreg( R_EDX, R_FPSCR );
2920 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2921 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
2922 load_fr_bank( R_EDX );
2923 load_fr( R_EDX, R_ECX, FRm );
2924 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
2926 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
2927 JMP_TARGET(doublesize);
2928 load_xf_bank( R_EDX );
2929 load_fr( R_EDX, R_ECX, FRm&0x0E );
2930 load_fr( R_EDX, R_EDX, FRm|0x01 );
2931 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2934 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
2935 JMP_TARGET(doublesize);
2936 load_fr_bank( R_EDX );
2937 load_fr( R_EDX, R_ECX, FRm&0x0E );
2938 load_fr( R_EDX, R_EDX, FRm|0x01 );
2939 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2942 sh4_x86.tstate = TSTATE_NONE;
2946 { /* FMOV @Rm, FRn */
2947 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2949 load_reg( R_EAX, Rm );
2950 check_ralign32( R_EAX );
2951 MMU_TRANSLATE_READ( R_EAX );
2952 load_spreg( R_EDX, R_FPSCR );
2953 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2954 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2955 MEM_READ_LONG( R_EAX, R_EAX );
2956 load_fr_bank( R_EDX );
2957 store_fr( R_EDX, R_EAX, FRn );
2959 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2960 JMP_TARGET(doublesize);
2961 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2962 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2963 load_xf_bank( R_EDX );
2964 store_fr( R_EDX, R_ECX, FRn&0x0E );
2965 store_fr( R_EDX, R_EAX, FRn|0x01 );
2968 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2969 JMP_TARGET(doublesize);
2970 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2971 load_fr_bank( R_EDX );
2972 store_fr( R_EDX, R_ECX, FRn&0x0E );
2973 store_fr( R_EDX, R_EAX, FRn|0x01 );
2976 sh4_x86.tstate = TSTATE_NONE;
2980 { /* FMOV @Rm+, FRn */
2981 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2983 load_reg( R_EAX, Rm );
2984 check_ralign32( R_EAX );
2985 MMU_TRANSLATE_READ( R_EAX );
2986 load_spreg( R_EDX, R_FPSCR );
2987 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2988 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
2989 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2990 MEM_READ_LONG( R_EAX, R_EAX );
2991 load_fr_bank( R_EDX );
2992 store_fr( R_EDX, R_EAX, FRn );
2994 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
2995 JMP_TARGET(doublesize);
2996 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
2997 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2998 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2999 load_xf_bank( R_EDX );
3000 store_fr( R_EDX, R_ECX, FRn&0x0E );
3001 store_fr( R_EDX, R_EAX, FRn|0x01 );
3004 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
3005 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3006 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3007 load_fr_bank( R_EDX );
3008 store_fr( R_EDX, R_ECX, FRn&0x0E );
3009 store_fr( R_EDX, R_EAX, FRn|0x01 );
3012 sh4_x86.tstate = TSTATE_NONE;
3016 { /* FMOV FRm, @Rn */
3017 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3019 load_reg( R_EAX, Rn );
3020 check_walign32( R_EAX );
3021 MMU_TRANSLATE_WRITE( R_EAX );
3022 load_spreg( R_EDX, R_FPSCR );
3023 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3024 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
3025 load_fr_bank( R_EDX );
3026 load_fr( R_EDX, R_ECX, FRm );
3027 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3029 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3030 JMP_TARGET(doublesize);
3031 load_xf_bank( R_EDX );
3032 load_fr( R_EDX, R_ECX, FRm&0x0E );
3033 load_fr( R_EDX, R_EDX, FRm|0x01 );
3034 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3037 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3038 JMP_TARGET(doublesize);
3039 load_fr_bank( R_EDX );
3040 load_fr( R_EDX, R_ECX, FRm&0x0E );
3041 load_fr( R_EDX, R_EDX, FRm|0x01 );
3042 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3045 sh4_x86.tstate = TSTATE_NONE;
3049 { /* FMOV FRm, @-Rn */
3050 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3052 load_reg( R_EAX, Rn );
3053 check_walign32( R_EAX );
3054 load_spreg( R_EDX, R_FPSCR );
3055 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3056 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
3057 ADD_imm8s_r32( -4, R_EAX );
3058 MMU_TRANSLATE_WRITE( R_EAX );
3059 load_fr_bank( R_EDX );
3060 load_fr( R_EDX, R_ECX, FRm );
3061 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
3062 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3064 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3065 JMP_TARGET(doublesize);
3066 ADD_imm8s_r32(-8,R_EAX);
3067 MMU_TRANSLATE_WRITE( R_EAX );
3068 load_xf_bank( R_EDX );
3069 load_fr( R_EDX, R_ECX, FRm&0x0E );
3070 load_fr( R_EDX, R_EDX, FRm|0x01 );
3071 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3072 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3075 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3076 JMP_TARGET(doublesize);
3077 ADD_imm8s_r32(-8,R_EAX);
3078 MMU_TRANSLATE_WRITE( R_EAX );
3079 load_fr_bank( R_EDX );
3080 load_fr( R_EDX, R_ECX, FRm&0x0E );
3081 load_fr( R_EDX, R_EDX, FRm|0x01 );
3082 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3083 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3086 sh4_x86.tstate = TSTATE_NONE;
3090 { /* FMOV FRm, FRn */
3091 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3092 /* As horrible as this looks, it's actually covering 5 separate cases:
3093 * 1. 32-bit fr-to-fr (PR=0)
3094 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3095 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3096 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3097 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3100 load_spreg( R_ECX, R_FPSCR );
3101 load_fr_bank( R_EDX );
3102 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3103 JNE_rel8(8, doublesize);
3104 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3105 store_fr( R_EDX, R_EAX, FRn );
3108 JMP_TARGET(doublesize);
3109 load_xf_bank( R_ECX );
3110 load_fr( R_ECX, R_EAX, FRm-1 );
3112 load_fr( R_ECX, R_EDX, FRm );
3113 store_fr( R_ECX, R_EAX, FRn-1 );
3114 store_fr( R_ECX, R_EDX, FRn );
3115 } else /* FRn&1 == 0 */ {
3116 load_fr( R_ECX, R_ECX, FRm );
3117 store_fr( R_EDX, R_EAX, FRn );
3118 store_fr( R_EDX, R_ECX, FRn+1 );
3121 } else /* FRm&1 == 0 */ {
3124 load_xf_bank( R_ECX );
3125 load_fr( R_EDX, R_EAX, FRm );
3126 load_fr( R_EDX, R_EDX, FRm+1 );
3127 store_fr( R_ECX, R_EAX, FRn-1 );
3128 store_fr( R_ECX, R_EDX, FRn );
3130 } else /* FRn&1 == 0 */ {
3132 load_fr( R_EDX, R_EAX, FRm );
3133 load_fr( R_EDX, R_ECX, FRm+1 );
3134 store_fr( R_EDX, R_EAX, FRn );
3135 store_fr( R_EDX, R_ECX, FRn+1 );
3139 sh4_x86.tstate = TSTATE_NONE;
3143 switch( (ir&0xF0) >> 4 ) {
3145 { /* FSTS FPUL, FRn */
3146 uint32_t FRn = ((ir>>8)&0xF);
3148 load_fr_bank( R_ECX );
3149 load_spreg( R_EAX, R_FPUL );
3150 store_fr( R_ECX, R_EAX, FRn );
3151 sh4_x86.tstate = TSTATE_NONE;
3155 { /* FLDS FRm, FPUL */
3156 uint32_t FRm = ((ir>>8)&0xF);
3158 load_fr_bank( R_ECX );
3159 load_fr( R_ECX, R_EAX, FRm );
3160 store_spreg( R_EAX, R_FPUL );
3161 sh4_x86.tstate = TSTATE_NONE;
3165 { /* FLOAT FPUL, FRn */
3166 uint32_t FRn = ((ir>>8)&0xF);
3168 load_spreg( R_ECX, R_FPSCR );
3169 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3171 TEST_imm32_r32( FPSCR_PR, R_ECX );
3172 JNE_rel8(5, doubleprec);
3173 pop_fr( R_EDX, FRn );
3175 JMP_TARGET(doubleprec);
3176 pop_dr( R_EDX, FRn );
3178 sh4_x86.tstate = TSTATE_NONE;
3182 { /* FTRC FRm, FPUL */
3183 uint32_t FRm = ((ir>>8)&0xF);
3185 load_spreg( R_ECX, R_FPSCR );
3186 load_fr_bank( R_EDX );
3187 TEST_imm32_r32( FPSCR_PR, R_ECX );
3188 JNE_rel8(5, doubleprec);
3189 push_fr( R_EDX, FRm );
3191 JMP_TARGET(doubleprec);
3192 push_dr( R_EDX, FRm );
3194 load_imm32( R_ECX, (uint32_t)&max_int );
3195 FILD_r32ind( R_ECX );
3197 JNA_rel8( 32, sat );
3198 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3199 FILD_r32ind( R_ECX ); // 2
3201 JAE_rel8( 21, sat2 ); // 2
3202 load_imm32( R_EAX, (uint32_t)&save_fcw );
3203 FNSTCW_r32ind( R_EAX );
3204 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3205 FLDCW_r32ind( R_EDX );
3206 FISTP_sh4r(R_FPUL); // 3
3207 FLDCW_r32ind( R_EAX );
3208 JMP_rel8( 9, end ); // 2
3212 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3213 store_spreg( R_ECX, R_FPUL );
3216 sh4_x86.tstate = TSTATE_NONE;
3221 uint32_t FRn = ((ir>>8)&0xF);
3223 load_spreg( R_ECX, R_FPSCR );
3224 TEST_imm32_r32( FPSCR_PR, R_ECX );
3225 load_fr_bank( R_EDX );
3226 JNE_rel8(10, doubleprec);
3227 push_fr(R_EDX, FRn);
3231 JMP_TARGET(doubleprec);
3232 push_dr(R_EDX, FRn);
3236 sh4_x86.tstate = TSTATE_NONE;
3241 uint32_t FRn = ((ir>>8)&0xF);
3243 load_spreg( R_ECX, R_FPSCR );
3244 load_fr_bank( R_EDX );
3245 TEST_imm32_r32( FPSCR_PR, R_ECX );
3246 JNE_rel8(10, doubleprec);
3247 push_fr(R_EDX, FRn); // 3
3249 pop_fr( R_EDX, FRn); //3
3250 JMP_rel8(8,end); // 2
3251 JMP_TARGET(doubleprec);
3252 push_dr(R_EDX, FRn);
3256 sh4_x86.tstate = TSTATE_NONE;
3261 uint32_t FRn = ((ir>>8)&0xF);
3263 load_spreg( R_ECX, R_FPSCR );
3264 TEST_imm32_r32( FPSCR_PR, R_ECX );
3265 load_fr_bank( R_EDX );
3266 JNE_rel8(10, doubleprec);
3267 push_fr(R_EDX, FRn);
3271 JMP_TARGET(doubleprec);
3272 push_dr(R_EDX, FRn);
3276 sh4_x86.tstate = TSTATE_NONE;
3281 uint32_t FRn = ((ir>>8)&0xF);
3283 load_spreg( R_ECX, R_FPSCR );
3284 TEST_imm32_r32( FPSCR_PR, R_ECX );
3285 load_fr_bank( R_EDX );
3286 JNE_rel8(12, end); // PR=0 only
3288 push_fr(R_EDX, FRn);
3293 sh4_x86.tstate = TSTATE_NONE;
3298 uint32_t FRn = ((ir>>8)&0xF);
3301 load_spreg( R_ECX, R_FPSCR );
3302 TEST_imm32_r32( FPSCR_PR, R_ECX );
3304 XOR_r32_r32( R_EAX, R_EAX );
3305 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3306 store_fr( R_ECX, R_EAX, FRn );
3308 sh4_x86.tstate = TSTATE_NONE;
3313 uint32_t FRn = ((ir>>8)&0xF);
3316 load_spreg( R_ECX, R_FPSCR );
3317 TEST_imm32_r32( FPSCR_PR, R_ECX );
3319 load_imm32(R_EAX, 0x3F800000);
3320 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3321 store_fr( R_ECX, R_EAX, FRn );
3323 sh4_x86.tstate = TSTATE_NONE;
3327 { /* FCNVSD FPUL, FRn */
3328 uint32_t FRn = ((ir>>8)&0xF);
3330 load_spreg( R_ECX, R_FPSCR );
3331 TEST_imm32_r32( FPSCR_PR, R_ECX );
3332 JE_rel8(9, end); // only when PR=1
3333 load_fr_bank( R_ECX );
3335 pop_dr( R_ECX, FRn );
3337 sh4_x86.tstate = TSTATE_NONE;
3341 { /* FCNVDS FRm, FPUL */
3342 uint32_t FRm = ((ir>>8)&0xF);
3344 load_spreg( R_ECX, R_FPSCR );
3345 TEST_imm32_r32( FPSCR_PR, R_ECX );
3346 JE_rel8(9, end); // only when PR=1
3347 load_fr_bank( R_ECX );
3348 push_dr( R_ECX, FRm );
3351 sh4_x86.tstate = TSTATE_NONE;
3355 { /* FIPR FVm, FVn */
3356 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3358 load_spreg( R_ECX, R_FPSCR );
3359 TEST_imm32_r32( FPSCR_PR, R_ECX );
3360 JNE_rel8(44, doubleprec);
3362 load_fr_bank( R_ECX );
3363 push_fr( R_ECX, FVm<<2 );
3364 push_fr( R_ECX, FVn<<2 );
3366 push_fr( R_ECX, (FVm<<2)+1);
3367 push_fr( R_ECX, (FVn<<2)+1);
3370 push_fr( R_ECX, (FVm<<2)+2);
3371 push_fr( R_ECX, (FVn<<2)+2);
3374 push_fr( R_ECX, (FVm<<2)+3);
3375 push_fr( R_ECX, (FVn<<2)+3);
3378 pop_fr( R_ECX, (FVn<<2)+3);
3379 JMP_TARGET(doubleprec);
3380 sh4_x86.tstate = TSTATE_NONE;
3384 switch( (ir&0x100) >> 8 ) {
3386 { /* FSCA FPUL, FRn */
3387 uint32_t FRn = ((ir>>9)&0x7)<<1;
3389 load_spreg( R_ECX, R_FPSCR );
3390 TEST_imm32_r32( FPSCR_PR, R_ECX );
3391 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3392 load_fr_bank( R_ECX );
3393 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3394 load_spreg( R_EDX, R_FPUL );
3395 call_func2( sh4_fsca, R_EDX, R_ECX );
3396 JMP_TARGET(doubleprec);
3397 sh4_x86.tstate = TSTATE_NONE;
3401 switch( (ir&0x200) >> 9 ) {
3403 { /* FTRV XMTRX, FVn */
3404 uint32_t FVn = ((ir>>10)&0x3);
3406 load_spreg( R_ECX, R_FPSCR );
3407 TEST_imm32_r32( FPSCR_PR, R_ECX );
3408 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3409 load_fr_bank( R_EDX ); // 3
3410 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3411 load_xf_bank( R_ECX ); // 12
3412 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3413 JMP_TARGET(doubleprec);
3414 sh4_x86.tstate = TSTATE_NONE;
3418 switch( (ir&0xC00) >> 10 ) {
3422 load_spreg( R_ECX, R_FPSCR );
3423 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3424 store_spreg( R_ECX, R_FPSCR );
3425 sh4_x86.tstate = TSTATE_NONE;
3431 load_spreg( R_ECX, R_FPSCR );
3432 XOR_imm32_r32( FPSCR_FR, R_ECX );
3433 store_spreg( R_ECX, R_FPSCR );
3434 update_fr_bank( R_ECX );
3435 sh4_x86.tstate = TSTATE_NONE;
3440 if( sh4_x86.in_delay_slot ) {
3443 JMP_exc(EXC_ILLEGAL);
3463 { /* FMAC FR0, FRm, FRn */
3464 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3466 load_spreg( R_ECX, R_FPSCR );
3467 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3468 TEST_imm32_r32( FPSCR_PR, R_ECX );
3469 JNE_rel8(18, doubleprec);
3470 push_fr( R_EDX, 0 );
3471 push_fr( R_EDX, FRm );
3473 push_fr( R_EDX, FRn );
3475 pop_fr( R_EDX, FRn );
3477 JMP_TARGET(doubleprec);
3478 push_dr( R_EDX, 0 );
3479 push_dr( R_EDX, FRm );
3481 push_dr( R_EDX, FRn );
3483 pop_dr( R_EDX, FRn );
3485 sh4_x86.tstate = TSTATE_NONE;
3495 sh4_x86.in_delay_slot = FALSE;
.