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/sh4stat.h"
32 #include "sh4/sh4mmio.h"
33 #include "sh4/x86op.h"
36 #define DEFAULT_BACKPATCH_SIZE 4096
38 struct backpatch_record {
39 uint32_t fixup_offset;
40 uint32_t fixup_icount;
44 #define MAX_RECOVERY_SIZE 2048
51 * Struct to manage internal translation state. This state is not saved -
52 * it is only valid between calls to sh4_translate_begin_block() and
53 * sh4_translate_end_block()
55 struct sh4_x86_state {
57 gboolean priv_checked; /* true if we've already checked the cpu mode. */
58 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
59 gboolean branch_taken; /* true if we branched unconditionally */
60 uint32_t block_start_pc;
61 uint32_t stack_posn; /* Trace stack height for alignment purposes */
65 gboolean tlb_on; /* True if tlb translation is active */
67 /* Allocated memory for the (block-wide) back-patch list */
68 struct backpatch_record *backpatch_list;
69 uint32_t backpatch_posn;
70 uint32_t backpatch_size;
73 #define TSTATE_NONE -1
83 #ifdef ENABLE_SH4STATS
84 #define COUNT_INST(id) load_imm32(R_EAX,id); call_func1(sh4_stats_add, R_EAX); sh4_x86.tstate = TSTATE_NONE
86 #define COUNT_INST(id)
89 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
90 #define JT_rel8(label) if( sh4_x86.tstate == TSTATE_NONE ) { \
91 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
92 OP(0x70+sh4_x86.tstate); MARK_JMP8(label); OP(-1)
94 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
95 #define JF_rel8(label) if( sh4_x86.tstate == TSTATE_NONE ) { \
96 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
97 OP(0x70+ (sh4_x86.tstate^1)); MARK_JMP8(label); OP(-1)
99 static struct sh4_x86_state sh4_x86;
101 static uint32_t max_int = 0x7FFFFFFF;
102 static uint32_t min_int = 0x80000000;
103 static uint32_t save_fcw; /* save value for fpu control word */
104 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
106 void sh4_translate_init(void)
108 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
109 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
113 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
115 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
116 sh4_x86.backpatch_size <<= 1;
117 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
118 sh4_x86.backpatch_size * sizeof(struct backpatch_record));
119 assert( sh4_x86.backpatch_list != NULL );
121 if( sh4_x86.in_delay_slot ) {
124 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_offset =
125 ((uint8_t *)fixup_addr) - ((uint8_t *)xlat_current_block->code);
126 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
127 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
128 sh4_x86.backpatch_posn++;
132 * Emit an instruction to load an SH4 reg into a real register
134 static inline void load_reg( int x86reg, int sh4reg )
136 /* mov [bp+n], reg */
138 OP(0x45 + (x86reg<<3));
139 OP(REG_OFFSET(r[sh4reg]));
142 static inline void load_reg16s( int x86reg, int sh4reg )
146 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
149 static inline void load_reg16u( int x86reg, int sh4reg )
153 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
157 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
158 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
160 * Emit an instruction to load an immediate value into a register
162 static inline void load_imm32( int x86reg, uint32_t value ) {
163 /* mov #value, reg */
169 * Load an immediate 64-bit quantity (note: x86-64 only)
171 static inline void load_imm64( int x86reg, uint32_t value ) {
172 /* mov #value, reg */
179 * Emit an instruction to store an SH4 reg (RN)
181 void static inline store_reg( int x86reg, int sh4reg ) {
182 /* mov reg, [bp+n] */
184 OP(0x45 + (x86reg<<3));
185 OP(REG_OFFSET(r[sh4reg]));
189 * Load an FR register (single-precision floating point) into an integer x86
190 * register (eg for register-to-register moves)
192 #define load_fr(reg,frm) OP(0x8B); MODRM_r32_ebp32(reg, REG_OFFSET(fr[0][(frm)^1]) )
193 #define load_xf(reg,frm) OP(0x8B); MODRM_r32_ebp32(reg, REG_OFFSET(fr[1][(frm)^1]) )
196 * Load the low half of a DR register (DR or XD) into an integer x86 register
198 #define load_dr0(reg,frm) OP(0x8B); MODRM_r32_ebp32(reg, REG_OFFSET(fr[frm&1][frm|0x01]) )
199 #define load_dr1(reg,frm) OP(0x8B); MODRM_r32_ebp32(reg, REG_OFFSET(fr[frm&1][frm&0x0E]) )
202 * Store an FR register (single-precision floating point) from an integer x86+
203 * register (eg for register-to-register moves)
205 #define store_fr(reg,frm) OP(0x89); MODRM_r32_ebp32( reg, REG_OFFSET(fr[0][(frm)^1]) )
206 #define store_xf(reg,frm) OP(0x89); MODRM_r32_ebp32( reg, REG_OFFSET(fr[1][(frm)^1]) )
208 #define store_dr0(reg,frm) OP(0x89); MODRM_r32_ebp32( reg, REG_OFFSET(fr[frm&1][frm|0x01]) )
209 #define store_dr1(reg,frm) OP(0x89); MODRM_r32_ebp32( reg, REG_OFFSET(fr[frm&1][frm&0x0E]) )
212 #define push_fpul() FLDF_sh4r(R_FPUL)
213 #define pop_fpul() FSTPF_sh4r(R_FPUL)
214 #define push_fr(frm) FLDF_sh4r( REG_OFFSET(fr[0][(frm)^1]) )
215 #define pop_fr(frm) FSTPF_sh4r( REG_OFFSET(fr[0][(frm)^1]) )
216 #define push_xf(frm) FLDF_sh4r( REG_OFFSET(fr[1][(frm)^1]) )
217 #define pop_xf(frm) FSTPF_sh4r( REG_OFFSET(fr[1][(frm)^1]) )
218 #define push_dr(frm) FLDD_sh4r( REG_OFFSET(fr[0][(frm)&0x0E]) )
219 #define pop_dr(frm) FSTPD_sh4r( REG_OFFSET(fr[0][(frm)&0x0E]) )
220 #define push_xdr(frm) FLDD_sh4r( REG_OFFSET(fr[1][(frm)&0x0E]) )
221 #define pop_xdr(frm) FSTPD_sh4r( REG_OFFSET(fr[1][(frm)&0x0E]) )
225 /* Exception checks - Note that all exception checks will clobber EAX */
227 #define check_priv( ) \
228 if( !sh4_x86.priv_checked ) { \
229 sh4_x86.priv_checked = TRUE;\
230 load_spreg( R_EAX, R_SR );\
231 AND_imm32_r32( SR_MD, R_EAX );\
232 if( sh4_x86.in_delay_slot ) {\
233 JE_exc( EXC_SLOT_ILLEGAL );\
235 JE_exc( EXC_ILLEGAL );\
239 #define check_fpuen( ) \
240 if( !sh4_x86.fpuen_checked ) {\
241 sh4_x86.fpuen_checked = TRUE;\
242 load_spreg( R_EAX, R_SR );\
243 AND_imm32_r32( SR_FD, R_EAX );\
244 if( sh4_x86.in_delay_slot ) {\
245 JNE_exc(EXC_SLOT_FPU_DISABLED);\
247 JNE_exc(EXC_FPU_DISABLED);\
251 #define check_ralign16( x86reg ) \
252 TEST_imm32_r32( 0x00000001, x86reg ); \
253 JNE_exc(EXC_DATA_ADDR_READ)
255 #define check_walign16( x86reg ) \
256 TEST_imm32_r32( 0x00000001, x86reg ); \
257 JNE_exc(EXC_DATA_ADDR_WRITE);
259 #define check_ralign32( x86reg ) \
260 TEST_imm32_r32( 0x00000003, x86reg ); \
261 JNE_exc(EXC_DATA_ADDR_READ)
263 #define check_walign32( x86reg ) \
264 TEST_imm32_r32( 0x00000003, x86reg ); \
265 JNE_exc(EXC_DATA_ADDR_WRITE);
268 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
269 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
270 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
271 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
272 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
273 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
274 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
277 * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
278 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
280 #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); }
282 #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) }
284 * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
285 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
287 #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); }
289 #define MEM_READ_SIZE (CALL_FUNC1_SIZE)
290 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
291 #define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
293 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = DELAY_NONE; return 1;
295 /****** Import appropriate calling conventions ******/
296 #if SH4_TRANSLATOR == TARGET_X86_64
297 #include "sh4/ia64abi.h"
298 #else /* SH4_TRANSLATOR == TARGET_X86 */
300 #include "sh4/ia32mac.h"
302 #include "sh4/ia32abi.h"
306 uint32_t sh4_translate_end_block_size()
308 if( sh4_x86.backpatch_posn <= 3 ) {
309 return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
311 return EPILOGUE_SIZE + 48 + (sh4_x86.backpatch_posn-3)*15;
317 * Embed a breakpoint into the generated code
319 void sh4_translate_emit_breakpoint( sh4vma_t pc )
321 load_imm32( R_EAX, pc );
322 call_func1( sh4_translate_breakpoint_hit, R_EAX );
326 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
329 * Embed a call to sh4_execute_instruction for situations that we
330 * can't translate (just page-crossing delay slots at the moment).
331 * Caller is responsible for setting new_pc before calling this function.
335 * Set sh4r.in_delay_slot = sh4_x86.in_delay_slot
336 * Update slice_cycle for endpc+2 (single step doesn't update slice_cycle)
337 * Call sh4_execute_instruction
338 * Call xlat_get_code_by_vma / xlat_get_code as for normal exit
340 void exit_block_emu( sh4vma_t endpc )
342 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 5
343 ADD_r32_sh4r( R_ECX, R_PC );
345 load_imm32( R_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 5
346 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
347 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );
348 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );
350 call_func0( sh4_execute_instruction );
351 load_spreg( R_EAX, R_PC );
352 if( sh4_x86.tlb_on ) {
353 call_func1(xlat_get_code_by_vma,R_EAX);
355 call_func1(xlat_get_code,R_EAX);
357 AND_imm8s_rptr( 0xFC, R_EAX );
363 * Translate a single instruction. Delayed branches are handled specially
364 * by translating both branch and delayed instruction as a single unit (as
366 * The instruction MUST be in the icache (assert check)
368 * @return true if the instruction marks the end of a basic block
371 uint32_t sh4_translate_instruction( sh4vma_t pc )
374 /* Read instruction from icache */
375 assert( IS_IN_ICACHE(pc) );
376 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
378 /* PC is not in the current icache - this usually means we're running
379 * with MMU on, and we've gone past the end of the page. And since
380 * sh4_translate_block is pretty careful about this, it means we're
381 * almost certainly in a delay slot.
383 * Since we can't assume the page is present (and we can't fault it in
384 * at this point, inline a call to sh4_execute_instruction (with a few
385 * small repairs to cope with the different environment).
388 if( !sh4_x86.in_delay_slot ) {
389 sh4_translate_add_recovery( (pc - sh4_x86.block_start_pc)>>1 );
391 switch( (ir&0xF000) >> 12 ) {
395 switch( (ir&0x80) >> 7 ) {
397 switch( (ir&0x70) >> 4 ) {
400 uint32_t Rn = ((ir>>8)&0xF);
403 call_func0(sh4_read_sr);
404 store_reg( R_EAX, Rn );
405 sh4_x86.tstate = TSTATE_NONE;
410 uint32_t Rn = ((ir>>8)&0xF);
412 load_spreg( R_EAX, R_GBR );
413 store_reg( R_EAX, Rn );
418 uint32_t Rn = ((ir>>8)&0xF);
421 load_spreg( R_EAX, R_VBR );
422 store_reg( R_EAX, Rn );
423 sh4_x86.tstate = TSTATE_NONE;
428 uint32_t Rn = ((ir>>8)&0xF);
431 load_spreg( R_EAX, R_SSR );
432 store_reg( R_EAX, Rn );
433 sh4_x86.tstate = TSTATE_NONE;
438 uint32_t Rn = ((ir>>8)&0xF);
441 load_spreg( R_EAX, R_SPC );
442 store_reg( R_EAX, Rn );
443 sh4_x86.tstate = TSTATE_NONE;
452 { /* STC Rm_BANK, Rn */
453 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
456 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
457 store_reg( R_EAX, Rn );
458 sh4_x86.tstate = TSTATE_NONE;
464 switch( (ir&0xF0) >> 4 ) {
467 uint32_t Rn = ((ir>>8)&0xF);
469 if( sh4_x86.in_delay_slot ) {
472 load_spreg( R_EAX, R_PC );
473 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
474 store_spreg( R_EAX, R_PR );
475 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
476 store_spreg( R_EAX, R_NEW_PC );
478 sh4_x86.in_delay_slot = DELAY_PC;
479 sh4_x86.tstate = TSTATE_NONE;
480 sh4_x86.branch_taken = TRUE;
481 if( UNTRANSLATABLE(pc+2) ) {
482 exit_block_emu(pc+2);
485 sh4_translate_instruction( pc + 2 );
486 exit_block_newpcset(pc+2);
494 uint32_t Rn = ((ir>>8)&0xF);
496 if( sh4_x86.in_delay_slot ) {
499 load_spreg( R_EAX, R_PC );
500 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
501 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
502 store_spreg( R_EAX, R_NEW_PC );
503 sh4_x86.in_delay_slot = DELAY_PC;
504 sh4_x86.tstate = TSTATE_NONE;
505 sh4_x86.branch_taken = TRUE;
506 if( UNTRANSLATABLE(pc+2) ) {
507 exit_block_emu(pc+2);
510 sh4_translate_instruction( pc + 2 );
511 exit_block_newpcset(pc+2);
519 uint32_t Rn = ((ir>>8)&0xF);
521 load_reg( R_EAX, Rn );
522 MOV_r32_r32( R_EAX, R_ECX );
523 AND_imm32_r32( 0xFC000000, R_EAX );
524 CMP_imm32_r32( 0xE0000000, R_EAX );
526 call_func1( sh4_flush_store_queue, R_ECX );
527 TEST_r32_r32( R_EAX, R_EAX );
530 sh4_x86.tstate = TSTATE_NONE;
535 uint32_t Rn = ((ir>>8)&0xF);
541 uint32_t Rn = ((ir>>8)&0xF);
547 uint32_t Rn = ((ir>>8)&0xF);
552 { /* MOVCA.L R0, @Rn */
553 uint32_t Rn = ((ir>>8)&0xF);
555 load_reg( R_EAX, Rn );
556 check_walign32( R_EAX );
557 MMU_TRANSLATE_WRITE( R_EAX );
558 load_reg( R_EDX, 0 );
559 MEM_WRITE_LONG( R_EAX, R_EDX );
560 sh4_x86.tstate = TSTATE_NONE;
569 { /* MOV.B Rm, @(R0, Rn) */
570 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
572 load_reg( R_EAX, 0 );
573 load_reg( R_ECX, Rn );
574 ADD_r32_r32( R_ECX, R_EAX );
575 MMU_TRANSLATE_WRITE( R_EAX );
576 load_reg( R_EDX, Rm );
577 MEM_WRITE_BYTE( R_EAX, R_EDX );
578 sh4_x86.tstate = TSTATE_NONE;
582 { /* MOV.W Rm, @(R0, Rn) */
583 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
585 load_reg( R_EAX, 0 );
586 load_reg( R_ECX, Rn );
587 ADD_r32_r32( R_ECX, R_EAX );
588 check_walign16( R_EAX );
589 MMU_TRANSLATE_WRITE( R_EAX );
590 load_reg( R_EDX, Rm );
591 MEM_WRITE_WORD( R_EAX, R_EDX );
592 sh4_x86.tstate = TSTATE_NONE;
596 { /* MOV.L Rm, @(R0, Rn) */
597 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
599 load_reg( R_EAX, 0 );
600 load_reg( R_ECX, Rn );
601 ADD_r32_r32( R_ECX, R_EAX );
602 check_walign32( R_EAX );
603 MMU_TRANSLATE_WRITE( R_EAX );
604 load_reg( R_EDX, Rm );
605 MEM_WRITE_LONG( R_EAX, R_EDX );
606 sh4_x86.tstate = TSTATE_NONE;
611 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
613 load_reg( R_EAX, Rm );
614 load_reg( R_ECX, Rn );
616 store_spreg( R_EAX, R_MACL );
617 sh4_x86.tstate = TSTATE_NONE;
621 switch( (ir&0xFF0) >> 4 ) {
627 sh4_x86.tstate = TSTATE_C;
635 sh4_x86.tstate = TSTATE_C;
640 COUNT_INST(I_CLRMAC);
641 XOR_r32_r32(R_EAX, R_EAX);
642 store_spreg( R_EAX, R_MACL );
643 store_spreg( R_EAX, R_MACH );
644 sh4_x86.tstate = TSTATE_NONE;
650 call_func0( MMU_ldtlb );
658 sh4_x86.tstate = TSTATE_C;
666 sh4_x86.tstate = TSTATE_C;
675 switch( (ir&0xF0) >> 4 ) {
679 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
685 XOR_r32_r32( R_EAX, R_EAX );
686 store_spreg( R_EAX, R_Q );
687 store_spreg( R_EAX, R_M );
688 store_spreg( R_EAX, R_T );
689 sh4_x86.tstate = TSTATE_C; // works for DIV1
694 uint32_t Rn = ((ir>>8)&0xF);
696 load_spreg( R_EAX, R_T );
697 store_reg( R_EAX, Rn );
706 switch( (ir&0xF0) >> 4 ) {
709 uint32_t Rn = ((ir>>8)&0xF);
711 load_spreg( R_EAX, R_MACH );
712 store_reg( R_EAX, Rn );
717 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);
727 load_spreg( R_EAX, R_PR );
728 store_reg( R_EAX, Rn );
733 uint32_t Rn = ((ir>>8)&0xF);
736 load_spreg( R_EAX, R_SGR );
737 store_reg( R_EAX, Rn );
738 sh4_x86.tstate = TSTATE_NONE;
743 uint32_t Rn = ((ir>>8)&0xF);
746 load_spreg( R_EAX, R_FPUL );
747 store_reg( R_EAX, Rn );
751 { /* STS FPSCR, Rn */
752 uint32_t Rn = ((ir>>8)&0xF);
753 COUNT_INST(I_STSFPSCR);
755 load_spreg( R_EAX, R_FPSCR );
756 store_reg( R_EAX, Rn );
761 uint32_t Rn = ((ir>>8)&0xF);
764 load_spreg( R_EAX, R_DBR );
765 store_reg( R_EAX, Rn );
766 sh4_x86.tstate = TSTATE_NONE;
775 switch( (ir&0xFF0) >> 4 ) {
779 if( sh4_x86.in_delay_slot ) {
782 load_spreg( R_ECX, R_PR );
783 store_spreg( R_ECX, R_NEW_PC );
784 sh4_x86.in_delay_slot = DELAY_PC;
785 sh4_x86.branch_taken = TRUE;
786 if( UNTRANSLATABLE(pc+2) ) {
787 exit_block_emu(pc+2);
790 sh4_translate_instruction(pc+2);
791 exit_block_newpcset(pc+2);
801 call_func0( sh4_sleep );
802 sh4_x86.tstate = TSTATE_NONE;
803 sh4_x86.in_delay_slot = DELAY_NONE;
810 if( sh4_x86.in_delay_slot ) {
814 load_spreg( R_ECX, R_SPC );
815 store_spreg( R_ECX, R_NEW_PC );
816 load_spreg( R_EAX, R_SSR );
817 call_func1( sh4_write_sr, R_EAX );
818 sh4_x86.in_delay_slot = DELAY_PC;
819 sh4_x86.priv_checked = FALSE;
820 sh4_x86.fpuen_checked = FALSE;
821 sh4_x86.tstate = TSTATE_NONE;
822 sh4_x86.branch_taken = TRUE;
823 if( UNTRANSLATABLE(pc+2) ) {
824 exit_block_emu(pc+2);
827 sh4_translate_instruction(pc+2);
828 exit_block_newpcset(pc+2);
840 { /* MOV.B @(R0, Rm), Rn */
841 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
843 load_reg( R_EAX, 0 );
844 load_reg( R_ECX, Rm );
845 ADD_r32_r32( R_ECX, R_EAX );
846 MMU_TRANSLATE_READ( R_EAX )
847 MEM_READ_BYTE( R_EAX, R_EAX );
848 store_reg( R_EAX, Rn );
849 sh4_x86.tstate = TSTATE_NONE;
853 { /* MOV.W @(R0, Rm), Rn */
854 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 check_ralign16( R_EAX );
860 MMU_TRANSLATE_READ( R_EAX );
861 MEM_READ_WORD( R_EAX, R_EAX );
862 store_reg( R_EAX, Rn );
863 sh4_x86.tstate = TSTATE_NONE;
867 { /* MOV.L @(R0, Rm), Rn */
868 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
870 load_reg( R_EAX, 0 );
871 load_reg( R_ECX, Rm );
872 ADD_r32_r32( R_ECX, R_EAX );
873 check_ralign32( R_EAX );
874 MMU_TRANSLATE_READ( R_EAX );
875 MEM_READ_LONG( R_EAX, R_EAX );
876 store_reg( R_EAX, Rn );
877 sh4_x86.tstate = TSTATE_NONE;
881 { /* MAC.L @Rm+, @Rn+ */
882 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
885 load_reg( R_EAX, Rm );
886 check_ralign32( R_EAX );
887 MMU_TRANSLATE_READ( R_EAX );
888 PUSH_realigned_r32( R_EAX );
889 load_reg( R_EAX, Rn );
890 ADD_imm8s_r32( 4, R_EAX );
891 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
892 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
893 // Note translate twice in case of page boundaries. Maybe worth
894 // adding a page-boundary check to skip the second translation
896 load_reg( R_EAX, Rm );
897 check_ralign32( R_EAX );
898 MMU_TRANSLATE_READ( R_EAX );
899 load_reg( R_ECX, Rn );
900 check_ralign32( R_ECX );
901 PUSH_realigned_r32( R_EAX );
902 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
903 MOV_r32_r32( R_ECX, R_EAX );
904 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
905 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
907 MEM_READ_LONG( R_EAX, R_EAX );
910 MEM_READ_LONG( R_ECX, R_EAX );
911 POP_realigned_r32( R_ECX );
914 ADD_r32_sh4r( R_EAX, R_MACL );
915 ADC_r32_sh4r( R_EDX, R_MACH );
917 load_spreg( R_ECX, R_S );
918 TEST_r32_r32(R_ECX, R_ECX);
920 call_func0( signsat48 );
922 sh4_x86.tstate = TSTATE_NONE;
931 { /* MOV.L Rm, @(disp, Rn) */
932 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
934 load_reg( R_EAX, Rn );
935 ADD_imm32_r32( disp, R_EAX );
936 check_walign32( R_EAX );
937 MMU_TRANSLATE_WRITE( R_EAX );
938 load_reg( R_EDX, Rm );
939 MEM_WRITE_LONG( R_EAX, R_EDX );
940 sh4_x86.tstate = TSTATE_NONE;
946 { /* MOV.B Rm, @Rn */
947 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
949 load_reg( R_EAX, Rn );
950 MMU_TRANSLATE_WRITE( R_EAX );
951 load_reg( R_EDX, Rm );
952 MEM_WRITE_BYTE( R_EAX, R_EDX );
953 sh4_x86.tstate = TSTATE_NONE;
957 { /* MOV.W Rm, @Rn */
958 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
960 load_reg( R_EAX, Rn );
961 check_walign16( R_EAX );
962 MMU_TRANSLATE_WRITE( R_EAX )
963 load_reg( R_EDX, Rm );
964 MEM_WRITE_WORD( R_EAX, R_EDX );
965 sh4_x86.tstate = TSTATE_NONE;
969 { /* MOV.L Rm, @Rn */
970 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
972 load_reg( R_EAX, Rn );
973 check_walign32(R_EAX);
974 MMU_TRANSLATE_WRITE( R_EAX );
975 load_reg( R_EDX, Rm );
976 MEM_WRITE_LONG( R_EAX, R_EDX );
977 sh4_x86.tstate = TSTATE_NONE;
981 { /* MOV.B Rm, @-Rn */
982 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
984 load_reg( R_EAX, Rn );
985 ADD_imm8s_r32( -1, R_EAX );
986 MMU_TRANSLATE_WRITE( R_EAX );
987 load_reg( R_EDX, Rm );
988 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
989 MEM_WRITE_BYTE( R_EAX, R_EDX );
990 sh4_x86.tstate = TSTATE_NONE;
994 { /* MOV.W Rm, @-Rn */
995 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
997 load_reg( R_EAX, Rn );
998 ADD_imm8s_r32( -2, R_EAX );
999 check_walign16( R_EAX );
1000 MMU_TRANSLATE_WRITE( R_EAX );
1001 load_reg( R_EDX, Rm );
1002 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
1003 MEM_WRITE_WORD( R_EAX, R_EDX );
1004 sh4_x86.tstate = TSTATE_NONE;
1008 { /* MOV.L Rm, @-Rn */
1009 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1011 load_reg( R_EAX, Rn );
1012 ADD_imm8s_r32( -4, R_EAX );
1013 check_walign32( R_EAX );
1014 MMU_TRANSLATE_WRITE( R_EAX );
1015 load_reg( R_EDX, Rm );
1016 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1017 MEM_WRITE_LONG( R_EAX, R_EDX );
1018 sh4_x86.tstate = TSTATE_NONE;
1022 { /* DIV0S Rm, Rn */
1023 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1024 COUNT_INST(I_DIV0S);
1025 load_reg( R_EAX, Rm );
1026 load_reg( R_ECX, Rn );
1027 SHR_imm8_r32( 31, R_EAX );
1028 SHR_imm8_r32( 31, R_ECX );
1029 store_spreg( R_EAX, R_M );
1030 store_spreg( R_ECX, R_Q );
1031 CMP_r32_r32( R_EAX, R_ECX );
1033 sh4_x86.tstate = TSTATE_NE;
1038 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1040 load_reg( R_EAX, Rm );
1041 load_reg( R_ECX, Rn );
1042 TEST_r32_r32( R_EAX, R_ECX );
1044 sh4_x86.tstate = TSTATE_E;
1049 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);
1062 load_reg( R_EAX, Rm );
1063 load_reg( R_ECX, Rn );
1064 XOR_r32_r32( R_EAX, R_ECX );
1065 store_reg( R_ECX, Rn );
1066 sh4_x86.tstate = TSTATE_NONE;
1071 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1073 load_reg( R_EAX, Rm );
1074 load_reg( R_ECX, Rn );
1075 OR_r32_r32( R_EAX, R_ECX );
1076 store_reg( R_ECX, Rn );
1077 sh4_x86.tstate = TSTATE_NONE;
1081 { /* CMP/STR Rm, Rn */
1082 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1083 COUNT_INST(I_CMPSTR);
1084 load_reg( R_EAX, Rm );
1085 load_reg( R_ECX, Rn );
1086 XOR_r32_r32( R_ECX, R_EAX );
1087 TEST_r8_r8( R_AL, R_AL );
1089 TEST_r8_r8( R_AH, R_AH );
1091 SHR_imm8_r32( 16, R_EAX );
1092 TEST_r8_r8( R_AL, R_AL );
1094 TEST_r8_r8( R_AH, R_AH );
1095 JMP_TARGET(target1);
1096 JMP_TARGET(target2);
1097 JMP_TARGET(target3);
1099 sh4_x86.tstate = TSTATE_E;
1103 { /* XTRCT Rm, Rn */
1104 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1105 COUNT_INST(I_XTRCT);
1106 load_reg( R_EAX, Rm );
1107 load_reg( R_ECX, Rn );
1108 SHL_imm8_r32( 16, R_EAX );
1109 SHR_imm8_r32( 16, R_ECX );
1110 OR_r32_r32( R_EAX, R_ECX );
1111 store_reg( R_ECX, Rn );
1112 sh4_x86.tstate = TSTATE_NONE;
1116 { /* MULU.W Rm, Rn */
1117 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1118 COUNT_INST(I_MULUW);
1119 load_reg16u( R_EAX, Rm );
1120 load_reg16u( R_ECX, Rn );
1122 store_spreg( R_EAX, R_MACL );
1123 sh4_x86.tstate = TSTATE_NONE;
1127 { /* MULS.W Rm, Rn */
1128 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1129 COUNT_INST(I_MULSW);
1130 load_reg16s( R_EAX, Rm );
1131 load_reg16s( R_ECX, Rn );
1133 store_spreg( R_EAX, R_MACL );
1134 sh4_x86.tstate = TSTATE_NONE;
1145 { /* CMP/EQ Rm, Rn */
1146 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1147 COUNT_INST(I_CMPEQ);
1148 load_reg( R_EAX, Rm );
1149 load_reg( R_ECX, Rn );
1150 CMP_r32_r32( R_EAX, R_ECX );
1152 sh4_x86.tstate = TSTATE_E;
1156 { /* CMP/HS Rm, Rn */
1157 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1158 COUNT_INST(I_CMPHS);
1159 load_reg( R_EAX, Rm );
1160 load_reg( R_ECX, Rn );
1161 CMP_r32_r32( R_EAX, R_ECX );
1163 sh4_x86.tstate = TSTATE_AE;
1167 { /* CMP/GE Rm, Rn */
1168 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1169 COUNT_INST(I_CMPGE);
1170 load_reg( R_EAX, Rm );
1171 load_reg( R_ECX, Rn );
1172 CMP_r32_r32( R_EAX, R_ECX );
1174 sh4_x86.tstate = TSTATE_GE;
1179 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1181 load_spreg( R_ECX, R_M );
1182 load_reg( R_EAX, Rn );
1183 if( sh4_x86.tstate != TSTATE_C ) {
1187 SETC_r8( R_DL ); // Q'
1188 CMP_sh4r_r32( R_Q, R_ECX );
1190 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1192 JMP_TARGET(mqequal);
1193 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1195 store_reg( R_EAX, Rn ); // Done with Rn now
1196 SETC_r8(R_AL); // tmp1
1197 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1198 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1199 store_spreg( R_ECX, R_Q );
1200 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1201 MOVZX_r8_r32( R_AL, R_EAX );
1202 store_spreg( R_EAX, R_T );
1203 sh4_x86.tstate = TSTATE_NONE;
1207 { /* DMULU.L Rm, Rn */
1208 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1209 COUNT_INST(I_DMULU);
1210 load_reg( R_EAX, Rm );
1211 load_reg( R_ECX, Rn );
1213 store_spreg( R_EDX, R_MACH );
1214 store_spreg( R_EAX, R_MACL );
1215 sh4_x86.tstate = TSTATE_NONE;
1219 { /* CMP/HI Rm, Rn */
1220 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1221 COUNT_INST(I_CMPHI);
1222 load_reg( R_EAX, Rm );
1223 load_reg( R_ECX, Rn );
1224 CMP_r32_r32( R_EAX, R_ECX );
1226 sh4_x86.tstate = TSTATE_A;
1230 { /* CMP/GT Rm, Rn */
1231 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1232 COUNT_INST(I_CMPGT);
1233 load_reg( R_EAX, Rm );
1234 load_reg( R_ECX, Rn );
1235 CMP_r32_r32( R_EAX, R_ECX );
1237 sh4_x86.tstate = TSTATE_G;
1242 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1244 load_reg( R_EAX, Rm );
1245 load_reg( R_ECX, Rn );
1246 SUB_r32_r32( R_EAX, R_ECX );
1247 store_reg( R_ECX, Rn );
1248 sh4_x86.tstate = TSTATE_NONE;
1253 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1255 load_reg( R_EAX, Rm );
1256 load_reg( R_ECX, Rn );
1257 if( sh4_x86.tstate != TSTATE_C ) {
1260 SBB_r32_r32( R_EAX, R_ECX );
1261 store_reg( R_ECX, Rn );
1263 sh4_x86.tstate = TSTATE_C;
1268 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1270 load_reg( R_EAX, Rm );
1271 load_reg( R_ECX, Rn );
1272 SUB_r32_r32( R_EAX, R_ECX );
1273 store_reg( R_ECX, Rn );
1275 sh4_x86.tstate = TSTATE_O;
1280 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1282 load_reg( R_EAX, Rm );
1283 load_reg( R_ECX, Rn );
1284 ADD_r32_r32( R_EAX, R_ECX );
1285 store_reg( R_ECX, Rn );
1286 sh4_x86.tstate = TSTATE_NONE;
1290 { /* DMULS.L Rm, Rn */
1291 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1292 COUNT_INST(I_DMULS);
1293 load_reg( R_EAX, Rm );
1294 load_reg( R_ECX, Rn );
1296 store_spreg( R_EDX, R_MACH );
1297 store_spreg( R_EAX, R_MACL );
1298 sh4_x86.tstate = TSTATE_NONE;
1303 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1305 if( sh4_x86.tstate != TSTATE_C ) {
1308 load_reg( R_EAX, Rm );
1309 load_reg( R_ECX, Rn );
1310 ADC_r32_r32( R_EAX, R_ECX );
1311 store_reg( R_ECX, Rn );
1313 sh4_x86.tstate = TSTATE_C;
1318 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1320 load_reg( R_EAX, Rm );
1321 load_reg( R_ECX, Rn );
1322 ADD_r32_r32( R_EAX, R_ECX );
1323 store_reg( R_ECX, Rn );
1325 sh4_x86.tstate = TSTATE_O;
1336 switch( (ir&0xF0) >> 4 ) {
1339 uint32_t Rn = ((ir>>8)&0xF);
1341 load_reg( R_EAX, Rn );
1344 store_reg( R_EAX, Rn );
1345 sh4_x86.tstate = TSTATE_C;
1350 uint32_t Rn = ((ir>>8)&0xF);
1352 load_reg( R_EAX, Rn );
1353 ADD_imm8s_r32( -1, R_EAX );
1354 store_reg( R_EAX, Rn );
1356 sh4_x86.tstate = TSTATE_E;
1361 uint32_t Rn = ((ir>>8)&0xF);
1363 load_reg( R_EAX, Rn );
1366 store_reg( R_EAX, Rn );
1367 sh4_x86.tstate = TSTATE_C;
1376 switch( (ir&0xF0) >> 4 ) {
1379 uint32_t Rn = ((ir>>8)&0xF);
1381 load_reg( R_EAX, Rn );
1384 store_reg( R_EAX, Rn );
1385 sh4_x86.tstate = TSTATE_C;
1390 uint32_t Rn = ((ir>>8)&0xF);
1391 COUNT_INST(I_CMPPZ);
1392 load_reg( R_EAX, Rn );
1393 CMP_imm8s_r32( 0, R_EAX );
1395 sh4_x86.tstate = TSTATE_GE;
1400 uint32_t Rn = ((ir>>8)&0xF);
1402 load_reg( R_EAX, Rn );
1405 store_reg( R_EAX, Rn );
1406 sh4_x86.tstate = TSTATE_C;
1415 switch( (ir&0xF0) >> 4 ) {
1417 { /* STS.L MACH, @-Rn */
1418 uint32_t Rn = ((ir>>8)&0xF);
1420 load_reg( R_EAX, Rn );
1421 check_walign32( R_EAX );
1422 ADD_imm8s_r32( -4, R_EAX );
1423 MMU_TRANSLATE_WRITE( R_EAX );
1424 load_spreg( R_EDX, R_MACH );
1425 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1426 MEM_WRITE_LONG( R_EAX, R_EDX );
1427 sh4_x86.tstate = TSTATE_NONE;
1431 { /* STS.L MACL, @-Rn */
1432 uint32_t Rn = ((ir>>8)&0xF);
1434 load_reg( R_EAX, Rn );
1435 check_walign32( R_EAX );
1436 ADD_imm8s_r32( -4, R_EAX );
1437 MMU_TRANSLATE_WRITE( R_EAX );
1438 load_spreg( R_EDX, R_MACL );
1439 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1440 MEM_WRITE_LONG( R_EAX, R_EDX );
1441 sh4_x86.tstate = TSTATE_NONE;
1445 { /* STS.L PR, @-Rn */
1446 uint32_t Rn = ((ir>>8)&0xF);
1448 load_reg( R_EAX, Rn );
1449 check_walign32( R_EAX );
1450 ADD_imm8s_r32( -4, R_EAX );
1451 MMU_TRANSLATE_WRITE( R_EAX );
1452 load_spreg( R_EDX, R_PR );
1453 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1454 MEM_WRITE_LONG( R_EAX, R_EDX );
1455 sh4_x86.tstate = TSTATE_NONE;
1459 { /* STC.L SGR, @-Rn */
1460 uint32_t Rn = ((ir>>8)&0xF);
1463 load_reg( R_EAX, Rn );
1464 check_walign32( R_EAX );
1465 ADD_imm8s_r32( -4, R_EAX );
1466 MMU_TRANSLATE_WRITE( R_EAX );
1467 load_spreg( R_EDX, R_SGR );
1468 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1469 MEM_WRITE_LONG( R_EAX, R_EDX );
1470 sh4_x86.tstate = TSTATE_NONE;
1474 { /* STS.L FPUL, @-Rn */
1475 uint32_t Rn = ((ir>>8)&0xF);
1478 load_reg( R_EAX, Rn );
1479 check_walign32( R_EAX );
1480 ADD_imm8s_r32( -4, R_EAX );
1481 MMU_TRANSLATE_WRITE( R_EAX );
1482 load_spreg( R_EDX, R_FPUL );
1483 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1484 MEM_WRITE_LONG( R_EAX, R_EDX );
1485 sh4_x86.tstate = TSTATE_NONE;
1489 { /* STS.L FPSCR, @-Rn */
1490 uint32_t Rn = ((ir>>8)&0xF);
1491 COUNT_INST(I_STSFPSCRM);
1493 load_reg( R_EAX, Rn );
1494 check_walign32( R_EAX );
1495 ADD_imm8s_r32( -4, R_EAX );
1496 MMU_TRANSLATE_WRITE( R_EAX );
1497 load_spreg( R_EDX, R_FPSCR );
1498 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1499 MEM_WRITE_LONG( R_EAX, R_EDX );
1500 sh4_x86.tstate = TSTATE_NONE;
1504 { /* STC.L DBR, @-Rn */
1505 uint32_t Rn = ((ir>>8)&0xF);
1508 load_reg( R_EAX, Rn );
1509 check_walign32( R_EAX );
1510 ADD_imm8s_r32( -4, R_EAX );
1511 MMU_TRANSLATE_WRITE( R_EAX );
1512 load_spreg( R_EDX, R_DBR );
1513 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1514 MEM_WRITE_LONG( R_EAX, R_EDX );
1515 sh4_x86.tstate = TSTATE_NONE;
1524 switch( (ir&0x80) >> 7 ) {
1526 switch( (ir&0x70) >> 4 ) {
1528 { /* STC.L SR, @-Rn */
1529 uint32_t Rn = ((ir>>8)&0xF);
1530 COUNT_INST(I_STCSRM);
1532 load_reg( R_EAX, Rn );
1533 check_walign32( R_EAX );
1534 ADD_imm8s_r32( -4, R_EAX );
1535 MMU_TRANSLATE_WRITE( R_EAX );
1536 PUSH_realigned_r32( R_EAX );
1537 call_func0( sh4_read_sr );
1538 POP_realigned_r32( R_ECX );
1539 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1540 MEM_WRITE_LONG( R_ECX, R_EAX );
1541 sh4_x86.tstate = TSTATE_NONE;
1545 { /* STC.L GBR, @-Rn */
1546 uint32_t Rn = ((ir>>8)&0xF);
1548 load_reg( R_EAX, Rn );
1549 check_walign32( R_EAX );
1550 ADD_imm8s_r32( -4, R_EAX );
1551 MMU_TRANSLATE_WRITE( R_EAX );
1552 load_spreg( R_EDX, R_GBR );
1553 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1554 MEM_WRITE_LONG( R_EAX, R_EDX );
1555 sh4_x86.tstate = TSTATE_NONE;
1559 { /* STC.L VBR, @-Rn */
1560 uint32_t Rn = ((ir>>8)&0xF);
1563 load_reg( R_EAX, Rn );
1564 check_walign32( R_EAX );
1565 ADD_imm8s_r32( -4, R_EAX );
1566 MMU_TRANSLATE_WRITE( R_EAX );
1567 load_spreg( R_EDX, R_VBR );
1568 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1569 MEM_WRITE_LONG( R_EAX, R_EDX );
1570 sh4_x86.tstate = TSTATE_NONE;
1574 { /* STC.L SSR, @-Rn */
1575 uint32_t Rn = ((ir>>8)&0xF);
1578 load_reg( R_EAX, Rn );
1579 check_walign32( R_EAX );
1580 ADD_imm8s_r32( -4, R_EAX );
1581 MMU_TRANSLATE_WRITE( R_EAX );
1582 load_spreg( R_EDX, R_SSR );
1583 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1584 MEM_WRITE_LONG( R_EAX, R_EDX );
1585 sh4_x86.tstate = TSTATE_NONE;
1589 { /* STC.L SPC, @-Rn */
1590 uint32_t Rn = ((ir>>8)&0xF);
1593 load_reg( R_EAX, Rn );
1594 check_walign32( R_EAX );
1595 ADD_imm8s_r32( -4, R_EAX );
1596 MMU_TRANSLATE_WRITE( R_EAX );
1597 load_spreg( R_EDX, R_SPC );
1598 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1599 MEM_WRITE_LONG( R_EAX, R_EDX );
1600 sh4_x86.tstate = TSTATE_NONE;
1609 { /* STC.L Rm_BANK, @-Rn */
1610 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1613 load_reg( R_EAX, Rn );
1614 check_walign32( R_EAX );
1615 ADD_imm8s_r32( -4, R_EAX );
1616 MMU_TRANSLATE_WRITE( R_EAX );
1617 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1618 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1619 MEM_WRITE_LONG( R_EAX, R_EDX );
1620 sh4_x86.tstate = TSTATE_NONE;
1626 switch( (ir&0xF0) >> 4 ) {
1629 uint32_t Rn = ((ir>>8)&0xF);
1631 load_reg( R_EAX, Rn );
1633 store_reg( R_EAX, Rn );
1635 sh4_x86.tstate = TSTATE_C;
1640 uint32_t Rn = ((ir>>8)&0xF);
1641 COUNT_INST(I_ROTCL);
1642 load_reg( R_EAX, Rn );
1643 if( sh4_x86.tstate != TSTATE_C ) {
1647 store_reg( R_EAX, Rn );
1649 sh4_x86.tstate = TSTATE_C;
1658 switch( (ir&0xF0) >> 4 ) {
1661 uint32_t Rn = ((ir>>8)&0xF);
1663 load_reg( R_EAX, Rn );
1665 store_reg( R_EAX, Rn );
1667 sh4_x86.tstate = TSTATE_C;
1672 uint32_t Rn = ((ir>>8)&0xF);
1673 COUNT_INST(I_CMPPL);
1674 load_reg( R_EAX, Rn );
1675 CMP_imm8s_r32( 0, R_EAX );
1677 sh4_x86.tstate = TSTATE_G;
1682 uint32_t Rn = ((ir>>8)&0xF);
1683 COUNT_INST(I_ROTCR);
1684 load_reg( R_EAX, Rn );
1685 if( sh4_x86.tstate != TSTATE_C ) {
1689 store_reg( R_EAX, Rn );
1691 sh4_x86.tstate = TSTATE_C;
1700 switch( (ir&0xF0) >> 4 ) {
1702 { /* LDS.L @Rm+, MACH */
1703 uint32_t Rm = ((ir>>8)&0xF);
1705 load_reg( R_EAX, Rm );
1706 check_ralign32( R_EAX );
1707 MMU_TRANSLATE_READ( R_EAX );
1708 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1709 MEM_READ_LONG( R_EAX, R_EAX );
1710 store_spreg( R_EAX, R_MACH );
1711 sh4_x86.tstate = TSTATE_NONE;
1715 { /* LDS.L @Rm+, MACL */
1716 uint32_t Rm = ((ir>>8)&0xF);
1718 load_reg( R_EAX, Rm );
1719 check_ralign32( R_EAX );
1720 MMU_TRANSLATE_READ( R_EAX );
1721 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1722 MEM_READ_LONG( R_EAX, R_EAX );
1723 store_spreg( R_EAX, R_MACL );
1724 sh4_x86.tstate = TSTATE_NONE;
1728 { /* LDS.L @Rm+, PR */
1729 uint32_t Rm = ((ir>>8)&0xF);
1731 load_reg( R_EAX, Rm );
1732 check_ralign32( R_EAX );
1733 MMU_TRANSLATE_READ( R_EAX );
1734 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1735 MEM_READ_LONG( R_EAX, R_EAX );
1736 store_spreg( R_EAX, R_PR );
1737 sh4_x86.tstate = TSTATE_NONE;
1741 { /* LDC.L @Rm+, SGR */
1742 uint32_t Rm = ((ir>>8)&0xF);
1745 load_reg( R_EAX, Rm );
1746 check_ralign32( R_EAX );
1747 MMU_TRANSLATE_READ( R_EAX );
1748 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1749 MEM_READ_LONG( R_EAX, R_EAX );
1750 store_spreg( R_EAX, R_SGR );
1751 sh4_x86.tstate = TSTATE_NONE;
1755 { /* LDS.L @Rm+, FPUL */
1756 uint32_t Rm = ((ir>>8)&0xF);
1759 load_reg( R_EAX, Rm );
1760 check_ralign32( R_EAX );
1761 MMU_TRANSLATE_READ( R_EAX );
1762 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1763 MEM_READ_LONG( R_EAX, R_EAX );
1764 store_spreg( R_EAX, R_FPUL );
1765 sh4_x86.tstate = TSTATE_NONE;
1769 { /* LDS.L @Rm+, FPSCR */
1770 uint32_t Rm = ((ir>>8)&0xF);
1771 COUNT_INST(I_LDSFPSCRM);
1773 load_reg( R_EAX, Rm );
1774 check_ralign32( R_EAX );
1775 MMU_TRANSLATE_READ( R_EAX );
1776 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1777 MEM_READ_LONG( R_EAX, R_EAX );
1778 call_func1( sh4_write_fpscr, R_EAX );
1779 sh4_x86.tstate = TSTATE_NONE;
1783 { /* LDC.L @Rm+, DBR */
1784 uint32_t Rm = ((ir>>8)&0xF);
1787 load_reg( R_EAX, Rm );
1788 check_ralign32( R_EAX );
1789 MMU_TRANSLATE_READ( R_EAX );
1790 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1791 MEM_READ_LONG( R_EAX, R_EAX );
1792 store_spreg( R_EAX, R_DBR );
1793 sh4_x86.tstate = TSTATE_NONE;
1802 switch( (ir&0x80) >> 7 ) {
1804 switch( (ir&0x70) >> 4 ) {
1806 { /* LDC.L @Rm+, SR */
1807 uint32_t Rm = ((ir>>8)&0xF);
1808 COUNT_INST(I_LDCSRM);
1809 if( sh4_x86.in_delay_slot ) {
1813 load_reg( R_EAX, Rm );
1814 check_ralign32( R_EAX );
1815 MMU_TRANSLATE_READ( R_EAX );
1816 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1817 MEM_READ_LONG( R_EAX, R_EAX );
1818 call_func1( sh4_write_sr, R_EAX );
1819 sh4_x86.priv_checked = FALSE;
1820 sh4_x86.fpuen_checked = FALSE;
1821 sh4_x86.tstate = TSTATE_NONE;
1826 { /* LDC.L @Rm+, GBR */
1827 uint32_t Rm = ((ir>>8)&0xF);
1829 load_reg( R_EAX, Rm );
1830 check_ralign32( R_EAX );
1831 MMU_TRANSLATE_READ( R_EAX );
1832 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1833 MEM_READ_LONG( R_EAX, R_EAX );
1834 store_spreg( R_EAX, R_GBR );
1835 sh4_x86.tstate = TSTATE_NONE;
1839 { /* LDC.L @Rm+, VBR */
1840 uint32_t Rm = ((ir>>8)&0xF);
1843 load_reg( R_EAX, Rm );
1844 check_ralign32( R_EAX );
1845 MMU_TRANSLATE_READ( R_EAX );
1846 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1847 MEM_READ_LONG( R_EAX, R_EAX );
1848 store_spreg( R_EAX, R_VBR );
1849 sh4_x86.tstate = TSTATE_NONE;
1853 { /* LDC.L @Rm+, SSR */
1854 uint32_t Rm = ((ir>>8)&0xF);
1857 load_reg( R_EAX, Rm );
1858 check_ralign32( R_EAX );
1859 MMU_TRANSLATE_READ( R_EAX );
1860 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1861 MEM_READ_LONG( R_EAX, R_EAX );
1862 store_spreg( R_EAX, R_SSR );
1863 sh4_x86.tstate = TSTATE_NONE;
1867 { /* LDC.L @Rm+, SPC */
1868 uint32_t Rm = ((ir>>8)&0xF);
1871 load_reg( R_EAX, Rm );
1872 check_ralign32( R_EAX );
1873 MMU_TRANSLATE_READ( R_EAX );
1874 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1875 MEM_READ_LONG( R_EAX, R_EAX );
1876 store_spreg( R_EAX, R_SPC );
1877 sh4_x86.tstate = TSTATE_NONE;
1886 { /* LDC.L @Rm+, Rn_BANK */
1887 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1890 load_reg( R_EAX, Rm );
1891 check_ralign32( R_EAX );
1892 MMU_TRANSLATE_READ( R_EAX );
1893 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1894 MEM_READ_LONG( R_EAX, R_EAX );
1895 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1896 sh4_x86.tstate = TSTATE_NONE;
1902 switch( (ir&0xF0) >> 4 ) {
1905 uint32_t Rn = ((ir>>8)&0xF);
1907 load_reg( R_EAX, Rn );
1908 SHL_imm8_r32( 2, R_EAX );
1909 store_reg( R_EAX, Rn );
1910 sh4_x86.tstate = TSTATE_NONE;
1915 uint32_t Rn = ((ir>>8)&0xF);
1917 load_reg( R_EAX, Rn );
1918 SHL_imm8_r32( 8, R_EAX );
1919 store_reg( R_EAX, Rn );
1920 sh4_x86.tstate = TSTATE_NONE;
1925 uint32_t Rn = ((ir>>8)&0xF);
1927 load_reg( R_EAX, Rn );
1928 SHL_imm8_r32( 16, R_EAX );
1929 store_reg( R_EAX, Rn );
1930 sh4_x86.tstate = TSTATE_NONE;
1939 switch( (ir&0xF0) >> 4 ) {
1942 uint32_t Rn = ((ir>>8)&0xF);
1944 load_reg( R_EAX, Rn );
1945 SHR_imm8_r32( 2, R_EAX );
1946 store_reg( R_EAX, Rn );
1947 sh4_x86.tstate = TSTATE_NONE;
1952 uint32_t Rn = ((ir>>8)&0xF);
1954 load_reg( R_EAX, Rn );
1955 SHR_imm8_r32( 8, R_EAX );
1956 store_reg( R_EAX, Rn );
1957 sh4_x86.tstate = TSTATE_NONE;
1962 uint32_t Rn = ((ir>>8)&0xF);
1964 load_reg( R_EAX, Rn );
1965 SHR_imm8_r32( 16, R_EAX );
1966 store_reg( R_EAX, Rn );
1967 sh4_x86.tstate = TSTATE_NONE;
1976 switch( (ir&0xF0) >> 4 ) {
1978 { /* LDS Rm, MACH */
1979 uint32_t Rm = ((ir>>8)&0xF);
1981 load_reg( R_EAX, Rm );
1982 store_spreg( R_EAX, R_MACH );
1986 { /* LDS Rm, MACL */
1987 uint32_t Rm = ((ir>>8)&0xF);
1989 load_reg( R_EAX, Rm );
1990 store_spreg( R_EAX, R_MACL );
1995 uint32_t Rm = ((ir>>8)&0xF);
1997 load_reg( R_EAX, Rm );
1998 store_spreg( R_EAX, R_PR );
2003 uint32_t Rm = ((ir>>8)&0xF);
2006 load_reg( R_EAX, Rm );
2007 store_spreg( R_EAX, R_SGR );
2008 sh4_x86.tstate = TSTATE_NONE;
2012 { /* LDS Rm, FPUL */
2013 uint32_t Rm = ((ir>>8)&0xF);
2016 load_reg( R_EAX, Rm );
2017 store_spreg( R_EAX, R_FPUL );
2021 { /* LDS Rm, FPSCR */
2022 uint32_t Rm = ((ir>>8)&0xF);
2023 COUNT_INST(I_LDSFPSCR);
2025 load_reg( R_EAX, Rm );
2026 call_func1( sh4_write_fpscr, R_EAX );
2027 sh4_x86.tstate = TSTATE_NONE;
2032 uint32_t Rm = ((ir>>8)&0xF);
2035 load_reg( R_EAX, Rm );
2036 store_spreg( R_EAX, R_DBR );
2037 sh4_x86.tstate = TSTATE_NONE;
2046 switch( (ir&0xF0) >> 4 ) {
2049 uint32_t Rn = ((ir>>8)&0xF);
2051 if( sh4_x86.in_delay_slot ) {
2054 load_spreg( R_EAX, R_PC );
2055 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
2056 store_spreg( R_EAX, R_PR );
2057 load_reg( R_ECX, Rn );
2058 store_spreg( R_ECX, R_NEW_PC );
2059 sh4_x86.in_delay_slot = DELAY_PC;
2060 sh4_x86.branch_taken = TRUE;
2061 sh4_x86.tstate = TSTATE_NONE;
2062 if( UNTRANSLATABLE(pc+2) ) {
2063 exit_block_emu(pc+2);
2066 sh4_translate_instruction(pc+2);
2067 exit_block_newpcset(pc+2);
2075 uint32_t Rn = ((ir>>8)&0xF);
2077 load_reg( R_EAX, Rn );
2078 MMU_TRANSLATE_WRITE( R_EAX );
2079 PUSH_realigned_r32( R_EAX );
2080 MEM_READ_BYTE( R_EAX, R_EAX );
2081 TEST_r8_r8( R_AL, R_AL );
2083 OR_imm8_r8( 0x80, R_AL );
2084 POP_realigned_r32( R_ECX );
2085 MEM_WRITE_BYTE( R_ECX, R_EAX );
2086 sh4_x86.tstate = TSTATE_NONE;
2091 uint32_t Rn = ((ir>>8)&0xF);
2093 if( sh4_x86.in_delay_slot ) {
2096 load_reg( R_ECX, Rn );
2097 store_spreg( R_ECX, R_NEW_PC );
2098 sh4_x86.in_delay_slot = DELAY_PC;
2099 sh4_x86.branch_taken = TRUE;
2100 if( UNTRANSLATABLE(pc+2) ) {
2101 exit_block_emu(pc+2);
2104 sh4_translate_instruction(pc+2);
2105 exit_block_newpcset(pc+2);
2118 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2120 /* Annoyingly enough, not directly convertible */
2121 load_reg( R_EAX, Rn );
2122 load_reg( R_ECX, Rm );
2123 CMP_imm32_r32( 0, R_ECX );
2126 NEG_r32( R_ECX ); // 2
2127 AND_imm8_r8( 0x1F, R_CL ); // 3
2128 JE_rel8(emptysar); // 2
2129 SAR_r32_CL( R_EAX ); // 2
2132 JMP_TARGET(emptysar);
2133 SAR_imm8_r32(31, R_EAX ); // 3
2137 AND_imm8_r8( 0x1F, R_CL ); // 3
2138 SHL_r32_CL( R_EAX ); // 2
2141 store_reg( R_EAX, Rn );
2142 sh4_x86.tstate = TSTATE_NONE;
2147 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2149 load_reg( R_EAX, Rn );
2150 load_reg( R_ECX, Rm );
2151 CMP_imm32_r32( 0, R_ECX );
2154 NEG_r32( R_ECX ); // 2
2155 AND_imm8_r8( 0x1F, R_CL ); // 3
2157 SHR_r32_CL( R_EAX ); // 2
2160 JMP_TARGET(emptyshr);
2161 XOR_r32_r32( R_EAX, R_EAX );
2165 AND_imm8_r8( 0x1F, R_CL ); // 3
2166 SHL_r32_CL( R_EAX ); // 2
2169 store_reg( R_EAX, Rn );
2170 sh4_x86.tstate = TSTATE_NONE;
2174 switch( (ir&0x80) >> 7 ) {
2176 switch( (ir&0x70) >> 4 ) {
2179 uint32_t Rm = ((ir>>8)&0xF);
2180 COUNT_INST(I_LDCSR);
2181 if( sh4_x86.in_delay_slot ) {
2185 load_reg( R_EAX, Rm );
2186 call_func1( sh4_write_sr, R_EAX );
2187 sh4_x86.priv_checked = FALSE;
2188 sh4_x86.fpuen_checked = FALSE;
2189 sh4_x86.tstate = TSTATE_NONE;
2195 uint32_t Rm = ((ir>>8)&0xF);
2197 load_reg( R_EAX, Rm );
2198 store_spreg( R_EAX, R_GBR );
2203 uint32_t Rm = ((ir>>8)&0xF);
2206 load_reg( R_EAX, Rm );
2207 store_spreg( R_EAX, R_VBR );
2208 sh4_x86.tstate = TSTATE_NONE;
2213 uint32_t Rm = ((ir>>8)&0xF);
2216 load_reg( R_EAX, Rm );
2217 store_spreg( R_EAX, R_SSR );
2218 sh4_x86.tstate = TSTATE_NONE;
2223 uint32_t Rm = ((ir>>8)&0xF);
2226 load_reg( R_EAX, Rm );
2227 store_spreg( R_EAX, R_SPC );
2228 sh4_x86.tstate = TSTATE_NONE;
2237 { /* LDC Rm, Rn_BANK */
2238 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2241 load_reg( R_EAX, Rm );
2242 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2243 sh4_x86.tstate = TSTATE_NONE;
2249 { /* MAC.W @Rm+, @Rn+ */
2250 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2253 load_reg( R_EAX, Rm );
2254 check_ralign16( R_EAX );
2255 MMU_TRANSLATE_READ( R_EAX );
2256 PUSH_realigned_r32( R_EAX );
2257 load_reg( R_EAX, Rn );
2258 ADD_imm8s_r32( 2, R_EAX );
2259 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
2260 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
2261 // Note translate twice in case of page boundaries. Maybe worth
2262 // adding a page-boundary check to skip the second translation
2264 load_reg( R_EAX, Rm );
2265 check_ralign16( R_EAX );
2266 MMU_TRANSLATE_READ( R_EAX );
2267 load_reg( R_ECX, Rn );
2268 check_ralign16( R_ECX );
2269 PUSH_realigned_r32( R_EAX );
2270 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
2271 MOV_r32_r32( R_ECX, R_EAX );
2272 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2273 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2275 MEM_READ_WORD( R_EAX, R_EAX );
2278 MEM_READ_WORD( R_ECX, R_EAX );
2279 POP_realigned_r32( R_ECX );
2282 load_spreg( R_ECX, R_S );
2283 TEST_r32_r32( R_ECX, R_ECX );
2286 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2287 JNO_rel8( end ); // 2
2288 load_imm32( R_EDX, 1 ); // 5
2289 store_spreg( R_EDX, R_MACH ); // 6
2290 JS_rel8( positive ); // 2
2291 load_imm32( R_EAX, 0x80000000 );// 5
2292 store_spreg( R_EAX, R_MACL ); // 6
2293 JMP_rel8(end2); // 2
2295 JMP_TARGET(positive);
2296 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2297 store_spreg( R_EAX, R_MACL ); // 6
2298 JMP_rel8(end3); // 2
2301 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2302 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2306 sh4_x86.tstate = TSTATE_NONE;
2312 { /* MOV.L @(disp, Rm), Rn */
2313 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2315 load_reg( R_EAX, Rm );
2316 ADD_imm8s_r32( disp, R_EAX );
2317 check_ralign32( R_EAX );
2318 MMU_TRANSLATE_READ( R_EAX );
2319 MEM_READ_LONG( R_EAX, R_EAX );
2320 store_reg( R_EAX, Rn );
2321 sh4_x86.tstate = TSTATE_NONE;
2327 { /* MOV.B @Rm, Rn */
2328 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2330 load_reg( R_EAX, Rm );
2331 MMU_TRANSLATE_READ( R_EAX );
2332 MEM_READ_BYTE( R_EAX, R_EAX );
2333 store_reg( R_EAX, Rn );
2334 sh4_x86.tstate = TSTATE_NONE;
2338 { /* MOV.W @Rm, Rn */
2339 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2341 load_reg( R_EAX, Rm );
2342 check_ralign16( R_EAX );
2343 MMU_TRANSLATE_READ( R_EAX );
2344 MEM_READ_WORD( R_EAX, R_EAX );
2345 store_reg( R_EAX, Rn );
2346 sh4_x86.tstate = TSTATE_NONE;
2350 { /* MOV.L @Rm, Rn */
2351 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2353 load_reg( R_EAX, Rm );
2354 check_ralign32( R_EAX );
2355 MMU_TRANSLATE_READ( R_EAX );
2356 MEM_READ_LONG( R_EAX, R_EAX );
2357 store_reg( R_EAX, Rn );
2358 sh4_x86.tstate = TSTATE_NONE;
2363 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2365 load_reg( R_EAX, Rm );
2366 store_reg( R_EAX, Rn );
2370 { /* MOV.B @Rm+, Rn */
2371 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2373 load_reg( R_EAX, Rm );
2374 MMU_TRANSLATE_READ( R_EAX );
2375 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
2376 MEM_READ_BYTE( R_EAX, R_EAX );
2377 store_reg( R_EAX, Rn );
2378 sh4_x86.tstate = TSTATE_NONE;
2382 { /* MOV.W @Rm+, Rn */
2383 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2385 load_reg( R_EAX, Rm );
2386 check_ralign16( R_EAX );
2387 MMU_TRANSLATE_READ( R_EAX );
2388 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2389 MEM_READ_WORD( R_EAX, R_EAX );
2390 store_reg( R_EAX, Rn );
2391 sh4_x86.tstate = TSTATE_NONE;
2395 { /* MOV.L @Rm+, Rn */
2396 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2398 load_reg( R_EAX, Rm );
2399 check_ralign32( R_EAX );
2400 MMU_TRANSLATE_READ( R_EAX );
2401 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2402 MEM_READ_LONG( R_EAX, R_EAX );
2403 store_reg( R_EAX, Rn );
2404 sh4_x86.tstate = TSTATE_NONE;
2409 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2411 load_reg( R_EAX, Rm );
2413 store_reg( R_EAX, Rn );
2414 sh4_x86.tstate = TSTATE_NONE;
2418 { /* SWAP.B Rm, Rn */
2419 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2420 COUNT_INST(I_SWAPB);
2421 load_reg( R_EAX, Rm );
2422 XCHG_r8_r8( R_AL, R_AH ); // NB: does not touch EFLAGS
2423 store_reg( R_EAX, Rn );
2427 { /* SWAP.W Rm, Rn */
2428 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2429 COUNT_INST(I_SWAPB);
2430 load_reg( R_EAX, Rm );
2431 MOV_r32_r32( R_EAX, R_ECX );
2432 SHL_imm8_r32( 16, R_ECX );
2433 SHR_imm8_r32( 16, R_EAX );
2434 OR_r32_r32( R_EAX, R_ECX );
2435 store_reg( R_ECX, Rn );
2436 sh4_x86.tstate = TSTATE_NONE;
2441 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2443 load_reg( R_EAX, Rm );
2444 XOR_r32_r32( R_ECX, R_ECX );
2446 SBB_r32_r32( R_EAX, R_ECX );
2447 store_reg( R_ECX, Rn );
2449 sh4_x86.tstate = TSTATE_C;
2454 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2456 load_reg( R_EAX, Rm );
2458 store_reg( R_EAX, Rn );
2459 sh4_x86.tstate = TSTATE_NONE;
2463 { /* EXTU.B Rm, Rn */
2464 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2465 COUNT_INST(I_EXTUB);
2466 load_reg( R_EAX, Rm );
2467 MOVZX_r8_r32( R_EAX, R_EAX );
2468 store_reg( R_EAX, Rn );
2472 { /* EXTU.W Rm, Rn */
2473 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2474 COUNT_INST(I_EXTUW);
2475 load_reg( R_EAX, Rm );
2476 MOVZX_r16_r32( R_EAX, R_EAX );
2477 store_reg( R_EAX, Rn );
2481 { /* EXTS.B Rm, Rn */
2482 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2483 COUNT_INST(I_EXTSB);
2484 load_reg( R_EAX, Rm );
2485 MOVSX_r8_r32( R_EAX, R_EAX );
2486 store_reg( R_EAX, Rn );
2490 { /* EXTS.W Rm, Rn */
2491 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2492 COUNT_INST(I_EXTSW);
2493 load_reg( R_EAX, Rm );
2494 MOVSX_r16_r32( R_EAX, R_EAX );
2495 store_reg( R_EAX, Rn );
2501 { /* ADD #imm, Rn */
2502 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2504 load_reg( R_EAX, Rn );
2505 ADD_imm8s_r32( imm, R_EAX );
2506 store_reg( R_EAX, Rn );
2507 sh4_x86.tstate = TSTATE_NONE;
2511 switch( (ir&0xF00) >> 8 ) {
2513 { /* MOV.B R0, @(disp, Rn) */
2514 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2516 load_reg( R_EAX, Rn );
2517 ADD_imm32_r32( disp, R_EAX );
2518 MMU_TRANSLATE_WRITE( R_EAX );
2519 load_reg( R_EDX, 0 );
2520 MEM_WRITE_BYTE( R_EAX, R_EDX );
2521 sh4_x86.tstate = TSTATE_NONE;
2525 { /* MOV.W R0, @(disp, Rn) */
2526 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2528 load_reg( R_EAX, Rn );
2529 ADD_imm32_r32( disp, R_EAX );
2530 check_walign16( R_EAX );
2531 MMU_TRANSLATE_WRITE( R_EAX );
2532 load_reg( R_EDX, 0 );
2533 MEM_WRITE_WORD( R_EAX, R_EDX );
2534 sh4_x86.tstate = TSTATE_NONE;
2538 { /* MOV.B @(disp, Rm), R0 */
2539 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2541 load_reg( R_EAX, Rm );
2542 ADD_imm32_r32( disp, R_EAX );
2543 MMU_TRANSLATE_READ( R_EAX );
2544 MEM_READ_BYTE( R_EAX, R_EAX );
2545 store_reg( R_EAX, 0 );
2546 sh4_x86.tstate = TSTATE_NONE;
2550 { /* MOV.W @(disp, Rm), R0 */
2551 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2553 load_reg( R_EAX, Rm );
2554 ADD_imm32_r32( disp, R_EAX );
2555 check_ralign16( R_EAX );
2556 MMU_TRANSLATE_READ( R_EAX );
2557 MEM_READ_WORD( R_EAX, R_EAX );
2558 store_reg( R_EAX, 0 );
2559 sh4_x86.tstate = TSTATE_NONE;
2563 { /* CMP/EQ #imm, R0 */
2564 int32_t imm = SIGNEXT8(ir&0xFF);
2565 COUNT_INST(I_CMPEQI);
2566 load_reg( R_EAX, 0 );
2567 CMP_imm8s_r32(imm, R_EAX);
2569 sh4_x86.tstate = TSTATE_E;
2574 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2576 if( sh4_x86.in_delay_slot ) {
2579 sh4vma_t target = disp + pc + 4;
2580 JF_rel8( nottaken );
2581 exit_block_rel(target, pc+2 );
2582 JMP_TARGET(nottaken);
2589 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2591 if( sh4_x86.in_delay_slot ) {
2594 sh4vma_t target = disp + pc + 4;
2595 JT_rel8( nottaken );
2596 exit_block_rel(target, pc+2 );
2597 JMP_TARGET(nottaken);
2604 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2606 if( sh4_x86.in_delay_slot ) {
2609 sh4_x86.in_delay_slot = DELAY_PC;
2610 if( UNTRANSLATABLE(pc+2) ) {
2611 load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );
2613 ADD_imm32_r32( disp, R_EAX );
2614 JMP_TARGET(nottaken);
2615 ADD_sh4r_r32( R_PC, R_EAX );
2616 store_spreg( R_EAX, R_NEW_PC );
2617 exit_block_emu(pc+2);
2618 sh4_x86.branch_taken = TRUE;
2621 if( sh4_x86.tstate == TSTATE_NONE ) {
2622 CMP_imm8s_sh4r( 1, R_T );
2623 sh4_x86.tstate = TSTATE_E;
2625 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JF rel32
2626 sh4_translate_instruction(pc+2);
2627 exit_block_rel( disp + pc + 4, pc+4 );
2629 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2630 sh4_translate_instruction(pc+2);
2638 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2640 if( sh4_x86.in_delay_slot ) {
2643 sh4_x86.in_delay_slot = DELAY_PC;
2644 if( UNTRANSLATABLE(pc+2) ) {
2645 load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );
2647 ADD_imm32_r32( disp, R_EAX );
2648 JMP_TARGET(nottaken);
2649 ADD_sh4r_r32( R_PC, R_EAX );
2650 store_spreg( R_EAX, R_NEW_PC );
2651 exit_block_emu(pc+2);
2652 sh4_x86.branch_taken = TRUE;
2655 if( sh4_x86.tstate == TSTATE_NONE ) {
2656 CMP_imm8s_sh4r( 1, R_T );
2657 sh4_x86.tstate = TSTATE_E;
2659 sh4vma_t target = disp + pc + 4;
2660 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JT rel32
2661 sh4_translate_instruction(pc+2);
2662 exit_block_rel( target, pc+4 );
2665 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2666 sh4_translate_instruction(pc+2);
2678 { /* MOV.W @(disp, PC), Rn */
2679 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2681 if( sh4_x86.in_delay_slot ) {
2684 // See comments for MOV.L @(disp, PC), Rn
2685 uint32_t target = pc + disp + 4;
2686 if( IS_IN_ICACHE(target) ) {
2687 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2688 MOV_moff32_EAX( ptr );
2689 MOVSX_r16_r32( R_EAX, R_EAX );
2691 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
2692 ADD_sh4r_r32( R_PC, R_EAX );
2693 MMU_TRANSLATE_READ( R_EAX );
2694 MEM_READ_WORD( R_EAX, R_EAX );
2695 sh4_x86.tstate = TSTATE_NONE;
2697 store_reg( R_EAX, Rn );
2703 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2705 if( sh4_x86.in_delay_slot ) {
2708 sh4_x86.in_delay_slot = DELAY_PC;
2709 sh4_x86.branch_taken = TRUE;
2710 if( UNTRANSLATABLE(pc+2) ) {
2711 load_spreg( R_EAX, R_PC );
2712 ADD_imm32_r32( pc + disp + 4 - sh4_x86.block_start_pc, R_EAX );
2713 store_spreg( R_EAX, R_NEW_PC );
2714 exit_block_emu(pc+2);
2717 sh4_translate_instruction( pc + 2 );
2718 exit_block_rel( disp + pc + 4, pc+4 );
2726 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2728 if( sh4_x86.in_delay_slot ) {
2731 load_spreg( R_EAX, R_PC );
2732 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
2733 store_spreg( R_EAX, R_PR );
2734 sh4_x86.in_delay_slot = DELAY_PC;
2735 sh4_x86.branch_taken = TRUE;
2736 sh4_x86.tstate = TSTATE_NONE;
2737 if( UNTRANSLATABLE(pc+2) ) {
2738 ADD_imm32_r32( disp, R_EAX );
2739 store_spreg( R_EAX, R_NEW_PC );
2740 exit_block_emu(pc+2);
2743 sh4_translate_instruction( pc + 2 );
2744 exit_block_rel( disp + pc + 4, pc+4 );
2751 switch( (ir&0xF00) >> 8 ) {
2753 { /* MOV.B R0, @(disp, GBR) */
2754 uint32_t disp = (ir&0xFF);
2756 load_spreg( R_EAX, R_GBR );
2757 ADD_imm32_r32( disp, R_EAX );
2758 MMU_TRANSLATE_WRITE( R_EAX );
2759 load_reg( R_EDX, 0 );
2760 MEM_WRITE_BYTE( R_EAX, R_EDX );
2761 sh4_x86.tstate = TSTATE_NONE;
2765 { /* MOV.W R0, @(disp, GBR) */
2766 uint32_t disp = (ir&0xFF)<<1;
2768 load_spreg( R_EAX, R_GBR );
2769 ADD_imm32_r32( disp, R_EAX );
2770 check_walign16( R_EAX );
2771 MMU_TRANSLATE_WRITE( R_EAX );
2772 load_reg( R_EDX, 0 );
2773 MEM_WRITE_WORD( R_EAX, R_EDX );
2774 sh4_x86.tstate = TSTATE_NONE;
2778 { /* MOV.L R0, @(disp, GBR) */
2779 uint32_t disp = (ir&0xFF)<<2;
2781 load_spreg( R_EAX, R_GBR );
2782 ADD_imm32_r32( disp, R_EAX );
2783 check_walign32( R_EAX );
2784 MMU_TRANSLATE_WRITE( R_EAX );
2785 load_reg( R_EDX, 0 );
2786 MEM_WRITE_LONG( R_EAX, R_EDX );
2787 sh4_x86.tstate = TSTATE_NONE;
2792 uint32_t imm = (ir&0xFF);
2793 COUNT_INST(I_TRAPA);
2794 if( sh4_x86.in_delay_slot ) {
2797 load_imm32( R_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
2798 ADD_r32_sh4r( R_ECX, R_PC );
2799 load_imm32( R_EAX, imm );
2800 call_func1( sh4_raise_trap, R_EAX );
2801 sh4_x86.tstate = TSTATE_NONE;
2802 exit_block_pcset(pc);
2803 sh4_x86.branch_taken = TRUE;
2809 { /* MOV.B @(disp, GBR), R0 */
2810 uint32_t disp = (ir&0xFF);
2812 load_spreg( R_EAX, R_GBR );
2813 ADD_imm32_r32( disp, R_EAX );
2814 MMU_TRANSLATE_READ( R_EAX );
2815 MEM_READ_BYTE( R_EAX, R_EAX );
2816 store_reg( R_EAX, 0 );
2817 sh4_x86.tstate = TSTATE_NONE;
2821 { /* MOV.W @(disp, GBR), R0 */
2822 uint32_t disp = (ir&0xFF)<<1;
2824 load_spreg( R_EAX, R_GBR );
2825 ADD_imm32_r32( disp, R_EAX );
2826 check_ralign16( R_EAX );
2827 MMU_TRANSLATE_READ( R_EAX );
2828 MEM_READ_WORD( R_EAX, R_EAX );
2829 store_reg( R_EAX, 0 );
2830 sh4_x86.tstate = TSTATE_NONE;
2834 { /* MOV.L @(disp, GBR), R0 */
2835 uint32_t disp = (ir&0xFF)<<2;
2837 load_spreg( R_EAX, R_GBR );
2838 ADD_imm32_r32( disp, R_EAX );
2839 check_ralign32( R_EAX );
2840 MMU_TRANSLATE_READ( R_EAX );
2841 MEM_READ_LONG( R_EAX, R_EAX );
2842 store_reg( R_EAX, 0 );
2843 sh4_x86.tstate = TSTATE_NONE;
2847 { /* MOVA @(disp, PC), R0 */
2848 uint32_t disp = (ir&0xFF)<<2;
2850 if( sh4_x86.in_delay_slot ) {
2853 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2854 ADD_sh4r_r32( R_PC, R_ECX );
2855 store_reg( R_ECX, 0 );
2856 sh4_x86.tstate = TSTATE_NONE;
2861 { /* TST #imm, R0 */
2862 uint32_t imm = (ir&0xFF);
2864 load_reg( R_EAX, 0 );
2865 TEST_imm32_r32( imm, R_EAX );
2867 sh4_x86.tstate = TSTATE_E;
2871 { /* AND #imm, R0 */
2872 uint32_t imm = (ir&0xFF);
2874 load_reg( R_EAX, 0 );
2875 AND_imm32_r32(imm, R_EAX);
2876 store_reg( R_EAX, 0 );
2877 sh4_x86.tstate = TSTATE_NONE;
2881 { /* XOR #imm, R0 */
2882 uint32_t imm = (ir&0xFF);
2884 load_reg( R_EAX, 0 );
2885 XOR_imm32_r32( imm, R_EAX );
2886 store_reg( R_EAX, 0 );
2887 sh4_x86.tstate = TSTATE_NONE;
2892 uint32_t imm = (ir&0xFF);
2894 load_reg( R_EAX, 0 );
2895 OR_imm32_r32(imm, R_EAX);
2896 store_reg( R_EAX, 0 );
2897 sh4_x86.tstate = TSTATE_NONE;
2901 { /* TST.B #imm, @(R0, GBR) */
2902 uint32_t imm = (ir&0xFF);
2904 load_reg( R_EAX, 0);
2905 load_reg( R_ECX, R_GBR);
2906 ADD_r32_r32( R_ECX, R_EAX );
2907 MMU_TRANSLATE_READ( R_EAX );
2908 MEM_READ_BYTE( R_EAX, R_EAX );
2909 TEST_imm8_r8( imm, R_AL );
2911 sh4_x86.tstate = TSTATE_E;
2915 { /* AND.B #imm, @(R0, GBR) */
2916 uint32_t imm = (ir&0xFF);
2918 load_reg( R_EAX, 0 );
2919 load_spreg( R_ECX, R_GBR );
2920 ADD_r32_r32( R_ECX, R_EAX );
2921 MMU_TRANSLATE_WRITE( R_EAX );
2922 PUSH_realigned_r32(R_EAX);
2923 MEM_READ_BYTE( R_EAX, R_EAX );
2924 POP_realigned_r32(R_ECX);
2925 AND_imm32_r32(imm, R_EAX );
2926 MEM_WRITE_BYTE( R_ECX, R_EAX );
2927 sh4_x86.tstate = TSTATE_NONE;
2931 { /* XOR.B #imm, @(R0, GBR) */
2932 uint32_t imm = (ir&0xFF);
2934 load_reg( R_EAX, 0 );
2935 load_spreg( R_ECX, R_GBR );
2936 ADD_r32_r32( R_ECX, R_EAX );
2937 MMU_TRANSLATE_WRITE( R_EAX );
2938 PUSH_realigned_r32(R_EAX);
2939 MEM_READ_BYTE(R_EAX, R_EAX);
2940 POP_realigned_r32(R_ECX);
2941 XOR_imm32_r32( imm, R_EAX );
2942 MEM_WRITE_BYTE( R_ECX, R_EAX );
2943 sh4_x86.tstate = TSTATE_NONE;
2947 { /* OR.B #imm, @(R0, GBR) */
2948 uint32_t imm = (ir&0xFF);
2950 load_reg( R_EAX, 0 );
2951 load_spreg( R_ECX, R_GBR );
2952 ADD_r32_r32( R_ECX, R_EAX );
2953 MMU_TRANSLATE_WRITE( R_EAX );
2954 PUSH_realigned_r32(R_EAX);
2955 MEM_READ_BYTE( R_EAX, R_EAX );
2956 POP_realigned_r32(R_ECX);
2957 OR_imm32_r32(imm, R_EAX );
2958 MEM_WRITE_BYTE( R_ECX, R_EAX );
2959 sh4_x86.tstate = TSTATE_NONE;
2965 { /* MOV.L @(disp, PC), Rn */
2966 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2967 COUNT_INST(I_MOVLPC);
2968 if( sh4_x86.in_delay_slot ) {
2971 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2972 if( IS_IN_ICACHE(target) ) {
2973 // If the target address is in the same page as the code, it's
2974 // pretty safe to just ref it directly and circumvent the whole
2975 // memory subsystem. (this is a big performance win)
2977 // FIXME: There's a corner-case that's not handled here when
2978 // the current code-page is in the ITLB but not in the UTLB.
2979 // (should generate a TLB miss although need to test SH4
2980 // behaviour to confirm) Unlikely to be anyone depending on this
2981 // behaviour though.
2982 sh4ptr_t ptr = GET_ICACHE_PTR(target);
2983 MOV_moff32_EAX( ptr );
2985 // Note: we use sh4r.pc for the calc as we could be running at a
2986 // different virtual address than the translation was done with,
2987 // but we can safely assume that the low bits are the same.
2988 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
2989 ADD_sh4r_r32( R_PC, R_EAX );
2990 MMU_TRANSLATE_READ( R_EAX );
2991 MEM_READ_LONG( R_EAX, R_EAX );
2992 sh4_x86.tstate = TSTATE_NONE;
2994 store_reg( R_EAX, Rn );
2999 { /* MOV #imm, Rn */
3000 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
3002 load_imm32( R_EAX, imm );
3003 store_reg( R_EAX, Rn );
3009 { /* FADD FRm, FRn */
3010 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3013 load_spreg( R_ECX, R_FPSCR );
3014 TEST_imm32_r32( FPSCR_PR, R_ECX );
3015 JNE_rel8(doubleprec);
3021 JMP_TARGET(doubleprec);
3027 sh4_x86.tstate = TSTATE_NONE;
3031 { /* FSUB FRm, FRn */
3032 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3035 load_spreg( R_ECX, R_FPSCR );
3036 TEST_imm32_r32( FPSCR_PR, R_ECX );
3037 JNE_rel8(doubleprec);
3043 JMP_TARGET(doubleprec);
3049 sh4_x86.tstate = TSTATE_NONE;
3053 { /* FMUL FRm, FRn */
3054 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3057 load_spreg( R_ECX, R_FPSCR );
3058 TEST_imm32_r32( FPSCR_PR, R_ECX );
3059 JNE_rel8(doubleprec);
3065 JMP_TARGET(doubleprec);
3071 sh4_x86.tstate = TSTATE_NONE;
3075 { /* FDIV FRm, FRn */
3076 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3079 load_spreg( R_ECX, R_FPSCR );
3080 TEST_imm32_r32( FPSCR_PR, R_ECX );
3081 JNE_rel8(doubleprec);
3087 JMP_TARGET(doubleprec);
3093 sh4_x86.tstate = TSTATE_NONE;
3097 { /* FCMP/EQ FRm, FRn */
3098 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3099 COUNT_INST(I_FCMPEQ);
3101 load_spreg( R_ECX, R_FPSCR );
3102 TEST_imm32_r32( FPSCR_PR, R_ECX );
3103 JNE_rel8(doubleprec);
3107 JMP_TARGET(doubleprec);
3114 sh4_x86.tstate = TSTATE_NONE;
3118 { /* FCMP/GT FRm, FRn */
3119 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3120 COUNT_INST(I_FCMPGT);
3122 load_spreg( R_ECX, R_FPSCR );
3123 TEST_imm32_r32( FPSCR_PR, R_ECX );
3124 JNE_rel8(doubleprec);
3128 JMP_TARGET(doubleprec);
3135 sh4_x86.tstate = TSTATE_NONE;
3139 { /* FMOV @(R0, Rm), FRn */
3140 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3141 COUNT_INST(I_FMOV7);
3143 load_reg( R_EAX, Rm );
3144 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
3145 check_ralign32( R_EAX );
3146 MMU_TRANSLATE_READ( R_EAX );
3147 load_spreg( R_EDX, R_FPSCR );
3148 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3149 JNE_rel8(doublesize);
3151 MEM_READ_LONG( R_EAX, R_EAX );
3152 store_fr( R_EAX, FRn );
3155 JMP_TARGET(doublesize);
3156 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3157 store_dr0( R_ECX, FRn );
3158 store_dr1( R_EAX, FRn );
3161 sh4_x86.tstate = TSTATE_NONE;
3165 { /* FMOV FRm, @(R0, Rn) */
3166 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3167 COUNT_INST(I_FMOV4);
3169 load_reg( R_EAX, Rn );
3170 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
3171 check_walign32( R_EAX );
3172 MMU_TRANSLATE_WRITE( R_EAX );
3173 load_spreg( R_EDX, R_FPSCR );
3174 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3175 JNE_rel8(doublesize);
3177 load_fr( R_ECX, FRm );
3178 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3181 JMP_TARGET(doublesize);
3182 load_dr0( R_ECX, FRm );
3183 load_dr1( R_EDX, FRm );
3184 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3187 sh4_x86.tstate = TSTATE_NONE;
3191 { /* FMOV @Rm, FRn */
3192 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3193 COUNT_INST(I_FMOV5);
3195 load_reg( R_EAX, Rm );
3196 check_ralign32( R_EAX );
3197 MMU_TRANSLATE_READ( R_EAX );
3198 load_spreg( R_EDX, R_FPSCR );
3199 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3200 JNE_rel8(doublesize);
3202 MEM_READ_LONG( R_EAX, R_EAX );
3203 store_fr( R_EAX, FRn );
3206 JMP_TARGET(doublesize);
3207 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3208 store_dr0( R_ECX, FRn );
3209 store_dr1( R_EAX, FRn );
3211 sh4_x86.tstate = TSTATE_NONE;
3215 { /* FMOV @Rm+, FRn */
3216 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3217 COUNT_INST(I_FMOV6);
3219 load_reg( R_EAX, Rm );
3220 check_ralign32( R_EAX );
3221 MMU_TRANSLATE_READ( R_EAX );
3222 load_spreg( R_EDX, R_FPSCR );
3223 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3224 JNE_rel8(doublesize);
3226 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
3227 MEM_READ_LONG( R_EAX, R_EAX );
3228 store_fr( R_EAX, FRn );
3231 JMP_TARGET(doublesize);
3232 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
3233 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
3234 store_dr0( R_ECX, FRn );
3235 store_dr1( R_EAX, FRn );
3238 sh4_x86.tstate = TSTATE_NONE;
3242 { /* FMOV FRm, @Rn */
3243 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3244 COUNT_INST(I_FMOV2);
3246 load_reg( R_EAX, Rn );
3247 check_walign32( R_EAX );
3248 MMU_TRANSLATE_WRITE( R_EAX );
3249 load_spreg( R_EDX, R_FPSCR );
3250 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3251 JNE_rel8(doublesize);
3253 load_fr( R_ECX, FRm );
3254 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
3257 JMP_TARGET(doublesize);
3258 load_dr0( R_ECX, FRm );
3259 load_dr1( R_EDX, FRm );
3260 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3262 sh4_x86.tstate = TSTATE_NONE;
3266 { /* FMOV FRm, @-Rn */
3267 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3268 COUNT_INST(I_FMOV3);
3270 load_reg( R_EAX, Rn );
3271 check_walign32( R_EAX );
3272 load_spreg( R_EDX, R_FPSCR );
3273 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3274 JNE_rel8(doublesize);
3276 ADD_imm8s_r32( -4, R_EAX );
3277 MMU_TRANSLATE_WRITE( R_EAX );
3278 load_fr( R_ECX, FRm );
3279 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
3280 MEM_WRITE_LONG( R_EAX, R_ECX );
3283 JMP_TARGET(doublesize);
3284 ADD_imm8s_r32(-8,R_EAX);
3285 MMU_TRANSLATE_WRITE( R_EAX );
3286 load_dr0( R_ECX, FRm );
3287 load_dr1( R_EDX, FRm );
3288 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
3289 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
3292 sh4_x86.tstate = TSTATE_NONE;
3296 { /* FMOV FRm, FRn */
3297 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3298 COUNT_INST(I_FMOV1);
3300 load_spreg( R_ECX, R_FPSCR );
3301 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3302 JNE_rel8(doublesize);
3303 load_fr( R_EAX, FRm ); // SZ=0 branch
3304 store_fr( R_EAX, FRn );
3306 JMP_TARGET(doublesize);
3307 load_dr0( R_EAX, FRm );
3308 load_dr1( R_ECX, FRm );
3309 store_dr0( R_EAX, FRn );
3310 store_dr1( R_ECX, FRn );
3312 sh4_x86.tstate = TSTATE_NONE;
3316 switch( (ir&0xF0) >> 4 ) {
3318 { /* FSTS FPUL, FRn */
3319 uint32_t FRn = ((ir>>8)&0xF);
3322 load_spreg( R_EAX, R_FPUL );
3323 store_fr( R_EAX, FRn );
3324 sh4_x86.tstate = TSTATE_NONE;
3328 { /* FLDS FRm, FPUL */
3329 uint32_t FRm = ((ir>>8)&0xF);
3332 load_fr( R_EAX, FRm );
3333 store_spreg( R_EAX, R_FPUL );
3334 sh4_x86.tstate = TSTATE_NONE;
3338 { /* FLOAT FPUL, FRn */
3339 uint32_t FRn = ((ir>>8)&0xF);
3340 COUNT_INST(I_FLOAT);
3342 load_spreg( R_ECX, R_FPSCR );
3344 TEST_imm32_r32( FPSCR_PR, R_ECX );
3345 JNE_rel8(doubleprec);
3348 JMP_TARGET(doubleprec);
3351 sh4_x86.tstate = TSTATE_NONE;
3355 { /* FTRC FRm, FPUL */
3356 uint32_t FRm = ((ir>>8)&0xF);
3359 load_spreg( R_ECX, R_FPSCR );
3360 TEST_imm32_r32( FPSCR_PR, R_ECX );
3361 JNE_rel8(doubleprec);
3364 JMP_TARGET(doubleprec);
3367 load_imm32( R_ECX, (uint32_t)&max_int );
3368 FILD_r32ind( R_ECX );
3371 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3372 FILD_r32ind( R_ECX ); // 2
3374 JAE_rel8( sat2 ); // 2
3375 load_imm32( R_EAX, (uint32_t)&save_fcw );
3376 FNSTCW_r32ind( R_EAX );
3377 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3378 FLDCW_r32ind( R_EDX );
3379 FISTP_sh4r(R_FPUL); // 3
3380 FLDCW_r32ind( R_EAX );
3385 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3386 store_spreg( R_ECX, R_FPUL );
3389 sh4_x86.tstate = TSTATE_NONE;
3394 uint32_t FRn = ((ir>>8)&0xF);
3397 load_spreg( R_ECX, R_FPSCR );
3398 TEST_imm32_r32( FPSCR_PR, R_ECX );
3399 JNE_rel8(doubleprec);
3404 JMP_TARGET(doubleprec);
3409 sh4_x86.tstate = TSTATE_NONE;
3414 uint32_t FRn = ((ir>>8)&0xF);
3417 load_spreg( R_ECX, R_FPSCR );
3418 TEST_imm32_r32( FPSCR_PR, R_ECX );
3419 JNE_rel8(doubleprec);
3424 JMP_TARGET(doubleprec);
3429 sh4_x86.tstate = TSTATE_NONE;
3434 uint32_t FRn = ((ir>>8)&0xF);
3435 COUNT_INST(I_FSQRT);
3437 load_spreg( R_ECX, R_FPSCR );
3438 TEST_imm32_r32( FPSCR_PR, R_ECX );
3439 JNE_rel8(doubleprec);
3444 JMP_TARGET(doubleprec);
3449 sh4_x86.tstate = TSTATE_NONE;
3454 uint32_t FRn = ((ir>>8)&0xF);
3455 COUNT_INST(I_FSRRA);
3457 load_spreg( R_ECX, R_FPSCR );
3458 TEST_imm32_r32( FPSCR_PR, R_ECX );
3459 JNE_rel8(end); // PR=0 only
3466 sh4_x86.tstate = TSTATE_NONE;
3471 uint32_t FRn = ((ir>>8)&0xF);
3473 COUNT_INST(I_FLDI0);
3475 load_spreg( R_ECX, R_FPSCR );
3476 TEST_imm32_r32( FPSCR_PR, R_ECX );
3478 XOR_r32_r32( R_EAX, R_EAX );
3479 store_fr( R_EAX, FRn );
3481 sh4_x86.tstate = TSTATE_NONE;
3486 uint32_t FRn = ((ir>>8)&0xF);
3488 COUNT_INST(I_FLDI1);
3490 load_spreg( R_ECX, R_FPSCR );
3491 TEST_imm32_r32( FPSCR_PR, R_ECX );
3493 load_imm32(R_EAX, 0x3F800000);
3494 store_fr( R_EAX, FRn );
3496 sh4_x86.tstate = TSTATE_NONE;
3500 { /* FCNVSD FPUL, FRn */
3501 uint32_t FRn = ((ir>>8)&0xF);
3502 COUNT_INST(I_FCNVSD);
3504 load_spreg( R_ECX, R_FPSCR );
3505 TEST_imm32_r32( FPSCR_PR, R_ECX );
3506 JE_rel8(end); // only when PR=1
3510 sh4_x86.tstate = TSTATE_NONE;
3514 { /* FCNVDS FRm, FPUL */
3515 uint32_t FRm = ((ir>>8)&0xF);
3516 COUNT_INST(I_FCNVDS);
3518 load_spreg( R_ECX, R_FPSCR );
3519 TEST_imm32_r32( FPSCR_PR, R_ECX );
3520 JE_rel8(end); // only when PR=1
3524 sh4_x86.tstate = TSTATE_NONE;
3528 { /* FIPR FVm, FVn */
3529 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3532 load_spreg( R_ECX, R_FPSCR );
3533 TEST_imm32_r32( FPSCR_PR, R_ECX );
3534 JNE_rel8( doubleprec);
3539 push_fr( (FVm<<2)+1);
3540 push_fr( (FVn<<2)+1);
3543 push_fr( (FVm<<2)+2);
3544 push_fr( (FVn<<2)+2);
3547 push_fr( (FVm<<2)+3);
3548 push_fr( (FVn<<2)+3);
3551 pop_fr( (FVn<<2)+3);
3552 JMP_TARGET(doubleprec);
3553 sh4_x86.tstate = TSTATE_NONE;
3557 switch( (ir&0x100) >> 8 ) {
3559 { /* FSCA FPUL, FRn */
3560 uint32_t FRn = ((ir>>9)&0x7)<<1;
3563 load_spreg( R_ECX, R_FPSCR );
3564 TEST_imm32_r32( FPSCR_PR, R_ECX );
3565 JNE_rel8(doubleprec );
3566 LEA_sh4r_r32( REG_OFFSET(fr[0][FRn&0x0E]), R_ECX );
3567 load_spreg( R_EDX, R_FPUL );
3568 call_func2( sh4_fsca, R_EDX, R_ECX );
3569 JMP_TARGET(doubleprec);
3570 sh4_x86.tstate = TSTATE_NONE;
3574 switch( (ir&0x200) >> 9 ) {
3576 { /* FTRV XMTRX, FVn */
3577 uint32_t FVn = ((ir>>10)&0x3);
3580 load_spreg( R_ECX, R_FPSCR );
3581 TEST_imm32_r32( FPSCR_PR, R_ECX );
3582 JNE_rel8( doubleprec );
3583 LEA_sh4r_r32( REG_OFFSET(fr[0][FVn<<2]), R_EDX );
3584 call_func1( sh4_ftrv, R_EDX ); // 12
3585 JMP_TARGET(doubleprec);
3586 sh4_x86.tstate = TSTATE_NONE;
3590 switch( (ir&0xC00) >> 10 ) {
3593 COUNT_INST(I_FSCHG);
3595 load_spreg( R_ECX, R_FPSCR );
3596 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3597 store_spreg( R_ECX, R_FPSCR );
3598 sh4_x86.tstate = TSTATE_NONE;
3603 COUNT_INST(I_FRCHG);
3605 load_spreg( R_ECX, R_FPSCR );
3606 XOR_imm32_r32( FPSCR_FR, R_ECX );
3607 store_spreg( R_ECX, R_FPSCR );
3608 call_func0( sh4_switch_fr_banks );
3609 sh4_x86.tstate = TSTATE_NONE;
3614 COUNT_INST(I_UNDEF);
3615 if( sh4_x86.in_delay_slot ) {
3618 JMP_exc(EXC_ILLEGAL);
3638 { /* FMAC FR0, FRm, FRn */
3639 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3642 load_spreg( R_ECX, R_FPSCR );
3643 TEST_imm32_r32( FPSCR_PR, R_ECX );
3644 JNE_rel8(doubleprec);
3652 JMP_TARGET(doubleprec);
3660 sh4_x86.tstate = TSTATE_NONE;
3670 sh4_x86.in_delay_slot = DELAY_NONE;
.