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
50 * Struct to manage internal translation state. This state is not saved -
51 * it is only valid between calls to sh4_translate_begin_block() and
52 * sh4_translate_end_block()
54 struct sh4_x86_state {
56 gboolean priv_checked; /* true if we've already checked the cpu mode. */
57 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
58 gboolean branch_taken; /* true if we branched unconditionally */
59 uint32_t block_start_pc;
60 uint32_t stack_posn; /* Trace stack height for alignment purposes */
64 gboolean tlb_on; /* True if tlb translation is active */
66 /* Allocated memory for the (block-wide) back-patch list */
67 struct backpatch_record *backpatch_list;
68 uint32_t backpatch_posn;
69 uint32_t backpatch_size;
72 #define TSTATE_NONE -1
82 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
83 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
84 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
85 OP(0x70+sh4_x86.tstate); OP(rel8); \
87 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
88 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
89 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
90 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
93 static struct sh4_x86_state sh4_x86;
95 static uint32_t max_int = 0x7FFFFFFF;
96 static uint32_t min_int = 0x80000000;
97 static uint32_t save_fcw; /* save value for fpu control word */
98 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
102 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
103 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
107 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
109 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
110 sh4_x86.backpatch_size <<= 1;
111 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
112 sh4_x86.backpatch_size * sizeof(struct backpatch_record));
113 assert( sh4_x86.backpatch_list != NULL );
115 if( sh4_x86.in_delay_slot ) {
118 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;
119 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
120 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
121 sh4_x86.backpatch_posn++;
125 * Emit an instruction to load an SH4 reg into a real register
127 static inline void load_reg( int x86reg, int sh4reg )
129 /* mov [bp+n], reg */
131 OP(0x45 + (x86reg<<3));
132 OP(REG_OFFSET(r[sh4reg]));
135 static inline void load_reg16s( int x86reg, int sh4reg )
139 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
142 static inline void load_reg16u( int x86reg, int sh4reg )
146 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
150 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
151 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
153 * Emit an instruction to load an immediate value into a register
155 static inline void load_imm32( int x86reg, uint32_t value ) {
156 /* mov #value, reg */
162 * Load an immediate 64-bit quantity (note: x86-64 only)
164 static inline void load_imm64( int x86reg, uint32_t value ) {
165 /* mov #value, reg */
173 * Emit an instruction to store an SH4 reg (RN)
175 void static inline store_reg( int x86reg, int sh4reg ) {
176 /* mov reg, [bp+n] */
178 OP(0x45 + (x86reg<<3));
179 OP(REG_OFFSET(r[sh4reg]));
182 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
185 * Load an FR register (single-precision floating point) into an integer x86
186 * register (eg for register-to-register moves)
188 void static inline load_fr( int bankreg, int x86reg, int frm )
190 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
194 * Store an FR register (single-precision floating point) into an integer x86
195 * register (eg for register-to-register moves)
197 void static inline store_fr( int bankreg, int x86reg, int frn )
199 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
204 * Load a pointer to the back fp back into the specified x86 register. The
205 * bankreg must have been previously loaded with FPSCR.
208 static inline void load_xf_bank( int bankreg )
211 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
212 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
213 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
217 * Update the fr_bank pointer based on the current fpscr value.
219 static inline void update_fr_bank( int fpscrreg )
221 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
222 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
223 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
224 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
227 * Push FPUL (as a 32-bit float) onto the FPU stack
229 static inline void push_fpul( )
231 OP(0xD9); OP(0x45); OP(R_FPUL);
235 * Pop FPUL (as a 32-bit float) from the FPU stack
237 static inline void pop_fpul( )
239 OP(0xD9); OP(0x5D); OP(R_FPUL);
243 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
244 * with the location of the current fp bank.
246 static inline void push_fr( int bankreg, int frm )
248 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
252 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
253 * with bankreg previously loaded with the location of the current fp bank.
255 static inline void pop_fr( int bankreg, int frm )
257 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
261 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
262 * with the location of the current fp bank.
264 static inline void push_dr( int bankreg, int frm )
266 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
269 static inline void pop_dr( int bankreg, int frm )
271 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
274 /* Exception checks - Note that all exception checks will clobber EAX */
276 #define check_priv( ) \
277 if( !sh4_x86.priv_checked ) { \
278 sh4_x86.priv_checked = TRUE;\
279 load_spreg( R_EAX, R_SR );\
280 AND_imm32_r32( SR_MD, R_EAX );\
281 if( sh4_x86.in_delay_slot ) {\
282 JE_exc( EXC_SLOT_ILLEGAL );\
284 JE_exc( EXC_ILLEGAL );\
288 #define check_fpuen( ) \
289 if( !sh4_x86.fpuen_checked ) {\
290 sh4_x86.fpuen_checked = TRUE;\
291 load_spreg( R_EAX, R_SR );\
292 AND_imm32_r32( SR_FD, R_EAX );\
293 if( sh4_x86.in_delay_slot ) {\
294 JNE_exc(EXC_SLOT_FPU_DISABLED);\
296 JNE_exc(EXC_FPU_DISABLED);\
300 #define check_ralign16( x86reg ) \
301 TEST_imm32_r32( 0x00000001, x86reg ); \
302 JNE_exc(EXC_DATA_ADDR_READ)
304 #define check_walign16( x86reg ) \
305 TEST_imm32_r32( 0x00000001, x86reg ); \
306 JNE_exc(EXC_DATA_ADDR_WRITE);
308 #define check_ralign32( x86reg ) \
309 TEST_imm32_r32( 0x00000003, x86reg ); \
310 JNE_exc(EXC_DATA_ADDR_READ)
312 #define check_walign32( x86reg ) \
313 TEST_imm32_r32( 0x00000003, x86reg ); \
314 JNE_exc(EXC_DATA_ADDR_WRITE);
317 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
318 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
319 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
320 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
321 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
322 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
323 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
326 * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
327 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
329 #define MMU_TRANSLATE_READ( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }
331 #define MMU_TRANSLATE_READ_EXC( addr_reg, exc_code ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_read, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(exc_code); MEM_RESULT(addr_reg) }
333 * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
334 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
336 #define MMU_TRANSLATE_WRITE( addr_reg ) if( sh4_x86.tlb_on ) { call_func1(mmu_vma_to_phys_write, addr_reg); CMP_imm32_r32(MMU_VMA_ERROR, R_EAX); JE_exc(-1); MEM_RESULT(addr_reg); }
338 #define MEM_READ_SIZE (CALL_FUNC1_SIZE)
339 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
340 #define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
342 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = DELAY_NONE; return 1;
344 /****** Import appropriate calling conventions ******/
345 #if SH4_TRANSLATOR == TARGET_X86_64
346 #include "sh4/ia64abi.h"
347 #else /* SH4_TRANSLATOR == TARGET_X86 */
349 #include "sh4/ia32mac.h"
351 #include "sh4/ia32abi.h"
355 uint32_t sh4_translate_end_block_size()
357 if( sh4_x86.backpatch_posn <= 3 ) {
358 return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
360 return EPILOGUE_SIZE + 48 + (sh4_x86.backpatch_posn-3)*15;
366 * Embed a breakpoint into the generated code
368 void sh4_translate_emit_breakpoint( sh4vma_t pc )
370 load_imm32( R_EAX, pc );
371 call_func1( sh4_translate_breakpoint_hit, R_EAX );
375 * Embed a call to sh4_execute_instruction for situations that we
376 * can't translate (mainly page-crossing delay slots at the moment).
377 * Caller is responsible for setting new_pc.
379 void sh4_emulator_exit( sh4vma_t endpc )
381 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 5
382 ADD_r32_sh4r( R_ECX, R_PC );
384 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
385 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
386 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );
387 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );
389 call_func0( sh4_execute_instruction );
390 load_imm32( R_EAX, R_PC );
391 if( sh4_x86.tlb_on ) {
392 call_func1(xlat_get_code_by_vma,R_EAX);
394 call_func1(xlat_get_code,R_EAX);
396 AND_imm8s_r32( 0xFC, R_EAX ); // 3
402 * Translate a single instruction. Delayed branches are handled specially
403 * by translating both branch and delayed instruction as a single unit (as
405 * The instruction MUST be in the icache (assert check)
407 * @return true if the instruction marks the end of a basic block
410 uint32_t sh4_translate_instruction( sh4vma_t pc )
413 /* Read instruction from icache */
414 assert( IS_IN_ICACHE(pc) );
415 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
417 /* PC is not in the current icache - this usually means we're running
418 * with MMU on, and we've gone past the end of the page. And since
419 * sh4_translate_block is pretty careful about this, it means we're
420 * almost certainly in a delay slot.
422 * Since we can't assume the page is present (and we can't fault it in
423 * at this point, inline a call to sh4_execute_instruction (with a few
424 * small repairs to cope with the different environment).
427 if( !sh4_x86.in_delay_slot ) {
428 sh4_translate_add_recovery( (pc - sh4_x86.block_start_pc)>>1 );
430 switch( (ir&0xF000) >> 12 ) {
434 switch( (ir&0x80) >> 7 ) {
436 switch( (ir&0x70) >> 4 ) {
439 uint32_t Rn = ((ir>>8)&0xF);
441 call_func0(sh4_read_sr);
442 store_reg( R_EAX, Rn );
443 sh4_x86.tstate = TSTATE_NONE;
448 uint32_t Rn = ((ir>>8)&0xF);
449 load_spreg( R_EAX, R_GBR );
450 store_reg( R_EAX, Rn );
455 uint32_t Rn = ((ir>>8)&0xF);
457 load_spreg( R_EAX, R_VBR );
458 store_reg( R_EAX, Rn );
459 sh4_x86.tstate = TSTATE_NONE;
464 uint32_t Rn = ((ir>>8)&0xF);
466 load_spreg( R_EAX, R_SSR );
467 store_reg( R_EAX, Rn );
468 sh4_x86.tstate = TSTATE_NONE;
473 uint32_t Rn = ((ir>>8)&0xF);
475 load_spreg( R_EAX, R_SPC );
476 store_reg( R_EAX, Rn );
477 sh4_x86.tstate = TSTATE_NONE;
486 { /* STC Rm_BANK, Rn */
487 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
489 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
490 store_reg( R_EAX, Rn );
491 sh4_x86.tstate = TSTATE_NONE;
497 switch( (ir&0xF0) >> 4 ) {
500 uint32_t Rn = ((ir>>8)&0xF);
501 if( sh4_x86.in_delay_slot ) {
504 load_spreg( R_EAX, R_PC );
505 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
506 store_spreg( R_EAX, R_PR );
507 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
508 store_spreg( R_EAX, R_NEW_PC );
510 sh4_x86.tstate = TSTATE_NONE;
511 sh4_translate_instruction( pc + 2 );
512 exit_block_newpcset(pc+2);
513 sh4_x86.branch_taken = TRUE;
520 uint32_t Rn = ((ir>>8)&0xF);
521 if( sh4_x86.in_delay_slot ) {
524 load_spreg( R_EAX, R_PC );
525 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
526 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
527 store_spreg( R_EAX, R_NEW_PC );
528 sh4_x86.in_delay_slot = DELAY_PC;
529 sh4_x86.tstate = TSTATE_NONE;
530 sh4_translate_instruction( pc + 2 );
531 exit_block_newpcset(pc+2);
532 sh4_x86.branch_taken = TRUE;
539 uint32_t Rn = ((ir>>8)&0xF);
540 load_reg( R_EAX, Rn );
541 MOV_r32_r32( R_EAX, R_ECX );
542 AND_imm32_r32( 0xFC000000, R_EAX );
543 CMP_imm32_r32( 0xE0000000, R_EAX );
544 JNE_rel8(8+CALL_FUNC1_SIZE, end);
545 call_func1( sh4_flush_store_queue, R_ECX );
546 TEST_r32_r32( R_EAX, R_EAX );
549 sh4_x86.tstate = TSTATE_NONE;
554 uint32_t Rn = ((ir>>8)&0xF);
559 uint32_t Rn = ((ir>>8)&0xF);
564 uint32_t Rn = ((ir>>8)&0xF);
568 { /* MOVCA.L R0, @Rn */
569 uint32_t Rn = ((ir>>8)&0xF);
570 load_reg( R_EAX, Rn );
571 check_walign32( R_EAX );
572 MMU_TRANSLATE_WRITE( R_EAX );
573 load_reg( R_EDX, 0 );
574 MEM_WRITE_LONG( R_EAX, R_EDX );
575 sh4_x86.tstate = TSTATE_NONE;
584 { /* MOV.B Rm, @(R0, Rn) */
585 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
586 load_reg( R_EAX, 0 );
587 load_reg( R_ECX, Rn );
588 ADD_r32_r32( R_ECX, R_EAX );
589 MMU_TRANSLATE_WRITE( R_EAX );
590 load_reg( R_EDX, Rm );
591 MEM_WRITE_BYTE( R_EAX, R_EDX );
592 sh4_x86.tstate = TSTATE_NONE;
596 { /* MOV.W Rm, @(R0, Rn) */
597 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
598 load_reg( R_EAX, 0 );
599 load_reg( R_ECX, Rn );
600 ADD_r32_r32( R_ECX, R_EAX );
601 check_walign16( R_EAX );
602 MMU_TRANSLATE_WRITE( R_EAX );
603 load_reg( R_EDX, Rm );
604 MEM_WRITE_WORD( R_EAX, R_EDX );
605 sh4_x86.tstate = TSTATE_NONE;
609 { /* MOV.L Rm, @(R0, Rn) */
610 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
611 load_reg( R_EAX, 0 );
612 load_reg( R_ECX, Rn );
613 ADD_r32_r32( R_ECX, R_EAX );
614 check_walign32( R_EAX );
615 MMU_TRANSLATE_WRITE( R_EAX );
616 load_reg( R_EDX, Rm );
617 MEM_WRITE_LONG( R_EAX, R_EDX );
618 sh4_x86.tstate = TSTATE_NONE;
623 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
624 load_reg( R_EAX, Rm );
625 load_reg( R_ECX, Rn );
627 store_spreg( R_EAX, R_MACL );
628 sh4_x86.tstate = TSTATE_NONE;
632 switch( (ir&0xFF0) >> 4 ) {
637 sh4_x86.tstate = TSTATE_C;
644 sh4_x86.tstate = TSTATE_C;
649 XOR_r32_r32(R_EAX, R_EAX);
650 store_spreg( R_EAX, R_MACL );
651 store_spreg( R_EAX, R_MACH );
652 sh4_x86.tstate = TSTATE_NONE;
657 call_func0( MMU_ldtlb );
664 sh4_x86.tstate = TSTATE_C;
671 sh4_x86.tstate = TSTATE_C;
680 switch( (ir&0xF0) >> 4 ) {
683 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
688 XOR_r32_r32( R_EAX, R_EAX );
689 store_spreg( R_EAX, R_Q );
690 store_spreg( R_EAX, R_M );
691 store_spreg( R_EAX, R_T );
692 sh4_x86.tstate = TSTATE_C; // works for DIV1
697 uint32_t Rn = ((ir>>8)&0xF);
698 load_spreg( R_EAX, R_T );
699 store_reg( R_EAX, Rn );
708 switch( (ir&0xF0) >> 4 ) {
711 uint32_t Rn = ((ir>>8)&0xF);
712 load_spreg( R_EAX, R_MACH );
713 store_reg( R_EAX, Rn );
718 uint32_t Rn = ((ir>>8)&0xF);
719 load_spreg( R_EAX, R_MACL );
720 store_reg( R_EAX, Rn );
725 uint32_t Rn = ((ir>>8)&0xF);
726 load_spreg( R_EAX, R_PR );
727 store_reg( R_EAX, Rn );
732 uint32_t Rn = ((ir>>8)&0xF);
734 load_spreg( R_EAX, R_SGR );
735 store_reg( R_EAX, Rn );
736 sh4_x86.tstate = TSTATE_NONE;
741 uint32_t Rn = ((ir>>8)&0xF);
742 load_spreg( R_EAX, R_FPUL );
743 store_reg( R_EAX, Rn );
747 { /* STS FPSCR, Rn */
748 uint32_t Rn = ((ir>>8)&0xF);
749 load_spreg( R_EAX, R_FPSCR );
750 store_reg( R_EAX, Rn );
755 uint32_t Rn = ((ir>>8)&0xF);
757 load_spreg( R_EAX, R_DBR );
758 store_reg( R_EAX, Rn );
759 sh4_x86.tstate = TSTATE_NONE;
768 switch( (ir&0xFF0) >> 4 ) {
771 if( sh4_x86.in_delay_slot ) {
774 load_spreg( R_ECX, R_PR );
775 store_spreg( R_ECX, R_NEW_PC );
776 sh4_x86.in_delay_slot = DELAY_PC;
777 sh4_translate_instruction(pc+2);
778 exit_block_newpcset(pc+2);
779 sh4_x86.branch_taken = TRUE;
787 call_func0( sh4_sleep );
788 sh4_x86.tstate = TSTATE_NONE;
789 sh4_x86.in_delay_slot = DELAY_NONE;
795 if( sh4_x86.in_delay_slot ) {
799 load_spreg( R_ECX, R_SPC );
800 store_spreg( R_ECX, R_NEW_PC );
801 load_spreg( R_EAX, R_SSR );
802 call_func1( sh4_write_sr, R_EAX );
803 sh4_x86.in_delay_slot = DELAY_PC;
804 sh4_x86.priv_checked = FALSE;
805 sh4_x86.fpuen_checked = FALSE;
806 sh4_x86.tstate = TSTATE_NONE;
807 sh4_translate_instruction(pc+2);
808 exit_block_newpcset(pc+2);
809 sh4_x86.branch_taken = TRUE;
820 { /* MOV.B @(R0, Rm), Rn */
821 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
822 load_reg( R_EAX, 0 );
823 load_reg( R_ECX, Rm );
824 ADD_r32_r32( R_ECX, R_EAX );
825 MMU_TRANSLATE_READ( R_EAX )
826 MEM_READ_BYTE( R_EAX, R_EAX );
827 store_reg( R_EAX, Rn );
828 sh4_x86.tstate = TSTATE_NONE;
832 { /* MOV.W @(R0, Rm), Rn */
833 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
834 load_reg( R_EAX, 0 );
835 load_reg( R_ECX, Rm );
836 ADD_r32_r32( R_ECX, R_EAX );
837 check_ralign16( R_EAX );
838 MMU_TRANSLATE_READ( R_EAX );
839 MEM_READ_WORD( R_EAX, R_EAX );
840 store_reg( R_EAX, Rn );
841 sh4_x86.tstate = TSTATE_NONE;
845 { /* MOV.L @(R0, Rm), Rn */
846 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
847 load_reg( R_EAX, 0 );
848 load_reg( R_ECX, Rm );
849 ADD_r32_r32( R_ECX, R_EAX );
850 check_ralign32( R_EAX );
851 MMU_TRANSLATE_READ( R_EAX );
852 MEM_READ_LONG( R_EAX, R_EAX );
853 store_reg( R_EAX, Rn );
854 sh4_x86.tstate = TSTATE_NONE;
858 { /* MAC.L @Rm+, @Rn+ */
859 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
861 load_reg( R_EAX, Rm );
862 check_ralign32( R_EAX );
863 MMU_TRANSLATE_READ( R_EAX );
864 PUSH_realigned_r32( R_EAX );
865 load_reg( R_EAX, Rn );
866 ADD_imm8s_r32( 4, R_EAX );
867 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
868 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
869 // Note translate twice in case of page boundaries. Maybe worth
870 // adding a page-boundary check to skip the second translation
872 load_reg( R_EAX, Rm );
873 check_ralign32( R_EAX );
874 MMU_TRANSLATE_READ( R_EAX );
875 load_reg( R_ECX, Rn );
876 check_ralign32( R_ECX );
877 PUSH_realigned_r32( R_EAX );
878 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
879 MOV_r32_r32( R_ECX, R_EAX );
880 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
881 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
883 MEM_READ_LONG( R_EAX, R_EAX );
886 MEM_READ_LONG( R_ECX, R_EAX );
887 POP_realigned_r32( R_ECX );
890 ADD_r32_sh4r( R_EAX, R_MACL );
891 ADC_r32_sh4r( R_EDX, R_MACH );
893 load_spreg( R_ECX, R_S );
894 TEST_r32_r32(R_ECX, R_ECX);
895 JE_rel8( CALL_FUNC0_SIZE, nosat );
896 call_func0( signsat48 );
898 sh4_x86.tstate = TSTATE_NONE;
907 { /* MOV.L Rm, @(disp, Rn) */
908 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
909 load_reg( R_EAX, Rn );
910 ADD_imm32_r32( disp, R_EAX );
911 check_walign32( R_EAX );
912 MMU_TRANSLATE_WRITE( R_EAX );
913 load_reg( R_EDX, Rm );
914 MEM_WRITE_LONG( R_EAX, R_EDX );
915 sh4_x86.tstate = TSTATE_NONE;
921 { /* MOV.B Rm, @Rn */
922 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
923 load_reg( R_EAX, Rn );
924 MMU_TRANSLATE_WRITE( R_EAX );
925 load_reg( R_EDX, Rm );
926 MEM_WRITE_BYTE( R_EAX, R_EDX );
927 sh4_x86.tstate = TSTATE_NONE;
931 { /* MOV.W Rm, @Rn */
932 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
933 load_reg( R_EAX, Rn );
934 check_walign16( R_EAX );
935 MMU_TRANSLATE_WRITE( R_EAX )
936 load_reg( R_EDX, Rm );
937 MEM_WRITE_WORD( R_EAX, R_EDX );
938 sh4_x86.tstate = TSTATE_NONE;
942 { /* MOV.L Rm, @Rn */
943 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
944 load_reg( R_EAX, Rn );
945 check_walign32(R_EAX);
946 MMU_TRANSLATE_WRITE( R_EAX );
947 load_reg( R_EDX, Rm );
948 MEM_WRITE_LONG( R_EAX, R_EDX );
949 sh4_x86.tstate = TSTATE_NONE;
953 { /* MOV.B Rm, @-Rn */
954 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
955 load_reg( R_EAX, Rn );
956 ADD_imm8s_r32( -1, R_EAX );
957 MMU_TRANSLATE_WRITE( R_EAX );
958 load_reg( R_EDX, Rm );
959 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
960 MEM_WRITE_BYTE( R_EAX, R_EDX );
961 sh4_x86.tstate = TSTATE_NONE;
965 { /* MOV.W Rm, @-Rn */
966 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
967 load_reg( R_EAX, Rn );
968 ADD_imm8s_r32( -2, R_EAX );
969 check_walign16( R_EAX );
970 MMU_TRANSLATE_WRITE( R_EAX );
971 load_reg( R_EDX, Rm );
972 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
973 MEM_WRITE_WORD( R_EAX, R_EDX );
974 sh4_x86.tstate = TSTATE_NONE;
978 { /* MOV.L Rm, @-Rn */
979 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
980 load_reg( R_EAX, Rn );
981 ADD_imm8s_r32( -4, R_EAX );
982 check_walign32( R_EAX );
983 MMU_TRANSLATE_WRITE( R_EAX );
984 load_reg( R_EDX, Rm );
985 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
986 MEM_WRITE_LONG( R_EAX, R_EDX );
987 sh4_x86.tstate = TSTATE_NONE;
992 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
993 load_reg( R_EAX, Rm );
994 load_reg( R_ECX, Rn );
995 SHR_imm8_r32( 31, R_EAX );
996 SHR_imm8_r32( 31, R_ECX );
997 store_spreg( R_EAX, R_M );
998 store_spreg( R_ECX, R_Q );
999 CMP_r32_r32( R_EAX, R_ECX );
1001 sh4_x86.tstate = TSTATE_NE;
1006 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1007 load_reg( R_EAX, Rm );
1008 load_reg( R_ECX, Rn );
1009 TEST_r32_r32( R_EAX, R_ECX );
1011 sh4_x86.tstate = TSTATE_E;
1016 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1017 load_reg( R_EAX, Rm );
1018 load_reg( R_ECX, Rn );
1019 AND_r32_r32( R_EAX, R_ECX );
1020 store_reg( R_ECX, Rn );
1021 sh4_x86.tstate = TSTATE_NONE;
1026 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1027 load_reg( R_EAX, Rm );
1028 load_reg( R_ECX, Rn );
1029 XOR_r32_r32( R_EAX, R_ECX );
1030 store_reg( R_ECX, Rn );
1031 sh4_x86.tstate = TSTATE_NONE;
1036 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1037 load_reg( R_EAX, Rm );
1038 load_reg( R_ECX, Rn );
1039 OR_r32_r32( R_EAX, R_ECX );
1040 store_reg( R_ECX, Rn );
1041 sh4_x86.tstate = TSTATE_NONE;
1045 { /* CMP/STR Rm, Rn */
1046 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1047 load_reg( R_EAX, Rm );
1048 load_reg( R_ECX, Rn );
1049 XOR_r32_r32( R_ECX, R_EAX );
1050 TEST_r8_r8( R_AL, R_AL );
1051 JE_rel8(13, target1);
1052 TEST_r8_r8( R_AH, R_AH ); // 2
1053 JE_rel8(9, target2);
1054 SHR_imm8_r32( 16, R_EAX ); // 3
1055 TEST_r8_r8( R_AL, R_AL ); // 2
1056 JE_rel8(2, target3);
1057 TEST_r8_r8( R_AH, R_AH ); // 2
1058 JMP_TARGET(target1);
1059 JMP_TARGET(target2);
1060 JMP_TARGET(target3);
1062 sh4_x86.tstate = TSTATE_E;
1066 { /* XTRCT Rm, Rn */
1067 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1068 load_reg( R_EAX, Rm );
1069 load_reg( R_ECX, Rn );
1070 SHL_imm8_r32( 16, R_EAX );
1071 SHR_imm8_r32( 16, R_ECX );
1072 OR_r32_r32( R_EAX, R_ECX );
1073 store_reg( R_ECX, Rn );
1074 sh4_x86.tstate = TSTATE_NONE;
1078 { /* MULU.W Rm, Rn */
1079 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1080 load_reg16u( R_EAX, Rm );
1081 load_reg16u( R_ECX, Rn );
1083 store_spreg( R_EAX, R_MACL );
1084 sh4_x86.tstate = TSTATE_NONE;
1088 { /* MULS.W Rm, Rn */
1089 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1090 load_reg16s( R_EAX, Rm );
1091 load_reg16s( R_ECX, Rn );
1093 store_spreg( R_EAX, R_MACL );
1094 sh4_x86.tstate = TSTATE_NONE;
1105 { /* CMP/EQ Rm, Rn */
1106 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1107 load_reg( R_EAX, Rm );
1108 load_reg( R_ECX, Rn );
1109 CMP_r32_r32( R_EAX, R_ECX );
1111 sh4_x86.tstate = TSTATE_E;
1115 { /* CMP/HS Rm, Rn */
1116 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1117 load_reg( R_EAX, Rm );
1118 load_reg( R_ECX, Rn );
1119 CMP_r32_r32( R_EAX, R_ECX );
1121 sh4_x86.tstate = TSTATE_AE;
1125 { /* CMP/GE Rm, Rn */
1126 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1127 load_reg( R_EAX, Rm );
1128 load_reg( R_ECX, Rn );
1129 CMP_r32_r32( R_EAX, R_ECX );
1131 sh4_x86.tstate = TSTATE_GE;
1136 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1137 load_spreg( R_ECX, R_M );
1138 load_reg( R_EAX, Rn );
1139 if( sh4_x86.tstate != TSTATE_C ) {
1143 SETC_r8( R_DL ); // Q'
1144 CMP_sh4r_r32( R_Q, R_ECX );
1145 JE_rel8(5, mqequal);
1146 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1148 JMP_TARGET(mqequal);
1149 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1151 store_reg( R_EAX, Rn ); // Done with Rn now
1152 SETC_r8(R_AL); // tmp1
1153 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1154 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1155 store_spreg( R_ECX, R_Q );
1156 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1157 MOVZX_r8_r32( R_AL, R_EAX );
1158 store_spreg( R_EAX, R_T );
1159 sh4_x86.tstate = TSTATE_NONE;
1163 { /* DMULU.L Rm, Rn */
1164 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1165 load_reg( R_EAX, Rm );
1166 load_reg( R_ECX, Rn );
1168 store_spreg( R_EDX, R_MACH );
1169 store_spreg( R_EAX, R_MACL );
1170 sh4_x86.tstate = TSTATE_NONE;
1174 { /* CMP/HI Rm, Rn */
1175 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1176 load_reg( R_EAX, Rm );
1177 load_reg( R_ECX, Rn );
1178 CMP_r32_r32( R_EAX, R_ECX );
1180 sh4_x86.tstate = TSTATE_A;
1184 { /* CMP/GT Rm, Rn */
1185 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1186 load_reg( R_EAX, Rm );
1187 load_reg( R_ECX, Rn );
1188 CMP_r32_r32( R_EAX, R_ECX );
1190 sh4_x86.tstate = TSTATE_G;
1195 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1196 load_reg( R_EAX, Rm );
1197 load_reg( R_ECX, Rn );
1198 SUB_r32_r32( R_EAX, R_ECX );
1199 store_reg( R_ECX, Rn );
1200 sh4_x86.tstate = TSTATE_NONE;
1205 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1206 load_reg( R_EAX, Rm );
1207 load_reg( R_ECX, Rn );
1208 if( sh4_x86.tstate != TSTATE_C ) {
1211 SBB_r32_r32( R_EAX, R_ECX );
1212 store_reg( R_ECX, Rn );
1214 sh4_x86.tstate = TSTATE_C;
1219 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1220 load_reg( R_EAX, Rm );
1221 load_reg( R_ECX, Rn );
1222 SUB_r32_r32( R_EAX, R_ECX );
1223 store_reg( R_ECX, Rn );
1225 sh4_x86.tstate = TSTATE_O;
1230 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1231 load_reg( R_EAX, Rm );
1232 load_reg( R_ECX, Rn );
1233 ADD_r32_r32( R_EAX, R_ECX );
1234 store_reg( R_ECX, Rn );
1235 sh4_x86.tstate = TSTATE_NONE;
1239 { /* DMULS.L Rm, Rn */
1240 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1241 load_reg( R_EAX, Rm );
1242 load_reg( R_ECX, Rn );
1244 store_spreg( R_EDX, R_MACH );
1245 store_spreg( R_EAX, R_MACL );
1246 sh4_x86.tstate = TSTATE_NONE;
1251 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1252 if( sh4_x86.tstate != TSTATE_C ) {
1255 load_reg( R_EAX, Rm );
1256 load_reg( R_ECX, Rn );
1257 ADC_r32_r32( R_EAX, R_ECX );
1258 store_reg( R_ECX, Rn );
1260 sh4_x86.tstate = TSTATE_C;
1265 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1266 load_reg( R_EAX, Rm );
1267 load_reg( R_ECX, Rn );
1268 ADD_r32_r32( R_EAX, R_ECX );
1269 store_reg( R_ECX, Rn );
1271 sh4_x86.tstate = TSTATE_O;
1282 switch( (ir&0xF0) >> 4 ) {
1285 uint32_t Rn = ((ir>>8)&0xF);
1286 load_reg( R_EAX, Rn );
1289 store_reg( R_EAX, Rn );
1290 sh4_x86.tstate = TSTATE_C;
1295 uint32_t Rn = ((ir>>8)&0xF);
1296 load_reg( R_EAX, Rn );
1297 ADD_imm8s_r32( -1, R_EAX );
1298 store_reg( R_EAX, Rn );
1300 sh4_x86.tstate = TSTATE_E;
1305 uint32_t Rn = ((ir>>8)&0xF);
1306 load_reg( R_EAX, Rn );
1309 store_reg( R_EAX, Rn );
1310 sh4_x86.tstate = TSTATE_C;
1319 switch( (ir&0xF0) >> 4 ) {
1322 uint32_t Rn = ((ir>>8)&0xF);
1323 load_reg( R_EAX, Rn );
1326 store_reg( R_EAX, Rn );
1327 sh4_x86.tstate = TSTATE_C;
1332 uint32_t Rn = ((ir>>8)&0xF);
1333 load_reg( R_EAX, Rn );
1334 CMP_imm8s_r32( 0, R_EAX );
1336 sh4_x86.tstate = TSTATE_GE;
1341 uint32_t Rn = ((ir>>8)&0xF);
1342 load_reg( R_EAX, Rn );
1345 store_reg( R_EAX, Rn );
1346 sh4_x86.tstate = TSTATE_C;
1355 switch( (ir&0xF0) >> 4 ) {
1357 { /* STS.L MACH, @-Rn */
1358 uint32_t Rn = ((ir>>8)&0xF);
1359 load_reg( R_EAX, Rn );
1360 check_walign32( R_EAX );
1361 ADD_imm8s_r32( -4, R_EAX );
1362 MMU_TRANSLATE_WRITE( R_EAX );
1363 load_spreg( R_EDX, R_MACH );
1364 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1365 MEM_WRITE_LONG( R_EAX, R_EDX );
1366 sh4_x86.tstate = TSTATE_NONE;
1370 { /* STS.L MACL, @-Rn */
1371 uint32_t Rn = ((ir>>8)&0xF);
1372 load_reg( R_EAX, Rn );
1373 check_walign32( R_EAX );
1374 ADD_imm8s_r32( -4, R_EAX );
1375 MMU_TRANSLATE_WRITE( R_EAX );
1376 load_spreg( R_EDX, R_MACL );
1377 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1378 MEM_WRITE_LONG( R_EAX, R_EDX );
1379 sh4_x86.tstate = TSTATE_NONE;
1383 { /* STS.L PR, @-Rn */
1384 uint32_t Rn = ((ir>>8)&0xF);
1385 load_reg( R_EAX, Rn );
1386 check_walign32( R_EAX );
1387 ADD_imm8s_r32( -4, R_EAX );
1388 MMU_TRANSLATE_WRITE( R_EAX );
1389 load_spreg( R_EDX, R_PR );
1390 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1391 MEM_WRITE_LONG( R_EAX, R_EDX );
1392 sh4_x86.tstate = TSTATE_NONE;
1396 { /* STC.L SGR, @-Rn */
1397 uint32_t Rn = ((ir>>8)&0xF);
1399 load_reg( R_EAX, Rn );
1400 check_walign32( R_EAX );
1401 ADD_imm8s_r32( -4, R_EAX );
1402 MMU_TRANSLATE_WRITE( R_EAX );
1403 load_spreg( R_EDX, R_SGR );
1404 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1405 MEM_WRITE_LONG( R_EAX, R_EDX );
1406 sh4_x86.tstate = TSTATE_NONE;
1410 { /* STS.L FPUL, @-Rn */
1411 uint32_t Rn = ((ir>>8)&0xF);
1412 load_reg( R_EAX, Rn );
1413 check_walign32( R_EAX );
1414 ADD_imm8s_r32( -4, R_EAX );
1415 MMU_TRANSLATE_WRITE( R_EAX );
1416 load_spreg( R_EDX, R_FPUL );
1417 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1418 MEM_WRITE_LONG( R_EAX, R_EDX );
1419 sh4_x86.tstate = TSTATE_NONE;
1423 { /* STS.L FPSCR, @-Rn */
1424 uint32_t Rn = ((ir>>8)&0xF);
1425 load_reg( R_EAX, Rn );
1426 check_walign32( R_EAX );
1427 ADD_imm8s_r32( -4, R_EAX );
1428 MMU_TRANSLATE_WRITE( R_EAX );
1429 load_spreg( R_EDX, R_FPSCR );
1430 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1431 MEM_WRITE_LONG( R_EAX, R_EDX );
1432 sh4_x86.tstate = TSTATE_NONE;
1436 { /* STC.L DBR, @-Rn */
1437 uint32_t Rn = ((ir>>8)&0xF);
1439 load_reg( R_EAX, Rn );
1440 check_walign32( R_EAX );
1441 ADD_imm8s_r32( -4, R_EAX );
1442 MMU_TRANSLATE_WRITE( R_EAX );
1443 load_spreg( R_EDX, R_DBR );
1444 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1445 MEM_WRITE_LONG( R_EAX, R_EDX );
1446 sh4_x86.tstate = TSTATE_NONE;
1455 switch( (ir&0x80) >> 7 ) {
1457 switch( (ir&0x70) >> 4 ) {
1459 { /* STC.L SR, @-Rn */
1460 uint32_t Rn = ((ir>>8)&0xF);
1462 load_reg( R_EAX, Rn );
1463 check_walign32( R_EAX );
1464 ADD_imm8s_r32( -4, R_EAX );
1465 MMU_TRANSLATE_WRITE( R_EAX );
1466 PUSH_realigned_r32( R_EAX );
1467 call_func0( sh4_read_sr );
1468 POP_realigned_r32( R_ECX );
1469 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1470 MEM_WRITE_LONG( R_ECX, R_EAX );
1471 sh4_x86.tstate = TSTATE_NONE;
1475 { /* STC.L GBR, @-Rn */
1476 uint32_t Rn = ((ir>>8)&0xF);
1477 load_reg( R_EAX, Rn );
1478 check_walign32( R_EAX );
1479 ADD_imm8s_r32( -4, R_EAX );
1480 MMU_TRANSLATE_WRITE( R_EAX );
1481 load_spreg( R_EDX, R_GBR );
1482 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1483 MEM_WRITE_LONG( R_EAX, R_EDX );
1484 sh4_x86.tstate = TSTATE_NONE;
1488 { /* STC.L VBR, @-Rn */
1489 uint32_t Rn = ((ir>>8)&0xF);
1491 load_reg( R_EAX, Rn );
1492 check_walign32( R_EAX );
1493 ADD_imm8s_r32( -4, R_EAX );
1494 MMU_TRANSLATE_WRITE( R_EAX );
1495 load_spreg( R_EDX, R_VBR );
1496 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1497 MEM_WRITE_LONG( R_EAX, R_EDX );
1498 sh4_x86.tstate = TSTATE_NONE;
1502 { /* STC.L SSR, @-Rn */
1503 uint32_t Rn = ((ir>>8)&0xF);
1505 load_reg( R_EAX, Rn );
1506 check_walign32( R_EAX );
1507 ADD_imm8s_r32( -4, R_EAX );
1508 MMU_TRANSLATE_WRITE( R_EAX );
1509 load_spreg( R_EDX, R_SSR );
1510 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1511 MEM_WRITE_LONG( R_EAX, R_EDX );
1512 sh4_x86.tstate = TSTATE_NONE;
1516 { /* STC.L SPC, @-Rn */
1517 uint32_t Rn = ((ir>>8)&0xF);
1519 load_reg( R_EAX, Rn );
1520 check_walign32( R_EAX );
1521 ADD_imm8s_r32( -4, R_EAX );
1522 MMU_TRANSLATE_WRITE( R_EAX );
1523 load_spreg( R_EDX, R_SPC );
1524 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1525 MEM_WRITE_LONG( R_EAX, R_EDX );
1526 sh4_x86.tstate = TSTATE_NONE;
1535 { /* STC.L Rm_BANK, @-Rn */
1536 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1538 load_reg( R_EAX, Rn );
1539 check_walign32( R_EAX );
1540 ADD_imm8s_r32( -4, R_EAX );
1541 MMU_TRANSLATE_WRITE( R_EAX );
1542 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1543 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1544 MEM_WRITE_LONG( R_EAX, R_EDX );
1545 sh4_x86.tstate = TSTATE_NONE;
1551 switch( (ir&0xF0) >> 4 ) {
1554 uint32_t Rn = ((ir>>8)&0xF);
1555 load_reg( R_EAX, Rn );
1557 store_reg( R_EAX, Rn );
1559 sh4_x86.tstate = TSTATE_C;
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 ) {
1584 uint32_t Rn = ((ir>>8)&0xF);
1585 load_reg( R_EAX, Rn );
1587 store_reg( R_EAX, Rn );
1589 sh4_x86.tstate = TSTATE_C;
1594 uint32_t Rn = ((ir>>8)&0xF);
1595 load_reg( R_EAX, Rn );
1596 CMP_imm8s_r32( 0, R_EAX );
1598 sh4_x86.tstate = TSTATE_G;
1603 uint32_t Rn = ((ir>>8)&0xF);
1604 load_reg( R_EAX, Rn );
1605 if( sh4_x86.tstate != TSTATE_C ) {
1609 store_reg( R_EAX, Rn );
1611 sh4_x86.tstate = TSTATE_C;
1620 switch( (ir&0xF0) >> 4 ) {
1622 { /* LDS.L @Rm+, MACH */
1623 uint32_t Rm = ((ir>>8)&0xF);
1624 load_reg( R_EAX, Rm );
1625 check_ralign32( R_EAX );
1626 MMU_TRANSLATE_READ( R_EAX );
1627 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1628 MEM_READ_LONG( R_EAX, R_EAX );
1629 store_spreg( R_EAX, R_MACH );
1630 sh4_x86.tstate = TSTATE_NONE;
1634 { /* LDS.L @Rm+, MACL */
1635 uint32_t Rm = ((ir>>8)&0xF);
1636 load_reg( R_EAX, Rm );
1637 check_ralign32( R_EAX );
1638 MMU_TRANSLATE_READ( R_EAX );
1639 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1640 MEM_READ_LONG( R_EAX, R_EAX );
1641 store_spreg( R_EAX, R_MACL );
1642 sh4_x86.tstate = TSTATE_NONE;
1646 { /* LDS.L @Rm+, PR */
1647 uint32_t Rm = ((ir>>8)&0xF);
1648 load_reg( R_EAX, Rm );
1649 check_ralign32( R_EAX );
1650 MMU_TRANSLATE_READ( R_EAX );
1651 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1652 MEM_READ_LONG( R_EAX, R_EAX );
1653 store_spreg( R_EAX, R_PR );
1654 sh4_x86.tstate = TSTATE_NONE;
1658 { /* LDC.L @Rm+, SGR */
1659 uint32_t Rm = ((ir>>8)&0xF);
1661 load_reg( R_EAX, Rm );
1662 check_ralign32( R_EAX );
1663 MMU_TRANSLATE_READ( R_EAX );
1664 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1665 MEM_READ_LONG( R_EAX, R_EAX );
1666 store_spreg( R_EAX, R_SGR );
1667 sh4_x86.tstate = TSTATE_NONE;
1671 { /* LDS.L @Rm+, FPUL */
1672 uint32_t Rm = ((ir>>8)&0xF);
1673 load_reg( R_EAX, Rm );
1674 check_ralign32( R_EAX );
1675 MMU_TRANSLATE_READ( R_EAX );
1676 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1677 MEM_READ_LONG( R_EAX, R_EAX );
1678 store_spreg( R_EAX, R_FPUL );
1679 sh4_x86.tstate = TSTATE_NONE;
1683 { /* LDS.L @Rm+, FPSCR */
1684 uint32_t Rm = ((ir>>8)&0xF);
1685 load_reg( R_EAX, Rm );
1686 check_ralign32( R_EAX );
1687 MMU_TRANSLATE_READ( R_EAX );
1688 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1689 MEM_READ_LONG( R_EAX, R_EAX );
1690 store_spreg( R_EAX, R_FPSCR );
1691 update_fr_bank( R_EAX );
1692 sh4_x86.tstate = TSTATE_NONE;
1696 { /* LDC.L @Rm+, DBR */
1697 uint32_t Rm = ((ir>>8)&0xF);
1699 load_reg( R_EAX, Rm );
1700 check_ralign32( R_EAX );
1701 MMU_TRANSLATE_READ( R_EAX );
1702 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1703 MEM_READ_LONG( R_EAX, R_EAX );
1704 store_spreg( R_EAX, R_DBR );
1705 sh4_x86.tstate = TSTATE_NONE;
1714 switch( (ir&0x80) >> 7 ) {
1716 switch( (ir&0x70) >> 4 ) {
1718 { /* LDC.L @Rm+, SR */
1719 uint32_t Rm = ((ir>>8)&0xF);
1720 if( sh4_x86.in_delay_slot ) {
1724 load_reg( R_EAX, Rm );
1725 check_ralign32( R_EAX );
1726 MMU_TRANSLATE_READ( R_EAX );
1727 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1728 MEM_READ_LONG( R_EAX, R_EAX );
1729 call_func1( sh4_write_sr, R_EAX );
1730 sh4_x86.priv_checked = FALSE;
1731 sh4_x86.fpuen_checked = FALSE;
1732 sh4_x86.tstate = TSTATE_NONE;
1737 { /* LDC.L @Rm+, GBR */
1738 uint32_t Rm = ((ir>>8)&0xF);
1739 load_reg( R_EAX, Rm );
1740 check_ralign32( R_EAX );
1741 MMU_TRANSLATE_READ( R_EAX );
1742 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1743 MEM_READ_LONG( R_EAX, R_EAX );
1744 store_spreg( R_EAX, R_GBR );
1745 sh4_x86.tstate = TSTATE_NONE;
1749 { /* LDC.L @Rm+, VBR */
1750 uint32_t Rm = ((ir>>8)&0xF);
1752 load_reg( R_EAX, Rm );
1753 check_ralign32( R_EAX );
1754 MMU_TRANSLATE_READ( R_EAX );
1755 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1756 MEM_READ_LONG( R_EAX, R_EAX );
1757 store_spreg( R_EAX, R_VBR );
1758 sh4_x86.tstate = TSTATE_NONE;
1762 { /* LDC.L @Rm+, SSR */
1763 uint32_t Rm = ((ir>>8)&0xF);
1765 load_reg( R_EAX, Rm );
1766 check_ralign32( R_EAX );
1767 MMU_TRANSLATE_READ( R_EAX );
1768 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1769 MEM_READ_LONG( R_EAX, R_EAX );
1770 store_spreg( R_EAX, R_SSR );
1771 sh4_x86.tstate = TSTATE_NONE;
1775 { /* LDC.L @Rm+, SPC */
1776 uint32_t Rm = ((ir>>8)&0xF);
1778 load_reg( R_EAX, Rm );
1779 check_ralign32( R_EAX );
1780 MMU_TRANSLATE_READ( R_EAX );
1781 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1782 MEM_READ_LONG( R_EAX, R_EAX );
1783 store_spreg( R_EAX, R_SPC );
1784 sh4_x86.tstate = TSTATE_NONE;
1793 { /* LDC.L @Rm+, Rn_BANK */
1794 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1796 load_reg( R_EAX, Rm );
1797 check_ralign32( R_EAX );
1798 MMU_TRANSLATE_READ( R_EAX );
1799 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1800 MEM_READ_LONG( R_EAX, R_EAX );
1801 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1802 sh4_x86.tstate = TSTATE_NONE;
1808 switch( (ir&0xF0) >> 4 ) {
1811 uint32_t Rn = ((ir>>8)&0xF);
1812 load_reg( R_EAX, Rn );
1813 SHL_imm8_r32( 2, R_EAX );
1814 store_reg( R_EAX, Rn );
1815 sh4_x86.tstate = TSTATE_NONE;
1820 uint32_t Rn = ((ir>>8)&0xF);
1821 load_reg( R_EAX, Rn );
1822 SHL_imm8_r32( 8, R_EAX );
1823 store_reg( R_EAX, Rn );
1824 sh4_x86.tstate = TSTATE_NONE;
1829 uint32_t Rn = ((ir>>8)&0xF);
1830 load_reg( R_EAX, Rn );
1831 SHL_imm8_r32( 16, R_EAX );
1832 store_reg( R_EAX, Rn );
1833 sh4_x86.tstate = TSTATE_NONE;
1842 switch( (ir&0xF0) >> 4 ) {
1845 uint32_t Rn = ((ir>>8)&0xF);
1846 load_reg( R_EAX, Rn );
1847 SHR_imm8_r32( 2, R_EAX );
1848 store_reg( R_EAX, Rn );
1849 sh4_x86.tstate = TSTATE_NONE;
1854 uint32_t Rn = ((ir>>8)&0xF);
1855 load_reg( R_EAX, Rn );
1856 SHR_imm8_r32( 8, R_EAX );
1857 store_reg( R_EAX, Rn );
1858 sh4_x86.tstate = TSTATE_NONE;
1863 uint32_t Rn = ((ir>>8)&0xF);
1864 load_reg( R_EAX, Rn );
1865 SHR_imm8_r32( 16, R_EAX );
1866 store_reg( R_EAX, Rn );
1867 sh4_x86.tstate = TSTATE_NONE;
1876 switch( (ir&0xF0) >> 4 ) {
1878 { /* LDS Rm, MACH */
1879 uint32_t Rm = ((ir>>8)&0xF);
1880 load_reg( R_EAX, Rm );
1881 store_spreg( R_EAX, R_MACH );
1885 { /* LDS Rm, MACL */
1886 uint32_t Rm = ((ir>>8)&0xF);
1887 load_reg( R_EAX, Rm );
1888 store_spreg( R_EAX, R_MACL );
1893 uint32_t Rm = ((ir>>8)&0xF);
1894 load_reg( R_EAX, Rm );
1895 store_spreg( R_EAX, R_PR );
1900 uint32_t Rm = ((ir>>8)&0xF);
1902 load_reg( R_EAX, Rm );
1903 store_spreg( R_EAX, R_SGR );
1904 sh4_x86.tstate = TSTATE_NONE;
1908 { /* LDS Rm, FPUL */
1909 uint32_t Rm = ((ir>>8)&0xF);
1910 load_reg( R_EAX, Rm );
1911 store_spreg( R_EAX, R_FPUL );
1915 { /* LDS Rm, FPSCR */
1916 uint32_t Rm = ((ir>>8)&0xF);
1917 load_reg( R_EAX, Rm );
1918 store_spreg( R_EAX, R_FPSCR );
1919 update_fr_bank( R_EAX );
1920 sh4_x86.tstate = TSTATE_NONE;
1925 uint32_t Rm = ((ir>>8)&0xF);
1927 load_reg( R_EAX, Rm );
1928 store_spreg( R_EAX, R_DBR );
1929 sh4_x86.tstate = TSTATE_NONE;
1938 switch( (ir&0xF0) >> 4 ) {
1941 uint32_t Rn = ((ir>>8)&0xF);
1942 if( sh4_x86.in_delay_slot ) {
1945 load_spreg( R_EAX, R_PC );
1946 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1947 store_spreg( R_EAX, R_PR );
1948 load_reg( R_ECX, Rn );
1949 store_spreg( R_ECX, R_NEW_PC );
1950 sh4_translate_instruction(pc+2);
1951 exit_block_newpcset(pc+2);
1952 sh4_x86.branch_taken = TRUE;
1959 uint32_t Rn = ((ir>>8)&0xF);
1960 load_reg( R_EAX, Rn );
1961 MMU_TRANSLATE_WRITE( R_EAX );
1962 PUSH_realigned_r32( R_EAX );
1963 MEM_READ_BYTE( R_EAX, R_EAX );
1964 TEST_r8_r8( R_AL, R_AL );
1966 OR_imm8_r8( 0x80, R_AL );
1967 POP_realigned_r32( R_ECX );
1968 MEM_WRITE_BYTE( R_ECX, R_EAX );
1969 sh4_x86.tstate = TSTATE_NONE;
1974 uint32_t Rn = ((ir>>8)&0xF);
1975 if( sh4_x86.in_delay_slot ) {
1978 load_reg( R_ECX, Rn );
1979 store_spreg( R_ECX, R_NEW_PC );
1980 sh4_x86.in_delay_slot = DELAY_PC;
1981 sh4_translate_instruction(pc+2);
1982 exit_block_newpcset(pc+2);
1983 sh4_x86.branch_taken = TRUE;
1995 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1996 /* Annoyingly enough, not directly convertible */
1997 load_reg( R_EAX, Rn );
1998 load_reg( R_ECX, Rm );
1999 CMP_imm32_r32( 0, R_ECX );
2000 JGE_rel8(16, doshl);
2002 NEG_r32( R_ECX ); // 2
2003 AND_imm8_r8( 0x1F, R_CL ); // 3
2004 JE_rel8( 4, emptysar); // 2
2005 SAR_r32_CL( R_EAX ); // 2
2006 JMP_rel8(10, end); // 2
2008 JMP_TARGET(emptysar);
2009 SAR_imm8_r32(31, R_EAX ); // 3
2013 AND_imm8_r8( 0x1F, R_CL ); // 3
2014 SHL_r32_CL( R_EAX ); // 2
2017 store_reg( R_EAX, Rn );
2018 sh4_x86.tstate = TSTATE_NONE;
2023 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2024 load_reg( R_EAX, Rn );
2025 load_reg( R_ECX, Rm );
2026 CMP_imm32_r32( 0, R_ECX );
2027 JGE_rel8(15, doshl);
2029 NEG_r32( R_ECX ); // 2
2030 AND_imm8_r8( 0x1F, R_CL ); // 3
2031 JE_rel8( 4, emptyshr );
2032 SHR_r32_CL( R_EAX ); // 2
2033 JMP_rel8(9, end); // 2
2035 JMP_TARGET(emptyshr);
2036 XOR_r32_r32( R_EAX, R_EAX );
2040 AND_imm8_r8( 0x1F, R_CL ); // 3
2041 SHL_r32_CL( R_EAX ); // 2
2044 store_reg( R_EAX, Rn );
2045 sh4_x86.tstate = TSTATE_NONE;
2049 switch( (ir&0x80) >> 7 ) {
2051 switch( (ir&0x70) >> 4 ) {
2054 uint32_t Rm = ((ir>>8)&0xF);
2055 if( sh4_x86.in_delay_slot ) {
2059 load_reg( R_EAX, Rm );
2060 call_func1( sh4_write_sr, R_EAX );
2061 sh4_x86.priv_checked = FALSE;
2062 sh4_x86.fpuen_checked = FALSE;
2063 sh4_x86.tstate = TSTATE_NONE;
2069 uint32_t Rm = ((ir>>8)&0xF);
2070 load_reg( R_EAX, Rm );
2071 store_spreg( R_EAX, R_GBR );
2076 uint32_t Rm = ((ir>>8)&0xF);
2078 load_reg( R_EAX, Rm );
2079 store_spreg( R_EAX, R_VBR );
2080 sh4_x86.tstate = TSTATE_NONE;
2085 uint32_t Rm = ((ir>>8)&0xF);
2087 load_reg( R_EAX, Rm );
2088 store_spreg( R_EAX, R_SSR );
2089 sh4_x86.tstate = TSTATE_NONE;
2094 uint32_t Rm = ((ir>>8)&0xF);
2096 load_reg( R_EAX, Rm );
2097 store_spreg( R_EAX, R_SPC );
2098 sh4_x86.tstate = TSTATE_NONE;
2107 { /* LDC Rm, Rn_BANK */
2108 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2110 load_reg( R_EAX, Rm );
2111 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2112 sh4_x86.tstate = TSTATE_NONE;
2118 { /* MAC.W @Rm+, @Rn+ */
2119 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2121 load_reg( R_EAX, Rm );
2122 check_ralign16( R_EAX );
2123 MMU_TRANSLATE_READ( R_EAX );
2124 PUSH_realigned_r32( R_EAX );
2125 load_reg( R_EAX, Rn );
2126 ADD_imm8s_r32( 2, R_EAX );
2127 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
2128 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
2129 // Note translate twice in case of page boundaries. Maybe worth
2130 // adding a page-boundary check to skip the second translation
2132 load_reg( R_EAX, Rm );
2133 check_ralign16( R_EAX );
2134 MMU_TRANSLATE_READ( R_EAX );
2135 load_reg( R_ECX, Rn );
2136 check_ralign16( R_ECX );
2137 PUSH_realigned_r32( R_EAX );
2138 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
2139 MOV_r32_r32( R_ECX, R_EAX );
2140 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2141 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2143 MEM_READ_WORD( R_EAX, R_EAX );
2146 MEM_READ_WORD( R_ECX, R_EAX );
2147 POP_realigned_r32( R_ECX );
2150 load_spreg( R_ECX, R_S );
2151 TEST_r32_r32( R_ECX, R_ECX );
2152 JE_rel8( 47, nosat );
2154 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2155 JNO_rel8( 51, end ); // 2
2156 load_imm32( R_EDX, 1 ); // 5
2157 store_spreg( R_EDX, R_MACH ); // 6
2158 JS_rel8( 13, positive ); // 2
2159 load_imm32( R_EAX, 0x80000000 );// 5
2160 store_spreg( R_EAX, R_MACL ); // 6
2161 JMP_rel8( 25, end2 ); // 2
2163 JMP_TARGET(positive);
2164 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2165 store_spreg( R_EAX, R_MACL ); // 6
2166 JMP_rel8( 12, end3); // 2
2169 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2170 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2174 sh4_x86.tstate = TSTATE_NONE;
2180 { /* MOV.L @(disp, Rm), Rn */
2181 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2182 load_reg( R_EAX, Rm );
2183 ADD_imm8s_r32( disp, R_EAX );
2184 check_ralign32( R_EAX );
2185 MMU_TRANSLATE_READ( R_EAX );
2186 MEM_READ_LONG( R_EAX, R_EAX );
2187 store_reg( R_EAX, Rn );
2188 sh4_x86.tstate = TSTATE_NONE;
2194 { /* MOV.B @Rm, Rn */
2195 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2196 load_reg( R_EAX, Rm );
2197 MMU_TRANSLATE_READ( R_EAX );
2198 MEM_READ_BYTE( R_EAX, R_EAX );
2199 store_reg( R_EAX, Rn );
2200 sh4_x86.tstate = TSTATE_NONE;
2204 { /* MOV.W @Rm, Rn */
2205 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2206 load_reg( R_EAX, Rm );
2207 check_ralign16( R_EAX );
2208 MMU_TRANSLATE_READ( R_EAX );
2209 MEM_READ_WORD( R_EAX, R_EAX );
2210 store_reg( R_EAX, Rn );
2211 sh4_x86.tstate = TSTATE_NONE;
2215 { /* MOV.L @Rm, Rn */
2216 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2217 load_reg( R_EAX, Rm );
2218 check_ralign32( R_EAX );
2219 MMU_TRANSLATE_READ( R_EAX );
2220 MEM_READ_LONG( R_EAX, R_EAX );
2221 store_reg( R_EAX, Rn );
2222 sh4_x86.tstate = TSTATE_NONE;
2227 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2228 load_reg( R_EAX, Rm );
2229 store_reg( R_EAX, Rn );
2233 { /* MOV.B @Rm+, Rn */
2234 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2235 load_reg( R_EAX, Rm );
2236 MMU_TRANSLATE_READ( R_EAX );
2237 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
2238 MEM_READ_BYTE( R_EAX, R_EAX );
2239 store_reg( R_EAX, Rn );
2240 sh4_x86.tstate = TSTATE_NONE;
2244 { /* MOV.W @Rm+, Rn */
2245 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2246 load_reg( R_EAX, Rm );
2247 check_ralign16( R_EAX );
2248 MMU_TRANSLATE_READ( R_EAX );
2249 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2250 MEM_READ_WORD( R_EAX, R_EAX );
2251 store_reg( R_EAX, Rn );
2252 sh4_x86.tstate = TSTATE_NONE;
2256 { /* MOV.L @Rm+, Rn */
2257 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2258 load_reg( R_EAX, Rm );
2259 check_ralign32( R_EAX );
2260 MMU_TRANSLATE_READ( R_EAX );
2261 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2262 MEM_READ_LONG( R_EAX, R_EAX );
2263 store_reg( R_EAX, Rn );
2264 sh4_x86.tstate = TSTATE_NONE;
2269 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2270 load_reg( R_EAX, Rm );
2272 store_reg( R_EAX, Rn );
2273 sh4_x86.tstate = TSTATE_NONE;
2277 { /* SWAP.B Rm, Rn */
2278 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2279 load_reg( R_EAX, Rm );
2280 XCHG_r8_r8( R_AL, R_AH );
2281 store_reg( R_EAX, Rn );
2285 { /* SWAP.W Rm, Rn */
2286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2287 load_reg( R_EAX, Rm );
2288 MOV_r32_r32( R_EAX, R_ECX );
2289 SHL_imm8_r32( 16, R_ECX );
2290 SHR_imm8_r32( 16, R_EAX );
2291 OR_r32_r32( R_EAX, R_ECX );
2292 store_reg( R_ECX, Rn );
2293 sh4_x86.tstate = TSTATE_NONE;
2298 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2299 load_reg( R_EAX, Rm );
2300 XOR_r32_r32( R_ECX, R_ECX );
2302 SBB_r32_r32( R_EAX, R_ECX );
2303 store_reg( R_ECX, Rn );
2305 sh4_x86.tstate = TSTATE_C;
2310 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2311 load_reg( R_EAX, Rm );
2313 store_reg( R_EAX, Rn );
2314 sh4_x86.tstate = TSTATE_NONE;
2318 { /* EXTU.B Rm, Rn */
2319 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2320 load_reg( R_EAX, Rm );
2321 MOVZX_r8_r32( R_EAX, R_EAX );
2322 store_reg( R_EAX, Rn );
2326 { /* EXTU.W Rm, Rn */
2327 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2328 load_reg( R_EAX, Rm );
2329 MOVZX_r16_r32( R_EAX, R_EAX );
2330 store_reg( R_EAX, Rn );
2334 { /* EXTS.B Rm, Rn */
2335 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2336 load_reg( R_EAX, Rm );
2337 MOVSX_r8_r32( R_EAX, R_EAX );
2338 store_reg( R_EAX, Rn );
2342 { /* EXTS.W Rm, Rn */
2343 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2344 load_reg( R_EAX, Rm );
2345 MOVSX_r16_r32( R_EAX, R_EAX );
2346 store_reg( R_EAX, Rn );
2352 { /* ADD #imm, Rn */
2353 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2354 load_reg( R_EAX, Rn );
2355 ADD_imm8s_r32( imm, R_EAX );
2356 store_reg( R_EAX, Rn );
2357 sh4_x86.tstate = TSTATE_NONE;
2361 switch( (ir&0xF00) >> 8 ) {
2363 { /* MOV.B R0, @(disp, Rn) */
2364 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2365 load_reg( R_EAX, Rn );
2366 ADD_imm32_r32( disp, R_EAX );
2367 MMU_TRANSLATE_WRITE( R_EAX );
2368 load_reg( R_EDX, 0 );
2369 MEM_WRITE_BYTE( R_EAX, R_EDX );
2370 sh4_x86.tstate = TSTATE_NONE;
2374 { /* MOV.W R0, @(disp, Rn) */
2375 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2376 load_reg( R_EAX, Rn );
2377 ADD_imm32_r32( disp, R_EAX );
2378 check_walign16( R_EAX );
2379 MMU_TRANSLATE_WRITE( R_EAX );
2380 load_reg( R_EDX, 0 );
2381 MEM_WRITE_WORD( R_EAX, R_EDX );
2382 sh4_x86.tstate = TSTATE_NONE;
2386 { /* MOV.B @(disp, Rm), R0 */
2387 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2388 load_reg( R_EAX, Rm );
2389 ADD_imm32_r32( disp, R_EAX );
2390 MMU_TRANSLATE_READ( R_EAX );
2391 MEM_READ_BYTE( R_EAX, R_EAX );
2392 store_reg( R_EAX, 0 );
2393 sh4_x86.tstate = TSTATE_NONE;
2397 { /* MOV.W @(disp, Rm), R0 */
2398 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2399 load_reg( R_EAX, Rm );
2400 ADD_imm32_r32( disp, R_EAX );
2401 check_ralign16( R_EAX );
2402 MMU_TRANSLATE_READ( R_EAX );
2403 MEM_READ_WORD( R_EAX, R_EAX );
2404 store_reg( R_EAX, 0 );
2405 sh4_x86.tstate = TSTATE_NONE;
2409 { /* CMP/EQ #imm, R0 */
2410 int32_t imm = SIGNEXT8(ir&0xFF);
2411 load_reg( R_EAX, 0 );
2412 CMP_imm8s_r32(imm, R_EAX);
2414 sh4_x86.tstate = TSTATE_E;
2419 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2420 if( sh4_x86.in_delay_slot ) {
2423 sh4vma_t target = disp + pc + 4;
2424 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2425 exit_block_rel(target, pc+2 );
2426 JMP_TARGET(nottaken);
2433 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2434 if( sh4_x86.in_delay_slot ) {
2437 sh4vma_t target = disp + pc + 4;
2438 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2439 exit_block_rel(target, pc+2 );
2440 JMP_TARGET(nottaken);
2447 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2448 if( sh4_x86.in_delay_slot ) {
2451 sh4_x86.in_delay_slot = DELAY_PC;
2452 if( sh4_x86.tstate == TSTATE_NONE ) {
2453 CMP_imm8s_sh4r( 1, R_T );
2454 sh4_x86.tstate = TSTATE_E;
2456 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2457 sh4_translate_instruction(pc+2);
2458 exit_block_rel( disp + pc + 4, pc+4 );
2460 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2461 sh4_translate_instruction(pc+2);
2468 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2469 if( sh4_x86.in_delay_slot ) {
2472 sh4vma_t target = disp + pc + 4;
2473 sh4_x86.in_delay_slot = DELAY_PC;
2474 if( sh4_x86.tstate == TSTATE_NONE ) {
2475 CMP_imm8s_sh4r( 1, R_T );
2476 sh4_x86.tstate = TSTATE_E;
2478 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2479 sh4_translate_instruction(pc+2);
2480 exit_block_rel( target, pc+4 );
2482 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2483 sh4_translate_instruction(pc+2);
2494 { /* MOV.W @(disp, PC), Rn */
2495 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2496 if( sh4_x86.in_delay_slot ) {
2499 // See comments for MOV.L @(disp, PC), Rn
2500 uint32_t target = pc + disp + 4;
2501 if( IS_IN_ICACHE(target) ) {
2502 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2503 MOV_moff32_EAX( ptr );
2504 MOVSX_r16_r32( R_EAX, R_EAX );
2506 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
2507 ADD_sh4r_r32( R_PC, R_EAX );
2508 MMU_TRANSLATE_READ( R_EAX );
2509 MEM_READ_WORD( R_EAX, R_EAX );
2510 sh4_x86.tstate = TSTATE_NONE;
2512 store_reg( R_EAX, Rn );
2518 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2519 if( sh4_x86.in_delay_slot ) {
2522 sh4_x86.in_delay_slot = DELAY_PC;
2523 sh4_translate_instruction( pc + 2 );
2524 exit_block_rel( disp + pc + 4, pc+4 );
2525 sh4_x86.branch_taken = TRUE;
2532 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2533 if( sh4_x86.in_delay_slot ) {
2536 load_spreg( R_EAX, R_PC );
2537 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
2538 store_spreg( R_EAX, R_PR );
2539 sh4_x86.in_delay_slot = DELAY_PC;
2540 sh4_translate_instruction( pc + 2 );
2541 exit_block_rel( disp + pc + 4, pc+4 );
2542 sh4_x86.branch_taken = TRUE;
2548 switch( (ir&0xF00) >> 8 ) {
2550 { /* MOV.B R0, @(disp, GBR) */
2551 uint32_t disp = (ir&0xFF);
2552 load_spreg( R_EAX, R_GBR );
2553 ADD_imm32_r32( disp, R_EAX );
2554 MMU_TRANSLATE_WRITE( R_EAX );
2555 load_reg( R_EDX, 0 );
2556 MEM_WRITE_BYTE( R_EAX, R_EDX );
2557 sh4_x86.tstate = TSTATE_NONE;
2561 { /* MOV.W R0, @(disp, GBR) */
2562 uint32_t disp = (ir&0xFF)<<1;
2563 load_spreg( R_EAX, R_GBR );
2564 ADD_imm32_r32( disp, R_EAX );
2565 check_walign16( R_EAX );
2566 MMU_TRANSLATE_WRITE( R_EAX );
2567 load_reg( R_EDX, 0 );
2568 MEM_WRITE_WORD( R_EAX, R_EDX );
2569 sh4_x86.tstate = TSTATE_NONE;
2573 { /* MOV.L R0, @(disp, GBR) */
2574 uint32_t disp = (ir&0xFF)<<2;
2575 load_spreg( R_EAX, R_GBR );
2576 ADD_imm32_r32( disp, R_EAX );
2577 check_walign32( R_EAX );
2578 MMU_TRANSLATE_WRITE( R_EAX );
2579 load_reg( R_EDX, 0 );
2580 MEM_WRITE_LONG( R_EAX, R_EDX );
2581 sh4_x86.tstate = TSTATE_NONE;
2586 uint32_t imm = (ir&0xFF);
2587 if( sh4_x86.in_delay_slot ) {
2590 load_imm32( R_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
2591 ADD_r32_sh4r( R_ECX, R_PC );
2592 load_imm32( R_EAX, imm );
2593 call_func1( sh4_raise_trap, R_EAX );
2594 sh4_x86.tstate = TSTATE_NONE;
2595 exit_block_pcset(pc);
2596 sh4_x86.branch_taken = TRUE;
2602 { /* MOV.B @(disp, GBR), R0 */
2603 uint32_t disp = (ir&0xFF);
2604 load_spreg( R_EAX, R_GBR );
2605 ADD_imm32_r32( disp, R_EAX );
2606 MMU_TRANSLATE_READ( R_EAX );
2607 MEM_READ_BYTE( R_EAX, R_EAX );
2608 store_reg( R_EAX, 0 );
2609 sh4_x86.tstate = TSTATE_NONE;
2613 { /* MOV.W @(disp, GBR), R0 */
2614 uint32_t disp = (ir&0xFF)<<1;
2615 load_spreg( R_EAX, R_GBR );
2616 ADD_imm32_r32( disp, R_EAX );
2617 check_ralign16( R_EAX );
2618 MMU_TRANSLATE_READ( R_EAX );
2619 MEM_READ_WORD( R_EAX, R_EAX );
2620 store_reg( R_EAX, 0 );
2621 sh4_x86.tstate = TSTATE_NONE;
2625 { /* MOV.L @(disp, GBR), R0 */
2626 uint32_t disp = (ir&0xFF)<<2;
2627 load_spreg( R_EAX, R_GBR );
2628 ADD_imm32_r32( disp, R_EAX );
2629 check_ralign32( R_EAX );
2630 MMU_TRANSLATE_READ( R_EAX );
2631 MEM_READ_LONG( R_EAX, R_EAX );
2632 store_reg( R_EAX, 0 );
2633 sh4_x86.tstate = TSTATE_NONE;
2637 { /* MOVA @(disp, PC), R0 */
2638 uint32_t disp = (ir&0xFF)<<2;
2639 if( sh4_x86.in_delay_slot ) {
2642 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2643 ADD_sh4r_r32( R_PC, R_ECX );
2644 store_reg( R_ECX, 0 );
2645 sh4_x86.tstate = TSTATE_NONE;
2650 { /* TST #imm, R0 */
2651 uint32_t imm = (ir&0xFF);
2652 load_reg( R_EAX, 0 );
2653 TEST_imm32_r32( imm, R_EAX );
2655 sh4_x86.tstate = TSTATE_E;
2659 { /* AND #imm, R0 */
2660 uint32_t imm = (ir&0xFF);
2661 load_reg( R_EAX, 0 );
2662 AND_imm32_r32(imm, R_EAX);
2663 store_reg( R_EAX, 0 );
2664 sh4_x86.tstate = TSTATE_NONE;
2668 { /* XOR #imm, R0 */
2669 uint32_t imm = (ir&0xFF);
2670 load_reg( R_EAX, 0 );
2671 XOR_imm32_r32( imm, R_EAX );
2672 store_reg( R_EAX, 0 );
2673 sh4_x86.tstate = TSTATE_NONE;
2678 uint32_t imm = (ir&0xFF);
2679 load_reg( R_EAX, 0 );
2680 OR_imm32_r32(imm, R_EAX);
2681 store_reg( R_EAX, 0 );
2682 sh4_x86.tstate = TSTATE_NONE;
2686 { /* TST.B #imm, @(R0, GBR) */
2687 uint32_t imm = (ir&0xFF);
2688 load_reg( R_EAX, 0);
2689 load_reg( R_ECX, R_GBR);
2690 ADD_r32_r32( R_ECX, R_EAX );
2691 MMU_TRANSLATE_READ( R_EAX );
2692 MEM_READ_BYTE( R_EAX, R_EAX );
2693 TEST_imm8_r8( imm, R_AL );
2695 sh4_x86.tstate = TSTATE_E;
2699 { /* AND.B #imm, @(R0, GBR) */
2700 uint32_t imm = (ir&0xFF);
2701 load_reg( R_EAX, 0 );
2702 load_spreg( R_ECX, R_GBR );
2703 ADD_r32_r32( R_ECX, R_EAX );
2704 MMU_TRANSLATE_WRITE( R_EAX );
2705 PUSH_realigned_r32(R_EAX);
2706 MEM_READ_BYTE( R_EAX, R_EAX );
2707 POP_realigned_r32(R_ECX);
2708 AND_imm32_r32(imm, R_EAX );
2709 MEM_WRITE_BYTE( R_ECX, R_EAX );
2710 sh4_x86.tstate = TSTATE_NONE;
2714 { /* XOR.B #imm, @(R0, GBR) */
2715 uint32_t imm = (ir&0xFF);
2716 load_reg( R_EAX, 0 );
2717 load_spreg( R_ECX, R_GBR );
2718 ADD_r32_r32( R_ECX, R_EAX );
2719 MMU_TRANSLATE_WRITE( R_EAX );
2720 PUSH_realigned_r32(R_EAX);
2721 MEM_READ_BYTE(R_EAX, R_EAX);
2722 POP_realigned_r32(R_ECX);
2723 XOR_imm32_r32( imm, R_EAX );
2724 MEM_WRITE_BYTE( R_ECX, R_EAX );
2725 sh4_x86.tstate = TSTATE_NONE;
2729 { /* OR.B #imm, @(R0, GBR) */
2730 uint32_t imm = (ir&0xFF);
2731 load_reg( R_EAX, 0 );
2732 load_spreg( R_ECX, R_GBR );
2733 ADD_r32_r32( R_ECX, R_EAX );
2734 MMU_TRANSLATE_WRITE( R_EAX );
2735 PUSH_realigned_r32(R_EAX);
2736 MEM_READ_BYTE( R_EAX, R_EAX );
2737 POP_realigned_r32(R_ECX);
2738 OR_imm32_r32(imm, R_EAX );
2739 MEM_WRITE_BYTE( R_ECX, R_EAX );
2740 sh4_x86.tstate = TSTATE_NONE;
2746 { /* MOV.L @(disp, PC), Rn */
2747 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2748 if( sh4_x86.in_delay_slot ) {
2751 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2752 if( IS_IN_ICACHE(target) ) {
2753 // If the target address is in the same page as the code, it's
2754 // pretty safe to just ref it directly and circumvent the whole
2755 // memory subsystem. (this is a big performance win)
2757 // FIXME: There's a corner-case that's not handled here when
2758 // the current code-page is in the ITLB but not in the UTLB.
2759 // (should generate a TLB miss although need to test SH4
2760 // behaviour to confirm) Unlikely to be anyone depending on this
2761 // behaviour though.
2762 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2763 MOV_moff32_EAX( ptr );
2765 // Note: we use sh4r.pc for the calc as we could be running at a
2766 // different virtual address than the translation was done with,
2767 // but we can safely assume that the low bits are the same.
2768 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2769 ADD_sh4r_r32( R_PC, R_EAX );
2770 MMU_TRANSLATE_READ( R_EAX );
2771 MEM_READ_LONG( R_EAX, R_EAX );
2772 sh4_x86.tstate = TSTATE_NONE;
2774 store_reg( R_EAX, Rn );
2779 { /* MOV #imm, Rn */
2780 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2781 load_imm32( R_EAX, imm );
2782 store_reg( R_EAX, Rn );
2788 { /* FADD FRm, FRn */
2789 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2791 load_spreg( R_ECX, R_FPSCR );
2792 TEST_imm32_r32( FPSCR_PR, R_ECX );
2793 load_fr_bank( R_EDX );
2794 JNE_rel8(13,doubleprec);
2795 push_fr(R_EDX, FRm);
2796 push_fr(R_EDX, FRn);
2800 JMP_TARGET(doubleprec);
2801 push_dr(R_EDX, FRm);
2802 push_dr(R_EDX, FRn);
2806 sh4_x86.tstate = TSTATE_NONE;
2810 { /* FSUB FRm, FRn */
2811 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2813 load_spreg( R_ECX, R_FPSCR );
2814 TEST_imm32_r32( FPSCR_PR, R_ECX );
2815 load_fr_bank( R_EDX );
2816 JNE_rel8(13, doubleprec);
2817 push_fr(R_EDX, FRn);
2818 push_fr(R_EDX, FRm);
2822 JMP_TARGET(doubleprec);
2823 push_dr(R_EDX, FRn);
2824 push_dr(R_EDX, FRm);
2828 sh4_x86.tstate = TSTATE_NONE;
2832 { /* FMUL FRm, FRn */
2833 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2835 load_spreg( R_ECX, R_FPSCR );
2836 TEST_imm32_r32( FPSCR_PR, R_ECX );
2837 load_fr_bank( R_EDX );
2838 JNE_rel8(13, doubleprec);
2839 push_fr(R_EDX, FRm);
2840 push_fr(R_EDX, FRn);
2844 JMP_TARGET(doubleprec);
2845 push_dr(R_EDX, FRm);
2846 push_dr(R_EDX, FRn);
2850 sh4_x86.tstate = TSTATE_NONE;
2854 { /* FDIV FRm, FRn */
2855 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2857 load_spreg( R_ECX, R_FPSCR );
2858 TEST_imm32_r32( FPSCR_PR, R_ECX );
2859 load_fr_bank( R_EDX );
2860 JNE_rel8(13, doubleprec);
2861 push_fr(R_EDX, FRn);
2862 push_fr(R_EDX, FRm);
2866 JMP_TARGET(doubleprec);
2867 push_dr(R_EDX, FRn);
2868 push_dr(R_EDX, FRm);
2872 sh4_x86.tstate = TSTATE_NONE;
2876 { /* FCMP/EQ FRm, FRn */
2877 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2879 load_spreg( R_ECX, R_FPSCR );
2880 TEST_imm32_r32( FPSCR_PR, R_ECX );
2881 load_fr_bank( R_EDX );
2882 JNE_rel8(8, doubleprec);
2883 push_fr(R_EDX, FRm);
2884 push_fr(R_EDX, FRn);
2886 JMP_TARGET(doubleprec);
2887 push_dr(R_EDX, FRm);
2888 push_dr(R_EDX, FRn);
2893 sh4_x86.tstate = TSTATE_NONE;
2897 { /* FCMP/GT FRm, FRn */
2898 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2900 load_spreg( R_ECX, R_FPSCR );
2901 TEST_imm32_r32( FPSCR_PR, R_ECX );
2902 load_fr_bank( R_EDX );
2903 JNE_rel8(8, doubleprec);
2904 push_fr(R_EDX, FRm);
2905 push_fr(R_EDX, FRn);
2907 JMP_TARGET(doubleprec);
2908 push_dr(R_EDX, FRm);
2909 push_dr(R_EDX, FRn);
2914 sh4_x86.tstate = TSTATE_NONE;
2918 { /* FMOV @(R0, Rm), FRn */
2919 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2921 load_reg( R_EAX, Rm );
2922 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2923 check_ralign32( R_EAX );
2924 MMU_TRANSLATE_READ( R_EAX );
2925 load_spreg( R_EDX, R_FPSCR );
2926 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2927 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2928 MEM_READ_LONG( R_EAX, R_EAX );
2929 load_fr_bank( R_EDX );
2930 store_fr( R_EDX, R_EAX, FRn );
2932 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
2933 JMP_TARGET(doublesize);
2934 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2935 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2936 load_xf_bank( R_EDX );
2937 store_fr( R_EDX, R_ECX, FRn&0x0E );
2938 store_fr( R_EDX, R_EAX, FRn|0x01 );
2941 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
2942 JMP_TARGET(doublesize);
2943 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
2944 load_fr_bank( R_EDX );
2945 store_fr( R_EDX, R_ECX, FRn&0x0E );
2946 store_fr( R_EDX, R_EAX, FRn|0x01 );
2949 sh4_x86.tstate = TSTATE_NONE;
2953 { /* FMOV FRm, @(R0, Rn) */
2954 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2956 load_reg( R_EAX, Rn );
2957 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
2958 check_walign32( R_EAX );
2959 MMU_TRANSLATE_WRITE( R_EAX );
2960 load_spreg( R_EDX, R_FPSCR );
2961 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2962 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
2963 load_fr_bank( R_EDX );
2964 load_fr( R_EDX, R_ECX, FRm );
2965 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
2967 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
2968 JMP_TARGET(doublesize);
2969 load_xf_bank( R_EDX );
2970 load_fr( R_EDX, R_ECX, FRm&0x0E );
2971 load_fr( R_EDX, R_EDX, FRm|0x01 );
2972 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2975 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
2976 JMP_TARGET(doublesize);
2977 load_fr_bank( R_EDX );
2978 load_fr( R_EDX, R_ECX, FRm&0x0E );
2979 load_fr( R_EDX, R_EDX, FRm|0x01 );
2980 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
2983 sh4_x86.tstate = TSTATE_NONE;
2987 { /* FMOV @Rm, FRn */
2988 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2990 load_reg( R_EAX, Rm );
2991 check_ralign32( R_EAX );
2992 MMU_TRANSLATE_READ( R_EAX );
2993 load_spreg( R_EDX, R_FPSCR );
2994 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2995 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
2996 MEM_READ_LONG( R_EAX, R_EAX );
2997 load_fr_bank( R_EDX );
2998 store_fr( R_EDX, R_EAX, FRn );
3000 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
3001 JMP_TARGET(doublesize);
3002 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3003 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3004 load_xf_bank( R_EDX );
3005 store_fr( R_EDX, R_ECX, FRn&0x0E );
3006 store_fr( R_EDX, R_EAX, FRn|0x01 );
3009 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
3010 JMP_TARGET(doublesize);
3011 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3012 load_fr_bank( R_EDX );
3013 store_fr( R_EDX, R_ECX, FRn&0x0E );
3014 store_fr( R_EDX, R_EAX, FRn|0x01 );
3017 sh4_x86.tstate = TSTATE_NONE;
3021 { /* FMOV @Rm+, FRn */
3022 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3024 load_reg( R_EAX, Rm );
3025 check_ralign32( R_EAX );
3026 MMU_TRANSLATE_READ( R_EAX );
3027 load_spreg( R_EDX, R_FPSCR );
3028 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3029 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
3030 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
3031 MEM_READ_LONG( R_EAX, R_EAX );
3032 load_fr_bank( R_EDX );
3033 store_fr( R_EDX, R_EAX, FRn );
3035 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
3036 JMP_TARGET(doublesize);
3037 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3038 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3039 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3040 load_xf_bank( R_EDX );
3041 store_fr( R_EDX, R_ECX, FRn&0x0E );
3042 store_fr( R_EDX, R_EAX, FRn|0x01 );
3045 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
3046 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3047 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3048 load_fr_bank( R_EDX );
3049 store_fr( R_EDX, R_ECX, FRn&0x0E );
3050 store_fr( R_EDX, R_EAX, FRn|0x01 );
3053 sh4_x86.tstate = TSTATE_NONE;
3057 { /* FMOV FRm, @Rn */
3058 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3060 load_reg( R_EAX, Rn );
3061 check_walign32( R_EAX );
3062 MMU_TRANSLATE_WRITE( R_EAX );
3063 load_spreg( R_EDX, R_FPSCR );
3064 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3065 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
3066 load_fr_bank( R_EDX );
3067 load_fr( R_EDX, R_ECX, FRm );
3068 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3070 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3071 JMP_TARGET(doublesize);
3072 load_xf_bank( R_EDX );
3073 load_fr( R_EDX, R_ECX, FRm&0x0E );
3074 load_fr( R_EDX, R_EDX, FRm|0x01 );
3075 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3078 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3079 JMP_TARGET(doublesize);
3080 load_fr_bank( R_EDX );
3081 load_fr( R_EDX, R_ECX, FRm&0x0E );
3082 load_fr( R_EDX, R_EDX, FRm|0x01 );
3083 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3086 sh4_x86.tstate = TSTATE_NONE;
3090 { /* FMOV FRm, @-Rn */
3091 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3093 load_reg( R_EAX, Rn );
3094 check_walign32( R_EAX );
3095 load_spreg( R_EDX, R_FPSCR );
3096 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3097 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
3098 ADD_imm8s_r32( -4, R_EAX );
3099 MMU_TRANSLATE_WRITE( R_EAX );
3100 load_fr_bank( R_EDX );
3101 load_fr( R_EDX, R_ECX, FRm );
3102 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
3103 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3105 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3106 JMP_TARGET(doublesize);
3107 ADD_imm8s_r32(-8,R_EAX);
3108 MMU_TRANSLATE_WRITE( R_EAX );
3109 load_xf_bank( R_EDX );
3110 load_fr( R_EDX, R_ECX, FRm&0x0E );
3111 load_fr( R_EDX, R_EDX, FRm|0x01 );
3112 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3113 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3116 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3117 JMP_TARGET(doublesize);
3118 ADD_imm8s_r32(-8,R_EAX);
3119 MMU_TRANSLATE_WRITE( R_EAX );
3120 load_fr_bank( R_EDX );
3121 load_fr( R_EDX, R_ECX, FRm&0x0E );
3122 load_fr( R_EDX, R_EDX, FRm|0x01 );
3123 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3124 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3127 sh4_x86.tstate = TSTATE_NONE;
3131 { /* FMOV FRm, FRn */
3132 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3133 /* As horrible as this looks, it's actually covering 5 separate cases:
3134 * 1. 32-bit fr-to-fr (PR=0)
3135 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3136 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3137 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3138 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3141 load_spreg( R_ECX, R_FPSCR );
3142 load_fr_bank( R_EDX );
3143 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3144 JNE_rel8(8, doublesize);
3145 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3146 store_fr( R_EDX, R_EAX, FRn );
3149 JMP_TARGET(doublesize);
3150 load_xf_bank( R_ECX );
3151 load_fr( R_ECX, R_EAX, FRm-1 );
3153 load_fr( R_ECX, R_EDX, FRm );
3154 store_fr( R_ECX, R_EAX, FRn-1 );
3155 store_fr( R_ECX, R_EDX, FRn );
3156 } else /* FRn&1 == 0 */ {
3157 load_fr( R_ECX, R_ECX, FRm );
3158 store_fr( R_EDX, R_EAX, FRn );
3159 store_fr( R_EDX, R_ECX, FRn+1 );
3162 } else /* FRm&1 == 0 */ {
3165 load_xf_bank( R_ECX );
3166 load_fr( R_EDX, R_EAX, FRm );
3167 load_fr( R_EDX, R_EDX, FRm+1 );
3168 store_fr( R_ECX, R_EAX, FRn-1 );
3169 store_fr( R_ECX, R_EDX, FRn );
3171 } else /* FRn&1 == 0 */ {
3173 load_fr( R_EDX, R_EAX, FRm );
3174 load_fr( R_EDX, R_ECX, FRm+1 );
3175 store_fr( R_EDX, R_EAX, FRn );
3176 store_fr( R_EDX, R_ECX, FRn+1 );
3180 sh4_x86.tstate = TSTATE_NONE;
3184 switch( (ir&0xF0) >> 4 ) {
3186 { /* FSTS FPUL, FRn */
3187 uint32_t FRn = ((ir>>8)&0xF);
3189 load_fr_bank( R_ECX );
3190 load_spreg( R_EAX, R_FPUL );
3191 store_fr( R_ECX, R_EAX, FRn );
3192 sh4_x86.tstate = TSTATE_NONE;
3196 { /* FLDS FRm, FPUL */
3197 uint32_t FRm = ((ir>>8)&0xF);
3199 load_fr_bank( R_ECX );
3200 load_fr( R_ECX, R_EAX, FRm );
3201 store_spreg( R_EAX, R_FPUL );
3202 sh4_x86.tstate = TSTATE_NONE;
3206 { /* FLOAT FPUL, FRn */
3207 uint32_t FRn = ((ir>>8)&0xF);
3209 load_spreg( R_ECX, R_FPSCR );
3210 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3212 TEST_imm32_r32( FPSCR_PR, R_ECX );
3213 JNE_rel8(5, doubleprec);
3214 pop_fr( R_EDX, FRn );
3216 JMP_TARGET(doubleprec);
3217 pop_dr( R_EDX, FRn );
3219 sh4_x86.tstate = TSTATE_NONE;
3223 { /* FTRC FRm, FPUL */
3224 uint32_t FRm = ((ir>>8)&0xF);
3226 load_spreg( R_ECX, R_FPSCR );
3227 load_fr_bank( R_EDX );
3228 TEST_imm32_r32( FPSCR_PR, R_ECX );
3229 JNE_rel8(5, doubleprec);
3230 push_fr( R_EDX, FRm );
3232 JMP_TARGET(doubleprec);
3233 push_dr( R_EDX, FRm );
3235 load_imm32( R_ECX, (uint32_t)&max_int );
3236 FILD_r32ind( R_ECX );
3238 JNA_rel8( 32, sat );
3239 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3240 FILD_r32ind( R_ECX ); // 2
3242 JAE_rel8( 21, sat2 ); // 2
3243 load_imm32( R_EAX, (uint32_t)&save_fcw );
3244 FNSTCW_r32ind( R_EAX );
3245 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3246 FLDCW_r32ind( R_EDX );
3247 FISTP_sh4r(R_FPUL); // 3
3248 FLDCW_r32ind( R_EAX );
3249 JMP_rel8( 9, end ); // 2
3253 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3254 store_spreg( R_ECX, R_FPUL );
3257 sh4_x86.tstate = TSTATE_NONE;
3262 uint32_t FRn = ((ir>>8)&0xF);
3264 load_spreg( R_ECX, R_FPSCR );
3265 TEST_imm32_r32( FPSCR_PR, R_ECX );
3266 load_fr_bank( R_EDX );
3267 JNE_rel8(10, doubleprec);
3268 push_fr(R_EDX, FRn);
3272 JMP_TARGET(doubleprec);
3273 push_dr(R_EDX, FRn);
3277 sh4_x86.tstate = TSTATE_NONE;
3282 uint32_t FRn = ((ir>>8)&0xF);
3284 load_spreg( R_ECX, R_FPSCR );
3285 load_fr_bank( R_EDX );
3286 TEST_imm32_r32( FPSCR_PR, R_ECX );
3287 JNE_rel8(10, doubleprec);
3288 push_fr(R_EDX, FRn); // 3
3290 pop_fr( R_EDX, FRn); //3
3291 JMP_rel8(8,end); // 2
3292 JMP_TARGET(doubleprec);
3293 push_dr(R_EDX, FRn);
3297 sh4_x86.tstate = TSTATE_NONE;
3302 uint32_t FRn = ((ir>>8)&0xF);
3304 load_spreg( R_ECX, R_FPSCR );
3305 TEST_imm32_r32( FPSCR_PR, R_ECX );
3306 load_fr_bank( R_EDX );
3307 JNE_rel8(10, doubleprec);
3308 push_fr(R_EDX, FRn);
3312 JMP_TARGET(doubleprec);
3313 push_dr(R_EDX, FRn);
3317 sh4_x86.tstate = TSTATE_NONE;
3322 uint32_t FRn = ((ir>>8)&0xF);
3324 load_spreg( R_ECX, R_FPSCR );
3325 TEST_imm32_r32( FPSCR_PR, R_ECX );
3326 load_fr_bank( R_EDX );
3327 JNE_rel8(12, end); // PR=0 only
3329 push_fr(R_EDX, FRn);
3334 sh4_x86.tstate = TSTATE_NONE;
3339 uint32_t FRn = ((ir>>8)&0xF);
3342 load_spreg( R_ECX, R_FPSCR );
3343 TEST_imm32_r32( FPSCR_PR, R_ECX );
3345 XOR_r32_r32( R_EAX, R_EAX );
3346 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3347 store_fr( R_ECX, R_EAX, FRn );
3349 sh4_x86.tstate = TSTATE_NONE;
3354 uint32_t FRn = ((ir>>8)&0xF);
3357 load_spreg( R_ECX, R_FPSCR );
3358 TEST_imm32_r32( FPSCR_PR, R_ECX );
3360 load_imm32(R_EAX, 0x3F800000);
3361 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3362 store_fr( R_ECX, R_EAX, FRn );
3364 sh4_x86.tstate = TSTATE_NONE;
3368 { /* FCNVSD FPUL, FRn */
3369 uint32_t FRn = ((ir>>8)&0xF);
3371 load_spreg( R_ECX, R_FPSCR );
3372 TEST_imm32_r32( FPSCR_PR, R_ECX );
3373 JE_rel8(9, end); // only when PR=1
3374 load_fr_bank( R_ECX );
3376 pop_dr( R_ECX, FRn );
3378 sh4_x86.tstate = TSTATE_NONE;
3382 { /* FCNVDS FRm, FPUL */
3383 uint32_t FRm = ((ir>>8)&0xF);
3385 load_spreg( R_ECX, R_FPSCR );
3386 TEST_imm32_r32( FPSCR_PR, R_ECX );
3387 JE_rel8(9, end); // only when PR=1
3388 load_fr_bank( R_ECX );
3389 push_dr( R_ECX, FRm );
3392 sh4_x86.tstate = TSTATE_NONE;
3396 { /* FIPR FVm, FVn */
3397 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3399 load_spreg( R_ECX, R_FPSCR );
3400 TEST_imm32_r32( FPSCR_PR, R_ECX );
3401 JNE_rel8(44, doubleprec);
3403 load_fr_bank( R_ECX );
3404 push_fr( R_ECX, FVm<<2 );
3405 push_fr( R_ECX, FVn<<2 );
3407 push_fr( R_ECX, (FVm<<2)+1);
3408 push_fr( R_ECX, (FVn<<2)+1);
3411 push_fr( R_ECX, (FVm<<2)+2);
3412 push_fr( R_ECX, (FVn<<2)+2);
3415 push_fr( R_ECX, (FVm<<2)+3);
3416 push_fr( R_ECX, (FVn<<2)+3);
3419 pop_fr( R_ECX, (FVn<<2)+3);
3420 JMP_TARGET(doubleprec);
3421 sh4_x86.tstate = TSTATE_NONE;
3425 switch( (ir&0x100) >> 8 ) {
3427 { /* FSCA FPUL, FRn */
3428 uint32_t FRn = ((ir>>9)&0x7)<<1;
3430 load_spreg( R_ECX, R_FPSCR );
3431 TEST_imm32_r32( FPSCR_PR, R_ECX );
3432 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3433 load_fr_bank( R_ECX );
3434 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3435 load_spreg( R_EDX, R_FPUL );
3436 call_func2( sh4_fsca, R_EDX, R_ECX );
3437 JMP_TARGET(doubleprec);
3438 sh4_x86.tstate = TSTATE_NONE;
3442 switch( (ir&0x200) >> 9 ) {
3444 { /* FTRV XMTRX, FVn */
3445 uint32_t FVn = ((ir>>10)&0x3);
3447 load_spreg( R_ECX, R_FPSCR );
3448 TEST_imm32_r32( FPSCR_PR, R_ECX );
3449 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3450 load_fr_bank( R_EDX ); // 3
3451 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3452 load_xf_bank( R_ECX ); // 12
3453 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3454 JMP_TARGET(doubleprec);
3455 sh4_x86.tstate = TSTATE_NONE;
3459 switch( (ir&0xC00) >> 10 ) {
3463 load_spreg( R_ECX, R_FPSCR );
3464 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3465 store_spreg( R_ECX, R_FPSCR );
3466 sh4_x86.tstate = TSTATE_NONE;
3472 load_spreg( R_ECX, R_FPSCR );
3473 XOR_imm32_r32( FPSCR_FR, R_ECX );
3474 store_spreg( R_ECX, R_FPSCR );
3475 update_fr_bank( R_ECX );
3476 sh4_x86.tstate = TSTATE_NONE;
3481 if( sh4_x86.in_delay_slot ) {
3484 JMP_exc(EXC_ILLEGAL);
3504 { /* FMAC FR0, FRm, FRn */
3505 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3507 load_spreg( R_ECX, R_FPSCR );
3508 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3509 TEST_imm32_r32( FPSCR_PR, R_ECX );
3510 JNE_rel8(18, doubleprec);
3511 push_fr( R_EDX, 0 );
3512 push_fr( R_EDX, FRm );
3514 push_fr( R_EDX, FRn );
3516 pop_fr( R_EDX, FRn );
3518 JMP_TARGET(doubleprec);
3519 push_dr( R_EDX, 0 );
3520 push_dr( R_EDX, FRm );
3522 push_dr( R_EDX, FRn );
3524 pop_dr( R_EDX, FRn );
3526 sh4_x86.tstate = TSTATE_NONE;
3536 sh4_x86.in_delay_slot = DELAY_NONE;
.