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 {
38 uint32_t fixup_offset;
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_offset =
119 ((uint8_t *)fixup_addr) - ((uint8_t *)xlat_current_block->code);
120 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
121 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
122 sh4_x86.backpatch_posn++;
126 * Emit an instruction to load an SH4 reg into a real register
128 static inline void load_reg( int x86reg, int sh4reg )
130 /* mov [bp+n], reg */
132 OP(0x45 + (x86reg<<3));
133 OP(REG_OFFSET(r[sh4reg]));
136 static inline void load_reg16s( int x86reg, int sh4reg )
140 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
143 static inline void load_reg16u( int x86reg, int sh4reg )
147 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
151 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
152 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
154 * Emit an instruction to load an immediate value into a register
156 static inline void load_imm32( int x86reg, uint32_t value ) {
157 /* mov #value, reg */
163 * Load an immediate 64-bit quantity (note: x86-64 only)
165 static inline void load_imm64( int x86reg, uint32_t value ) {
166 /* mov #value, reg */
174 * Emit an instruction to store an SH4 reg (RN)
176 void static inline store_reg( int x86reg, int sh4reg ) {
177 /* mov reg, [bp+n] */
179 OP(0x45 + (x86reg<<3));
180 OP(REG_OFFSET(r[sh4reg]));
183 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
186 * Load an FR register (single-precision floating point) into an integer x86
187 * register (eg for register-to-register moves)
189 void static inline load_fr( int bankreg, int x86reg, int frm )
191 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
195 * Store an FR register (single-precision floating point) into an integer x86
196 * register (eg for register-to-register moves)
198 void static inline store_fr( int bankreg, int x86reg, int frn )
200 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
205 * Load a pointer to the back fp back into the specified x86 register. The
206 * bankreg must have been previously loaded with FPSCR.
209 static inline void load_xf_bank( int bankreg )
212 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
213 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
214 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
218 * Update the fr_bank pointer based on the current fpscr value.
220 static inline void update_fr_bank( int fpscrreg )
222 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
223 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
224 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
225 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
228 * Push FPUL (as a 32-bit float) onto the FPU stack
230 static inline void push_fpul( )
232 OP(0xD9); OP(0x45); OP(R_FPUL);
236 * Pop FPUL (as a 32-bit float) from the FPU stack
238 static inline void pop_fpul( )
240 OP(0xD9); OP(0x5D); OP(R_FPUL);
244 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
245 * with the location of the current fp bank.
247 static inline void push_fr( int bankreg, int frm )
249 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
253 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
254 * with bankreg previously loaded with the location of the current fp bank.
256 static inline void pop_fr( int bankreg, int frm )
258 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
262 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
263 * with the location of the current fp bank.
265 static inline void push_dr( int bankreg, int frm )
267 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
270 static inline void pop_dr( int bankreg, int frm )
272 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
275 /* Exception checks - Note that all exception checks will clobber EAX */
277 #define check_priv( ) \
278 if( !sh4_x86.priv_checked ) { \
279 sh4_x86.priv_checked = TRUE;\
280 load_spreg( R_EAX, R_SR );\
281 AND_imm32_r32( SR_MD, R_EAX );\
282 if( sh4_x86.in_delay_slot ) {\
283 JE_exc( EXC_SLOT_ILLEGAL );\
285 JE_exc( EXC_ILLEGAL );\
289 #define check_fpuen( ) \
290 if( !sh4_x86.fpuen_checked ) {\
291 sh4_x86.fpuen_checked = TRUE;\
292 load_spreg( R_EAX, R_SR );\
293 AND_imm32_r32( SR_FD, R_EAX );\
294 if( sh4_x86.in_delay_slot ) {\
295 JNE_exc(EXC_SLOT_FPU_DISABLED);\
297 JNE_exc(EXC_FPU_DISABLED);\
301 #define check_ralign16( x86reg ) \
302 TEST_imm32_r32( 0x00000001, x86reg ); \
303 JNE_exc(EXC_DATA_ADDR_READ)
305 #define check_walign16( x86reg ) \
306 TEST_imm32_r32( 0x00000001, x86reg ); \
307 JNE_exc(EXC_DATA_ADDR_WRITE);
309 #define check_ralign32( x86reg ) \
310 TEST_imm32_r32( 0x00000003, x86reg ); \
311 JNE_exc(EXC_DATA_ADDR_READ)
313 #define check_walign32( x86reg ) \
314 TEST_imm32_r32( 0x00000003, x86reg ); \
315 JNE_exc(EXC_DATA_ADDR_WRITE);
318 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
319 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
320 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
321 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
322 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
323 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
324 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
327 * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
328 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
330 #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); }
332 #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) }
334 * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
335 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
337 #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); }
339 #define MEM_READ_SIZE (CALL_FUNC1_SIZE)
340 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
341 #define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
343 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = DELAY_NONE; return 1;
345 /****** Import appropriate calling conventions ******/
346 #if SH4_TRANSLATOR == TARGET_X86_64
347 #include "sh4/ia64abi.h"
348 #else /* SH4_TRANSLATOR == TARGET_X86 */
350 #include "sh4/ia32mac.h"
352 #include "sh4/ia32abi.h"
356 uint32_t sh4_translate_end_block_size()
358 if( sh4_x86.backpatch_posn <= 3 ) {
359 return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
361 return EPILOGUE_SIZE + 48 + (sh4_x86.backpatch_posn-3)*15;
367 * Embed a breakpoint into the generated code
369 void sh4_translate_emit_breakpoint( sh4vma_t pc )
371 load_imm32( R_EAX, pc );
372 call_func1( sh4_translate_breakpoint_hit, R_EAX );
376 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
379 * Embed a call to sh4_execute_instruction for situations that we
380 * can't translate (just page-crossing delay slots at the moment).
381 * Caller is responsible for setting new_pc before calling this function.
385 * Set sh4r.in_delay_slot = sh4_x86.in_delay_slot
386 * Update slice_cycle for endpc+2 (single step doesn't update slice_cycle)
387 * Call sh4_execute_instruction
388 * Call xlat_get_code_by_vma / xlat_get_code as for normal exit
390 void exit_block_emu( sh4vma_t endpc )
392 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 5
393 ADD_r32_sh4r( R_ECX, R_PC );
395 load_imm32( R_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 5
396 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
397 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );
398 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );
400 call_func0( sh4_execute_instruction );
401 load_spreg( R_EAX, R_PC );
402 if( sh4_x86.tlb_on ) {
403 call_func1(xlat_get_code_by_vma,R_EAX);
405 call_func1(xlat_get_code,R_EAX);
407 AND_imm8s_rptr( 0xFC, R_EAX );
413 * Translate a single instruction. Delayed branches are handled specially
414 * by translating both branch and delayed instruction as a single unit (as
416 * The instruction MUST be in the icache (assert check)
418 * @return true if the instruction marks the end of a basic block
421 uint32_t sh4_translate_instruction( sh4vma_t pc )
424 /* Read instruction from icache */
425 assert( IS_IN_ICACHE(pc) );
426 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
428 /* PC is not in the current icache - this usually means we're running
429 * with MMU on, and we've gone past the end of the page. And since
430 * sh4_translate_block is pretty careful about this, it means we're
431 * almost certainly in a delay slot.
433 * Since we can't assume the page is present (and we can't fault it in
434 * at this point, inline a call to sh4_execute_instruction (with a few
435 * small repairs to cope with the different environment).
438 if( !sh4_x86.in_delay_slot ) {
439 sh4_translate_add_recovery( (pc - sh4_x86.block_start_pc)>>1 );
441 switch( (ir&0xF000) >> 12 ) {
445 switch( (ir&0x80) >> 7 ) {
447 switch( (ir&0x70) >> 4 ) {
450 uint32_t Rn = ((ir>>8)&0xF);
452 call_func0(sh4_read_sr);
453 store_reg( R_EAX, Rn );
454 sh4_x86.tstate = TSTATE_NONE;
459 uint32_t Rn = ((ir>>8)&0xF);
460 load_spreg( R_EAX, R_GBR );
461 store_reg( R_EAX, Rn );
466 uint32_t Rn = ((ir>>8)&0xF);
468 load_spreg( R_EAX, R_VBR );
469 store_reg( R_EAX, Rn );
470 sh4_x86.tstate = TSTATE_NONE;
475 uint32_t Rn = ((ir>>8)&0xF);
477 load_spreg( R_EAX, R_SSR );
478 store_reg( R_EAX, Rn );
479 sh4_x86.tstate = TSTATE_NONE;
484 uint32_t Rn = ((ir>>8)&0xF);
486 load_spreg( R_EAX, R_SPC );
487 store_reg( R_EAX, Rn );
488 sh4_x86.tstate = TSTATE_NONE;
497 { /* STC Rm_BANK, Rn */
498 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
500 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
501 store_reg( R_EAX, Rn );
502 sh4_x86.tstate = TSTATE_NONE;
508 switch( (ir&0xF0) >> 4 ) {
511 uint32_t Rn = ((ir>>8)&0xF);
512 if( sh4_x86.in_delay_slot ) {
515 load_spreg( R_EAX, R_PC );
516 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
517 store_spreg( R_EAX, R_PR );
518 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
519 store_spreg( R_EAX, R_NEW_PC );
521 sh4_x86.in_delay_slot = DELAY_PC;
522 sh4_x86.tstate = TSTATE_NONE;
523 sh4_x86.branch_taken = TRUE;
524 if( UNTRANSLATABLE(pc+2) ) {
525 exit_block_emu(pc+2);
528 sh4_translate_instruction( pc + 2 );
529 exit_block_newpcset(pc+2);
537 uint32_t Rn = ((ir>>8)&0xF);
538 if( sh4_x86.in_delay_slot ) {
541 load_spreg( R_EAX, R_PC );
542 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
543 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
544 store_spreg( R_EAX, R_NEW_PC );
545 sh4_x86.in_delay_slot = DELAY_PC;
546 sh4_x86.tstate = TSTATE_NONE;
547 sh4_x86.branch_taken = TRUE;
548 if( UNTRANSLATABLE(pc+2) ) {
549 exit_block_emu(pc+2);
552 sh4_translate_instruction( pc + 2 );
553 exit_block_newpcset(pc+2);
561 uint32_t Rn = ((ir>>8)&0xF);
562 load_reg( R_EAX, Rn );
563 MOV_r32_r32( R_EAX, R_ECX );
564 AND_imm32_r32( 0xFC000000, R_EAX );
565 CMP_imm32_r32( 0xE0000000, R_EAX );
566 JNE_rel8(8+CALL_FUNC1_SIZE, end);
567 call_func1( sh4_flush_store_queue, R_ECX );
568 TEST_r32_r32( R_EAX, R_EAX );
571 sh4_x86.tstate = TSTATE_NONE;
576 uint32_t Rn = ((ir>>8)&0xF);
581 uint32_t Rn = ((ir>>8)&0xF);
586 uint32_t Rn = ((ir>>8)&0xF);
590 { /* MOVCA.L R0, @Rn */
591 uint32_t Rn = ((ir>>8)&0xF);
592 load_reg( R_EAX, Rn );
593 check_walign32( R_EAX );
594 MMU_TRANSLATE_WRITE( R_EAX );
595 load_reg( R_EDX, 0 );
596 MEM_WRITE_LONG( R_EAX, R_EDX );
597 sh4_x86.tstate = TSTATE_NONE;
606 { /* MOV.B Rm, @(R0, Rn) */
607 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
608 load_reg( R_EAX, 0 );
609 load_reg( R_ECX, Rn );
610 ADD_r32_r32( R_ECX, R_EAX );
611 MMU_TRANSLATE_WRITE( R_EAX );
612 load_reg( R_EDX, Rm );
613 MEM_WRITE_BYTE( R_EAX, R_EDX );
614 sh4_x86.tstate = TSTATE_NONE;
618 { /* MOV.W Rm, @(R0, Rn) */
619 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
620 load_reg( R_EAX, 0 );
621 load_reg( R_ECX, Rn );
622 ADD_r32_r32( R_ECX, R_EAX );
623 check_walign16( R_EAX );
624 MMU_TRANSLATE_WRITE( R_EAX );
625 load_reg( R_EDX, Rm );
626 MEM_WRITE_WORD( R_EAX, R_EDX );
627 sh4_x86.tstate = TSTATE_NONE;
631 { /* MOV.L Rm, @(R0, Rn) */
632 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
633 load_reg( R_EAX, 0 );
634 load_reg( R_ECX, Rn );
635 ADD_r32_r32( R_ECX, R_EAX );
636 check_walign32( R_EAX );
637 MMU_TRANSLATE_WRITE( R_EAX );
638 load_reg( R_EDX, Rm );
639 MEM_WRITE_LONG( R_EAX, R_EDX );
640 sh4_x86.tstate = TSTATE_NONE;
645 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
646 load_reg( R_EAX, Rm );
647 load_reg( R_ECX, Rn );
649 store_spreg( R_EAX, R_MACL );
650 sh4_x86.tstate = TSTATE_NONE;
654 switch( (ir&0xFF0) >> 4 ) {
659 sh4_x86.tstate = TSTATE_C;
666 sh4_x86.tstate = TSTATE_C;
671 XOR_r32_r32(R_EAX, R_EAX);
672 store_spreg( R_EAX, R_MACL );
673 store_spreg( R_EAX, R_MACH );
674 sh4_x86.tstate = TSTATE_NONE;
679 call_func0( MMU_ldtlb );
686 sh4_x86.tstate = TSTATE_C;
693 sh4_x86.tstate = TSTATE_C;
702 switch( (ir&0xF0) >> 4 ) {
705 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
710 XOR_r32_r32( R_EAX, R_EAX );
711 store_spreg( R_EAX, R_Q );
712 store_spreg( R_EAX, R_M );
713 store_spreg( R_EAX, R_T );
714 sh4_x86.tstate = TSTATE_C; // works for DIV1
719 uint32_t Rn = ((ir>>8)&0xF);
720 load_spreg( R_EAX, R_T );
721 store_reg( R_EAX, Rn );
730 switch( (ir&0xF0) >> 4 ) {
733 uint32_t Rn = ((ir>>8)&0xF);
734 load_spreg( R_EAX, R_MACH );
735 store_reg( R_EAX, Rn );
740 uint32_t Rn = ((ir>>8)&0xF);
741 load_spreg( R_EAX, R_MACL );
742 store_reg( R_EAX, Rn );
747 uint32_t Rn = ((ir>>8)&0xF);
748 load_spreg( R_EAX, R_PR );
749 store_reg( R_EAX, Rn );
754 uint32_t Rn = ((ir>>8)&0xF);
756 load_spreg( R_EAX, R_SGR );
757 store_reg( R_EAX, Rn );
758 sh4_x86.tstate = TSTATE_NONE;
763 uint32_t Rn = ((ir>>8)&0xF);
765 load_spreg( R_EAX, R_FPUL );
766 store_reg( R_EAX, Rn );
770 { /* STS FPSCR, Rn */
771 uint32_t Rn = ((ir>>8)&0xF);
773 load_spreg( R_EAX, R_FPSCR );
774 store_reg( R_EAX, Rn );
779 uint32_t Rn = ((ir>>8)&0xF);
781 load_spreg( R_EAX, R_DBR );
782 store_reg( R_EAX, Rn );
783 sh4_x86.tstate = TSTATE_NONE;
792 switch( (ir&0xFF0) >> 4 ) {
795 if( sh4_x86.in_delay_slot ) {
798 load_spreg( R_ECX, R_PR );
799 store_spreg( R_ECX, R_NEW_PC );
800 sh4_x86.in_delay_slot = DELAY_PC;
801 sh4_x86.branch_taken = TRUE;
802 if( UNTRANSLATABLE(pc+2) ) {
803 exit_block_emu(pc+2);
806 sh4_translate_instruction(pc+2);
807 exit_block_newpcset(pc+2);
816 call_func0( sh4_sleep );
817 sh4_x86.tstate = TSTATE_NONE;
818 sh4_x86.in_delay_slot = DELAY_NONE;
824 if( sh4_x86.in_delay_slot ) {
828 load_spreg( R_ECX, R_SPC );
829 store_spreg( R_ECX, R_NEW_PC );
830 load_spreg( R_EAX, R_SSR );
831 call_func1( sh4_write_sr, R_EAX );
832 sh4_x86.in_delay_slot = DELAY_PC;
833 sh4_x86.priv_checked = FALSE;
834 sh4_x86.fpuen_checked = FALSE;
835 sh4_x86.tstate = TSTATE_NONE;
836 sh4_x86.branch_taken = TRUE;
837 if( UNTRANSLATABLE(pc+2) ) {
838 exit_block_emu(pc+2);
841 sh4_translate_instruction(pc+2);
842 exit_block_newpcset(pc+2);
854 { /* MOV.B @(R0, Rm), Rn */
855 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
856 load_reg( R_EAX, 0 );
857 load_reg( R_ECX, Rm );
858 ADD_r32_r32( R_ECX, R_EAX );
859 MMU_TRANSLATE_READ( R_EAX )
860 MEM_READ_BYTE( R_EAX, R_EAX );
861 store_reg( R_EAX, Rn );
862 sh4_x86.tstate = TSTATE_NONE;
866 { /* MOV.W @(R0, Rm), Rn */
867 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
868 load_reg( R_EAX, 0 );
869 load_reg( R_ECX, Rm );
870 ADD_r32_r32( R_ECX, R_EAX );
871 check_ralign16( R_EAX );
872 MMU_TRANSLATE_READ( R_EAX );
873 MEM_READ_WORD( R_EAX, R_EAX );
874 store_reg( R_EAX, Rn );
875 sh4_x86.tstate = TSTATE_NONE;
879 { /* MOV.L @(R0, Rm), Rn */
880 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
881 load_reg( R_EAX, 0 );
882 load_reg( R_ECX, Rm );
883 ADD_r32_r32( R_ECX, R_EAX );
884 check_ralign32( R_EAX );
885 MMU_TRANSLATE_READ( R_EAX );
886 MEM_READ_LONG( R_EAX, R_EAX );
887 store_reg( R_EAX, Rn );
888 sh4_x86.tstate = TSTATE_NONE;
892 { /* MAC.L @Rm+, @Rn+ */
893 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
895 load_reg( R_EAX, Rm );
896 check_ralign32( R_EAX );
897 MMU_TRANSLATE_READ( R_EAX );
898 PUSH_realigned_r32( R_EAX );
899 load_reg( R_EAX, Rn );
900 ADD_imm8s_r32( 4, R_EAX );
901 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
902 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
903 // Note translate twice in case of page boundaries. Maybe worth
904 // adding a page-boundary check to skip the second translation
906 load_reg( R_EAX, Rm );
907 check_ralign32( R_EAX );
908 MMU_TRANSLATE_READ( R_EAX );
909 load_reg( R_ECX, Rn );
910 check_ralign32( R_ECX );
911 PUSH_realigned_r32( R_EAX );
912 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
913 MOV_r32_r32( R_ECX, R_EAX );
914 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
915 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
917 MEM_READ_LONG( R_EAX, R_EAX );
920 MEM_READ_LONG( R_ECX, R_EAX );
921 POP_realigned_r32( R_ECX );
924 ADD_r32_sh4r( R_EAX, R_MACL );
925 ADC_r32_sh4r( R_EDX, R_MACH );
927 load_spreg( R_ECX, R_S );
928 TEST_r32_r32(R_ECX, R_ECX);
929 JE_rel8( CALL_FUNC0_SIZE, nosat );
930 call_func0( signsat48 );
932 sh4_x86.tstate = TSTATE_NONE;
941 { /* MOV.L Rm, @(disp, Rn) */
942 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
943 load_reg( R_EAX, Rn );
944 ADD_imm32_r32( disp, R_EAX );
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;
955 { /* MOV.B Rm, @Rn */
956 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
957 load_reg( R_EAX, Rn );
958 MMU_TRANSLATE_WRITE( R_EAX );
959 load_reg( R_EDX, Rm );
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 check_walign16( R_EAX );
969 MMU_TRANSLATE_WRITE( R_EAX )
970 load_reg( R_EDX, Rm );
971 MEM_WRITE_WORD( R_EAX, R_EDX );
972 sh4_x86.tstate = TSTATE_NONE;
976 { /* MOV.L Rm, @Rn */
977 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
978 load_reg( R_EAX, Rn );
979 check_walign32(R_EAX);
980 MMU_TRANSLATE_WRITE( R_EAX );
981 load_reg( R_EDX, Rm );
982 MEM_WRITE_LONG( R_EAX, R_EDX );
983 sh4_x86.tstate = TSTATE_NONE;
987 { /* MOV.B Rm, @-Rn */
988 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
989 load_reg( R_EAX, Rn );
990 ADD_imm8s_r32( -1, R_EAX );
991 MMU_TRANSLATE_WRITE( R_EAX );
992 load_reg( R_EDX, Rm );
993 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
994 MEM_WRITE_BYTE( R_EAX, R_EDX );
995 sh4_x86.tstate = TSTATE_NONE;
999 { /* MOV.W Rm, @-Rn */
1000 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1001 load_reg( R_EAX, Rn );
1002 ADD_imm8s_r32( -2, R_EAX );
1003 check_walign16( R_EAX );
1004 MMU_TRANSLATE_WRITE( R_EAX );
1005 load_reg( R_EDX, Rm );
1006 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
1007 MEM_WRITE_WORD( R_EAX, R_EDX );
1008 sh4_x86.tstate = TSTATE_NONE;
1012 { /* MOV.L Rm, @-Rn */
1013 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1014 load_reg( R_EAX, Rn );
1015 ADD_imm8s_r32( -4, R_EAX );
1016 check_walign32( R_EAX );
1017 MMU_TRANSLATE_WRITE( R_EAX );
1018 load_reg( R_EDX, Rm );
1019 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1020 MEM_WRITE_LONG( R_EAX, R_EDX );
1021 sh4_x86.tstate = TSTATE_NONE;
1025 { /* DIV0S 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 SHR_imm8_r32( 31, R_EAX );
1030 SHR_imm8_r32( 31, R_ECX );
1031 store_spreg( R_EAX, R_M );
1032 store_spreg( R_ECX, R_Q );
1033 CMP_r32_r32( R_EAX, R_ECX );
1035 sh4_x86.tstate = TSTATE_NE;
1040 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1041 load_reg( R_EAX, Rm );
1042 load_reg( R_ECX, Rn );
1043 TEST_r32_r32( R_EAX, R_ECX );
1045 sh4_x86.tstate = TSTATE_E;
1050 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1051 load_reg( R_EAX, Rm );
1052 load_reg( R_ECX, Rn );
1053 AND_r32_r32( R_EAX, R_ECX );
1054 store_reg( R_ECX, Rn );
1055 sh4_x86.tstate = TSTATE_NONE;
1060 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1061 load_reg( R_EAX, Rm );
1062 load_reg( R_ECX, Rn );
1063 XOR_r32_r32( R_EAX, R_ECX );
1064 store_reg( R_ECX, Rn );
1065 sh4_x86.tstate = TSTATE_NONE;
1070 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1071 load_reg( R_EAX, Rm );
1072 load_reg( R_ECX, Rn );
1073 OR_r32_r32( R_EAX, R_ECX );
1074 store_reg( R_ECX, Rn );
1075 sh4_x86.tstate = TSTATE_NONE;
1079 { /* CMP/STR Rm, Rn */
1080 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1081 load_reg( R_EAX, Rm );
1082 load_reg( R_ECX, Rn );
1083 XOR_r32_r32( R_ECX, R_EAX );
1084 TEST_r8_r8( R_AL, R_AL );
1085 JE_rel8(13, target1);
1086 TEST_r8_r8( R_AH, R_AH ); // 2
1087 JE_rel8(9, target2);
1088 SHR_imm8_r32( 16, R_EAX ); // 3
1089 TEST_r8_r8( R_AL, R_AL ); // 2
1090 JE_rel8(2, target3);
1091 TEST_r8_r8( R_AH, R_AH ); // 2
1092 JMP_TARGET(target1);
1093 JMP_TARGET(target2);
1094 JMP_TARGET(target3);
1096 sh4_x86.tstate = TSTATE_E;
1100 { /* XTRCT Rm, Rn */
1101 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1102 load_reg( R_EAX, Rm );
1103 load_reg( R_ECX, Rn );
1104 SHL_imm8_r32( 16, R_EAX );
1105 SHR_imm8_r32( 16, R_ECX );
1106 OR_r32_r32( R_EAX, R_ECX );
1107 store_reg( R_ECX, Rn );
1108 sh4_x86.tstate = TSTATE_NONE;
1112 { /* MULU.W Rm, Rn */
1113 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1114 load_reg16u( R_EAX, Rm );
1115 load_reg16u( R_ECX, Rn );
1117 store_spreg( R_EAX, R_MACL );
1118 sh4_x86.tstate = TSTATE_NONE;
1122 { /* MULS.W Rm, Rn */
1123 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1124 load_reg16s( R_EAX, Rm );
1125 load_reg16s( R_ECX, Rn );
1127 store_spreg( R_EAX, R_MACL );
1128 sh4_x86.tstate = TSTATE_NONE;
1139 { /* CMP/EQ 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 );
1143 CMP_r32_r32( R_EAX, R_ECX );
1145 sh4_x86.tstate = TSTATE_E;
1149 { /* CMP/HS Rm, Rn */
1150 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1151 load_reg( R_EAX, Rm );
1152 load_reg( R_ECX, Rn );
1153 CMP_r32_r32( R_EAX, R_ECX );
1155 sh4_x86.tstate = TSTATE_AE;
1159 { /* CMP/GE Rm, Rn */
1160 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1161 load_reg( R_EAX, Rm );
1162 load_reg( R_ECX, Rn );
1163 CMP_r32_r32( R_EAX, R_ECX );
1165 sh4_x86.tstate = TSTATE_GE;
1170 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1171 load_spreg( R_ECX, R_M );
1172 load_reg( R_EAX, Rn );
1173 if( sh4_x86.tstate != TSTATE_C ) {
1177 SETC_r8( R_DL ); // Q'
1178 CMP_sh4r_r32( R_Q, R_ECX );
1179 JE_rel8(5, mqequal);
1180 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1182 JMP_TARGET(mqequal);
1183 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1185 store_reg( R_EAX, Rn ); // Done with Rn now
1186 SETC_r8(R_AL); // tmp1
1187 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1188 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1189 store_spreg( R_ECX, R_Q );
1190 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1191 MOVZX_r8_r32( R_AL, R_EAX );
1192 store_spreg( R_EAX, R_T );
1193 sh4_x86.tstate = TSTATE_NONE;
1197 { /* DMULU.L Rm, Rn */
1198 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1199 load_reg( R_EAX, Rm );
1200 load_reg( R_ECX, Rn );
1202 store_spreg( R_EDX, R_MACH );
1203 store_spreg( R_EAX, R_MACL );
1204 sh4_x86.tstate = TSTATE_NONE;
1208 { /* CMP/HI Rm, Rn */
1209 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1210 load_reg( R_EAX, Rm );
1211 load_reg( R_ECX, Rn );
1212 CMP_r32_r32( R_EAX, R_ECX );
1214 sh4_x86.tstate = TSTATE_A;
1218 { /* CMP/GT Rm, Rn */
1219 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1220 load_reg( R_EAX, Rm );
1221 load_reg( R_ECX, Rn );
1222 CMP_r32_r32( R_EAX, R_ECX );
1224 sh4_x86.tstate = TSTATE_G;
1229 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1230 load_reg( R_EAX, Rm );
1231 load_reg( R_ECX, Rn );
1232 SUB_r32_r32( R_EAX, R_ECX );
1233 store_reg( R_ECX, Rn );
1234 sh4_x86.tstate = TSTATE_NONE;
1239 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1240 load_reg( R_EAX, Rm );
1241 load_reg( R_ECX, Rn );
1242 if( sh4_x86.tstate != TSTATE_C ) {
1245 SBB_r32_r32( R_EAX, R_ECX );
1246 store_reg( R_ECX, Rn );
1248 sh4_x86.tstate = TSTATE_C;
1253 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1254 load_reg( R_EAX, Rm );
1255 load_reg( R_ECX, Rn );
1256 SUB_r32_r32( R_EAX, R_ECX );
1257 store_reg( R_ECX, Rn );
1259 sh4_x86.tstate = TSTATE_O;
1264 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1265 load_reg( R_EAX, Rm );
1266 load_reg( R_ECX, Rn );
1267 ADD_r32_r32( R_EAX, R_ECX );
1268 store_reg( R_ECX, Rn );
1269 sh4_x86.tstate = TSTATE_NONE;
1273 { /* DMULS.L Rm, Rn */
1274 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1275 load_reg( R_EAX, Rm );
1276 load_reg( R_ECX, Rn );
1278 store_spreg( R_EDX, R_MACH );
1279 store_spreg( R_EAX, R_MACL );
1280 sh4_x86.tstate = TSTATE_NONE;
1285 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1286 if( sh4_x86.tstate != TSTATE_C ) {
1289 load_reg( R_EAX, Rm );
1290 load_reg( R_ECX, Rn );
1291 ADC_r32_r32( R_EAX, R_ECX );
1292 store_reg( R_ECX, Rn );
1294 sh4_x86.tstate = TSTATE_C;
1299 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1300 load_reg( R_EAX, Rm );
1301 load_reg( R_ECX, Rn );
1302 ADD_r32_r32( R_EAX, R_ECX );
1303 store_reg( R_ECX, Rn );
1305 sh4_x86.tstate = TSTATE_O;
1316 switch( (ir&0xF0) >> 4 ) {
1319 uint32_t Rn = ((ir>>8)&0xF);
1320 load_reg( R_EAX, Rn );
1323 store_reg( R_EAX, Rn );
1324 sh4_x86.tstate = TSTATE_C;
1329 uint32_t Rn = ((ir>>8)&0xF);
1330 load_reg( R_EAX, Rn );
1331 ADD_imm8s_r32( -1, R_EAX );
1332 store_reg( R_EAX, Rn );
1334 sh4_x86.tstate = TSTATE_E;
1339 uint32_t Rn = ((ir>>8)&0xF);
1340 load_reg( R_EAX, Rn );
1343 store_reg( R_EAX, Rn );
1344 sh4_x86.tstate = TSTATE_C;
1353 switch( (ir&0xF0) >> 4 ) {
1356 uint32_t Rn = ((ir>>8)&0xF);
1357 load_reg( R_EAX, Rn );
1360 store_reg( R_EAX, Rn );
1361 sh4_x86.tstate = TSTATE_C;
1366 uint32_t Rn = ((ir>>8)&0xF);
1367 load_reg( R_EAX, Rn );
1368 CMP_imm8s_r32( 0, R_EAX );
1370 sh4_x86.tstate = TSTATE_GE;
1375 uint32_t Rn = ((ir>>8)&0xF);
1376 load_reg( R_EAX, Rn );
1379 store_reg( R_EAX, Rn );
1380 sh4_x86.tstate = TSTATE_C;
1389 switch( (ir&0xF0) >> 4 ) {
1391 { /* STS.L MACH, @-Rn */
1392 uint32_t Rn = ((ir>>8)&0xF);
1393 load_reg( R_EAX, Rn );
1394 check_walign32( R_EAX );
1395 ADD_imm8s_r32( -4, R_EAX );
1396 MMU_TRANSLATE_WRITE( R_EAX );
1397 load_spreg( R_EDX, R_MACH );
1398 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1399 MEM_WRITE_LONG( R_EAX, R_EDX );
1400 sh4_x86.tstate = TSTATE_NONE;
1404 { /* STS.L MACL, @-Rn */
1405 uint32_t Rn = ((ir>>8)&0xF);
1406 load_reg( R_EAX, Rn );
1407 check_walign32( R_EAX );
1408 ADD_imm8s_r32( -4, R_EAX );
1409 MMU_TRANSLATE_WRITE( R_EAX );
1410 load_spreg( R_EDX, R_MACL );
1411 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1412 MEM_WRITE_LONG( R_EAX, R_EDX );
1413 sh4_x86.tstate = TSTATE_NONE;
1417 { /* STS.L PR, @-Rn */
1418 uint32_t Rn = ((ir>>8)&0xF);
1419 load_reg( R_EAX, Rn );
1420 check_walign32( R_EAX );
1421 ADD_imm8s_r32( -4, R_EAX );
1422 MMU_TRANSLATE_WRITE( R_EAX );
1423 load_spreg( R_EDX, R_PR );
1424 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1425 MEM_WRITE_LONG( R_EAX, R_EDX );
1426 sh4_x86.tstate = TSTATE_NONE;
1430 { /* STC.L SGR, @-Rn */
1431 uint32_t Rn = ((ir>>8)&0xF);
1433 load_reg( R_EAX, Rn );
1434 check_walign32( R_EAX );
1435 ADD_imm8s_r32( -4, R_EAX );
1436 MMU_TRANSLATE_WRITE( R_EAX );
1437 load_spreg( R_EDX, R_SGR );
1438 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1439 MEM_WRITE_LONG( R_EAX, R_EDX );
1440 sh4_x86.tstate = TSTATE_NONE;
1444 { /* STS.L FPUL, @-Rn */
1445 uint32_t Rn = ((ir>>8)&0xF);
1447 load_reg( R_EAX, Rn );
1448 check_walign32( R_EAX );
1449 ADD_imm8s_r32( -4, R_EAX );
1450 MMU_TRANSLATE_WRITE( R_EAX );
1451 load_spreg( R_EDX, R_FPUL );
1452 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1453 MEM_WRITE_LONG( R_EAX, R_EDX );
1454 sh4_x86.tstate = TSTATE_NONE;
1458 { /* STS.L FPSCR, @-Rn */
1459 uint32_t Rn = ((ir>>8)&0xF);
1461 load_reg( R_EAX, Rn );
1462 check_walign32( R_EAX );
1463 ADD_imm8s_r32( -4, R_EAX );
1464 MMU_TRANSLATE_WRITE( R_EAX );
1465 load_spreg( R_EDX, R_FPSCR );
1466 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1467 MEM_WRITE_LONG( R_EAX, R_EDX );
1468 sh4_x86.tstate = TSTATE_NONE;
1472 { /* STC.L DBR, @-Rn */
1473 uint32_t Rn = ((ir>>8)&0xF);
1475 load_reg( R_EAX, Rn );
1476 check_walign32( R_EAX );
1477 ADD_imm8s_r32( -4, R_EAX );
1478 MMU_TRANSLATE_WRITE( R_EAX );
1479 load_spreg( R_EDX, R_DBR );
1480 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1481 MEM_WRITE_LONG( R_EAX, R_EDX );
1482 sh4_x86.tstate = TSTATE_NONE;
1491 switch( (ir&0x80) >> 7 ) {
1493 switch( (ir&0x70) >> 4 ) {
1495 { /* STC.L SR, @-Rn */
1496 uint32_t Rn = ((ir>>8)&0xF);
1498 load_reg( R_EAX, Rn );
1499 check_walign32( R_EAX );
1500 ADD_imm8s_r32( -4, R_EAX );
1501 MMU_TRANSLATE_WRITE( R_EAX );
1502 PUSH_realigned_r32( R_EAX );
1503 call_func0( sh4_read_sr );
1504 POP_realigned_r32( R_ECX );
1505 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1506 MEM_WRITE_LONG( R_ECX, R_EAX );
1507 sh4_x86.tstate = TSTATE_NONE;
1511 { /* STC.L GBR, @-Rn */
1512 uint32_t Rn = ((ir>>8)&0xF);
1513 load_reg( R_EAX, Rn );
1514 check_walign32( R_EAX );
1515 ADD_imm8s_r32( -4, R_EAX );
1516 MMU_TRANSLATE_WRITE( R_EAX );
1517 load_spreg( R_EDX, R_GBR );
1518 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1519 MEM_WRITE_LONG( R_EAX, R_EDX );
1520 sh4_x86.tstate = TSTATE_NONE;
1524 { /* STC.L VBR, @-Rn */
1525 uint32_t Rn = ((ir>>8)&0xF);
1527 load_reg( R_EAX, Rn );
1528 check_walign32( R_EAX );
1529 ADD_imm8s_r32( -4, R_EAX );
1530 MMU_TRANSLATE_WRITE( R_EAX );
1531 load_spreg( R_EDX, R_VBR );
1532 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1533 MEM_WRITE_LONG( R_EAX, R_EDX );
1534 sh4_x86.tstate = TSTATE_NONE;
1538 { /* STC.L SSR, @-Rn */
1539 uint32_t Rn = ((ir>>8)&0xF);
1541 load_reg( R_EAX, Rn );
1542 check_walign32( R_EAX );
1543 ADD_imm8s_r32( -4, R_EAX );
1544 MMU_TRANSLATE_WRITE( R_EAX );
1545 load_spreg( R_EDX, R_SSR );
1546 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1547 MEM_WRITE_LONG( R_EAX, R_EDX );
1548 sh4_x86.tstate = TSTATE_NONE;
1552 { /* STC.L SPC, @-Rn */
1553 uint32_t Rn = ((ir>>8)&0xF);
1555 load_reg( R_EAX, Rn );
1556 check_walign32( R_EAX );
1557 ADD_imm8s_r32( -4, R_EAX );
1558 MMU_TRANSLATE_WRITE( R_EAX );
1559 load_spreg( R_EDX, R_SPC );
1560 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1561 MEM_WRITE_LONG( R_EAX, R_EDX );
1562 sh4_x86.tstate = TSTATE_NONE;
1571 { /* STC.L Rm_BANK, @-Rn */
1572 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1574 load_reg( R_EAX, Rn );
1575 check_walign32( R_EAX );
1576 ADD_imm8s_r32( -4, R_EAX );
1577 MMU_TRANSLATE_WRITE( R_EAX );
1578 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1579 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1580 MEM_WRITE_LONG( R_EAX, R_EDX );
1581 sh4_x86.tstate = TSTATE_NONE;
1587 switch( (ir&0xF0) >> 4 ) {
1590 uint32_t Rn = ((ir>>8)&0xF);
1591 load_reg( R_EAX, Rn );
1593 store_reg( R_EAX, Rn );
1595 sh4_x86.tstate = TSTATE_C;
1600 uint32_t Rn = ((ir>>8)&0xF);
1601 load_reg( R_EAX, Rn );
1602 if( sh4_x86.tstate != TSTATE_C ) {
1606 store_reg( R_EAX, Rn );
1608 sh4_x86.tstate = TSTATE_C;
1617 switch( (ir&0xF0) >> 4 ) {
1620 uint32_t Rn = ((ir>>8)&0xF);
1621 load_reg( R_EAX, Rn );
1623 store_reg( R_EAX, Rn );
1625 sh4_x86.tstate = TSTATE_C;
1630 uint32_t Rn = ((ir>>8)&0xF);
1631 load_reg( R_EAX, Rn );
1632 CMP_imm8s_r32( 0, R_EAX );
1634 sh4_x86.tstate = TSTATE_G;
1639 uint32_t Rn = ((ir>>8)&0xF);
1640 load_reg( R_EAX, Rn );
1641 if( sh4_x86.tstate != TSTATE_C ) {
1645 store_reg( R_EAX, Rn );
1647 sh4_x86.tstate = TSTATE_C;
1656 switch( (ir&0xF0) >> 4 ) {
1658 { /* LDS.L @Rm+, MACH */
1659 uint32_t Rm = ((ir>>8)&0xF);
1660 load_reg( R_EAX, Rm );
1661 check_ralign32( R_EAX );
1662 MMU_TRANSLATE_READ( R_EAX );
1663 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1664 MEM_READ_LONG( R_EAX, R_EAX );
1665 store_spreg( R_EAX, R_MACH );
1666 sh4_x86.tstate = TSTATE_NONE;
1670 { /* LDS.L @Rm+, MACL */
1671 uint32_t Rm = ((ir>>8)&0xF);
1672 load_reg( R_EAX, Rm );
1673 check_ralign32( R_EAX );
1674 MMU_TRANSLATE_READ( R_EAX );
1675 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1676 MEM_READ_LONG( R_EAX, R_EAX );
1677 store_spreg( R_EAX, R_MACL );
1678 sh4_x86.tstate = TSTATE_NONE;
1682 { /* LDS.L @Rm+, PR */
1683 uint32_t Rm = ((ir>>8)&0xF);
1684 load_reg( R_EAX, Rm );
1685 check_ralign32( R_EAX );
1686 MMU_TRANSLATE_READ( R_EAX );
1687 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1688 MEM_READ_LONG( R_EAX, R_EAX );
1689 store_spreg( R_EAX, R_PR );
1690 sh4_x86.tstate = TSTATE_NONE;
1694 { /* LDC.L @Rm+, SGR */
1695 uint32_t Rm = ((ir>>8)&0xF);
1697 load_reg( R_EAX, Rm );
1698 check_ralign32( R_EAX );
1699 MMU_TRANSLATE_READ( R_EAX );
1700 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1701 MEM_READ_LONG( R_EAX, R_EAX );
1702 store_spreg( R_EAX, R_SGR );
1703 sh4_x86.tstate = TSTATE_NONE;
1707 { /* LDS.L @Rm+, FPUL */
1708 uint32_t Rm = ((ir>>8)&0xF);
1710 load_reg( R_EAX, Rm );
1711 check_ralign32( R_EAX );
1712 MMU_TRANSLATE_READ( R_EAX );
1713 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1714 MEM_READ_LONG( R_EAX, R_EAX );
1715 store_spreg( R_EAX, R_FPUL );
1716 sh4_x86.tstate = TSTATE_NONE;
1720 { /* LDS.L @Rm+, FPSCR */
1721 uint32_t Rm = ((ir>>8)&0xF);
1723 load_reg( R_EAX, Rm );
1724 check_ralign32( R_EAX );
1725 MMU_TRANSLATE_READ( R_EAX );
1726 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1727 MEM_READ_LONG( R_EAX, R_EAX );
1728 store_spreg( R_EAX, R_FPSCR );
1729 update_fr_bank( R_EAX );
1730 sh4_x86.tstate = TSTATE_NONE;
1734 { /* LDC.L @Rm+, DBR */
1735 uint32_t Rm = ((ir>>8)&0xF);
1737 load_reg( R_EAX, Rm );
1738 check_ralign32( R_EAX );
1739 MMU_TRANSLATE_READ( R_EAX );
1740 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1741 MEM_READ_LONG( R_EAX, R_EAX );
1742 store_spreg( R_EAX, R_DBR );
1743 sh4_x86.tstate = TSTATE_NONE;
1752 switch( (ir&0x80) >> 7 ) {
1754 switch( (ir&0x70) >> 4 ) {
1756 { /* LDC.L @Rm+, SR */
1757 uint32_t Rm = ((ir>>8)&0xF);
1758 if( sh4_x86.in_delay_slot ) {
1762 load_reg( R_EAX, Rm );
1763 check_ralign32( R_EAX );
1764 MMU_TRANSLATE_READ( R_EAX );
1765 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1766 MEM_READ_LONG( R_EAX, R_EAX );
1767 call_func1( sh4_write_sr, R_EAX );
1768 sh4_x86.priv_checked = FALSE;
1769 sh4_x86.fpuen_checked = FALSE;
1770 sh4_x86.tstate = TSTATE_NONE;
1775 { /* LDC.L @Rm+, GBR */
1776 uint32_t Rm = ((ir>>8)&0xF);
1777 load_reg( R_EAX, Rm );
1778 check_ralign32( R_EAX );
1779 MMU_TRANSLATE_READ( R_EAX );
1780 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1781 MEM_READ_LONG( R_EAX, R_EAX );
1782 store_spreg( R_EAX, R_GBR );
1783 sh4_x86.tstate = TSTATE_NONE;
1787 { /* LDC.L @Rm+, VBR */
1788 uint32_t Rm = ((ir>>8)&0xF);
1790 load_reg( R_EAX, Rm );
1791 check_ralign32( R_EAX );
1792 MMU_TRANSLATE_READ( R_EAX );
1793 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1794 MEM_READ_LONG( R_EAX, R_EAX );
1795 store_spreg( R_EAX, R_VBR );
1796 sh4_x86.tstate = TSTATE_NONE;
1800 { /* LDC.L @Rm+, SSR */
1801 uint32_t Rm = ((ir>>8)&0xF);
1803 load_reg( R_EAX, Rm );
1804 check_ralign32( R_EAX );
1805 MMU_TRANSLATE_READ( R_EAX );
1806 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1807 MEM_READ_LONG( R_EAX, R_EAX );
1808 store_spreg( R_EAX, R_SSR );
1809 sh4_x86.tstate = TSTATE_NONE;
1813 { /* LDC.L @Rm+, SPC */
1814 uint32_t Rm = ((ir>>8)&0xF);
1816 load_reg( R_EAX, Rm );
1817 check_ralign32( R_EAX );
1818 MMU_TRANSLATE_READ( R_EAX );
1819 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1820 MEM_READ_LONG( R_EAX, R_EAX );
1821 store_spreg( R_EAX, R_SPC );
1822 sh4_x86.tstate = TSTATE_NONE;
1831 { /* LDC.L @Rm+, Rn_BANK */
1832 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1834 load_reg( R_EAX, Rm );
1835 check_ralign32( R_EAX );
1836 MMU_TRANSLATE_READ( R_EAX );
1837 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1838 MEM_READ_LONG( R_EAX, R_EAX );
1839 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1840 sh4_x86.tstate = TSTATE_NONE;
1846 switch( (ir&0xF0) >> 4 ) {
1849 uint32_t Rn = ((ir>>8)&0xF);
1850 load_reg( R_EAX, Rn );
1851 SHL_imm8_r32( 2, R_EAX );
1852 store_reg( R_EAX, Rn );
1853 sh4_x86.tstate = TSTATE_NONE;
1858 uint32_t Rn = ((ir>>8)&0xF);
1859 load_reg( R_EAX, Rn );
1860 SHL_imm8_r32( 8, R_EAX );
1861 store_reg( R_EAX, Rn );
1862 sh4_x86.tstate = TSTATE_NONE;
1867 uint32_t Rn = ((ir>>8)&0xF);
1868 load_reg( R_EAX, Rn );
1869 SHL_imm8_r32( 16, R_EAX );
1870 store_reg( R_EAX, Rn );
1871 sh4_x86.tstate = TSTATE_NONE;
1880 switch( (ir&0xF0) >> 4 ) {
1883 uint32_t Rn = ((ir>>8)&0xF);
1884 load_reg( R_EAX, Rn );
1885 SHR_imm8_r32( 2, R_EAX );
1886 store_reg( R_EAX, Rn );
1887 sh4_x86.tstate = TSTATE_NONE;
1892 uint32_t Rn = ((ir>>8)&0xF);
1893 load_reg( R_EAX, Rn );
1894 SHR_imm8_r32( 8, R_EAX );
1895 store_reg( R_EAX, Rn );
1896 sh4_x86.tstate = TSTATE_NONE;
1901 uint32_t Rn = ((ir>>8)&0xF);
1902 load_reg( R_EAX, Rn );
1903 SHR_imm8_r32( 16, R_EAX );
1904 store_reg( R_EAX, Rn );
1905 sh4_x86.tstate = TSTATE_NONE;
1914 switch( (ir&0xF0) >> 4 ) {
1916 { /* LDS Rm, MACH */
1917 uint32_t Rm = ((ir>>8)&0xF);
1918 load_reg( R_EAX, Rm );
1919 store_spreg( R_EAX, R_MACH );
1923 { /* LDS Rm, MACL */
1924 uint32_t Rm = ((ir>>8)&0xF);
1925 load_reg( R_EAX, Rm );
1926 store_spreg( R_EAX, R_MACL );
1931 uint32_t Rm = ((ir>>8)&0xF);
1932 load_reg( R_EAX, Rm );
1933 store_spreg( R_EAX, R_PR );
1938 uint32_t Rm = ((ir>>8)&0xF);
1940 load_reg( R_EAX, Rm );
1941 store_spreg( R_EAX, R_SGR );
1942 sh4_x86.tstate = TSTATE_NONE;
1946 { /* LDS Rm, FPUL */
1947 uint32_t Rm = ((ir>>8)&0xF);
1949 load_reg( R_EAX, Rm );
1950 store_spreg( R_EAX, R_FPUL );
1954 { /* LDS Rm, FPSCR */
1955 uint32_t Rm = ((ir>>8)&0xF);
1957 load_reg( R_EAX, Rm );
1958 store_spreg( R_EAX, R_FPSCR );
1959 update_fr_bank( R_EAX );
1960 sh4_x86.tstate = TSTATE_NONE;
1965 uint32_t Rm = ((ir>>8)&0xF);
1967 load_reg( R_EAX, Rm );
1968 store_spreg( R_EAX, R_DBR );
1969 sh4_x86.tstate = TSTATE_NONE;
1978 switch( (ir&0xF0) >> 4 ) {
1981 uint32_t Rn = ((ir>>8)&0xF);
1982 if( sh4_x86.in_delay_slot ) {
1985 load_spreg( R_EAX, R_PC );
1986 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1987 store_spreg( R_EAX, R_PR );
1988 load_reg( R_ECX, Rn );
1989 store_spreg( R_ECX, R_NEW_PC );
1990 sh4_x86.in_delay_slot = DELAY_PC;
1991 sh4_x86.branch_taken = TRUE;
1992 sh4_x86.tstate = TSTATE_NONE;
1993 if( UNTRANSLATABLE(pc+2) ) {
1994 exit_block_emu(pc+2);
1997 sh4_translate_instruction(pc+2);
1998 exit_block_newpcset(pc+2);
2006 uint32_t Rn = ((ir>>8)&0xF);
2007 load_reg( R_EAX, Rn );
2008 MMU_TRANSLATE_WRITE( R_EAX );
2009 PUSH_realigned_r32( R_EAX );
2010 MEM_READ_BYTE( R_EAX, R_EAX );
2011 TEST_r8_r8( R_AL, R_AL );
2013 OR_imm8_r8( 0x80, R_AL );
2014 POP_realigned_r32( R_ECX );
2015 MEM_WRITE_BYTE( R_ECX, R_EAX );
2016 sh4_x86.tstate = TSTATE_NONE;
2021 uint32_t Rn = ((ir>>8)&0xF);
2022 if( sh4_x86.in_delay_slot ) {
2025 load_reg( R_ECX, Rn );
2026 store_spreg( R_ECX, R_NEW_PC );
2027 sh4_x86.in_delay_slot = DELAY_PC;
2028 sh4_x86.branch_taken = TRUE;
2029 if( UNTRANSLATABLE(pc+2) ) {
2030 exit_block_emu(pc+2);
2033 sh4_translate_instruction(pc+2);
2034 exit_block_newpcset(pc+2);
2047 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2048 /* Annoyingly enough, not directly convertible */
2049 load_reg( R_EAX, Rn );
2050 load_reg( R_ECX, Rm );
2051 CMP_imm32_r32( 0, R_ECX );
2052 JGE_rel8(16, doshl);
2054 NEG_r32( R_ECX ); // 2
2055 AND_imm8_r8( 0x1F, R_CL ); // 3
2056 JE_rel8( 4, emptysar); // 2
2057 SAR_r32_CL( R_EAX ); // 2
2058 JMP_rel8(10, end); // 2
2060 JMP_TARGET(emptysar);
2061 SAR_imm8_r32(31, R_EAX ); // 3
2065 AND_imm8_r8( 0x1F, R_CL ); // 3
2066 SHL_r32_CL( R_EAX ); // 2
2069 store_reg( R_EAX, Rn );
2070 sh4_x86.tstate = TSTATE_NONE;
2075 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2076 load_reg( R_EAX, Rn );
2077 load_reg( R_ECX, Rm );
2078 CMP_imm32_r32( 0, R_ECX );
2079 JGE_rel8(15, doshl);
2081 NEG_r32( R_ECX ); // 2
2082 AND_imm8_r8( 0x1F, R_CL ); // 3
2083 JE_rel8( 4, emptyshr );
2084 SHR_r32_CL( R_EAX ); // 2
2085 JMP_rel8(9, end); // 2
2087 JMP_TARGET(emptyshr);
2088 XOR_r32_r32( R_EAX, R_EAX );
2092 AND_imm8_r8( 0x1F, R_CL ); // 3
2093 SHL_r32_CL( R_EAX ); // 2
2096 store_reg( R_EAX, Rn );
2097 sh4_x86.tstate = TSTATE_NONE;
2101 switch( (ir&0x80) >> 7 ) {
2103 switch( (ir&0x70) >> 4 ) {
2106 uint32_t Rm = ((ir>>8)&0xF);
2107 if( sh4_x86.in_delay_slot ) {
2111 load_reg( R_EAX, Rm );
2112 call_func1( sh4_write_sr, R_EAX );
2113 sh4_x86.priv_checked = FALSE;
2114 sh4_x86.fpuen_checked = FALSE;
2115 sh4_x86.tstate = TSTATE_NONE;
2121 uint32_t Rm = ((ir>>8)&0xF);
2122 load_reg( R_EAX, Rm );
2123 store_spreg( R_EAX, R_GBR );
2128 uint32_t Rm = ((ir>>8)&0xF);
2130 load_reg( R_EAX, Rm );
2131 store_spreg( R_EAX, R_VBR );
2132 sh4_x86.tstate = TSTATE_NONE;
2137 uint32_t Rm = ((ir>>8)&0xF);
2139 load_reg( R_EAX, Rm );
2140 store_spreg( R_EAX, R_SSR );
2141 sh4_x86.tstate = TSTATE_NONE;
2146 uint32_t Rm = ((ir>>8)&0xF);
2148 load_reg( R_EAX, Rm );
2149 store_spreg( R_EAX, R_SPC );
2150 sh4_x86.tstate = TSTATE_NONE;
2159 { /* LDC Rm, Rn_BANK */
2160 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2162 load_reg( R_EAX, Rm );
2163 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2164 sh4_x86.tstate = TSTATE_NONE;
2170 { /* MAC.W @Rm+, @Rn+ */
2171 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2173 load_reg( R_EAX, Rm );
2174 check_ralign16( R_EAX );
2175 MMU_TRANSLATE_READ( R_EAX );
2176 PUSH_realigned_r32( R_EAX );
2177 load_reg( R_EAX, Rn );
2178 ADD_imm8s_r32( 2, R_EAX );
2179 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
2180 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
2181 // Note translate twice in case of page boundaries. Maybe worth
2182 // adding a page-boundary check to skip the second translation
2184 load_reg( R_EAX, Rm );
2185 check_ralign16( R_EAX );
2186 MMU_TRANSLATE_READ( R_EAX );
2187 load_reg( R_ECX, Rn );
2188 check_ralign16( R_ECX );
2189 PUSH_realigned_r32( R_EAX );
2190 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
2191 MOV_r32_r32( R_ECX, R_EAX );
2192 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2193 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2195 MEM_READ_WORD( R_EAX, R_EAX );
2198 MEM_READ_WORD( R_ECX, R_EAX );
2199 POP_realigned_r32( R_ECX );
2202 load_spreg( R_ECX, R_S );
2203 TEST_r32_r32( R_ECX, R_ECX );
2204 JE_rel8( 47, nosat );
2206 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2207 JNO_rel8( 51, end ); // 2
2208 load_imm32( R_EDX, 1 ); // 5
2209 store_spreg( R_EDX, R_MACH ); // 6
2210 JS_rel8( 13, positive ); // 2
2211 load_imm32( R_EAX, 0x80000000 );// 5
2212 store_spreg( R_EAX, R_MACL ); // 6
2213 JMP_rel8( 25, end2 ); // 2
2215 JMP_TARGET(positive);
2216 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2217 store_spreg( R_EAX, R_MACL ); // 6
2218 JMP_rel8( 12, end3); // 2
2221 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2222 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2226 sh4_x86.tstate = TSTATE_NONE;
2232 { /* MOV.L @(disp, Rm), Rn */
2233 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2234 load_reg( R_EAX, Rm );
2235 ADD_imm8s_r32( disp, R_EAX );
2236 check_ralign32( R_EAX );
2237 MMU_TRANSLATE_READ( R_EAX );
2238 MEM_READ_LONG( R_EAX, R_EAX );
2239 store_reg( R_EAX, Rn );
2240 sh4_x86.tstate = TSTATE_NONE;
2246 { /* MOV.B @Rm, Rn */
2247 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2248 load_reg( R_EAX, Rm );
2249 MMU_TRANSLATE_READ( R_EAX );
2250 MEM_READ_BYTE( R_EAX, R_EAX );
2251 store_reg( R_EAX, Rn );
2252 sh4_x86.tstate = TSTATE_NONE;
2256 { /* MOV.W @Rm, Rn */
2257 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2258 load_reg( R_EAX, Rm );
2259 check_ralign16( R_EAX );
2260 MMU_TRANSLATE_READ( R_EAX );
2261 MEM_READ_WORD( R_EAX, R_EAX );
2262 store_reg( R_EAX, Rn );
2263 sh4_x86.tstate = TSTATE_NONE;
2267 { /* MOV.L @Rm, Rn */
2268 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2269 load_reg( R_EAX, Rm );
2270 check_ralign32( R_EAX );
2271 MMU_TRANSLATE_READ( R_EAX );
2272 MEM_READ_LONG( R_EAX, R_EAX );
2273 store_reg( R_EAX, Rn );
2274 sh4_x86.tstate = TSTATE_NONE;
2279 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2280 load_reg( R_EAX, Rm );
2281 store_reg( R_EAX, Rn );
2285 { /* MOV.B @Rm+, Rn */
2286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2287 load_reg( R_EAX, Rm );
2288 MMU_TRANSLATE_READ( R_EAX );
2289 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
2290 MEM_READ_BYTE( R_EAX, R_EAX );
2291 store_reg( R_EAX, Rn );
2292 sh4_x86.tstate = TSTATE_NONE;
2296 { /* MOV.W @Rm+, Rn */
2297 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2298 load_reg( R_EAX, Rm );
2299 check_ralign16( R_EAX );
2300 MMU_TRANSLATE_READ( R_EAX );
2301 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2302 MEM_READ_WORD( R_EAX, R_EAX );
2303 store_reg( R_EAX, Rn );
2304 sh4_x86.tstate = TSTATE_NONE;
2308 { /* MOV.L @Rm+, Rn */
2309 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2310 load_reg( R_EAX, Rm );
2311 check_ralign32( R_EAX );
2312 MMU_TRANSLATE_READ( R_EAX );
2313 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2314 MEM_READ_LONG( R_EAX, R_EAX );
2315 store_reg( R_EAX, Rn );
2316 sh4_x86.tstate = TSTATE_NONE;
2321 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2322 load_reg( R_EAX, Rm );
2324 store_reg( R_EAX, Rn );
2325 sh4_x86.tstate = TSTATE_NONE;
2329 { /* SWAP.B Rm, Rn */
2330 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2331 load_reg( R_EAX, Rm );
2332 XCHG_r8_r8( R_AL, R_AH ); // NB: does not touch EFLAGS
2333 store_reg( R_EAX, Rn );
2337 { /* SWAP.W Rm, Rn */
2338 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2339 load_reg( R_EAX, Rm );
2340 MOV_r32_r32( R_EAX, R_ECX );
2341 SHL_imm8_r32( 16, R_ECX );
2342 SHR_imm8_r32( 16, R_EAX );
2343 OR_r32_r32( R_EAX, R_ECX );
2344 store_reg( R_ECX, Rn );
2345 sh4_x86.tstate = TSTATE_NONE;
2350 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2351 load_reg( R_EAX, Rm );
2352 XOR_r32_r32( R_ECX, R_ECX );
2354 SBB_r32_r32( R_EAX, R_ECX );
2355 store_reg( R_ECX, Rn );
2357 sh4_x86.tstate = TSTATE_C;
2362 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2363 load_reg( R_EAX, Rm );
2365 store_reg( R_EAX, Rn );
2366 sh4_x86.tstate = TSTATE_NONE;
2370 { /* EXTU.B Rm, Rn */
2371 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2372 load_reg( R_EAX, Rm );
2373 MOVZX_r8_r32( R_EAX, R_EAX );
2374 store_reg( R_EAX, Rn );
2378 { /* EXTU.W Rm, Rn */
2379 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2380 load_reg( R_EAX, Rm );
2381 MOVZX_r16_r32( R_EAX, R_EAX );
2382 store_reg( R_EAX, Rn );
2386 { /* EXTS.B Rm, Rn */
2387 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2388 load_reg( R_EAX, Rm );
2389 MOVSX_r8_r32( R_EAX, R_EAX );
2390 store_reg( R_EAX, Rn );
2394 { /* EXTS.W Rm, Rn */
2395 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2396 load_reg( R_EAX, Rm );
2397 MOVSX_r16_r32( R_EAX, R_EAX );
2398 store_reg( R_EAX, Rn );
2404 { /* ADD #imm, Rn */
2405 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2406 load_reg( R_EAX, Rn );
2407 ADD_imm8s_r32( imm, R_EAX );
2408 store_reg( R_EAX, Rn );
2409 sh4_x86.tstate = TSTATE_NONE;
2413 switch( (ir&0xF00) >> 8 ) {
2415 { /* MOV.B R0, @(disp, Rn) */
2416 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2417 load_reg( R_EAX, Rn );
2418 ADD_imm32_r32( disp, R_EAX );
2419 MMU_TRANSLATE_WRITE( R_EAX );
2420 load_reg( R_EDX, 0 );
2421 MEM_WRITE_BYTE( R_EAX, R_EDX );
2422 sh4_x86.tstate = TSTATE_NONE;
2426 { /* MOV.W R0, @(disp, Rn) */
2427 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2428 load_reg( R_EAX, Rn );
2429 ADD_imm32_r32( disp, R_EAX );
2430 check_walign16( R_EAX );
2431 MMU_TRANSLATE_WRITE( R_EAX );
2432 load_reg( R_EDX, 0 );
2433 MEM_WRITE_WORD( R_EAX, R_EDX );
2434 sh4_x86.tstate = TSTATE_NONE;
2438 { /* MOV.B @(disp, Rm), R0 */
2439 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2440 load_reg( R_EAX, Rm );
2441 ADD_imm32_r32( disp, R_EAX );
2442 MMU_TRANSLATE_READ( R_EAX );
2443 MEM_READ_BYTE( R_EAX, R_EAX );
2444 store_reg( R_EAX, 0 );
2445 sh4_x86.tstate = TSTATE_NONE;
2449 { /* MOV.W @(disp, Rm), R0 */
2450 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2451 load_reg( R_EAX, Rm );
2452 ADD_imm32_r32( disp, R_EAX );
2453 check_ralign16( R_EAX );
2454 MMU_TRANSLATE_READ( R_EAX );
2455 MEM_READ_WORD( R_EAX, R_EAX );
2456 store_reg( R_EAX, 0 );
2457 sh4_x86.tstate = TSTATE_NONE;
2461 { /* CMP/EQ #imm, R0 */
2462 int32_t imm = SIGNEXT8(ir&0xFF);
2463 load_reg( R_EAX, 0 );
2464 CMP_imm8s_r32(imm, R_EAX);
2466 sh4_x86.tstate = TSTATE_E;
2471 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2472 if( sh4_x86.in_delay_slot ) {
2475 sh4vma_t target = disp + pc + 4;
2476 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2477 exit_block_rel(target, pc+2 );
2478 JMP_TARGET(nottaken);
2485 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2486 if( sh4_x86.in_delay_slot ) {
2489 sh4vma_t target = disp + pc + 4;
2490 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
2491 exit_block_rel(target, pc+2 );
2492 JMP_TARGET(nottaken);
2499 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2500 if( sh4_x86.in_delay_slot ) {
2503 sh4_x86.in_delay_slot = DELAY_PC;
2504 if( UNTRANSLATABLE(pc+2) ) {
2505 load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );
2506 JF_rel8(6,nottaken);
2507 ADD_imm32_r32( disp, R_EAX );
2508 JMP_TARGET(nottaken);
2509 ADD_sh4r_r32( R_PC, R_EAX );
2510 store_spreg( R_EAX, R_NEW_PC );
2511 exit_block_emu(pc+2);
2512 sh4_x86.branch_taken = TRUE;
2515 if( sh4_x86.tstate == TSTATE_NONE ) {
2516 CMP_imm8s_sh4r( 1, R_T );
2517 sh4_x86.tstate = TSTATE_E;
2519 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JF rel32
2520 sh4_translate_instruction(pc+2);
2521 exit_block_rel( disp + pc + 4, pc+4 );
2523 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2524 sh4_translate_instruction(pc+2);
2532 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2533 if( sh4_x86.in_delay_slot ) {
2536 sh4_x86.in_delay_slot = DELAY_PC;
2537 if( UNTRANSLATABLE(pc+2) ) {
2538 load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );
2539 JT_rel8(6,nottaken);
2540 ADD_imm32_r32( disp, R_EAX );
2541 JMP_TARGET(nottaken);
2542 ADD_sh4r_r32( R_PC, R_EAX );
2543 store_spreg( R_EAX, R_NEW_PC );
2544 exit_block_emu(pc+2);
2545 sh4_x86.branch_taken = TRUE;
2548 if( sh4_x86.tstate == TSTATE_NONE ) {
2549 CMP_imm8s_sh4r( 1, R_T );
2550 sh4_x86.tstate = TSTATE_E;
2552 sh4vma_t target = disp + pc + 4;
2553 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JT rel32
2554 sh4_translate_instruction(pc+2);
2555 exit_block_rel( target, pc+4 );
2558 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2559 sh4_translate_instruction(pc+2);
2571 { /* MOV.W @(disp, PC), Rn */
2572 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2573 if( sh4_x86.in_delay_slot ) {
2576 // See comments for MOV.L @(disp, PC), Rn
2577 uint32_t target = pc + disp + 4;
2578 if( IS_IN_ICACHE(target) ) {
2579 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2580 MOV_moff32_EAX( ptr );
2581 MOVSX_r16_r32( R_EAX, R_EAX );
2583 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
2584 ADD_sh4r_r32( R_PC, R_EAX );
2585 MMU_TRANSLATE_READ( R_EAX );
2586 MEM_READ_WORD( R_EAX, R_EAX );
2587 sh4_x86.tstate = TSTATE_NONE;
2589 store_reg( R_EAX, Rn );
2595 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2596 if( sh4_x86.in_delay_slot ) {
2599 sh4_x86.in_delay_slot = DELAY_PC;
2600 sh4_x86.branch_taken = TRUE;
2601 if( UNTRANSLATABLE(pc+2) ) {
2602 load_spreg( R_EAX, R_PC );
2603 ADD_imm32_r32( pc + disp + 4 - sh4_x86.block_start_pc, R_EAX );
2604 store_spreg( R_EAX, R_NEW_PC );
2605 exit_block_emu(pc+2);
2608 sh4_translate_instruction( pc + 2 );
2609 exit_block_rel( disp + pc + 4, pc+4 );
2617 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2618 if( sh4_x86.in_delay_slot ) {
2621 load_spreg( R_EAX, R_PC );
2622 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
2623 store_spreg( R_EAX, R_PR );
2624 sh4_x86.in_delay_slot = DELAY_PC;
2625 sh4_x86.branch_taken = TRUE;
2626 sh4_x86.tstate = TSTATE_NONE;
2627 if( UNTRANSLATABLE(pc+2) ) {
2628 ADD_imm32_r32( disp, R_EAX );
2629 store_spreg( R_EAX, R_NEW_PC );
2630 exit_block_emu(pc+2);
2633 sh4_translate_instruction( pc + 2 );
2634 exit_block_rel( disp + pc + 4, pc+4 );
2641 switch( (ir&0xF00) >> 8 ) {
2643 { /* MOV.B R0, @(disp, GBR) */
2644 uint32_t disp = (ir&0xFF);
2645 load_spreg( R_EAX, R_GBR );
2646 ADD_imm32_r32( disp, R_EAX );
2647 MMU_TRANSLATE_WRITE( R_EAX );
2648 load_reg( R_EDX, 0 );
2649 MEM_WRITE_BYTE( R_EAX, R_EDX );
2650 sh4_x86.tstate = TSTATE_NONE;
2654 { /* MOV.W R0, @(disp, GBR) */
2655 uint32_t disp = (ir&0xFF)<<1;
2656 load_spreg( R_EAX, R_GBR );
2657 ADD_imm32_r32( disp, R_EAX );
2658 check_walign16( R_EAX );
2659 MMU_TRANSLATE_WRITE( R_EAX );
2660 load_reg( R_EDX, 0 );
2661 MEM_WRITE_WORD( R_EAX, R_EDX );
2662 sh4_x86.tstate = TSTATE_NONE;
2666 { /* MOV.L R0, @(disp, GBR) */
2667 uint32_t disp = (ir&0xFF)<<2;
2668 load_spreg( R_EAX, R_GBR );
2669 ADD_imm32_r32( disp, R_EAX );
2670 check_walign32( R_EAX );
2671 MMU_TRANSLATE_WRITE( R_EAX );
2672 load_reg( R_EDX, 0 );
2673 MEM_WRITE_LONG( R_EAX, R_EDX );
2674 sh4_x86.tstate = TSTATE_NONE;
2679 uint32_t imm = (ir&0xFF);
2680 if( sh4_x86.in_delay_slot ) {
2683 load_imm32( R_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
2684 ADD_r32_sh4r( R_ECX, R_PC );
2685 load_imm32( R_EAX, imm );
2686 call_func1( sh4_raise_trap, R_EAX );
2687 sh4_x86.tstate = TSTATE_NONE;
2688 exit_block_pcset(pc);
2689 sh4_x86.branch_taken = TRUE;
2695 { /* MOV.B @(disp, GBR), R0 */
2696 uint32_t disp = (ir&0xFF);
2697 load_spreg( R_EAX, R_GBR );
2698 ADD_imm32_r32( disp, R_EAX );
2699 MMU_TRANSLATE_READ( R_EAX );
2700 MEM_READ_BYTE( R_EAX, R_EAX );
2701 store_reg( R_EAX, 0 );
2702 sh4_x86.tstate = TSTATE_NONE;
2706 { /* MOV.W @(disp, GBR), R0 */
2707 uint32_t disp = (ir&0xFF)<<1;
2708 load_spreg( R_EAX, R_GBR );
2709 ADD_imm32_r32( disp, R_EAX );
2710 check_ralign16( R_EAX );
2711 MMU_TRANSLATE_READ( R_EAX );
2712 MEM_READ_WORD( R_EAX, R_EAX );
2713 store_reg( R_EAX, 0 );
2714 sh4_x86.tstate = TSTATE_NONE;
2718 { /* MOV.L @(disp, GBR), R0 */
2719 uint32_t disp = (ir&0xFF)<<2;
2720 load_spreg( R_EAX, R_GBR );
2721 ADD_imm32_r32( disp, R_EAX );
2722 check_ralign32( R_EAX );
2723 MMU_TRANSLATE_READ( R_EAX );
2724 MEM_READ_LONG( R_EAX, R_EAX );
2725 store_reg( R_EAX, 0 );
2726 sh4_x86.tstate = TSTATE_NONE;
2730 { /* MOVA @(disp, PC), R0 */
2731 uint32_t disp = (ir&0xFF)<<2;
2732 if( sh4_x86.in_delay_slot ) {
2735 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2736 ADD_sh4r_r32( R_PC, R_ECX );
2737 store_reg( R_ECX, 0 );
2738 sh4_x86.tstate = TSTATE_NONE;
2743 { /* TST #imm, R0 */
2744 uint32_t imm = (ir&0xFF);
2745 load_reg( R_EAX, 0 );
2746 TEST_imm32_r32( imm, R_EAX );
2748 sh4_x86.tstate = TSTATE_E;
2752 { /* AND #imm, R0 */
2753 uint32_t imm = (ir&0xFF);
2754 load_reg( R_EAX, 0 );
2755 AND_imm32_r32(imm, R_EAX);
2756 store_reg( R_EAX, 0 );
2757 sh4_x86.tstate = TSTATE_NONE;
2761 { /* XOR #imm, R0 */
2762 uint32_t imm = (ir&0xFF);
2763 load_reg( R_EAX, 0 );
2764 XOR_imm32_r32( imm, R_EAX );
2765 store_reg( R_EAX, 0 );
2766 sh4_x86.tstate = TSTATE_NONE;
2771 uint32_t imm = (ir&0xFF);
2772 load_reg( R_EAX, 0 );
2773 OR_imm32_r32(imm, R_EAX);
2774 store_reg( R_EAX, 0 );
2775 sh4_x86.tstate = TSTATE_NONE;
2779 { /* TST.B #imm, @(R0, GBR) */
2780 uint32_t imm = (ir&0xFF);
2781 load_reg( R_EAX, 0);
2782 load_reg( R_ECX, R_GBR);
2783 ADD_r32_r32( R_ECX, R_EAX );
2784 MMU_TRANSLATE_READ( R_EAX );
2785 MEM_READ_BYTE( R_EAX, R_EAX );
2786 TEST_imm8_r8( imm, R_AL );
2788 sh4_x86.tstate = TSTATE_E;
2792 { /* AND.B #imm, @(R0, GBR) */
2793 uint32_t imm = (ir&0xFF);
2794 load_reg( R_EAX, 0 );
2795 load_spreg( R_ECX, R_GBR );
2796 ADD_r32_r32( R_ECX, R_EAX );
2797 MMU_TRANSLATE_WRITE( R_EAX );
2798 PUSH_realigned_r32(R_EAX);
2799 MEM_READ_BYTE( R_EAX, R_EAX );
2800 POP_realigned_r32(R_ECX);
2801 AND_imm32_r32(imm, R_EAX );
2802 MEM_WRITE_BYTE( R_ECX, R_EAX );
2803 sh4_x86.tstate = TSTATE_NONE;
2807 { /* XOR.B #imm, @(R0, GBR) */
2808 uint32_t imm = (ir&0xFF);
2809 load_reg( R_EAX, 0 );
2810 load_spreg( R_ECX, R_GBR );
2811 ADD_r32_r32( R_ECX, R_EAX );
2812 MMU_TRANSLATE_WRITE( R_EAX );
2813 PUSH_realigned_r32(R_EAX);
2814 MEM_READ_BYTE(R_EAX, R_EAX);
2815 POP_realigned_r32(R_ECX);
2816 XOR_imm32_r32( imm, R_EAX );
2817 MEM_WRITE_BYTE( R_ECX, R_EAX );
2818 sh4_x86.tstate = TSTATE_NONE;
2822 { /* OR.B #imm, @(R0, GBR) */
2823 uint32_t imm = (ir&0xFF);
2824 load_reg( R_EAX, 0 );
2825 load_spreg( R_ECX, R_GBR );
2826 ADD_r32_r32( R_ECX, R_EAX );
2827 MMU_TRANSLATE_WRITE( R_EAX );
2828 PUSH_realigned_r32(R_EAX);
2829 MEM_READ_BYTE( R_EAX, R_EAX );
2830 POP_realigned_r32(R_ECX);
2831 OR_imm32_r32(imm, R_EAX );
2832 MEM_WRITE_BYTE( R_ECX, R_EAX );
2833 sh4_x86.tstate = TSTATE_NONE;
2839 { /* MOV.L @(disp, PC), Rn */
2840 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2841 if( sh4_x86.in_delay_slot ) {
2844 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2845 if( IS_IN_ICACHE(target) ) {
2846 // If the target address is in the same page as the code, it's
2847 // pretty safe to just ref it directly and circumvent the whole
2848 // memory subsystem. (this is a big performance win)
2850 // FIXME: There's a corner-case that's not handled here when
2851 // the current code-page is in the ITLB but not in the UTLB.
2852 // (should generate a TLB miss although need to test SH4
2853 // behaviour to confirm) Unlikely to be anyone depending on this
2854 // behaviour though.
2855 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2856 MOV_moff32_EAX( ptr );
2858 // Note: we use sh4r.pc for the calc as we could be running at a
2859 // different virtual address than the translation was done with,
2860 // but we can safely assume that the low bits are the same.
2861 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2862 ADD_sh4r_r32( R_PC, R_EAX );
2863 MMU_TRANSLATE_READ( R_EAX );
2864 MEM_READ_LONG( R_EAX, R_EAX );
2865 sh4_x86.tstate = TSTATE_NONE;
2867 store_reg( R_EAX, Rn );
2872 { /* MOV #imm, Rn */
2873 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2874 load_imm32( R_EAX, imm );
2875 store_reg( R_EAX, Rn );
2881 { /* FADD FRm, FRn */
2882 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2884 load_spreg( R_ECX, R_FPSCR );
2885 TEST_imm32_r32( FPSCR_PR, R_ECX );
2886 load_fr_bank( R_EDX );
2887 JNE_rel8(13,doubleprec);
2888 push_fr(R_EDX, FRm);
2889 push_fr(R_EDX, FRn);
2893 JMP_TARGET(doubleprec);
2894 push_dr(R_EDX, FRm);
2895 push_dr(R_EDX, FRn);
2899 sh4_x86.tstate = TSTATE_NONE;
2903 { /* FSUB FRm, FRn */
2904 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2906 load_spreg( R_ECX, R_FPSCR );
2907 TEST_imm32_r32( FPSCR_PR, R_ECX );
2908 load_fr_bank( R_EDX );
2909 JNE_rel8(13, doubleprec);
2910 push_fr(R_EDX, FRn);
2911 push_fr(R_EDX, FRm);
2915 JMP_TARGET(doubleprec);
2916 push_dr(R_EDX, FRn);
2917 push_dr(R_EDX, FRm);
2921 sh4_x86.tstate = TSTATE_NONE;
2925 { /* FMUL FRm, FRn */
2926 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2928 load_spreg( R_ECX, R_FPSCR );
2929 TEST_imm32_r32( FPSCR_PR, R_ECX );
2930 load_fr_bank( R_EDX );
2931 JNE_rel8(13, doubleprec);
2932 push_fr(R_EDX, FRm);
2933 push_fr(R_EDX, FRn);
2937 JMP_TARGET(doubleprec);
2938 push_dr(R_EDX, FRm);
2939 push_dr(R_EDX, FRn);
2943 sh4_x86.tstate = TSTATE_NONE;
2947 { /* FDIV FRm, FRn */
2948 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2950 load_spreg( R_ECX, R_FPSCR );
2951 TEST_imm32_r32( FPSCR_PR, R_ECX );
2952 load_fr_bank( R_EDX );
2953 JNE_rel8(13, doubleprec);
2954 push_fr(R_EDX, FRn);
2955 push_fr(R_EDX, FRm);
2959 JMP_TARGET(doubleprec);
2960 push_dr(R_EDX, FRn);
2961 push_dr(R_EDX, FRm);
2965 sh4_x86.tstate = TSTATE_NONE;
2969 { /* FCMP/EQ FRm, FRn */
2970 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2972 load_spreg( R_ECX, R_FPSCR );
2973 TEST_imm32_r32( FPSCR_PR, R_ECX );
2974 load_fr_bank( R_EDX );
2975 JNE_rel8(8, doubleprec);
2976 push_fr(R_EDX, FRm);
2977 push_fr(R_EDX, FRn);
2979 JMP_TARGET(doubleprec);
2980 push_dr(R_EDX, FRm);
2981 push_dr(R_EDX, FRn);
2986 sh4_x86.tstate = TSTATE_NONE;
2990 { /* FCMP/GT FRm, FRn */
2991 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2993 load_spreg( R_ECX, R_FPSCR );
2994 TEST_imm32_r32( FPSCR_PR, R_ECX );
2995 load_fr_bank( R_EDX );
2996 JNE_rel8(8, doubleprec);
2997 push_fr(R_EDX, FRm);
2998 push_fr(R_EDX, FRn);
3000 JMP_TARGET(doubleprec);
3001 push_dr(R_EDX, FRm);
3002 push_dr(R_EDX, FRn);
3007 sh4_x86.tstate = TSTATE_NONE;
3011 { /* FMOV @(R0, Rm), FRn */
3012 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3014 load_reg( R_EAX, Rm );
3015 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
3016 check_ralign32( R_EAX );
3017 MMU_TRANSLATE_READ( R_EAX );
3018 load_spreg( R_EDX, R_FPSCR );
3019 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3020 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
3021 MEM_READ_LONG( R_EAX, R_EAX );
3022 load_fr_bank( R_EDX );
3023 store_fr( R_EDX, R_EAX, FRn );
3025 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
3026 JMP_TARGET(doublesize);
3027 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3028 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3029 load_xf_bank( R_EDX );
3030 store_fr( R_EDX, R_ECX, FRn&0x0E );
3031 store_fr( R_EDX, R_EAX, FRn|0x01 );
3034 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
3035 JMP_TARGET(doublesize);
3036 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3037 load_fr_bank( R_EDX );
3038 store_fr( R_EDX, R_ECX, FRn&0x0E );
3039 store_fr( R_EDX, R_EAX, FRn|0x01 );
3042 sh4_x86.tstate = TSTATE_NONE;
3046 { /* FMOV FRm, @(R0, Rn) */
3047 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3049 load_reg( R_EAX, Rn );
3050 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
3051 check_walign32( R_EAX );
3052 MMU_TRANSLATE_WRITE( R_EAX );
3053 load_spreg( R_EDX, R_FPSCR );
3054 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3055 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
3056 load_fr_bank( R_EDX );
3057 load_fr( R_EDX, R_ECX, FRm );
3058 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3060 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3061 JMP_TARGET(doublesize);
3062 load_xf_bank( R_EDX );
3063 load_fr( R_EDX, R_ECX, FRm&0x0E );
3064 load_fr( R_EDX, R_EDX, FRm|0x01 );
3065 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3068 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3069 JMP_TARGET(doublesize);
3070 load_fr_bank( R_EDX );
3071 load_fr( R_EDX, R_ECX, FRm&0x0E );
3072 load_fr( R_EDX, R_EDX, FRm|0x01 );
3073 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3076 sh4_x86.tstate = TSTATE_NONE;
3080 { /* FMOV @Rm, FRn */
3081 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3083 load_reg( R_EAX, Rm );
3084 check_ralign32( R_EAX );
3085 MMU_TRANSLATE_READ( R_EAX );
3086 load_spreg( R_EDX, R_FPSCR );
3087 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3088 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
3089 MEM_READ_LONG( R_EAX, R_EAX );
3090 load_fr_bank( R_EDX );
3091 store_fr( R_EDX, R_EAX, FRn );
3093 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
3094 JMP_TARGET(doublesize);
3095 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3096 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3097 load_xf_bank( R_EDX );
3098 store_fr( R_EDX, R_ECX, FRn&0x0E );
3099 store_fr( R_EDX, R_EAX, FRn|0x01 );
3102 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
3103 JMP_TARGET(doublesize);
3104 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3105 load_fr_bank( R_EDX );
3106 store_fr( R_EDX, R_ECX, FRn&0x0E );
3107 store_fr( R_EDX, R_EAX, FRn|0x01 );
3110 sh4_x86.tstate = TSTATE_NONE;
3114 { /* FMOV @Rm+, FRn */
3115 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3117 load_reg( R_EAX, Rm );
3118 check_ralign32( R_EAX );
3119 MMU_TRANSLATE_READ( R_EAX );
3120 load_spreg( R_EDX, R_FPSCR );
3121 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3122 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
3123 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
3124 MEM_READ_LONG( R_EAX, R_EAX );
3125 load_fr_bank( R_EDX );
3126 store_fr( R_EDX, R_EAX, FRn );
3128 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
3129 JMP_TARGET(doublesize);
3130 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3131 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3132 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3133 load_xf_bank( R_EDX );
3134 store_fr( R_EDX, R_ECX, FRn&0x0E );
3135 store_fr( R_EDX, R_EAX, FRn|0x01 );
3138 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
3139 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3140 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3141 load_fr_bank( R_EDX );
3142 store_fr( R_EDX, R_ECX, FRn&0x0E );
3143 store_fr( R_EDX, R_EAX, FRn|0x01 );
3146 sh4_x86.tstate = TSTATE_NONE;
3150 { /* FMOV FRm, @Rn */
3151 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3153 load_reg( R_EAX, Rn );
3154 check_walign32( R_EAX );
3155 MMU_TRANSLATE_WRITE( R_EAX );
3156 load_spreg( R_EDX, R_FPSCR );
3157 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3158 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
3159 load_fr_bank( R_EDX );
3160 load_fr( R_EDX, R_ECX, FRm );
3161 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3163 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3164 JMP_TARGET(doublesize);
3165 load_xf_bank( R_EDX );
3166 load_fr( R_EDX, R_ECX, FRm&0x0E );
3167 load_fr( R_EDX, R_EDX, FRm|0x01 );
3168 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3171 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3172 JMP_TARGET(doublesize);
3173 load_fr_bank( R_EDX );
3174 load_fr( R_EDX, R_ECX, FRm&0x0E );
3175 load_fr( R_EDX, R_EDX, FRm|0x01 );
3176 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3179 sh4_x86.tstate = TSTATE_NONE;
3183 { /* FMOV FRm, @-Rn */
3184 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3186 load_reg( R_EAX, Rn );
3187 check_walign32( R_EAX );
3188 load_spreg( R_EDX, R_FPSCR );
3189 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3190 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
3191 ADD_imm8s_r32( -4, R_EAX );
3192 MMU_TRANSLATE_WRITE( R_EAX );
3193 load_fr_bank( R_EDX );
3194 load_fr( R_EDX, R_ECX, FRm );
3195 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
3196 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3198 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3199 JMP_TARGET(doublesize);
3200 ADD_imm8s_r32(-8,R_EAX);
3201 MMU_TRANSLATE_WRITE( R_EAX );
3202 load_xf_bank( R_EDX );
3203 load_fr( R_EDX, R_ECX, FRm&0x0E );
3204 load_fr( R_EDX, R_EDX, FRm|0x01 );
3205 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3206 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3209 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
3210 JMP_TARGET(doublesize);
3211 ADD_imm8s_r32(-8,R_EAX);
3212 MMU_TRANSLATE_WRITE( R_EAX );
3213 load_fr_bank( R_EDX );
3214 load_fr( R_EDX, R_ECX, FRm&0x0E );
3215 load_fr( R_EDX, R_EDX, FRm|0x01 );
3216 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3217 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3220 sh4_x86.tstate = TSTATE_NONE;
3224 { /* FMOV FRm, FRn */
3225 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3226 /* As horrible as this looks, it's actually covering 5 separate cases:
3227 * 1. 32-bit fr-to-fr (PR=0)
3228 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3229 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3230 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3231 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3234 load_spreg( R_ECX, R_FPSCR );
3235 load_fr_bank( R_EDX );
3236 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3237 JNE_rel8(8, doublesize);
3238 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3239 store_fr( R_EDX, R_EAX, FRn );
3242 JMP_TARGET(doublesize);
3243 load_xf_bank( R_ECX );
3244 load_fr( R_ECX, R_EAX, FRm-1 );
3246 load_fr( R_ECX, R_EDX, FRm );
3247 store_fr( R_ECX, R_EAX, FRn-1 );
3248 store_fr( R_ECX, R_EDX, FRn );
3249 } else /* FRn&1 == 0 */ {
3250 load_fr( R_ECX, R_ECX, FRm );
3251 store_fr( R_EDX, R_EAX, FRn );
3252 store_fr( R_EDX, R_ECX, FRn+1 );
3255 } else /* FRm&1 == 0 */ {
3258 load_xf_bank( R_ECX );
3259 load_fr( R_EDX, R_EAX, FRm );
3260 load_fr( R_EDX, R_EDX, FRm+1 );
3261 store_fr( R_ECX, R_EAX, FRn-1 );
3262 store_fr( R_ECX, R_EDX, FRn );
3264 } else /* FRn&1 == 0 */ {
3266 load_fr( R_EDX, R_EAX, FRm );
3267 load_fr( R_EDX, R_ECX, FRm+1 );
3268 store_fr( R_EDX, R_EAX, FRn );
3269 store_fr( R_EDX, R_ECX, FRn+1 );
3273 sh4_x86.tstate = TSTATE_NONE;
3277 switch( (ir&0xF0) >> 4 ) {
3279 { /* FSTS FPUL, FRn */
3280 uint32_t FRn = ((ir>>8)&0xF);
3282 load_fr_bank( R_ECX );
3283 load_spreg( R_EAX, R_FPUL );
3284 store_fr( R_ECX, R_EAX, FRn );
3285 sh4_x86.tstate = TSTATE_NONE;
3289 { /* FLDS FRm, FPUL */
3290 uint32_t FRm = ((ir>>8)&0xF);
3292 load_fr_bank( R_ECX );
3293 load_fr( R_ECX, R_EAX, FRm );
3294 store_spreg( R_EAX, R_FPUL );
3295 sh4_x86.tstate = TSTATE_NONE;
3299 { /* FLOAT FPUL, FRn */
3300 uint32_t FRn = ((ir>>8)&0xF);
3302 load_spreg( R_ECX, R_FPSCR );
3303 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3305 TEST_imm32_r32( FPSCR_PR, R_ECX );
3306 JNE_rel8(5, doubleprec);
3307 pop_fr( R_EDX, FRn );
3309 JMP_TARGET(doubleprec);
3310 pop_dr( R_EDX, FRn );
3312 sh4_x86.tstate = TSTATE_NONE;
3316 { /* FTRC FRm, FPUL */
3317 uint32_t FRm = ((ir>>8)&0xF);
3319 load_spreg( R_ECX, R_FPSCR );
3320 load_fr_bank( R_EDX );
3321 TEST_imm32_r32( FPSCR_PR, R_ECX );
3322 JNE_rel8(5, doubleprec);
3323 push_fr( R_EDX, FRm );
3325 JMP_TARGET(doubleprec);
3326 push_dr( R_EDX, FRm );
3328 load_imm32( R_ECX, (uint32_t)&max_int );
3329 FILD_r32ind( R_ECX );
3331 JNA_rel8( 32, sat );
3332 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3333 FILD_r32ind( R_ECX ); // 2
3335 JAE_rel8( 21, sat2 ); // 2
3336 load_imm32( R_EAX, (uint32_t)&save_fcw );
3337 FNSTCW_r32ind( R_EAX );
3338 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3339 FLDCW_r32ind( R_EDX );
3340 FISTP_sh4r(R_FPUL); // 3
3341 FLDCW_r32ind( R_EAX );
3342 JMP_rel8( 9, end ); // 2
3346 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3347 store_spreg( R_ECX, R_FPUL );
3350 sh4_x86.tstate = TSTATE_NONE;
3355 uint32_t FRn = ((ir>>8)&0xF);
3357 load_spreg( R_ECX, R_FPSCR );
3358 TEST_imm32_r32( FPSCR_PR, R_ECX );
3359 load_fr_bank( R_EDX );
3360 JNE_rel8(10, doubleprec);
3361 push_fr(R_EDX, FRn);
3365 JMP_TARGET(doubleprec);
3366 push_dr(R_EDX, FRn);
3370 sh4_x86.tstate = TSTATE_NONE;
3375 uint32_t FRn = ((ir>>8)&0xF);
3377 load_spreg( R_ECX, R_FPSCR );
3378 load_fr_bank( R_EDX );
3379 TEST_imm32_r32( FPSCR_PR, R_ECX );
3380 JNE_rel8(10, doubleprec);
3381 push_fr(R_EDX, FRn); // 3
3383 pop_fr( R_EDX, FRn); //3
3384 JMP_rel8(8,end); // 2
3385 JMP_TARGET(doubleprec);
3386 push_dr(R_EDX, FRn);
3390 sh4_x86.tstate = TSTATE_NONE;
3395 uint32_t FRn = ((ir>>8)&0xF);
3397 load_spreg( R_ECX, R_FPSCR );
3398 TEST_imm32_r32( FPSCR_PR, R_ECX );
3399 load_fr_bank( R_EDX );
3400 JNE_rel8(10, doubleprec);
3401 push_fr(R_EDX, FRn);
3405 JMP_TARGET(doubleprec);
3406 push_dr(R_EDX, FRn);
3410 sh4_x86.tstate = TSTATE_NONE;
3415 uint32_t FRn = ((ir>>8)&0xF);
3417 load_spreg( R_ECX, R_FPSCR );
3418 TEST_imm32_r32( FPSCR_PR, R_ECX );
3419 load_fr_bank( R_EDX );
3420 JNE_rel8(12, end); // PR=0 only
3422 push_fr(R_EDX, FRn);
3427 sh4_x86.tstate = TSTATE_NONE;
3432 uint32_t FRn = ((ir>>8)&0xF);
3435 load_spreg( R_ECX, R_FPSCR );
3436 TEST_imm32_r32( FPSCR_PR, R_ECX );
3438 XOR_r32_r32( R_EAX, R_EAX );
3439 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3440 store_fr( R_ECX, R_EAX, FRn );
3442 sh4_x86.tstate = TSTATE_NONE;
3447 uint32_t FRn = ((ir>>8)&0xF);
3450 load_spreg( R_ECX, R_FPSCR );
3451 TEST_imm32_r32( FPSCR_PR, R_ECX );
3453 load_imm32(R_EAX, 0x3F800000);
3454 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3455 store_fr( R_ECX, R_EAX, FRn );
3457 sh4_x86.tstate = TSTATE_NONE;
3461 { /* FCNVSD FPUL, FRn */
3462 uint32_t FRn = ((ir>>8)&0xF);
3464 load_spreg( R_ECX, R_FPSCR );
3465 TEST_imm32_r32( FPSCR_PR, R_ECX );
3466 JE_rel8(9, end); // only when PR=1
3467 load_fr_bank( R_ECX );
3469 pop_dr( R_ECX, FRn );
3471 sh4_x86.tstate = TSTATE_NONE;
3475 { /* FCNVDS FRm, FPUL */
3476 uint32_t FRm = ((ir>>8)&0xF);
3478 load_spreg( R_ECX, R_FPSCR );
3479 TEST_imm32_r32( FPSCR_PR, R_ECX );
3480 JE_rel8(9, end); // only when PR=1
3481 load_fr_bank( R_ECX );
3482 push_dr( R_ECX, FRm );
3485 sh4_x86.tstate = TSTATE_NONE;
3489 { /* FIPR FVm, FVn */
3490 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3492 load_spreg( R_ECX, R_FPSCR );
3493 TEST_imm32_r32( FPSCR_PR, R_ECX );
3494 JNE_rel8(44, doubleprec);
3496 load_fr_bank( R_ECX );
3497 push_fr( R_ECX, FVm<<2 );
3498 push_fr( R_ECX, FVn<<2 );
3500 push_fr( R_ECX, (FVm<<2)+1);
3501 push_fr( R_ECX, (FVn<<2)+1);
3504 push_fr( R_ECX, (FVm<<2)+2);
3505 push_fr( R_ECX, (FVn<<2)+2);
3508 push_fr( R_ECX, (FVm<<2)+3);
3509 push_fr( R_ECX, (FVn<<2)+3);
3512 pop_fr( R_ECX, (FVn<<2)+3);
3513 JMP_TARGET(doubleprec);
3514 sh4_x86.tstate = TSTATE_NONE;
3518 switch( (ir&0x100) >> 8 ) {
3520 { /* FSCA FPUL, FRn */
3521 uint32_t FRn = ((ir>>9)&0x7)<<1;
3523 load_spreg( R_ECX, R_FPSCR );
3524 TEST_imm32_r32( FPSCR_PR, R_ECX );
3525 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3526 load_fr_bank( R_ECX );
3527 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3528 load_spreg( R_EDX, R_FPUL );
3529 call_func2( sh4_fsca, R_EDX, R_ECX );
3530 JMP_TARGET(doubleprec);
3531 sh4_x86.tstate = TSTATE_NONE;
3535 switch( (ir&0x200) >> 9 ) {
3537 { /* FTRV XMTRX, FVn */
3538 uint32_t FVn = ((ir>>10)&0x3);
3540 load_spreg( R_ECX, R_FPSCR );
3541 TEST_imm32_r32( FPSCR_PR, R_ECX );
3542 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3543 load_fr_bank( R_EDX ); // 3
3544 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3545 load_xf_bank( R_ECX ); // 12
3546 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3547 JMP_TARGET(doubleprec);
3548 sh4_x86.tstate = TSTATE_NONE;
3552 switch( (ir&0xC00) >> 10 ) {
3556 load_spreg( R_ECX, R_FPSCR );
3557 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3558 store_spreg( R_ECX, R_FPSCR );
3559 sh4_x86.tstate = TSTATE_NONE;
3565 load_spreg( R_ECX, R_FPSCR );
3566 XOR_imm32_r32( FPSCR_FR, R_ECX );
3567 store_spreg( R_ECX, R_FPSCR );
3568 update_fr_bank( R_ECX );
3569 sh4_x86.tstate = TSTATE_NONE;
3574 if( sh4_x86.in_delay_slot ) {
3577 JMP_exc(EXC_ILLEGAL);
3597 { /* FMAC FR0, FRm, FRn */
3598 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3600 load_spreg( R_ECX, R_FPSCR );
3601 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3602 TEST_imm32_r32( FPSCR_PR, R_ECX );
3603 JNE_rel8(18, doubleprec);
3604 push_fr( R_EDX, 0 );
3605 push_fr( R_EDX, FRm );
3607 push_fr( R_EDX, FRn );
3609 pop_fr( R_EDX, FRn );
3611 JMP_TARGET(doubleprec);
3612 push_dr( R_EDX, 0 );
3613 push_dr( R_EDX, FRm );
3615 push_dr( R_EDX, FRn );
3617 pop_dr( R_EDX, FRn );
3619 sh4_x86.tstate = TSTATE_NONE;
3629 sh4_x86.in_delay_slot = DELAY_NONE;
.