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;
44 * Struct to manage internal translation state. This state is not saved -
45 * it is only valid between calls to sh4_translate_begin_block() and
46 * sh4_translate_end_block()
48 struct sh4_x86_state {
49 gboolean in_delay_slot;
50 gboolean priv_checked; /* true if we've already checked the cpu mode. */
51 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
52 gboolean branch_taken; /* true if we branched unconditionally */
53 uint32_t block_start_pc;
54 uint32_t stack_posn; /* Trace stack height for alignment purposes */
57 /* Allocated memory for the (block-wide) back-patch list */
58 struct backpatch_record *backpatch_list;
59 uint32_t backpatch_posn;
60 uint32_t backpatch_size;
63 #define TSTATE_NONE -1
73 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
74 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
75 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
76 OP(0x70+sh4_x86.tstate); OP(rel8); \
78 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
79 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
80 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
81 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
84 static struct sh4_x86_state sh4_x86;
86 static uint32_t max_int = 0x7FFFFFFF;
87 static uint32_t min_int = 0x80000000;
88 static uint32_t save_fcw; /* save value for fpu control word */
89 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
93 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
94 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
98 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
100 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
101 sh4_x86.backpatch_size <<= 1;
102 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
103 sh4_x86.backpatch_size * sizeof(struct backpatch_record));
104 assert( sh4_x86.backpatch_list != NULL );
106 if( sh4_x86.in_delay_slot ) {
109 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;
110 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
111 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
112 sh4_x86.backpatch_posn++;
116 * Emit an instruction to load an SH4 reg into a real register
118 static inline void load_reg( int x86reg, int sh4reg )
120 /* mov [bp+n], reg */
122 OP(0x45 + (x86reg<<3));
123 OP(REG_OFFSET(r[sh4reg]));
126 static inline void load_reg16s( int x86reg, int sh4reg )
130 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
133 static inline void load_reg16u( int x86reg, int sh4reg )
137 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
141 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
142 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
144 * Emit an instruction to load an immediate value into a register
146 static inline void load_imm32( int x86reg, uint32_t value ) {
147 /* mov #value, reg */
153 * Load an immediate 64-bit quantity (note: x86-64 only)
155 static inline void load_imm64( int x86reg, uint32_t value ) {
156 /* mov #value, reg */
164 * Emit an instruction to store an SH4 reg (RN)
166 void static inline store_reg( int x86reg, int sh4reg ) {
167 /* mov reg, [bp+n] */
169 OP(0x45 + (x86reg<<3));
170 OP(REG_OFFSET(r[sh4reg]));
173 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
176 * Load an FR register (single-precision floating point) into an integer x86
177 * register (eg for register-to-register moves)
179 void static inline load_fr( int bankreg, int x86reg, int frm )
181 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
185 * Store an FR register (single-precision floating point) into an integer x86
186 * register (eg for register-to-register moves)
188 void static inline store_fr( int bankreg, int x86reg, int frn )
190 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
195 * Load a pointer to the back fp back into the specified x86 register. The
196 * bankreg must have been previously loaded with FPSCR.
199 static inline void load_xf_bank( int bankreg )
202 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
203 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
204 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
208 * Update the fr_bank pointer based on the current fpscr value.
210 static inline void update_fr_bank( int fpscrreg )
212 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
213 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
214 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
215 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
218 * Push FPUL (as a 32-bit float) onto the FPU stack
220 static inline void push_fpul( )
222 OP(0xD9); OP(0x45); OP(R_FPUL);
226 * Pop FPUL (as a 32-bit float) from the FPU stack
228 static inline void pop_fpul( )
230 OP(0xD9); OP(0x5D); OP(R_FPUL);
234 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
235 * with the location of the current fp bank.
237 static inline void push_fr( int bankreg, int frm )
239 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
243 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
244 * with bankreg previously loaded with the location of the current fp bank.
246 static inline void pop_fr( int bankreg, int frm )
248 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
252 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
253 * with the location of the current fp bank.
255 static inline void push_dr( int bankreg, int frm )
257 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
260 static inline void pop_dr( int bankreg, int frm )
262 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
265 /* Exception checks - Note that all exception checks will clobber EAX */
267 #define check_priv( ) \
268 if( !sh4_x86.priv_checked ) { \
269 sh4_x86.priv_checked = TRUE;\
270 load_spreg( R_EAX, R_SR );\
271 AND_imm32_r32( SR_MD, R_EAX );\
272 if( sh4_x86.in_delay_slot ) {\
273 JE_exc( EXC_SLOT_ILLEGAL );\
275 JE_exc( EXC_ILLEGAL );\
279 #define check_fpuen( ) \
280 if( !sh4_x86.fpuen_checked ) {\
281 sh4_x86.fpuen_checked = TRUE;\
282 load_spreg( R_EAX, R_SR );\
283 AND_imm32_r32( SR_FD, R_EAX );\
284 if( sh4_x86.in_delay_slot ) {\
285 JNE_exc(EXC_SLOT_FPU_DISABLED);\
287 JNE_exc(EXC_FPU_DISABLED);\
291 #define check_ralign16( x86reg ) \
292 TEST_imm32_r32( 0x00000001, x86reg ); \
293 JNE_exc(EXC_DATA_ADDR_READ)
295 #define check_walign16( x86reg ) \
296 TEST_imm32_r32( 0x00000001, x86reg ); \
297 JNE_exc(EXC_DATA_ADDR_WRITE);
299 #define check_ralign32( x86reg ) \
300 TEST_imm32_r32( 0x00000003, x86reg ); \
301 JNE_exc(EXC_DATA_ADDR_READ)
303 #define check_walign32( x86reg ) \
304 TEST_imm32_r32( 0x00000003, x86reg ); \
305 JNE_exc(EXC_DATA_ADDR_WRITE);
308 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
309 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); TEST_r32_r32( R_EDX, R_EDX ); JNE_exc(-1); MEM_RESULT(value_reg)
310 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); TEST_r32_r32( R_EDX, R_EDX ); JNE_exc(-1); MEM_RESULT(value_reg)
311 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); TEST_r32_r32( R_EDX, R_EDX ); JNE_exc(-1); MEM_RESULT(value_reg)
312 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg); TEST_r32_r32( R_EAX, R_EAX ); JNE_exc(-1);
313 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg); TEST_r32_r32( R_EAX, R_EAX ); JNE_exc(-1);
314 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg); TEST_r32_r32( R_EAX, R_EAX ); JNE_exc(-1);
316 #define MEM_READ_SIZE (CALL_FUNC1_SIZE+8)
317 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE+8)
319 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
321 extern uint16_t *sh4_icache;
322 extern uint32_t sh4_icache_addr;
324 /****** Import appropriate calling conventions ******/
325 #if SH4_TRANSLATOR == TARGET_X86_64
326 #include "sh4/ia64abi.h"
327 #else /* SH4_TRANSLATOR == TARGET_X86 */
329 #include "sh4/ia32mac.h"
331 #include "sh4/ia32abi.h"
337 * Translate a single instruction. Delayed branches are handled specially
338 * by translating both branch and delayed instruction as a single unit (as
341 * @return true if the instruction marks the end of a basic block
344 uint32_t sh4_translate_instruction( sh4addr_t pc )
347 /* Read instruction */
348 uint32_t pageaddr = pc >> 12;
349 if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
350 ir = sh4_icache[(pc&0xFFF)>>1];
352 uint64_t phys = mmu_vma_to_phys_exec(pc);
353 sh4_icache = (uint16_t *)mem_get_page((uint32_t)phys);
354 if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {
355 /* If someone's actually been so daft as to try to execute out of an IO
356 * region, fallback on the full-blown memory read
359 ir = sh4_read_word(pc);
361 sh4_icache_addr = pageaddr;
362 ir = sh4_icache[(pc&0xFFF)>>1];
366 switch( (ir&0xF000) >> 12 ) {
370 switch( (ir&0x80) >> 7 ) {
372 switch( (ir&0x70) >> 4 ) {
375 uint32_t Rn = ((ir>>8)&0xF);
377 call_func0(sh4_read_sr);
378 store_reg( R_EAX, Rn );
379 sh4_x86.tstate = TSTATE_NONE;
384 uint32_t Rn = ((ir>>8)&0xF);
385 load_spreg( R_EAX, R_GBR );
386 store_reg( R_EAX, Rn );
391 uint32_t Rn = ((ir>>8)&0xF);
393 load_spreg( R_EAX, R_VBR );
394 store_reg( R_EAX, Rn );
395 sh4_x86.tstate = TSTATE_NONE;
400 uint32_t Rn = ((ir>>8)&0xF);
402 load_spreg( R_EAX, R_SSR );
403 store_reg( R_EAX, Rn );
404 sh4_x86.tstate = TSTATE_NONE;
409 uint32_t Rn = ((ir>>8)&0xF);
411 load_spreg( R_EAX, R_SPC );
412 store_reg( R_EAX, Rn );
413 sh4_x86.tstate = TSTATE_NONE;
422 { /* STC Rm_BANK, Rn */
423 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
425 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
426 store_reg( R_EAX, Rn );
427 sh4_x86.tstate = TSTATE_NONE;
433 switch( (ir&0xF0) >> 4 ) {
436 uint32_t Rn = ((ir>>8)&0xF);
437 if( sh4_x86.in_delay_slot ) {
440 load_imm32( R_ECX, pc + 4 );
441 store_spreg( R_ECX, R_PR );
442 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_ECX );
443 store_spreg( R_ECX, REG_OFFSET(pc) );
444 sh4_x86.in_delay_slot = TRUE;
445 sh4_x86.tstate = TSTATE_NONE;
446 sh4_translate_instruction( pc + 2 );
447 exit_block_pcset(pc+2);
448 sh4_x86.branch_taken = TRUE;
455 uint32_t Rn = ((ir>>8)&0xF);
456 if( sh4_x86.in_delay_slot ) {
459 load_reg( R_EAX, Rn );
460 ADD_imm32_r32( pc + 4, R_EAX );
461 store_spreg( R_EAX, REG_OFFSET(pc) );
462 sh4_x86.in_delay_slot = TRUE;
463 sh4_x86.tstate = TSTATE_NONE;
464 sh4_translate_instruction( pc + 2 );
465 exit_block_pcset(pc+2);
466 sh4_x86.branch_taken = TRUE;
473 uint32_t Rn = ((ir>>8)&0xF);
474 load_reg( R_EAX, Rn );
475 MOV_r32_r32( R_EAX, R_ECX );
476 AND_imm32_r32( 0xFC000000, R_EAX );
477 CMP_imm32_r32( 0xE0000000, R_EAX );
478 JNE_rel8(CALL_FUNC1_SIZE, end);
479 call_func1( sh4_flush_store_queue, R_ECX );
481 sh4_x86.tstate = TSTATE_NONE;
486 uint32_t Rn = ((ir>>8)&0xF);
491 uint32_t Rn = ((ir>>8)&0xF);
496 uint32_t Rn = ((ir>>8)&0xF);
500 { /* MOVCA.L R0, @Rn */
501 uint32_t Rn = ((ir>>8)&0xF);
502 load_reg( R_EAX, 0 );
503 load_reg( R_ECX, Rn );
504 check_walign32( R_ECX );
505 MEM_WRITE_LONG( R_ECX, R_EAX );
506 sh4_x86.tstate = TSTATE_NONE;
515 { /* MOV.B Rm, @(R0, Rn) */
516 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
517 load_reg( R_EAX, 0 );
518 load_reg( R_ECX, Rn );
519 ADD_r32_r32( R_EAX, R_ECX );
520 load_reg( R_EAX, Rm );
521 MEM_WRITE_BYTE( R_ECX, R_EAX );
522 sh4_x86.tstate = TSTATE_NONE;
526 { /* MOV.W Rm, @(R0, Rn) */
527 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
528 load_reg( R_EAX, 0 );
529 load_reg( R_ECX, Rn );
530 ADD_r32_r32( R_EAX, R_ECX );
531 check_walign16( R_ECX );
532 load_reg( R_EAX, Rm );
533 MEM_WRITE_WORD( R_ECX, R_EAX );
534 sh4_x86.tstate = TSTATE_NONE;
538 { /* MOV.L Rm, @(R0, Rn) */
539 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
540 load_reg( R_EAX, 0 );
541 load_reg( R_ECX, Rn );
542 ADD_r32_r32( R_EAX, R_ECX );
543 check_walign32( R_ECX );
544 load_reg( R_EAX, Rm );
545 MEM_WRITE_LONG( R_ECX, R_EAX );
546 sh4_x86.tstate = TSTATE_NONE;
551 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
552 load_reg( R_EAX, Rm );
553 load_reg( R_ECX, Rn );
555 store_spreg( R_EAX, R_MACL );
556 sh4_x86.tstate = TSTATE_NONE;
560 switch( (ir&0xFF0) >> 4 ) {
565 sh4_x86.tstate = TSTATE_C;
572 sh4_x86.tstate = TSTATE_C;
577 XOR_r32_r32(R_EAX, R_EAX);
578 store_spreg( R_EAX, R_MACL );
579 store_spreg( R_EAX, R_MACH );
580 sh4_x86.tstate = TSTATE_NONE;
585 call_func0( MMU_ldtlb );
592 sh4_x86.tstate = TSTATE_C;
599 sh4_x86.tstate = TSTATE_C;
608 switch( (ir&0xF0) >> 4 ) {
611 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
616 XOR_r32_r32( R_EAX, R_EAX );
617 store_spreg( R_EAX, R_Q );
618 store_spreg( R_EAX, R_M );
619 store_spreg( R_EAX, R_T );
620 sh4_x86.tstate = TSTATE_C; // works for DIV1
625 uint32_t Rn = ((ir>>8)&0xF);
626 load_spreg( R_EAX, R_T );
627 store_reg( R_EAX, Rn );
636 switch( (ir&0xF0) >> 4 ) {
639 uint32_t Rn = ((ir>>8)&0xF);
640 load_spreg( R_EAX, R_MACH );
641 store_reg( R_EAX, Rn );
646 uint32_t Rn = ((ir>>8)&0xF);
647 load_spreg( R_EAX, R_MACL );
648 store_reg( R_EAX, Rn );
653 uint32_t Rn = ((ir>>8)&0xF);
654 load_spreg( R_EAX, R_PR );
655 store_reg( R_EAX, Rn );
660 uint32_t Rn = ((ir>>8)&0xF);
662 load_spreg( R_EAX, R_SGR );
663 store_reg( R_EAX, Rn );
664 sh4_x86.tstate = TSTATE_NONE;
669 uint32_t Rn = ((ir>>8)&0xF);
670 load_spreg( R_EAX, R_FPUL );
671 store_reg( R_EAX, Rn );
675 { /* STS FPSCR, Rn */
676 uint32_t Rn = ((ir>>8)&0xF);
677 load_spreg( R_EAX, R_FPSCR );
678 store_reg( R_EAX, Rn );
683 uint32_t Rn = ((ir>>8)&0xF);
685 load_spreg( R_EAX, R_DBR );
686 store_reg( R_EAX, Rn );
687 sh4_x86.tstate = TSTATE_NONE;
696 switch( (ir&0xFF0) >> 4 ) {
699 if( sh4_x86.in_delay_slot ) {
702 load_spreg( R_ECX, R_PR );
703 store_spreg( R_ECX, REG_OFFSET(pc) );
704 sh4_x86.in_delay_slot = TRUE;
705 sh4_translate_instruction(pc+2);
706 exit_block_pcset(pc+2);
707 sh4_x86.branch_taken = TRUE;
715 call_func0( sh4_sleep );
716 sh4_x86.tstate = TSTATE_NONE;
717 sh4_x86.in_delay_slot = FALSE;
723 if( sh4_x86.in_delay_slot ) {
727 load_spreg( R_ECX, R_SPC );
728 store_spreg( R_ECX, REG_OFFSET(pc) );
729 load_spreg( R_EAX, R_SSR );
730 call_func1( sh4_write_sr, R_EAX );
731 sh4_x86.in_delay_slot = TRUE;
732 sh4_x86.priv_checked = FALSE;
733 sh4_x86.fpuen_checked = FALSE;
734 sh4_x86.tstate = TSTATE_NONE;
735 sh4_translate_instruction(pc+2);
736 exit_block_pcset(pc+2);
737 sh4_x86.branch_taken = TRUE;
748 { /* MOV.B @(R0, Rm), Rn */
749 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
750 load_reg( R_EAX, 0 );
751 load_reg( R_ECX, Rm );
752 ADD_r32_r32( R_EAX, R_ECX );
753 MEM_READ_BYTE( R_ECX, R_EAX );
754 store_reg( R_EAX, Rn );
755 sh4_x86.tstate = TSTATE_NONE;
759 { /* MOV.W @(R0, Rm), Rn */
760 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
761 load_reg( R_EAX, 0 );
762 load_reg( R_ECX, Rm );
763 ADD_r32_r32( R_EAX, R_ECX );
764 check_ralign16( R_ECX );
765 MEM_READ_WORD( R_ECX, R_EAX );
766 store_reg( R_EAX, Rn );
767 sh4_x86.tstate = TSTATE_NONE;
771 { /* MOV.L @(R0, Rm), Rn */
772 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
773 load_reg( R_EAX, 0 );
774 load_reg( R_ECX, Rm );
775 ADD_r32_r32( R_EAX, R_ECX );
776 check_ralign32( R_ECX );
777 MEM_READ_LONG( R_ECX, R_EAX );
778 store_reg( R_EAX, Rn );
779 sh4_x86.tstate = TSTATE_NONE;
783 { /* MAC.L @Rm+, @Rn+ */
784 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
785 load_reg( R_ECX, Rm );
786 check_ralign32( R_ECX );
787 load_reg( R_ECX, Rn );
788 check_ralign32( R_ECX );
789 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
790 MEM_READ_LONG( R_ECX, R_EAX );
791 PUSH_realigned_r32( R_EAX );
792 load_reg( R_ECX, Rm );
793 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
794 MEM_READ_LONG( R_ECX, R_EAX );
795 POP_realigned_r32( R_ECX );
797 ADD_r32_sh4r( R_EAX, R_MACL );
798 ADC_r32_sh4r( R_EDX, R_MACH );
800 load_spreg( R_ECX, R_S );
801 TEST_r32_r32(R_ECX, R_ECX);
802 JE_rel8( CALL_FUNC0_SIZE, nosat );
803 call_func0( signsat48 );
805 sh4_x86.tstate = TSTATE_NONE;
814 { /* MOV.L Rm, @(disp, Rn) */
815 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
816 load_reg( R_ECX, Rn );
817 load_reg( R_EAX, Rm );
818 ADD_imm32_r32( disp, R_ECX );
819 check_walign32( R_ECX );
820 MEM_WRITE_LONG( R_ECX, R_EAX );
821 sh4_x86.tstate = TSTATE_NONE;
827 { /* MOV.B Rm, @Rn */
828 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
829 load_reg( R_EAX, Rm );
830 load_reg( R_ECX, Rn );
831 MEM_WRITE_BYTE( R_ECX, R_EAX );
832 sh4_x86.tstate = TSTATE_NONE;
836 { /* MOV.W Rm, @Rn */
837 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
838 load_reg( R_ECX, Rn );
839 check_walign16( R_ECX );
840 load_reg( R_EAX, Rm );
841 MEM_WRITE_WORD( R_ECX, R_EAX );
842 sh4_x86.tstate = TSTATE_NONE;
846 { /* MOV.L Rm, @Rn */
847 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
848 load_reg( R_EAX, Rm );
849 load_reg( R_ECX, Rn );
850 check_walign32(R_ECX);
851 MEM_WRITE_LONG( R_ECX, R_EAX );
852 sh4_x86.tstate = TSTATE_NONE;
856 { /* MOV.B Rm, @-Rn */
857 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
858 load_reg( R_EAX, Rm );
859 load_reg( R_ECX, Rn );
860 ADD_imm8s_r32( -1, R_ECX );
861 store_reg( R_ECX, Rn );
862 MEM_WRITE_BYTE( R_ECX, R_EAX );
863 sh4_x86.tstate = TSTATE_NONE;
867 { /* MOV.W Rm, @-Rn */
868 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
869 load_reg( R_ECX, Rn );
870 check_walign16( R_ECX );
871 load_reg( R_EAX, Rm );
872 ADD_imm8s_r32( -2, R_ECX );
873 store_reg( R_ECX, Rn );
874 MEM_WRITE_WORD( R_ECX, R_EAX );
875 sh4_x86.tstate = TSTATE_NONE;
879 { /* MOV.L Rm, @-Rn */
880 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
881 load_reg( R_EAX, Rm );
882 load_reg( R_ECX, Rn );
883 check_walign32( R_ECX );
884 ADD_imm8s_r32( -4, R_ECX );
885 store_reg( R_ECX, Rn );
886 MEM_WRITE_LONG( R_ECX, R_EAX );
887 sh4_x86.tstate = TSTATE_NONE;
892 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
893 load_reg( R_EAX, Rm );
894 load_reg( R_ECX, Rn );
895 SHR_imm8_r32( 31, R_EAX );
896 SHR_imm8_r32( 31, R_ECX );
897 store_spreg( R_EAX, R_M );
898 store_spreg( R_ECX, R_Q );
899 CMP_r32_r32( R_EAX, R_ECX );
901 sh4_x86.tstate = TSTATE_NE;
906 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
907 load_reg( R_EAX, Rm );
908 load_reg( R_ECX, Rn );
909 TEST_r32_r32( R_EAX, R_ECX );
911 sh4_x86.tstate = TSTATE_E;
916 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
917 load_reg( R_EAX, Rm );
918 load_reg( R_ECX, Rn );
919 AND_r32_r32( R_EAX, R_ECX );
920 store_reg( R_ECX, Rn );
921 sh4_x86.tstate = TSTATE_NONE;
926 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
927 load_reg( R_EAX, Rm );
928 load_reg( R_ECX, Rn );
929 XOR_r32_r32( R_EAX, R_ECX );
930 store_reg( R_ECX, Rn );
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 OR_r32_r32( R_EAX, R_ECX );
940 store_reg( R_ECX, Rn );
941 sh4_x86.tstate = TSTATE_NONE;
945 { /* CMP/STR Rm, Rn */
946 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
947 load_reg( R_EAX, Rm );
948 load_reg( R_ECX, Rn );
949 XOR_r32_r32( R_ECX, R_EAX );
950 TEST_r8_r8( R_AL, R_AL );
951 JE_rel8(13, target1);
952 TEST_r8_r8( R_AH, R_AH ); // 2
954 SHR_imm8_r32( 16, R_EAX ); // 3
955 TEST_r8_r8( R_AL, R_AL ); // 2
957 TEST_r8_r8( R_AH, R_AH ); // 2
962 sh4_x86.tstate = TSTATE_E;
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 SHL_imm8_r32( 16, R_EAX );
971 SHR_imm8_r32( 16, R_ECX );
972 OR_r32_r32( R_EAX, R_ECX );
973 store_reg( R_ECX, Rn );
974 sh4_x86.tstate = TSTATE_NONE;
978 { /* MULU.W Rm, Rn */
979 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
980 load_reg16u( R_EAX, Rm );
981 load_reg16u( R_ECX, Rn );
983 store_spreg( R_EAX, R_MACL );
984 sh4_x86.tstate = TSTATE_NONE;
988 { /* MULS.W Rm, Rn */
989 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
990 load_reg16s( R_EAX, Rm );
991 load_reg16s( R_ECX, Rn );
993 store_spreg( R_EAX, R_MACL );
994 sh4_x86.tstate = TSTATE_NONE;
1005 { /* CMP/EQ Rm, Rn */
1006 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1007 load_reg( R_EAX, Rm );
1008 load_reg( R_ECX, Rn );
1009 CMP_r32_r32( R_EAX, R_ECX );
1011 sh4_x86.tstate = TSTATE_E;
1015 { /* CMP/HS Rm, Rn */
1016 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1017 load_reg( R_EAX, Rm );
1018 load_reg( R_ECX, Rn );
1019 CMP_r32_r32( R_EAX, R_ECX );
1021 sh4_x86.tstate = TSTATE_AE;
1025 { /* CMP/GE Rm, Rn */
1026 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1027 load_reg( R_EAX, Rm );
1028 load_reg( R_ECX, Rn );
1029 CMP_r32_r32( R_EAX, R_ECX );
1031 sh4_x86.tstate = TSTATE_GE;
1036 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1037 load_spreg( R_ECX, R_M );
1038 load_reg( R_EAX, Rn );
1039 if( sh4_x86.tstate != TSTATE_C ) {
1043 SETC_r8( R_DL ); // Q'
1044 CMP_sh4r_r32( R_Q, R_ECX );
1045 JE_rel8(5, mqequal);
1046 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1048 JMP_TARGET(mqequal);
1049 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1051 store_reg( R_EAX, Rn ); // Done with Rn now
1052 SETC_r8(R_AL); // tmp1
1053 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1054 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1055 store_spreg( R_ECX, R_Q );
1056 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1057 MOVZX_r8_r32( R_AL, R_EAX );
1058 store_spreg( R_EAX, R_T );
1059 sh4_x86.tstate = TSTATE_NONE;
1063 { /* DMULU.L Rm, Rn */
1064 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1065 load_reg( R_EAX, Rm );
1066 load_reg( R_ECX, Rn );
1068 store_spreg( R_EDX, R_MACH );
1069 store_spreg( R_EAX, R_MACL );
1070 sh4_x86.tstate = TSTATE_NONE;
1074 { /* CMP/HI Rm, Rn */
1075 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1076 load_reg( R_EAX, Rm );
1077 load_reg( R_ECX, Rn );
1078 CMP_r32_r32( R_EAX, R_ECX );
1080 sh4_x86.tstate = TSTATE_A;
1084 { /* CMP/GT Rm, Rn */
1085 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1086 load_reg( R_EAX, Rm );
1087 load_reg( R_ECX, Rn );
1088 CMP_r32_r32( R_EAX, R_ECX );
1090 sh4_x86.tstate = TSTATE_G;
1095 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1096 load_reg( R_EAX, Rm );
1097 load_reg( R_ECX, Rn );
1098 SUB_r32_r32( R_EAX, R_ECX );
1099 store_reg( R_ECX, Rn );
1100 sh4_x86.tstate = TSTATE_NONE;
1105 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1106 load_reg( R_EAX, Rm );
1107 load_reg( R_ECX, Rn );
1108 if( sh4_x86.tstate != TSTATE_C ) {
1111 SBB_r32_r32( R_EAX, R_ECX );
1112 store_reg( R_ECX, Rn );
1114 sh4_x86.tstate = TSTATE_C;
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 SUB_r32_r32( R_EAX, R_ECX );
1123 store_reg( R_ECX, Rn );
1125 sh4_x86.tstate = TSTATE_O;
1130 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1131 load_reg( R_EAX, Rm );
1132 load_reg( R_ECX, Rn );
1133 ADD_r32_r32( R_EAX, R_ECX );
1134 store_reg( R_ECX, Rn );
1135 sh4_x86.tstate = TSTATE_NONE;
1139 { /* DMULS.L Rm, Rn */
1140 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1141 load_reg( R_EAX, Rm );
1142 load_reg( R_ECX, Rn );
1144 store_spreg( R_EDX, R_MACH );
1145 store_spreg( R_EAX, R_MACL );
1146 sh4_x86.tstate = TSTATE_NONE;
1151 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1152 if( sh4_x86.tstate != TSTATE_C ) {
1155 load_reg( R_EAX, Rm );
1156 load_reg( R_ECX, Rn );
1157 ADC_r32_r32( R_EAX, R_ECX );
1158 store_reg( R_ECX, Rn );
1160 sh4_x86.tstate = TSTATE_C;
1165 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1166 load_reg( R_EAX, Rm );
1167 load_reg( R_ECX, Rn );
1168 ADD_r32_r32( R_EAX, R_ECX );
1169 store_reg( R_ECX, Rn );
1171 sh4_x86.tstate = TSTATE_O;
1182 switch( (ir&0xF0) >> 4 ) {
1185 uint32_t Rn = ((ir>>8)&0xF);
1186 load_reg( R_EAX, Rn );
1189 store_reg( R_EAX, Rn );
1190 sh4_x86.tstate = TSTATE_C;
1195 uint32_t Rn = ((ir>>8)&0xF);
1196 load_reg( R_EAX, Rn );
1197 ADD_imm8s_r32( -1, R_EAX );
1198 store_reg( R_EAX, Rn );
1200 sh4_x86.tstate = TSTATE_E;
1205 uint32_t Rn = ((ir>>8)&0xF);
1206 load_reg( R_EAX, Rn );
1209 store_reg( R_EAX, Rn );
1210 sh4_x86.tstate = TSTATE_C;
1219 switch( (ir&0xF0) >> 4 ) {
1222 uint32_t Rn = ((ir>>8)&0xF);
1223 load_reg( R_EAX, Rn );
1226 store_reg( R_EAX, Rn );
1227 sh4_x86.tstate = TSTATE_C;
1232 uint32_t Rn = ((ir>>8)&0xF);
1233 load_reg( R_EAX, Rn );
1234 CMP_imm8s_r32( 0, R_EAX );
1236 sh4_x86.tstate = TSTATE_GE;
1241 uint32_t Rn = ((ir>>8)&0xF);
1242 load_reg( R_EAX, Rn );
1245 store_reg( R_EAX, Rn );
1246 sh4_x86.tstate = TSTATE_C;
1255 switch( (ir&0xF0) >> 4 ) {
1257 { /* STS.L MACH, @-Rn */
1258 uint32_t Rn = ((ir>>8)&0xF);
1259 load_reg( R_ECX, Rn );
1260 check_walign32( R_ECX );
1261 ADD_imm8s_r32( -4, R_ECX );
1262 store_reg( R_ECX, Rn );
1263 load_spreg( R_EAX, R_MACH );
1264 MEM_WRITE_LONG( R_ECX, R_EAX );
1265 sh4_x86.tstate = TSTATE_NONE;
1269 { /* STS.L MACL, @-Rn */
1270 uint32_t Rn = ((ir>>8)&0xF);
1271 load_reg( R_ECX, Rn );
1272 check_walign32( R_ECX );
1273 ADD_imm8s_r32( -4, R_ECX );
1274 store_reg( R_ECX, Rn );
1275 load_spreg( R_EAX, R_MACL );
1276 MEM_WRITE_LONG( R_ECX, R_EAX );
1277 sh4_x86.tstate = TSTATE_NONE;
1281 { /* STS.L PR, @-Rn */
1282 uint32_t Rn = ((ir>>8)&0xF);
1283 load_reg( R_ECX, Rn );
1284 check_walign32( R_ECX );
1285 ADD_imm8s_r32( -4, R_ECX );
1286 store_reg( R_ECX, Rn );
1287 load_spreg( R_EAX, R_PR );
1288 MEM_WRITE_LONG( R_ECX, R_EAX );
1289 sh4_x86.tstate = TSTATE_NONE;
1293 { /* STC.L SGR, @-Rn */
1294 uint32_t Rn = ((ir>>8)&0xF);
1296 load_reg( R_ECX, Rn );
1297 check_walign32( R_ECX );
1298 ADD_imm8s_r32( -4, R_ECX );
1299 store_reg( R_ECX, Rn );
1300 load_spreg( R_EAX, R_SGR );
1301 MEM_WRITE_LONG( R_ECX, R_EAX );
1302 sh4_x86.tstate = TSTATE_NONE;
1306 { /* STS.L FPUL, @-Rn */
1307 uint32_t Rn = ((ir>>8)&0xF);
1308 load_reg( R_ECX, Rn );
1309 check_walign32( R_ECX );
1310 ADD_imm8s_r32( -4, R_ECX );
1311 store_reg( R_ECX, Rn );
1312 load_spreg( R_EAX, R_FPUL );
1313 MEM_WRITE_LONG( R_ECX, R_EAX );
1314 sh4_x86.tstate = TSTATE_NONE;
1318 { /* STS.L FPSCR, @-Rn */
1319 uint32_t Rn = ((ir>>8)&0xF);
1320 load_reg( R_ECX, Rn );
1321 check_walign32( R_ECX );
1322 ADD_imm8s_r32( -4, R_ECX );
1323 store_reg( R_ECX, Rn );
1324 load_spreg( R_EAX, R_FPSCR );
1325 MEM_WRITE_LONG( R_ECX, R_EAX );
1326 sh4_x86.tstate = TSTATE_NONE;
1330 { /* STC.L DBR, @-Rn */
1331 uint32_t Rn = ((ir>>8)&0xF);
1333 load_reg( R_ECX, Rn );
1334 check_walign32( R_ECX );
1335 ADD_imm8s_r32( -4, R_ECX );
1336 store_reg( R_ECX, Rn );
1337 load_spreg( R_EAX, R_DBR );
1338 MEM_WRITE_LONG( R_ECX, R_EAX );
1339 sh4_x86.tstate = TSTATE_NONE;
1348 switch( (ir&0x80) >> 7 ) {
1350 switch( (ir&0x70) >> 4 ) {
1352 { /* STC.L SR, @-Rn */
1353 uint32_t Rn = ((ir>>8)&0xF);
1355 call_func0( sh4_read_sr );
1356 load_reg( R_ECX, Rn );
1357 check_walign32( R_ECX );
1358 ADD_imm8s_r32( -4, R_ECX );
1359 store_reg( R_ECX, Rn );
1360 MEM_WRITE_LONG( R_ECX, R_EAX );
1361 sh4_x86.tstate = TSTATE_NONE;
1365 { /* STC.L GBR, @-Rn */
1366 uint32_t Rn = ((ir>>8)&0xF);
1367 load_reg( R_ECX, Rn );
1368 check_walign32( R_ECX );
1369 ADD_imm8s_r32( -4, R_ECX );
1370 store_reg( R_ECX, Rn );
1371 load_spreg( R_EAX, R_GBR );
1372 MEM_WRITE_LONG( R_ECX, R_EAX );
1373 sh4_x86.tstate = TSTATE_NONE;
1377 { /* STC.L VBR, @-Rn */
1378 uint32_t Rn = ((ir>>8)&0xF);
1380 load_reg( R_ECX, Rn );
1381 check_walign32( R_ECX );
1382 ADD_imm8s_r32( -4, R_ECX );
1383 store_reg( R_ECX, Rn );
1384 load_spreg( R_EAX, R_VBR );
1385 MEM_WRITE_LONG( R_ECX, R_EAX );
1386 sh4_x86.tstate = TSTATE_NONE;
1390 { /* STC.L SSR, @-Rn */
1391 uint32_t Rn = ((ir>>8)&0xF);
1393 load_reg( R_ECX, Rn );
1394 check_walign32( R_ECX );
1395 ADD_imm8s_r32( -4, R_ECX );
1396 store_reg( R_ECX, Rn );
1397 load_spreg( R_EAX, R_SSR );
1398 MEM_WRITE_LONG( R_ECX, R_EAX );
1399 sh4_x86.tstate = TSTATE_NONE;
1403 { /* STC.L SPC, @-Rn */
1404 uint32_t Rn = ((ir>>8)&0xF);
1406 load_reg( R_ECX, Rn );
1407 check_walign32( R_ECX );
1408 ADD_imm8s_r32( -4, R_ECX );
1409 store_reg( R_ECX, Rn );
1410 load_spreg( R_EAX, R_SPC );
1411 MEM_WRITE_LONG( R_ECX, R_EAX );
1412 sh4_x86.tstate = TSTATE_NONE;
1421 { /* STC.L Rm_BANK, @-Rn */
1422 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1424 load_reg( R_ECX, Rn );
1425 check_walign32( R_ECX );
1426 ADD_imm8s_r32( -4, R_ECX );
1427 store_reg( R_ECX, Rn );
1428 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1429 MEM_WRITE_LONG( R_ECX, R_EAX );
1430 sh4_x86.tstate = TSTATE_NONE;
1436 switch( (ir&0xF0) >> 4 ) {
1439 uint32_t Rn = ((ir>>8)&0xF);
1440 load_reg( R_EAX, Rn );
1442 store_reg( R_EAX, Rn );
1444 sh4_x86.tstate = TSTATE_C;
1449 uint32_t Rn = ((ir>>8)&0xF);
1450 load_reg( R_EAX, Rn );
1451 if( sh4_x86.tstate != TSTATE_C ) {
1455 store_reg( R_EAX, Rn );
1457 sh4_x86.tstate = TSTATE_C;
1466 switch( (ir&0xF0) >> 4 ) {
1469 uint32_t Rn = ((ir>>8)&0xF);
1470 load_reg( R_EAX, Rn );
1472 store_reg( R_EAX, Rn );
1474 sh4_x86.tstate = TSTATE_C;
1479 uint32_t Rn = ((ir>>8)&0xF);
1480 load_reg( R_EAX, Rn );
1481 CMP_imm8s_r32( 0, R_EAX );
1483 sh4_x86.tstate = TSTATE_G;
1488 uint32_t Rn = ((ir>>8)&0xF);
1489 load_reg( R_EAX, Rn );
1490 if( sh4_x86.tstate != TSTATE_C ) {
1494 store_reg( R_EAX, Rn );
1496 sh4_x86.tstate = TSTATE_C;
1505 switch( (ir&0xF0) >> 4 ) {
1507 { /* LDS.L @Rm+, MACH */
1508 uint32_t Rm = ((ir>>8)&0xF);
1509 load_reg( R_EAX, Rm );
1510 check_ralign32( R_EAX );
1511 MOV_r32_r32( R_EAX, R_ECX );
1512 ADD_imm8s_r32( 4, R_EAX );
1513 store_reg( R_EAX, Rm );
1514 MEM_READ_LONG( R_ECX, R_EAX );
1515 store_spreg( R_EAX, R_MACH );
1516 sh4_x86.tstate = TSTATE_NONE;
1520 { /* LDS.L @Rm+, MACL */
1521 uint32_t Rm = ((ir>>8)&0xF);
1522 load_reg( R_EAX, Rm );
1523 check_ralign32( R_EAX );
1524 MOV_r32_r32( R_EAX, R_ECX );
1525 ADD_imm8s_r32( 4, R_EAX );
1526 store_reg( R_EAX, Rm );
1527 MEM_READ_LONG( R_ECX, R_EAX );
1528 store_spreg( R_EAX, R_MACL );
1529 sh4_x86.tstate = TSTATE_NONE;
1533 { /* LDS.L @Rm+, PR */
1534 uint32_t Rm = ((ir>>8)&0xF);
1535 load_reg( R_EAX, Rm );
1536 check_ralign32( R_EAX );
1537 MOV_r32_r32( R_EAX, R_ECX );
1538 ADD_imm8s_r32( 4, R_EAX );
1539 store_reg( R_EAX, Rm );
1540 MEM_READ_LONG( R_ECX, R_EAX );
1541 store_spreg( R_EAX, R_PR );
1542 sh4_x86.tstate = TSTATE_NONE;
1546 { /* LDC.L @Rm+, SGR */
1547 uint32_t Rm = ((ir>>8)&0xF);
1549 load_reg( R_EAX, Rm );
1550 check_ralign32( R_EAX );
1551 MOV_r32_r32( R_EAX, R_ECX );
1552 ADD_imm8s_r32( 4, R_EAX );
1553 store_reg( R_EAX, Rm );
1554 MEM_READ_LONG( R_ECX, R_EAX );
1555 store_spreg( R_EAX, R_SGR );
1556 sh4_x86.tstate = TSTATE_NONE;
1560 { /* LDS.L @Rm+, FPUL */
1561 uint32_t Rm = ((ir>>8)&0xF);
1562 load_reg( R_EAX, Rm );
1563 check_ralign32( R_EAX );
1564 MOV_r32_r32( R_EAX, R_ECX );
1565 ADD_imm8s_r32( 4, R_EAX );
1566 store_reg( R_EAX, Rm );
1567 MEM_READ_LONG( R_ECX, R_EAX );
1568 store_spreg( R_EAX, R_FPUL );
1569 sh4_x86.tstate = TSTATE_NONE;
1573 { /* LDS.L @Rm+, FPSCR */
1574 uint32_t Rm = ((ir>>8)&0xF);
1575 load_reg( R_EAX, Rm );
1576 check_ralign32( R_EAX );
1577 MOV_r32_r32( R_EAX, R_ECX );
1578 ADD_imm8s_r32( 4, R_EAX );
1579 store_reg( R_EAX, Rm );
1580 MEM_READ_LONG( R_ECX, R_EAX );
1581 store_spreg( R_EAX, R_FPSCR );
1582 update_fr_bank( R_EAX );
1583 sh4_x86.tstate = TSTATE_NONE;
1587 { /* LDC.L @Rm+, DBR */
1588 uint32_t Rm = ((ir>>8)&0xF);
1590 load_reg( R_EAX, Rm );
1591 check_ralign32( R_EAX );
1592 MOV_r32_r32( R_EAX, R_ECX );
1593 ADD_imm8s_r32( 4, R_EAX );
1594 store_reg( R_EAX, Rm );
1595 MEM_READ_LONG( R_ECX, R_EAX );
1596 store_spreg( R_EAX, R_DBR );
1597 sh4_x86.tstate = TSTATE_NONE;
1606 switch( (ir&0x80) >> 7 ) {
1608 switch( (ir&0x70) >> 4 ) {
1610 { /* LDC.L @Rm+, SR */
1611 uint32_t Rm = ((ir>>8)&0xF);
1612 if( sh4_x86.in_delay_slot ) {
1616 load_reg( R_EAX, Rm );
1617 check_ralign32( R_EAX );
1618 MOV_r32_r32( R_EAX, R_ECX );
1619 ADD_imm8s_r32( 4, R_EAX );
1620 store_reg( R_EAX, Rm );
1621 MEM_READ_LONG( R_ECX, R_EAX );
1622 call_func1( sh4_write_sr, R_EAX );
1623 sh4_x86.priv_checked = FALSE;
1624 sh4_x86.fpuen_checked = FALSE;
1625 sh4_x86.tstate = TSTATE_NONE;
1630 { /* LDC.L @Rm+, GBR */
1631 uint32_t Rm = ((ir>>8)&0xF);
1632 load_reg( R_EAX, Rm );
1633 check_ralign32( R_EAX );
1634 MOV_r32_r32( R_EAX, R_ECX );
1635 ADD_imm8s_r32( 4, R_EAX );
1636 store_reg( R_EAX, Rm );
1637 MEM_READ_LONG( R_ECX, R_EAX );
1638 store_spreg( R_EAX, R_GBR );
1639 sh4_x86.tstate = TSTATE_NONE;
1643 { /* LDC.L @Rm+, VBR */
1644 uint32_t Rm = ((ir>>8)&0xF);
1646 load_reg( R_EAX, Rm );
1647 check_ralign32( R_EAX );
1648 MOV_r32_r32( R_EAX, R_ECX );
1649 ADD_imm8s_r32( 4, R_EAX );
1650 store_reg( R_EAX, Rm );
1651 MEM_READ_LONG( R_ECX, R_EAX );
1652 store_spreg( R_EAX, R_VBR );
1653 sh4_x86.tstate = TSTATE_NONE;
1657 { /* LDC.L @Rm+, SSR */
1658 uint32_t Rm = ((ir>>8)&0xF);
1660 load_reg( R_EAX, Rm );
1661 check_ralign32( R_EAX );
1662 MOV_r32_r32( R_EAX, R_ECX );
1663 ADD_imm8s_r32( 4, R_EAX );
1664 store_reg( R_EAX, Rm );
1665 MEM_READ_LONG( R_ECX, R_EAX );
1666 store_spreg( R_EAX, R_SSR );
1667 sh4_x86.tstate = TSTATE_NONE;
1671 { /* LDC.L @Rm+, SPC */
1672 uint32_t Rm = ((ir>>8)&0xF);
1674 load_reg( R_EAX, Rm );
1675 check_ralign32( R_EAX );
1676 MOV_r32_r32( R_EAX, R_ECX );
1677 ADD_imm8s_r32( 4, R_EAX );
1678 store_reg( R_EAX, Rm );
1679 MEM_READ_LONG( R_ECX, R_EAX );
1680 store_spreg( R_EAX, R_SPC );
1681 sh4_x86.tstate = TSTATE_NONE;
1690 { /* LDC.L @Rm+, Rn_BANK */
1691 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1693 load_reg( R_EAX, Rm );
1694 check_ralign32( R_EAX );
1695 MOV_r32_r32( R_EAX, R_ECX );
1696 ADD_imm8s_r32( 4, R_EAX );
1697 store_reg( R_EAX, Rm );
1698 MEM_READ_LONG( R_ECX, R_EAX );
1699 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1700 sh4_x86.tstate = TSTATE_NONE;
1706 switch( (ir&0xF0) >> 4 ) {
1709 uint32_t Rn = ((ir>>8)&0xF);
1710 load_reg( R_EAX, Rn );
1711 SHL_imm8_r32( 2, R_EAX );
1712 store_reg( R_EAX, Rn );
1713 sh4_x86.tstate = TSTATE_NONE;
1718 uint32_t Rn = ((ir>>8)&0xF);
1719 load_reg( R_EAX, Rn );
1720 SHL_imm8_r32( 8, R_EAX );
1721 store_reg( R_EAX, Rn );
1722 sh4_x86.tstate = TSTATE_NONE;
1727 uint32_t Rn = ((ir>>8)&0xF);
1728 load_reg( R_EAX, Rn );
1729 SHL_imm8_r32( 16, R_EAX );
1730 store_reg( R_EAX, Rn );
1731 sh4_x86.tstate = TSTATE_NONE;
1740 switch( (ir&0xF0) >> 4 ) {
1743 uint32_t Rn = ((ir>>8)&0xF);
1744 load_reg( R_EAX, Rn );
1745 SHR_imm8_r32( 2, R_EAX );
1746 store_reg( R_EAX, Rn );
1747 sh4_x86.tstate = TSTATE_NONE;
1752 uint32_t Rn = ((ir>>8)&0xF);
1753 load_reg( R_EAX, Rn );
1754 SHR_imm8_r32( 8, R_EAX );
1755 store_reg( R_EAX, Rn );
1756 sh4_x86.tstate = TSTATE_NONE;
1761 uint32_t Rn = ((ir>>8)&0xF);
1762 load_reg( R_EAX, Rn );
1763 SHR_imm8_r32( 16, R_EAX );
1764 store_reg( R_EAX, Rn );
1765 sh4_x86.tstate = TSTATE_NONE;
1774 switch( (ir&0xF0) >> 4 ) {
1776 { /* LDS Rm, MACH */
1777 uint32_t Rm = ((ir>>8)&0xF);
1778 load_reg( R_EAX, Rm );
1779 store_spreg( R_EAX, R_MACH );
1783 { /* LDS Rm, MACL */
1784 uint32_t Rm = ((ir>>8)&0xF);
1785 load_reg( R_EAX, Rm );
1786 store_spreg( R_EAX, R_MACL );
1791 uint32_t Rm = ((ir>>8)&0xF);
1792 load_reg( R_EAX, Rm );
1793 store_spreg( R_EAX, R_PR );
1798 uint32_t Rm = ((ir>>8)&0xF);
1800 load_reg( R_EAX, Rm );
1801 store_spreg( R_EAX, R_SGR );
1802 sh4_x86.tstate = TSTATE_NONE;
1806 { /* LDS Rm, FPUL */
1807 uint32_t Rm = ((ir>>8)&0xF);
1808 load_reg( R_EAX, Rm );
1809 store_spreg( R_EAX, R_FPUL );
1813 { /* LDS Rm, FPSCR */
1814 uint32_t Rm = ((ir>>8)&0xF);
1815 load_reg( R_EAX, Rm );
1816 store_spreg( R_EAX, R_FPSCR );
1817 update_fr_bank( R_EAX );
1818 sh4_x86.tstate = TSTATE_NONE;
1823 uint32_t Rm = ((ir>>8)&0xF);
1825 load_reg( R_EAX, Rm );
1826 store_spreg( R_EAX, R_DBR );
1827 sh4_x86.tstate = TSTATE_NONE;
1836 switch( (ir&0xF0) >> 4 ) {
1839 uint32_t Rn = ((ir>>8)&0xF);
1840 if( sh4_x86.in_delay_slot ) {
1843 load_imm32( R_EAX, pc + 4 );
1844 store_spreg( R_EAX, R_PR );
1845 load_reg( R_ECX, Rn );
1846 store_spreg( R_ECX, REG_OFFSET(pc) );
1847 sh4_x86.in_delay_slot = TRUE;
1848 sh4_translate_instruction(pc+2);
1849 exit_block_pcset(pc+2);
1850 sh4_x86.branch_taken = TRUE;
1857 uint32_t Rn = ((ir>>8)&0xF);
1858 load_reg( R_ECX, Rn );
1859 MEM_READ_BYTE( R_ECX, R_EAX );
1860 TEST_r8_r8( R_AL, R_AL );
1862 OR_imm8_r8( 0x80, R_AL );
1863 load_reg( R_ECX, Rn );
1864 MEM_WRITE_BYTE( R_ECX, R_EAX );
1865 sh4_x86.tstate = TSTATE_NONE;
1870 uint32_t Rn = ((ir>>8)&0xF);
1871 if( sh4_x86.in_delay_slot ) {
1874 load_reg( R_ECX, Rn );
1875 store_spreg( R_ECX, REG_OFFSET(pc) );
1876 sh4_x86.in_delay_slot = TRUE;
1877 sh4_translate_instruction(pc+2);
1878 exit_block_pcset(pc+2);
1879 sh4_x86.branch_taken = TRUE;
1891 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1892 /* Annoyingly enough, not directly convertible */
1893 load_reg( R_EAX, Rn );
1894 load_reg( R_ECX, Rm );
1895 CMP_imm32_r32( 0, R_ECX );
1896 JGE_rel8(16, doshl);
1898 NEG_r32( R_ECX ); // 2
1899 AND_imm8_r8( 0x1F, R_CL ); // 3
1900 JE_rel8( 4, emptysar); // 2
1901 SAR_r32_CL( R_EAX ); // 2
1902 JMP_rel8(10, end); // 2
1904 JMP_TARGET(emptysar);
1905 SAR_imm8_r32(31, R_EAX ); // 3
1909 AND_imm8_r8( 0x1F, R_CL ); // 3
1910 SHL_r32_CL( R_EAX ); // 2
1913 store_reg( R_EAX, Rn );
1914 sh4_x86.tstate = TSTATE_NONE;
1919 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1920 load_reg( R_EAX, Rn );
1921 load_reg( R_ECX, Rm );
1922 CMP_imm32_r32( 0, R_ECX );
1923 JGE_rel8(15, doshl);
1925 NEG_r32( R_ECX ); // 2
1926 AND_imm8_r8( 0x1F, R_CL ); // 3
1927 JE_rel8( 4, emptyshr );
1928 SHR_r32_CL( R_EAX ); // 2
1929 JMP_rel8(9, end); // 2
1931 JMP_TARGET(emptyshr);
1932 XOR_r32_r32( R_EAX, R_EAX );
1936 AND_imm8_r8( 0x1F, R_CL ); // 3
1937 SHL_r32_CL( R_EAX ); // 2
1940 store_reg( R_EAX, Rn );
1941 sh4_x86.tstate = TSTATE_NONE;
1945 switch( (ir&0x80) >> 7 ) {
1947 switch( (ir&0x70) >> 4 ) {
1950 uint32_t Rm = ((ir>>8)&0xF);
1951 if( sh4_x86.in_delay_slot ) {
1955 load_reg( R_EAX, Rm );
1956 call_func1( sh4_write_sr, R_EAX );
1957 sh4_x86.priv_checked = FALSE;
1958 sh4_x86.fpuen_checked = FALSE;
1959 sh4_x86.tstate = TSTATE_NONE;
1965 uint32_t Rm = ((ir>>8)&0xF);
1966 load_reg( R_EAX, Rm );
1967 store_spreg( R_EAX, R_GBR );
1972 uint32_t Rm = ((ir>>8)&0xF);
1974 load_reg( R_EAX, Rm );
1975 store_spreg( R_EAX, R_VBR );
1976 sh4_x86.tstate = TSTATE_NONE;
1981 uint32_t Rm = ((ir>>8)&0xF);
1983 load_reg( R_EAX, Rm );
1984 store_spreg( R_EAX, R_SSR );
1985 sh4_x86.tstate = TSTATE_NONE;
1990 uint32_t Rm = ((ir>>8)&0xF);
1992 load_reg( R_EAX, Rm );
1993 store_spreg( R_EAX, R_SPC );
1994 sh4_x86.tstate = TSTATE_NONE;
2003 { /* LDC Rm, Rn_BANK */
2004 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2006 load_reg( R_EAX, Rm );
2007 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2008 sh4_x86.tstate = TSTATE_NONE;
2014 { /* MAC.W @Rm+, @Rn+ */
2015 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2016 load_reg( R_ECX, Rm );
2017 check_ralign16( R_ECX );
2018 load_reg( R_ECX, Rn );
2019 check_ralign16( R_ECX );
2020 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2021 MEM_READ_WORD( R_ECX, R_EAX );
2022 PUSH_realigned_r32( R_EAX );
2023 load_reg( R_ECX, Rm );
2024 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2025 MEM_READ_WORD( R_ECX, R_EAX );
2026 POP_realigned_r32( R_ECX );
2029 load_spreg( R_ECX, R_S );
2030 TEST_r32_r32( R_ECX, R_ECX );
2031 JE_rel8( 47, nosat );
2033 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2034 JNO_rel8( 51, end ); // 2
2035 load_imm32( R_EDX, 1 ); // 5
2036 store_spreg( R_EDX, R_MACH ); // 6
2037 JS_rel8( 13, positive ); // 2
2038 load_imm32( R_EAX, 0x80000000 );// 5
2039 store_spreg( R_EAX, R_MACL ); // 6
2040 JMP_rel8( 25, end2 ); // 2
2042 JMP_TARGET(positive);
2043 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2044 store_spreg( R_EAX, R_MACL ); // 6
2045 JMP_rel8( 12, end3); // 2
2048 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2049 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2053 sh4_x86.tstate = TSTATE_NONE;
2059 { /* MOV.L @(disp, Rm), Rn */
2060 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2061 load_reg( R_ECX, Rm );
2062 ADD_imm8s_r32( disp, R_ECX );
2063 check_ralign32( R_ECX );
2064 MEM_READ_LONG( R_ECX, R_EAX );
2065 store_reg( R_EAX, Rn );
2066 sh4_x86.tstate = TSTATE_NONE;
2072 { /* MOV.B @Rm, Rn */
2073 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2074 load_reg( R_ECX, Rm );
2075 MEM_READ_BYTE( R_ECX, R_EAX );
2076 store_reg( R_EAX, Rn );
2077 sh4_x86.tstate = TSTATE_NONE;
2081 { /* MOV.W @Rm, Rn */
2082 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2083 load_reg( R_ECX, Rm );
2084 check_ralign16( R_ECX );
2085 MEM_READ_WORD( R_ECX, R_EAX );
2086 store_reg( R_EAX, Rn );
2087 sh4_x86.tstate = TSTATE_NONE;
2091 { /* MOV.L @Rm, Rn */
2092 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2093 load_reg( R_ECX, Rm );
2094 check_ralign32( R_ECX );
2095 MEM_READ_LONG( R_ECX, R_EAX );
2096 store_reg( R_EAX, Rn );
2097 sh4_x86.tstate = TSTATE_NONE;
2102 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2103 load_reg( R_EAX, Rm );
2104 store_reg( R_EAX, Rn );
2108 { /* MOV.B @Rm+, Rn */
2109 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2110 load_reg( R_ECX, Rm );
2111 MOV_r32_r32( R_ECX, R_EAX );
2112 ADD_imm8s_r32( 1, R_EAX );
2113 store_reg( R_EAX, Rm );
2114 MEM_READ_BYTE( R_ECX, R_EAX );
2115 store_reg( R_EAX, Rn );
2116 sh4_x86.tstate = TSTATE_NONE;
2120 { /* MOV.W @Rm+, Rn */
2121 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2122 load_reg( R_EAX, Rm );
2123 check_ralign16( R_EAX );
2124 MOV_r32_r32( R_EAX, R_ECX );
2125 ADD_imm8s_r32( 2, R_EAX );
2126 store_reg( R_EAX, Rm );
2127 MEM_READ_WORD( R_ECX, R_EAX );
2128 store_reg( R_EAX, Rn );
2129 sh4_x86.tstate = TSTATE_NONE;
2133 { /* MOV.L @Rm+, Rn */
2134 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2135 load_reg( R_EAX, Rm );
2136 check_ralign32( R_EAX );
2137 MOV_r32_r32( R_EAX, R_ECX );
2138 ADD_imm8s_r32( 4, R_EAX );
2139 store_reg( R_EAX, Rm );
2140 MEM_READ_LONG( R_ECX, R_EAX );
2141 store_reg( R_EAX, Rn );
2142 sh4_x86.tstate = TSTATE_NONE;
2147 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2148 load_reg( R_EAX, Rm );
2150 store_reg( R_EAX, Rn );
2151 sh4_x86.tstate = TSTATE_NONE;
2155 { /* SWAP.B Rm, Rn */
2156 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2157 load_reg( R_EAX, Rm );
2158 XCHG_r8_r8( R_AL, R_AH );
2159 store_reg( R_EAX, Rn );
2163 { /* SWAP.W Rm, Rn */
2164 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2165 load_reg( R_EAX, Rm );
2166 MOV_r32_r32( R_EAX, R_ECX );
2167 SHL_imm8_r32( 16, R_ECX );
2168 SHR_imm8_r32( 16, R_EAX );
2169 OR_r32_r32( R_EAX, R_ECX );
2170 store_reg( R_ECX, Rn );
2171 sh4_x86.tstate = TSTATE_NONE;
2176 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2177 load_reg( R_EAX, Rm );
2178 XOR_r32_r32( R_ECX, R_ECX );
2180 SBB_r32_r32( R_EAX, R_ECX );
2181 store_reg( R_ECX, Rn );
2183 sh4_x86.tstate = TSTATE_C;
2188 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2189 load_reg( R_EAX, Rm );
2191 store_reg( R_EAX, Rn );
2192 sh4_x86.tstate = TSTATE_NONE;
2196 { /* EXTU.B Rm, Rn */
2197 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2198 load_reg( R_EAX, Rm );
2199 MOVZX_r8_r32( R_EAX, R_EAX );
2200 store_reg( R_EAX, Rn );
2204 { /* EXTU.W Rm, Rn */
2205 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2206 load_reg( R_EAX, Rm );
2207 MOVZX_r16_r32( R_EAX, R_EAX );
2208 store_reg( R_EAX, Rn );
2212 { /* EXTS.B Rm, Rn */
2213 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2214 load_reg( R_EAX, Rm );
2215 MOVSX_r8_r32( R_EAX, R_EAX );
2216 store_reg( R_EAX, Rn );
2220 { /* EXTS.W Rm, Rn */
2221 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2222 load_reg( R_EAX, Rm );
2223 MOVSX_r16_r32( R_EAX, R_EAX );
2224 store_reg( R_EAX, Rn );
2230 { /* ADD #imm, Rn */
2231 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2232 load_reg( R_EAX, Rn );
2233 ADD_imm8s_r32( imm, R_EAX );
2234 store_reg( R_EAX, Rn );
2235 sh4_x86.tstate = TSTATE_NONE;
2239 switch( (ir&0xF00) >> 8 ) {
2241 { /* MOV.B R0, @(disp, Rn) */
2242 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2243 load_reg( R_EAX, 0 );
2244 load_reg( R_ECX, Rn );
2245 ADD_imm32_r32( disp, R_ECX );
2246 MEM_WRITE_BYTE( R_ECX, R_EAX );
2247 sh4_x86.tstate = TSTATE_NONE;
2251 { /* MOV.W R0, @(disp, Rn) */
2252 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2253 load_reg( R_ECX, Rn );
2254 load_reg( R_EAX, 0 );
2255 ADD_imm32_r32( disp, R_ECX );
2256 check_walign16( R_ECX );
2257 MEM_WRITE_WORD( R_ECX, R_EAX );
2258 sh4_x86.tstate = TSTATE_NONE;
2262 { /* MOV.B @(disp, Rm), R0 */
2263 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2264 load_reg( R_ECX, Rm );
2265 ADD_imm32_r32( disp, R_ECX );
2266 MEM_READ_BYTE( R_ECX, R_EAX );
2267 store_reg( R_EAX, 0 );
2268 sh4_x86.tstate = TSTATE_NONE;
2272 { /* MOV.W @(disp, Rm), R0 */
2273 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2274 load_reg( R_ECX, Rm );
2275 ADD_imm32_r32( disp, R_ECX );
2276 check_ralign16( R_ECX );
2277 MEM_READ_WORD( R_ECX, R_EAX );
2278 store_reg( R_EAX, 0 );
2279 sh4_x86.tstate = TSTATE_NONE;
2283 { /* CMP/EQ #imm, R0 */
2284 int32_t imm = SIGNEXT8(ir&0xFF);
2285 load_reg( R_EAX, 0 );
2286 CMP_imm8s_r32(imm, R_EAX);
2288 sh4_x86.tstate = TSTATE_E;
2293 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2294 if( sh4_x86.in_delay_slot ) {
2297 JF_rel8( EXIT_BLOCK_SIZE, nottaken );
2298 exit_block( disp + pc + 4, pc+2 );
2299 JMP_TARGET(nottaken);
2306 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2307 if( sh4_x86.in_delay_slot ) {
2310 JT_rel8( EXIT_BLOCK_SIZE, nottaken );
2311 exit_block( disp + pc + 4, pc+2 );
2312 JMP_TARGET(nottaken);
2319 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2320 if( sh4_x86.in_delay_slot ) {
2323 sh4_x86.in_delay_slot = TRUE;
2324 if( sh4_x86.tstate == TSTATE_NONE ) {
2325 CMP_imm8s_sh4r( 1, R_T );
2326 sh4_x86.tstate = TSTATE_E;
2328 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2329 sh4_translate_instruction(pc+2);
2330 exit_block( disp + pc + 4, pc+4 );
2332 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2333 sh4_translate_instruction(pc+2);
2340 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2341 if( sh4_x86.in_delay_slot ) {
2344 sh4_x86.in_delay_slot = TRUE;
2345 if( sh4_x86.tstate == TSTATE_NONE ) {
2346 CMP_imm8s_sh4r( 1, R_T );
2347 sh4_x86.tstate = TSTATE_E;
2349 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2350 sh4_translate_instruction(pc+2);
2351 exit_block( disp + pc + 4, pc+4 );
2353 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2354 sh4_translate_instruction(pc+2);
2365 { /* MOV.W @(disp, PC), Rn */
2366 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2367 if( sh4_x86.in_delay_slot ) {
2370 load_imm32( R_ECX, pc + disp + 4 );
2371 MEM_READ_WORD( R_ECX, R_EAX );
2372 store_reg( R_EAX, Rn );
2373 sh4_x86.tstate = TSTATE_NONE;
2379 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2380 if( sh4_x86.in_delay_slot ) {
2383 sh4_x86.in_delay_slot = TRUE;
2384 sh4_translate_instruction( pc + 2 );
2385 exit_block( disp + pc + 4, pc+4 );
2386 sh4_x86.branch_taken = TRUE;
2393 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2394 if( sh4_x86.in_delay_slot ) {
2397 load_imm32( R_EAX, pc + 4 );
2398 store_spreg( R_EAX, R_PR );
2399 sh4_x86.in_delay_slot = TRUE;
2400 sh4_translate_instruction( pc + 2 );
2401 exit_block( disp + pc + 4, pc+4 );
2402 sh4_x86.branch_taken = TRUE;
2408 switch( (ir&0xF00) >> 8 ) {
2410 { /* MOV.B R0, @(disp, GBR) */
2411 uint32_t disp = (ir&0xFF);
2412 load_reg( R_EAX, 0 );
2413 load_spreg( R_ECX, R_GBR );
2414 ADD_imm32_r32( disp, R_ECX );
2415 MEM_WRITE_BYTE( R_ECX, R_EAX );
2416 sh4_x86.tstate = TSTATE_NONE;
2420 { /* MOV.W R0, @(disp, GBR) */
2421 uint32_t disp = (ir&0xFF)<<1;
2422 load_spreg( R_ECX, R_GBR );
2423 load_reg( R_EAX, 0 );
2424 ADD_imm32_r32( disp, R_ECX );
2425 check_walign16( R_ECX );
2426 MEM_WRITE_WORD( R_ECX, R_EAX );
2427 sh4_x86.tstate = TSTATE_NONE;
2431 { /* MOV.L R0, @(disp, GBR) */
2432 uint32_t disp = (ir&0xFF)<<2;
2433 load_spreg( R_ECX, R_GBR );
2434 load_reg( R_EAX, 0 );
2435 ADD_imm32_r32( disp, R_ECX );
2436 check_walign32( R_ECX );
2437 MEM_WRITE_LONG( R_ECX, R_EAX );
2438 sh4_x86.tstate = TSTATE_NONE;
2443 uint32_t imm = (ir&0xFF);
2444 if( sh4_x86.in_delay_slot ) {
2447 load_imm32( R_ECX, pc+2 );
2448 store_spreg( R_ECX, REG_OFFSET(pc) );
2449 load_imm32( R_EAX, imm );
2450 call_func1( sh4_raise_trap, R_EAX );
2451 sh4_x86.tstate = TSTATE_NONE;
2452 exit_block_pcset(pc);
2453 sh4_x86.branch_taken = TRUE;
2459 { /* MOV.B @(disp, GBR), R0 */
2460 uint32_t disp = (ir&0xFF);
2461 load_spreg( R_ECX, R_GBR );
2462 ADD_imm32_r32( disp, R_ECX );
2463 MEM_READ_BYTE( R_ECX, R_EAX );
2464 store_reg( R_EAX, 0 );
2465 sh4_x86.tstate = TSTATE_NONE;
2469 { /* MOV.W @(disp, GBR), R0 */
2470 uint32_t disp = (ir&0xFF)<<1;
2471 load_spreg( R_ECX, R_GBR );
2472 ADD_imm32_r32( disp, R_ECX );
2473 check_ralign16( R_ECX );
2474 MEM_READ_WORD( R_ECX, R_EAX );
2475 store_reg( R_EAX, 0 );
2476 sh4_x86.tstate = TSTATE_NONE;
2480 { /* MOV.L @(disp, GBR), R0 */
2481 uint32_t disp = (ir&0xFF)<<2;
2482 load_spreg( R_ECX, R_GBR );
2483 ADD_imm32_r32( disp, R_ECX );
2484 check_ralign32( R_ECX );
2485 MEM_READ_LONG( R_ECX, R_EAX );
2486 store_reg( R_EAX, 0 );
2487 sh4_x86.tstate = TSTATE_NONE;
2491 { /* MOVA @(disp, PC), R0 */
2492 uint32_t disp = (ir&0xFF)<<2;
2493 if( sh4_x86.in_delay_slot ) {
2496 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2497 store_reg( R_ECX, 0 );
2502 { /* TST #imm, R0 */
2503 uint32_t imm = (ir&0xFF);
2504 load_reg( R_EAX, 0 );
2505 TEST_imm32_r32( imm, R_EAX );
2507 sh4_x86.tstate = TSTATE_E;
2511 { /* AND #imm, R0 */
2512 uint32_t imm = (ir&0xFF);
2513 load_reg( R_EAX, 0 );
2514 AND_imm32_r32(imm, R_EAX);
2515 store_reg( R_EAX, 0 );
2516 sh4_x86.tstate = TSTATE_NONE;
2520 { /* XOR #imm, R0 */
2521 uint32_t imm = (ir&0xFF);
2522 load_reg( R_EAX, 0 );
2523 XOR_imm32_r32( imm, R_EAX );
2524 store_reg( R_EAX, 0 );
2525 sh4_x86.tstate = TSTATE_NONE;
2530 uint32_t imm = (ir&0xFF);
2531 load_reg( R_EAX, 0 );
2532 OR_imm32_r32(imm, R_EAX);
2533 store_reg( R_EAX, 0 );
2534 sh4_x86.tstate = TSTATE_NONE;
2538 { /* TST.B #imm, @(R0, GBR) */
2539 uint32_t imm = (ir&0xFF);
2540 load_reg( R_EAX, 0);
2541 load_reg( R_ECX, R_GBR);
2542 ADD_r32_r32( R_EAX, R_ECX );
2543 MEM_READ_BYTE( R_ECX, R_EAX );
2544 TEST_imm8_r8( imm, R_AL );
2546 sh4_x86.tstate = TSTATE_E;
2550 { /* AND.B #imm, @(R0, GBR) */
2551 uint32_t imm = (ir&0xFF);
2552 load_reg( R_EAX, 0 );
2553 load_spreg( R_ECX, R_GBR );
2554 ADD_r32_r32( R_EAX, R_ECX );
2555 PUSH_realigned_r32(R_ECX);
2556 MEM_READ_BYTE( R_ECX, R_EAX );
2557 POP_realigned_r32(R_ECX);
2558 AND_imm32_r32(imm, R_EAX );
2559 MEM_WRITE_BYTE( R_ECX, R_EAX );
2560 sh4_x86.tstate = TSTATE_NONE;
2564 { /* XOR.B #imm, @(R0, GBR) */
2565 uint32_t imm = (ir&0xFF);
2566 load_reg( R_EAX, 0 );
2567 load_spreg( R_ECX, R_GBR );
2568 ADD_r32_r32( R_EAX, R_ECX );
2569 PUSH_realigned_r32(R_ECX);
2570 MEM_READ_BYTE(R_ECX, R_EAX);
2571 POP_realigned_r32(R_ECX);
2572 XOR_imm32_r32( imm, R_EAX );
2573 MEM_WRITE_BYTE( R_ECX, R_EAX );
2574 sh4_x86.tstate = TSTATE_NONE;
2578 { /* OR.B #imm, @(R0, GBR) */
2579 uint32_t imm = (ir&0xFF);
2580 load_reg( R_EAX, 0 );
2581 load_spreg( R_ECX, R_GBR );
2582 ADD_r32_r32( R_EAX, R_ECX );
2583 PUSH_realigned_r32(R_ECX);
2584 MEM_READ_BYTE( R_ECX, R_EAX );
2585 POP_realigned_r32(R_ECX);
2586 OR_imm32_r32(imm, R_EAX );
2587 MEM_WRITE_BYTE( R_ECX, R_EAX );
2588 sh4_x86.tstate = TSTATE_NONE;
2594 { /* MOV.L @(disp, PC), Rn */
2595 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2596 if( sh4_x86.in_delay_slot ) {
2599 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2600 sh4ptr_t ptr = sh4_get_region_by_vma(target);
2602 MOV_moff32_EAX( ptr );
2604 load_imm32( R_ECX, target );
2605 MEM_READ_LONG( R_ECX, R_EAX );
2607 store_reg( R_EAX, Rn );
2608 sh4_x86.tstate = TSTATE_NONE;
2613 { /* MOV #imm, Rn */
2614 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2615 load_imm32( R_EAX, imm );
2616 store_reg( R_EAX, Rn );
2622 { /* FADD FRm, FRn */
2623 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2625 load_spreg( R_ECX, R_FPSCR );
2626 TEST_imm32_r32( FPSCR_PR, R_ECX );
2627 load_fr_bank( R_EDX );
2628 JNE_rel8(13,doubleprec);
2629 push_fr(R_EDX, FRm);
2630 push_fr(R_EDX, FRn);
2634 JMP_TARGET(doubleprec);
2635 push_dr(R_EDX, FRm);
2636 push_dr(R_EDX, FRn);
2640 sh4_x86.tstate = TSTATE_NONE;
2644 { /* FSUB FRm, FRn */
2645 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2647 load_spreg( R_ECX, R_FPSCR );
2648 TEST_imm32_r32( FPSCR_PR, R_ECX );
2649 load_fr_bank( R_EDX );
2650 JNE_rel8(13, doubleprec);
2651 push_fr(R_EDX, FRn);
2652 push_fr(R_EDX, FRm);
2656 JMP_TARGET(doubleprec);
2657 push_dr(R_EDX, FRn);
2658 push_dr(R_EDX, FRm);
2662 sh4_x86.tstate = TSTATE_NONE;
2666 { /* FMUL FRm, FRn */
2667 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2669 load_spreg( R_ECX, R_FPSCR );
2670 TEST_imm32_r32( FPSCR_PR, R_ECX );
2671 load_fr_bank( R_EDX );
2672 JNE_rel8(13, doubleprec);
2673 push_fr(R_EDX, FRm);
2674 push_fr(R_EDX, FRn);
2678 JMP_TARGET(doubleprec);
2679 push_dr(R_EDX, FRm);
2680 push_dr(R_EDX, FRn);
2684 sh4_x86.tstate = TSTATE_NONE;
2688 { /* FDIV FRm, FRn */
2689 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2691 load_spreg( R_ECX, R_FPSCR );
2692 TEST_imm32_r32( FPSCR_PR, R_ECX );
2693 load_fr_bank( R_EDX );
2694 JNE_rel8(13, doubleprec);
2695 push_fr(R_EDX, FRn);
2696 push_fr(R_EDX, FRm);
2700 JMP_TARGET(doubleprec);
2701 push_dr(R_EDX, FRn);
2702 push_dr(R_EDX, FRm);
2706 sh4_x86.tstate = TSTATE_NONE;
2710 { /* FCMP/EQ FRm, FRn */
2711 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2713 load_spreg( R_ECX, R_FPSCR );
2714 TEST_imm32_r32( FPSCR_PR, R_ECX );
2715 load_fr_bank( R_EDX );
2716 JNE_rel8(8, doubleprec);
2717 push_fr(R_EDX, FRm);
2718 push_fr(R_EDX, FRn);
2720 JMP_TARGET(doubleprec);
2721 push_dr(R_EDX, FRm);
2722 push_dr(R_EDX, FRn);
2727 sh4_x86.tstate = TSTATE_NONE;
2731 { /* FCMP/GT FRm, FRn */
2732 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2734 load_spreg( R_ECX, R_FPSCR );
2735 TEST_imm32_r32( FPSCR_PR, R_ECX );
2736 load_fr_bank( R_EDX );
2737 JNE_rel8(8, doubleprec);
2738 push_fr(R_EDX, FRm);
2739 push_fr(R_EDX, FRn);
2741 JMP_TARGET(doubleprec);
2742 push_dr(R_EDX, FRm);
2743 push_dr(R_EDX, FRn);
2748 sh4_x86.tstate = TSTATE_NONE;
2752 { /* FMOV @(R0, Rm), FRn */
2753 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2755 load_reg( R_ECX, Rm );
2756 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
2757 check_ralign32( R_ECX );
2758 load_spreg( R_EDX, R_FPSCR );
2759 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2760 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2761 MEM_READ_LONG( R_ECX, R_EAX );
2762 load_fr_bank( R_EDX );
2763 store_fr( R_EDX, R_EAX, FRn );
2765 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2766 JMP_TARGET(doublesize);
2767 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2768 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2769 load_xf_bank( R_EDX );
2770 store_fr( R_EDX, R_EAX, FRn&0x0E );
2771 store_fr( R_EDX, R_ECX, FRn|0x01 );
2774 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2775 JMP_TARGET(doublesize);
2776 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2777 load_fr_bank( R_EDX );
2778 store_fr( R_EDX, R_EAX, FRn&0x0E );
2779 store_fr( R_EDX, R_ECX, FRn|0x01 );
2782 sh4_x86.tstate = TSTATE_NONE;
2786 { /* FMOV FRm, @(R0, Rn) */
2787 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2789 load_reg( R_ECX, Rn );
2790 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
2791 check_walign32( R_ECX );
2792 load_spreg( R_EDX, R_FPSCR );
2793 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2794 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
2795 load_fr_bank( R_EDX );
2796 load_fr( R_EDX, R_EAX, FRm );
2797 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
2799 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
2800 JMP_TARGET(doublesize);
2801 load_xf_bank( R_EDX );
2802 load_fr( R_EDX, R_EAX, FRm&0x0E );
2803 load_fr( R_EDX, R_EDX, FRm|0x01 );
2804 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2807 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
2808 JMP_TARGET(doublesize);
2809 load_fr_bank( R_EDX );
2810 load_fr( R_EDX, R_EAX, FRm&0x0E );
2811 load_fr( R_EDX, R_EDX, FRm|0x01 );
2812 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2815 sh4_x86.tstate = TSTATE_NONE;
2819 { /* FMOV @Rm, FRn */
2820 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2822 load_reg( R_ECX, Rm );
2823 check_ralign32( R_ECX );
2824 load_spreg( R_EDX, R_FPSCR );
2825 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2826 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2827 MEM_READ_LONG( R_ECX, R_EAX );
2828 load_fr_bank( R_EDX );
2829 store_fr( R_EDX, R_EAX, FRn );
2831 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2832 JMP_TARGET(doublesize);
2833 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2834 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2835 load_xf_bank( R_EDX );
2836 store_fr( R_EDX, R_EAX, FRn&0x0E );
2837 store_fr( R_EDX, R_ECX, FRn|0x01 );
2840 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2841 JMP_TARGET(doublesize);
2842 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2843 load_fr_bank( R_EDX );
2844 store_fr( R_EDX, R_EAX, FRn&0x0E );
2845 store_fr( R_EDX, R_ECX, FRn|0x01 );
2848 sh4_x86.tstate = TSTATE_NONE;
2852 { /* FMOV @Rm+, FRn */
2853 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2855 load_reg( R_ECX, Rm );
2856 check_ralign32( R_ECX );
2857 MOV_r32_r32( R_ECX, R_EAX );
2858 load_spreg( R_EDX, R_FPSCR );
2859 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2860 JNE_rel8(14 + MEM_READ_SIZE, doublesize);
2861 ADD_imm8s_r32( 4, R_EAX );
2862 store_reg( R_EAX, Rm );
2863 MEM_READ_LONG( R_ECX, R_EAX );
2864 load_fr_bank( R_EDX );
2865 store_fr( R_EDX, R_EAX, FRn );
2867 JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);
2868 JMP_TARGET(doublesize);
2869 ADD_imm8s_r32( 8, R_EAX );
2870 store_reg(R_EAX, Rm);
2871 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2872 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2873 load_xf_bank( R_EDX );
2874 store_fr( R_EDX, R_EAX, FRn&0x0E );
2875 store_fr( R_EDX, R_ECX, FRn|0x01 );
2878 JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);
2879 ADD_imm8s_r32( 8, R_EAX );
2880 store_reg(R_EAX, Rm);
2881 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2882 load_fr_bank( R_EDX );
2883 store_fr( R_EDX, R_EAX, FRn&0x0E );
2884 store_fr( R_EDX, R_ECX, FRn|0x01 );
2887 sh4_x86.tstate = TSTATE_NONE;
2891 { /* FMOV FRm, @Rn */
2892 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2894 load_reg( R_ECX, Rn );
2895 check_walign32( R_ECX );
2896 load_spreg( R_EDX, R_FPSCR );
2897 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2898 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
2899 load_fr_bank( R_EDX );
2900 load_fr( R_EDX, R_EAX, FRm );
2901 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
2903 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
2904 JMP_TARGET(doublesize);
2905 load_xf_bank( R_EDX );
2906 load_fr( R_EDX, R_EAX, FRm&0x0E );
2907 load_fr( R_EDX, R_EDX, FRm|0x01 );
2908 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2911 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
2912 JMP_TARGET(doublesize);
2913 load_fr_bank( R_EDX );
2914 load_fr( R_EDX, R_EAX, FRm&0x0E );
2915 load_fr( R_EDX, R_EDX, FRm|0x01 );
2916 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2919 sh4_x86.tstate = TSTATE_NONE;
2923 { /* FMOV FRm, @-Rn */
2924 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2926 load_reg( R_ECX, Rn );
2927 check_walign32( R_ECX );
2928 load_spreg( R_EDX, R_FPSCR );
2929 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2930 JNE_rel8(14 + MEM_WRITE_SIZE, doublesize);
2931 load_fr_bank( R_EDX );
2932 load_fr( R_EDX, R_EAX, FRm );
2933 ADD_imm8s_r32(-4,R_ECX);
2934 store_reg( R_ECX, Rn );
2935 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
2937 JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );
2938 JMP_TARGET(doublesize);
2939 load_xf_bank( R_EDX );
2940 load_fr( R_EDX, R_EAX, FRm&0x0E );
2941 load_fr( R_EDX, R_EDX, FRm|0x01 );
2942 ADD_imm8s_r32(-8,R_ECX);
2943 store_reg( R_ECX, Rn );
2944 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2947 JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );
2948 JMP_TARGET(doublesize);
2949 load_fr_bank( R_EDX );
2950 load_fr( R_EDX, R_EAX, FRm&0x0E );
2951 load_fr( R_EDX, R_EDX, FRm|0x01 );
2952 ADD_imm8s_r32(-8,R_ECX);
2953 store_reg( R_ECX, Rn );
2954 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
2957 sh4_x86.tstate = TSTATE_NONE;
2961 { /* FMOV FRm, FRn */
2962 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2963 /* As horrible as this looks, it's actually covering 5 separate cases:
2964 * 1. 32-bit fr-to-fr (PR=0)
2965 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
2966 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
2967 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
2968 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
2971 load_spreg( R_ECX, R_FPSCR );
2972 load_fr_bank( R_EDX );
2973 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2974 JNE_rel8(8, doublesize);
2975 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
2976 store_fr( R_EDX, R_EAX, FRn );
2979 JMP_TARGET(doublesize);
2980 load_xf_bank( R_ECX );
2981 load_fr( R_ECX, R_EAX, FRm-1 );
2983 load_fr( R_ECX, R_EDX, FRm );
2984 store_fr( R_ECX, R_EAX, FRn-1 );
2985 store_fr( R_ECX, R_EDX, FRn );
2986 } else /* FRn&1 == 0 */ {
2987 load_fr( R_ECX, R_ECX, FRm );
2988 store_fr( R_EDX, R_EAX, FRn );
2989 store_fr( R_EDX, R_ECX, FRn+1 );
2992 } else /* FRm&1 == 0 */ {
2995 load_xf_bank( R_ECX );
2996 load_fr( R_EDX, R_EAX, FRm );
2997 load_fr( R_EDX, R_EDX, FRm+1 );
2998 store_fr( R_ECX, R_EAX, FRn-1 );
2999 store_fr( R_ECX, R_EDX, FRn );
3001 } else /* FRn&1 == 0 */ {
3003 load_fr( R_EDX, R_EAX, FRm );
3004 load_fr( R_EDX, R_ECX, FRm+1 );
3005 store_fr( R_EDX, R_EAX, FRn );
3006 store_fr( R_EDX, R_ECX, FRn+1 );
3010 sh4_x86.tstate = TSTATE_NONE;
3014 switch( (ir&0xF0) >> 4 ) {
3016 { /* FSTS FPUL, FRn */
3017 uint32_t FRn = ((ir>>8)&0xF);
3019 load_fr_bank( R_ECX );
3020 load_spreg( R_EAX, R_FPUL );
3021 store_fr( R_ECX, R_EAX, FRn );
3022 sh4_x86.tstate = TSTATE_NONE;
3026 { /* FLDS FRm, FPUL */
3027 uint32_t FRm = ((ir>>8)&0xF);
3029 load_fr_bank( R_ECX );
3030 load_fr( R_ECX, R_EAX, FRm );
3031 store_spreg( R_EAX, R_FPUL );
3032 sh4_x86.tstate = TSTATE_NONE;
3036 { /* FLOAT FPUL, FRn */
3037 uint32_t FRn = ((ir>>8)&0xF);
3039 load_spreg( R_ECX, R_FPSCR );
3040 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3042 TEST_imm32_r32( FPSCR_PR, R_ECX );
3043 JNE_rel8(5, doubleprec);
3044 pop_fr( R_EDX, FRn );
3046 JMP_TARGET(doubleprec);
3047 pop_dr( R_EDX, FRn );
3049 sh4_x86.tstate = TSTATE_NONE;
3053 { /* FTRC FRm, FPUL */
3054 uint32_t FRm = ((ir>>8)&0xF);
3056 load_spreg( R_ECX, R_FPSCR );
3057 load_fr_bank( R_EDX );
3058 TEST_imm32_r32( FPSCR_PR, R_ECX );
3059 JNE_rel8(5, doubleprec);
3060 push_fr( R_EDX, FRm );
3062 JMP_TARGET(doubleprec);
3063 push_dr( R_EDX, FRm );
3065 load_imm32( R_ECX, (uint32_t)&max_int );
3066 FILD_r32ind( R_ECX );
3068 JNA_rel8( 32, sat );
3069 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3070 FILD_r32ind( R_ECX ); // 2
3072 JAE_rel8( 21, sat2 ); // 2
3073 load_imm32( R_EAX, (uint32_t)&save_fcw );
3074 FNSTCW_r32ind( R_EAX );
3075 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3076 FLDCW_r32ind( R_EDX );
3077 FISTP_sh4r(R_FPUL); // 3
3078 FLDCW_r32ind( R_EAX );
3079 JMP_rel8( 9, end ); // 2
3083 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3084 store_spreg( R_ECX, R_FPUL );
3087 sh4_x86.tstate = TSTATE_NONE;
3092 uint32_t FRn = ((ir>>8)&0xF);
3094 load_spreg( R_ECX, R_FPSCR );
3095 TEST_imm32_r32( FPSCR_PR, R_ECX );
3096 load_fr_bank( R_EDX );
3097 JNE_rel8(10, doubleprec);
3098 push_fr(R_EDX, FRn);
3102 JMP_TARGET(doubleprec);
3103 push_dr(R_EDX, FRn);
3107 sh4_x86.tstate = TSTATE_NONE;
3112 uint32_t FRn = ((ir>>8)&0xF);
3114 load_spreg( R_ECX, R_FPSCR );
3115 load_fr_bank( R_EDX );
3116 TEST_imm32_r32( FPSCR_PR, R_ECX );
3117 JNE_rel8(10, doubleprec);
3118 push_fr(R_EDX, FRn); // 3
3120 pop_fr( R_EDX, FRn); //3
3121 JMP_rel8(8,end); // 2
3122 JMP_TARGET(doubleprec);
3123 push_dr(R_EDX, FRn);
3127 sh4_x86.tstate = TSTATE_NONE;
3132 uint32_t FRn = ((ir>>8)&0xF);
3134 load_spreg( R_ECX, R_FPSCR );
3135 TEST_imm32_r32( FPSCR_PR, R_ECX );
3136 load_fr_bank( R_EDX );
3137 JNE_rel8(10, doubleprec);
3138 push_fr(R_EDX, FRn);
3142 JMP_TARGET(doubleprec);
3143 push_dr(R_EDX, FRn);
3147 sh4_x86.tstate = TSTATE_NONE;
3152 uint32_t FRn = ((ir>>8)&0xF);
3154 load_spreg( R_ECX, R_FPSCR );
3155 TEST_imm32_r32( FPSCR_PR, R_ECX );
3156 load_fr_bank( R_EDX );
3157 JNE_rel8(12, end); // PR=0 only
3159 push_fr(R_EDX, FRn);
3164 sh4_x86.tstate = TSTATE_NONE;
3169 uint32_t FRn = ((ir>>8)&0xF);
3172 load_spreg( R_ECX, R_FPSCR );
3173 TEST_imm32_r32( FPSCR_PR, R_ECX );
3175 XOR_r32_r32( R_EAX, R_EAX );
3176 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3177 store_fr( R_ECX, R_EAX, FRn );
3179 sh4_x86.tstate = TSTATE_NONE;
3184 uint32_t FRn = ((ir>>8)&0xF);
3187 load_spreg( R_ECX, R_FPSCR );
3188 TEST_imm32_r32( FPSCR_PR, R_ECX );
3190 load_imm32(R_EAX, 0x3F800000);
3191 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3192 store_fr( R_ECX, R_EAX, FRn );
3194 sh4_x86.tstate = TSTATE_NONE;
3198 { /* FCNVSD FPUL, FRn */
3199 uint32_t FRn = ((ir>>8)&0xF);
3201 load_spreg( R_ECX, R_FPSCR );
3202 TEST_imm32_r32( FPSCR_PR, R_ECX );
3203 JE_rel8(9, end); // only when PR=1
3204 load_fr_bank( R_ECX );
3206 pop_dr( R_ECX, FRn );
3208 sh4_x86.tstate = TSTATE_NONE;
3212 { /* FCNVDS FRm, FPUL */
3213 uint32_t FRm = ((ir>>8)&0xF);
3215 load_spreg( R_ECX, R_FPSCR );
3216 TEST_imm32_r32( FPSCR_PR, R_ECX );
3217 JE_rel8(9, end); // only when PR=1
3218 load_fr_bank( R_ECX );
3219 push_dr( R_ECX, FRm );
3222 sh4_x86.tstate = TSTATE_NONE;
3226 { /* FIPR FVm, FVn */
3227 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3229 load_spreg( R_ECX, R_FPSCR );
3230 TEST_imm32_r32( FPSCR_PR, R_ECX );
3231 JNE_rel8(44, doubleprec);
3233 load_fr_bank( R_ECX );
3234 push_fr( R_ECX, FVm<<2 );
3235 push_fr( R_ECX, FVn<<2 );
3237 push_fr( R_ECX, (FVm<<2)+1);
3238 push_fr( R_ECX, (FVn<<2)+1);
3241 push_fr( R_ECX, (FVm<<2)+2);
3242 push_fr( R_ECX, (FVn<<2)+2);
3245 push_fr( R_ECX, (FVm<<2)+3);
3246 push_fr( R_ECX, (FVn<<2)+3);
3249 pop_fr( R_ECX, (FVn<<2)+3);
3250 JMP_TARGET(doubleprec);
3251 sh4_x86.tstate = TSTATE_NONE;
3255 switch( (ir&0x100) >> 8 ) {
3257 { /* FSCA FPUL, FRn */
3258 uint32_t FRn = ((ir>>9)&0x7)<<1;
3260 load_spreg( R_ECX, R_FPSCR );
3261 TEST_imm32_r32( FPSCR_PR, R_ECX );
3262 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3263 load_fr_bank( R_ECX );
3264 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3265 load_spreg( R_EDX, R_FPUL );
3266 call_func2( sh4_fsca, R_EDX, R_ECX );
3267 JMP_TARGET(doubleprec);
3268 sh4_x86.tstate = TSTATE_NONE;
3272 switch( (ir&0x200) >> 9 ) {
3274 { /* FTRV XMTRX, FVn */
3275 uint32_t FVn = ((ir>>10)&0x3);
3277 load_spreg( R_ECX, R_FPSCR );
3278 TEST_imm32_r32( FPSCR_PR, R_ECX );
3279 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3280 load_fr_bank( R_EDX ); // 3
3281 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3282 load_xf_bank( R_ECX ); // 12
3283 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3284 JMP_TARGET(doubleprec);
3285 sh4_x86.tstate = TSTATE_NONE;
3289 switch( (ir&0xC00) >> 10 ) {
3293 load_spreg( R_ECX, R_FPSCR );
3294 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3295 store_spreg( R_ECX, R_FPSCR );
3296 sh4_x86.tstate = TSTATE_NONE;
3302 load_spreg( R_ECX, R_FPSCR );
3303 XOR_imm32_r32( FPSCR_FR, R_ECX );
3304 store_spreg( R_ECX, R_FPSCR );
3305 update_fr_bank( R_ECX );
3306 sh4_x86.tstate = TSTATE_NONE;
3311 if( sh4_x86.in_delay_slot ) {
3314 JMP_exc(EXC_ILLEGAL);
3334 { /* FMAC FR0, FRm, FRn */
3335 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3337 load_spreg( R_ECX, R_FPSCR );
3338 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3339 TEST_imm32_r32( FPSCR_PR, R_ECX );
3340 JNE_rel8(18, doubleprec);
3341 push_fr( R_EDX, 0 );
3342 push_fr( R_EDX, FRm );
3344 push_fr( R_EDX, FRn );
3346 pop_fr( R_EDX, FRn );
3348 JMP_TARGET(doubleprec);
3349 push_dr( R_EDX, 0 );
3350 push_dr( R_EDX, FRm );
3352 push_dr( R_EDX, FRn );
3354 pop_dr( R_EDX, FRn );
3356 sh4_x86.tstate = TSTATE_NONE;
3366 sh4_x86.in_delay_slot = FALSE;
.