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 );
444 load_reg( R_EAX, Rm );
445 load_reg( R_ECX, Rn );
446 ADD_r32_r32( R_EAX, R_ECX );
447 store_reg( R_ECX, Rn );
448 sh4_x86.tstate = TSTATE_NONE;
451 load_reg( R_EAX, Rn );
452 ADD_imm8s_r32( imm, R_EAX );
453 store_reg( R_EAX, Rn );
454 sh4_x86.tstate = TSTATE_NONE;
457 if( sh4_x86.tstate != TSTATE_C ) {
460 load_reg( R_EAX, Rm );
461 load_reg( R_ECX, Rn );
462 ADC_r32_r32( R_EAX, R_ECX );
463 store_reg( R_ECX, Rn );
465 sh4_x86.tstate = TSTATE_C;
468 load_reg( R_EAX, Rm );
469 load_reg( R_ECX, Rn );
470 ADD_r32_r32( R_EAX, R_ECX );
471 store_reg( R_ECX, Rn );
473 sh4_x86.tstate = TSTATE_O;
476 load_reg( R_EAX, Rm );
477 load_reg( R_ECX, Rn );
478 AND_r32_r32( R_EAX, R_ECX );
479 store_reg( R_ECX, Rn );
480 sh4_x86.tstate = TSTATE_NONE;
483 load_reg( R_EAX, 0 );
484 AND_imm32_r32(imm, R_EAX);
485 store_reg( R_EAX, 0 );
486 sh4_x86.tstate = TSTATE_NONE;
488 AND.B #imm, @(R0, GBR) {:
489 load_reg( R_EAX, 0 );
490 load_spreg( R_ECX, R_GBR );
491 ADD_r32_r32( R_ECX, R_EAX );
492 MMU_TRANSLATE_WRITE( R_EAX );
493 PUSH_realigned_r32(R_EAX);
494 MEM_READ_BYTE( R_EAX, R_EAX );
495 POP_realigned_r32(R_ECX);
496 AND_imm32_r32(imm, R_EAX );
497 MEM_WRITE_BYTE( R_ECX, R_EAX );
498 sh4_x86.tstate = TSTATE_NONE;
501 load_reg( R_EAX, Rm );
502 load_reg( R_ECX, Rn );
503 CMP_r32_r32( R_EAX, R_ECX );
505 sh4_x86.tstate = TSTATE_E;
508 load_reg( R_EAX, 0 );
509 CMP_imm8s_r32(imm, R_EAX);
511 sh4_x86.tstate = TSTATE_E;
514 load_reg( R_EAX, Rm );
515 load_reg( R_ECX, Rn );
516 CMP_r32_r32( R_EAX, R_ECX );
518 sh4_x86.tstate = TSTATE_GE;
521 load_reg( R_EAX, Rm );
522 load_reg( R_ECX, Rn );
523 CMP_r32_r32( R_EAX, R_ECX );
525 sh4_x86.tstate = TSTATE_G;
528 load_reg( R_EAX, Rm );
529 load_reg( R_ECX, Rn );
530 CMP_r32_r32( R_EAX, R_ECX );
532 sh4_x86.tstate = TSTATE_A;
535 load_reg( R_EAX, Rm );
536 load_reg( R_ECX, Rn );
537 CMP_r32_r32( R_EAX, R_ECX );
539 sh4_x86.tstate = TSTATE_AE;
542 load_reg( R_EAX, Rn );
543 CMP_imm8s_r32( 0, R_EAX );
545 sh4_x86.tstate = TSTATE_G;
548 load_reg( R_EAX, Rn );
549 CMP_imm8s_r32( 0, R_EAX );
551 sh4_x86.tstate = TSTATE_GE;
554 load_reg( R_EAX, Rm );
555 load_reg( R_ECX, Rn );
556 XOR_r32_r32( R_ECX, R_EAX );
557 TEST_r8_r8( R_AL, R_AL );
558 JE_rel8(13, target1);
559 TEST_r8_r8( R_AH, R_AH ); // 2
561 SHR_imm8_r32( 16, R_EAX ); // 3
562 TEST_r8_r8( R_AL, R_AL ); // 2
564 TEST_r8_r8( R_AH, R_AH ); // 2
569 sh4_x86.tstate = TSTATE_E;
572 load_reg( R_EAX, Rm );
573 load_reg( R_ECX, Rn );
574 SHR_imm8_r32( 31, R_EAX );
575 SHR_imm8_r32( 31, R_ECX );
576 store_spreg( R_EAX, R_M );
577 store_spreg( R_ECX, R_Q );
578 CMP_r32_r32( R_EAX, R_ECX );
580 sh4_x86.tstate = TSTATE_NE;
583 XOR_r32_r32( R_EAX, R_EAX );
584 store_spreg( R_EAX, R_Q );
585 store_spreg( R_EAX, R_M );
586 store_spreg( R_EAX, R_T );
587 sh4_x86.tstate = TSTATE_C; // works for DIV1
590 load_spreg( R_ECX, R_M );
591 load_reg( R_EAX, Rn );
592 if( sh4_x86.tstate != TSTATE_C ) {
596 SETC_r8( R_DL ); // Q'
597 CMP_sh4r_r32( R_Q, R_ECX );
599 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
602 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
604 store_reg( R_EAX, Rn ); // Done with Rn now
605 SETC_r8(R_AL); // tmp1
606 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
607 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
608 store_spreg( R_ECX, R_Q );
609 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
610 MOVZX_r8_r32( R_AL, R_EAX );
611 store_spreg( R_EAX, R_T );
612 sh4_x86.tstate = TSTATE_NONE;
615 load_reg( R_EAX, Rm );
616 load_reg( R_ECX, Rn );
618 store_spreg( R_EDX, R_MACH );
619 store_spreg( R_EAX, R_MACL );
620 sh4_x86.tstate = TSTATE_NONE;
623 load_reg( R_EAX, Rm );
624 load_reg( R_ECX, Rn );
626 store_spreg( R_EDX, R_MACH );
627 store_spreg( R_EAX, R_MACL );
628 sh4_x86.tstate = TSTATE_NONE;
631 load_reg( R_EAX, Rn );
632 ADD_imm8s_r32( -1, R_EAX );
633 store_reg( R_EAX, Rn );
635 sh4_x86.tstate = TSTATE_E;
638 load_reg( R_EAX, Rm );
639 MOVSX_r8_r32( R_EAX, R_EAX );
640 store_reg( R_EAX, Rn );
643 load_reg( R_EAX, Rm );
644 MOVSX_r16_r32( R_EAX, R_EAX );
645 store_reg( R_EAX, Rn );
648 load_reg( R_EAX, Rm );
649 MOVZX_r8_r32( R_EAX, R_EAX );
650 store_reg( R_EAX, Rn );
653 load_reg( R_EAX, Rm );
654 MOVZX_r16_r32( R_EAX, R_EAX );
655 store_reg( R_EAX, Rn );
659 load_reg( R_EAX, Rm );
660 check_ralign32( R_EAX );
661 MMU_TRANSLATE_READ( R_EAX );
662 PUSH_realigned_r32( R_EAX );
663 load_reg( R_EAX, Rn );
664 ADD_imm8s_r32( 4, R_EAX );
665 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
666 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
667 // Note translate twice in case of page boundaries. Maybe worth
668 // adding a page-boundary check to skip the second translation
670 load_reg( R_EAX, Rm );
671 check_ralign32( R_EAX );
672 MMU_TRANSLATE_READ( R_EAX );
673 load_reg( R_ECX, Rn );
674 check_ralign32( R_ECX );
675 PUSH_realigned_r32( R_EAX );
676 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
677 MOV_r32_r32( R_ECX, R_EAX );
678 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
679 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
681 MEM_READ_LONG( R_EAX, R_EAX );
684 MEM_READ_LONG( R_ECX, R_EAX );
685 POP_realigned_r32( R_ECX );
688 ADD_r32_sh4r( R_EAX, R_MACL );
689 ADC_r32_sh4r( R_EDX, R_MACH );
691 load_spreg( R_ECX, R_S );
692 TEST_r32_r32(R_ECX, R_ECX);
693 JE_rel8( CALL_FUNC0_SIZE, nosat );
694 call_func0( signsat48 );
696 sh4_x86.tstate = TSTATE_NONE;
700 load_reg( R_EAX, Rm );
701 check_ralign16( R_EAX );
702 MMU_TRANSLATE_READ( R_EAX );
703 PUSH_realigned_r32( R_EAX );
704 load_reg( R_EAX, Rn );
705 ADD_imm8s_r32( 2, R_EAX );
706 MMU_TRANSLATE_READ_EXC( R_EAX, -5 );
707 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
708 // Note translate twice in case of page boundaries. Maybe worth
709 // adding a page-boundary check to skip the second translation
711 load_reg( R_EAX, Rm );
712 check_ralign16( R_EAX );
713 MMU_TRANSLATE_READ( R_EAX );
714 load_reg( R_ECX, Rn );
715 check_ralign16( R_ECX );
716 PUSH_realigned_r32( R_EAX );
717 MMU_TRANSLATE_READ_EXC( R_ECX, -5 );
718 MOV_r32_r32( R_ECX, R_EAX );
719 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
720 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
722 MEM_READ_WORD( R_EAX, R_EAX );
725 MEM_READ_WORD( R_ECX, R_EAX );
726 POP_realigned_r32( R_ECX );
729 load_spreg( R_ECX, R_S );
730 TEST_r32_r32( R_ECX, R_ECX );
731 JE_rel8( 47, nosat );
733 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
734 JNO_rel8( 51, end ); // 2
735 load_imm32( R_EDX, 1 ); // 5
736 store_spreg( R_EDX, R_MACH ); // 6
737 JS_rel8( 13, positive ); // 2
738 load_imm32( R_EAX, 0x80000000 );// 5
739 store_spreg( R_EAX, R_MACL ); // 6
740 JMP_rel8( 25, end2 ); // 2
742 JMP_TARGET(positive);
743 load_imm32( R_EAX, 0x7FFFFFFF );// 5
744 store_spreg( R_EAX, R_MACL ); // 6
745 JMP_rel8( 12, end3); // 2
748 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
749 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
753 sh4_x86.tstate = TSTATE_NONE;
756 load_spreg( R_EAX, R_T );
757 store_reg( R_EAX, Rn );
760 load_reg( R_EAX, Rm );
761 load_reg( R_ECX, Rn );
763 store_spreg( R_EAX, R_MACL );
764 sh4_x86.tstate = TSTATE_NONE;
767 load_reg16s( R_EAX, Rm );
768 load_reg16s( R_ECX, Rn );
770 store_spreg( R_EAX, R_MACL );
771 sh4_x86.tstate = TSTATE_NONE;
774 load_reg16u( R_EAX, Rm );
775 load_reg16u( R_ECX, Rn );
777 store_spreg( R_EAX, R_MACL );
778 sh4_x86.tstate = TSTATE_NONE;
781 load_reg( R_EAX, Rm );
783 store_reg( R_EAX, Rn );
784 sh4_x86.tstate = TSTATE_NONE;
787 load_reg( R_EAX, Rm );
788 XOR_r32_r32( R_ECX, R_ECX );
790 SBB_r32_r32( R_EAX, R_ECX );
791 store_reg( R_ECX, Rn );
793 sh4_x86.tstate = TSTATE_C;
796 load_reg( R_EAX, Rm );
798 store_reg( R_EAX, Rn );
799 sh4_x86.tstate = TSTATE_NONE;
802 load_reg( R_EAX, Rm );
803 load_reg( R_ECX, Rn );
804 OR_r32_r32( R_EAX, R_ECX );
805 store_reg( R_ECX, Rn );
806 sh4_x86.tstate = TSTATE_NONE;
809 load_reg( R_EAX, 0 );
810 OR_imm32_r32(imm, R_EAX);
811 store_reg( R_EAX, 0 );
812 sh4_x86.tstate = TSTATE_NONE;
814 OR.B #imm, @(R0, GBR) {:
815 load_reg( R_EAX, 0 );
816 load_spreg( R_ECX, R_GBR );
817 ADD_r32_r32( R_ECX, R_EAX );
818 MMU_TRANSLATE_WRITE( R_EAX );
819 PUSH_realigned_r32(R_EAX);
820 MEM_READ_BYTE( R_EAX, R_EAX );
821 POP_realigned_r32(R_ECX);
822 OR_imm32_r32(imm, R_EAX );
823 MEM_WRITE_BYTE( R_ECX, R_EAX );
824 sh4_x86.tstate = TSTATE_NONE;
827 load_reg( R_EAX, Rn );
828 if( sh4_x86.tstate != TSTATE_C ) {
832 store_reg( R_EAX, Rn );
834 sh4_x86.tstate = TSTATE_C;
837 load_reg( R_EAX, Rn );
838 if( sh4_x86.tstate != TSTATE_C ) {
842 store_reg( R_EAX, Rn );
844 sh4_x86.tstate = TSTATE_C;
847 load_reg( R_EAX, Rn );
849 store_reg( R_EAX, Rn );
851 sh4_x86.tstate = TSTATE_C;
854 load_reg( R_EAX, Rn );
856 store_reg( R_EAX, Rn );
858 sh4_x86.tstate = TSTATE_C;
861 /* Annoyingly enough, not directly convertible */
862 load_reg( R_EAX, Rn );
863 load_reg( R_ECX, Rm );
864 CMP_imm32_r32( 0, R_ECX );
867 NEG_r32( R_ECX ); // 2
868 AND_imm8_r8( 0x1F, R_CL ); // 3
869 JE_rel8( 4, emptysar); // 2
870 SAR_r32_CL( R_EAX ); // 2
871 JMP_rel8(10, end); // 2
873 JMP_TARGET(emptysar);
874 SAR_imm8_r32(31, R_EAX ); // 3
878 AND_imm8_r8( 0x1F, R_CL ); // 3
879 SHL_r32_CL( R_EAX ); // 2
882 store_reg( R_EAX, Rn );
883 sh4_x86.tstate = TSTATE_NONE;
886 load_reg( R_EAX, Rn );
887 load_reg( R_ECX, Rm );
888 CMP_imm32_r32( 0, R_ECX );
891 NEG_r32( R_ECX ); // 2
892 AND_imm8_r8( 0x1F, R_CL ); // 3
893 JE_rel8( 4, emptyshr );
894 SHR_r32_CL( R_EAX ); // 2
895 JMP_rel8(9, end); // 2
897 JMP_TARGET(emptyshr);
898 XOR_r32_r32( R_EAX, R_EAX );
902 AND_imm8_r8( 0x1F, R_CL ); // 3
903 SHL_r32_CL( R_EAX ); // 2
906 store_reg( R_EAX, Rn );
907 sh4_x86.tstate = TSTATE_NONE;
910 load_reg( R_EAX, Rn );
913 store_reg( R_EAX, Rn );
914 sh4_x86.tstate = TSTATE_C;
917 load_reg( R_EAX, Rn );
920 store_reg( R_EAX, Rn );
921 sh4_x86.tstate = TSTATE_C;
924 load_reg( R_EAX, Rn );
927 store_reg( R_EAX, Rn );
928 sh4_x86.tstate = TSTATE_C;
931 load_reg( R_EAX, Rn );
932 SHL_imm8_r32( 2, R_EAX );
933 store_reg( R_EAX, Rn );
934 sh4_x86.tstate = TSTATE_NONE;
937 load_reg( R_EAX, Rn );
938 SHL_imm8_r32( 8, R_EAX );
939 store_reg( R_EAX, Rn );
940 sh4_x86.tstate = TSTATE_NONE;
943 load_reg( R_EAX, Rn );
944 SHL_imm8_r32( 16, R_EAX );
945 store_reg( R_EAX, Rn );
946 sh4_x86.tstate = TSTATE_NONE;
949 load_reg( R_EAX, Rn );
952 store_reg( R_EAX, Rn );
953 sh4_x86.tstate = TSTATE_C;
956 load_reg( R_EAX, Rn );
957 SHR_imm8_r32( 2, R_EAX );
958 store_reg( R_EAX, Rn );
959 sh4_x86.tstate = TSTATE_NONE;
962 load_reg( R_EAX, Rn );
963 SHR_imm8_r32( 8, R_EAX );
964 store_reg( R_EAX, Rn );
965 sh4_x86.tstate = TSTATE_NONE;
968 load_reg( R_EAX, Rn );
969 SHR_imm8_r32( 16, R_EAX );
970 store_reg( R_EAX, Rn );
971 sh4_x86.tstate = TSTATE_NONE;
974 load_reg( R_EAX, Rm );
975 load_reg( R_ECX, Rn );
976 SUB_r32_r32( R_EAX, R_ECX );
977 store_reg( R_ECX, Rn );
978 sh4_x86.tstate = TSTATE_NONE;
981 load_reg( R_EAX, Rm );
982 load_reg( R_ECX, Rn );
983 if( sh4_x86.tstate != TSTATE_C ) {
986 SBB_r32_r32( R_EAX, R_ECX );
987 store_reg( R_ECX, Rn );
989 sh4_x86.tstate = TSTATE_C;
992 load_reg( R_EAX, Rm );
993 load_reg( R_ECX, Rn );
994 SUB_r32_r32( R_EAX, R_ECX );
995 store_reg( R_ECX, Rn );
997 sh4_x86.tstate = TSTATE_O;
1000 load_reg( R_EAX, Rm );
1001 XCHG_r8_r8( R_AL, R_AH ); // NB: does not touch EFLAGS
1002 store_reg( R_EAX, Rn );
1005 load_reg( R_EAX, Rm );
1006 MOV_r32_r32( R_EAX, R_ECX );
1007 SHL_imm8_r32( 16, R_ECX );
1008 SHR_imm8_r32( 16, R_EAX );
1009 OR_r32_r32( R_EAX, R_ECX );
1010 store_reg( R_ECX, Rn );
1011 sh4_x86.tstate = TSTATE_NONE;
1014 load_reg( R_EAX, Rn );
1015 MMU_TRANSLATE_WRITE( R_EAX );
1016 PUSH_realigned_r32( R_EAX );
1017 MEM_READ_BYTE( R_EAX, R_EAX );
1018 TEST_r8_r8( R_AL, R_AL );
1020 OR_imm8_r8( 0x80, R_AL );
1021 POP_realigned_r32( R_ECX );
1022 MEM_WRITE_BYTE( R_ECX, R_EAX );
1023 sh4_x86.tstate = TSTATE_NONE;
1026 load_reg( R_EAX, Rm );
1027 load_reg( R_ECX, Rn );
1028 TEST_r32_r32( R_EAX, R_ECX );
1030 sh4_x86.tstate = TSTATE_E;
1033 load_reg( R_EAX, 0 );
1034 TEST_imm32_r32( imm, R_EAX );
1036 sh4_x86.tstate = TSTATE_E;
1038 TST.B #imm, @(R0, GBR) {:
1039 load_reg( R_EAX, 0);
1040 load_reg( R_ECX, R_GBR);
1041 ADD_r32_r32( R_ECX, R_EAX );
1042 MMU_TRANSLATE_READ( R_EAX );
1043 MEM_READ_BYTE( R_EAX, R_EAX );
1044 TEST_imm8_r8( imm, R_AL );
1046 sh4_x86.tstate = TSTATE_E;
1049 load_reg( R_EAX, Rm );
1050 load_reg( R_ECX, Rn );
1051 XOR_r32_r32( R_EAX, R_ECX );
1052 store_reg( R_ECX, Rn );
1053 sh4_x86.tstate = TSTATE_NONE;
1056 load_reg( R_EAX, 0 );
1057 XOR_imm32_r32( imm, R_EAX );
1058 store_reg( R_EAX, 0 );
1059 sh4_x86.tstate = TSTATE_NONE;
1061 XOR.B #imm, @(R0, GBR) {:
1062 load_reg( R_EAX, 0 );
1063 load_spreg( R_ECX, R_GBR );
1064 ADD_r32_r32( R_ECX, R_EAX );
1065 MMU_TRANSLATE_WRITE( R_EAX );
1066 PUSH_realigned_r32(R_EAX);
1067 MEM_READ_BYTE(R_EAX, R_EAX);
1068 POP_realigned_r32(R_ECX);
1069 XOR_imm32_r32( imm, R_EAX );
1070 MEM_WRITE_BYTE( R_ECX, R_EAX );
1071 sh4_x86.tstate = TSTATE_NONE;
1074 load_reg( R_EAX, Rm );
1075 load_reg( R_ECX, Rn );
1076 SHL_imm8_r32( 16, R_EAX );
1077 SHR_imm8_r32( 16, R_ECX );
1078 OR_r32_r32( R_EAX, R_ECX );
1079 store_reg( R_ECX, Rn );
1080 sh4_x86.tstate = TSTATE_NONE;
1083 /* Data move instructions */
1085 load_reg( R_EAX, Rm );
1086 store_reg( R_EAX, Rn );
1089 load_imm32( R_EAX, imm );
1090 store_reg( R_EAX, Rn );
1093 load_reg( R_EAX, Rn );
1094 MMU_TRANSLATE_WRITE( R_EAX );
1095 load_reg( R_EDX, Rm );
1096 MEM_WRITE_BYTE( R_EAX, R_EDX );
1097 sh4_x86.tstate = TSTATE_NONE;
1100 load_reg( R_EAX, Rn );
1101 ADD_imm8s_r32( -1, R_EAX );
1102 MMU_TRANSLATE_WRITE( R_EAX );
1103 load_reg( R_EDX, Rm );
1104 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
1105 MEM_WRITE_BYTE( R_EAX, R_EDX );
1106 sh4_x86.tstate = TSTATE_NONE;
1108 MOV.B Rm, @(R0, Rn) {:
1109 load_reg( R_EAX, 0 );
1110 load_reg( R_ECX, Rn );
1111 ADD_r32_r32( R_ECX, R_EAX );
1112 MMU_TRANSLATE_WRITE( R_EAX );
1113 load_reg( R_EDX, Rm );
1114 MEM_WRITE_BYTE( R_EAX, R_EDX );
1115 sh4_x86.tstate = TSTATE_NONE;
1117 MOV.B R0, @(disp, GBR) {:
1118 load_spreg( R_EAX, R_GBR );
1119 ADD_imm32_r32( disp, R_EAX );
1120 MMU_TRANSLATE_WRITE( R_EAX );
1121 load_reg( R_EDX, 0 );
1122 MEM_WRITE_BYTE( R_EAX, R_EDX );
1123 sh4_x86.tstate = TSTATE_NONE;
1125 MOV.B R0, @(disp, Rn) {:
1126 load_reg( R_EAX, Rn );
1127 ADD_imm32_r32( disp, R_EAX );
1128 MMU_TRANSLATE_WRITE( R_EAX );
1129 load_reg( R_EDX, 0 );
1130 MEM_WRITE_BYTE( R_EAX, R_EDX );
1131 sh4_x86.tstate = TSTATE_NONE;
1134 load_reg( R_EAX, Rm );
1135 MMU_TRANSLATE_READ( R_EAX );
1136 MEM_READ_BYTE( R_EAX, R_EAX );
1137 store_reg( R_EAX, Rn );
1138 sh4_x86.tstate = TSTATE_NONE;
1141 load_reg( R_EAX, Rm );
1142 MMU_TRANSLATE_READ( R_EAX );
1143 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
1144 MEM_READ_BYTE( R_EAX, R_EAX );
1145 store_reg( R_EAX, Rn );
1146 sh4_x86.tstate = TSTATE_NONE;
1148 MOV.B @(R0, Rm), Rn {:
1149 load_reg( R_EAX, 0 );
1150 load_reg( R_ECX, Rm );
1151 ADD_r32_r32( R_ECX, R_EAX );
1152 MMU_TRANSLATE_READ( R_EAX )
1153 MEM_READ_BYTE( R_EAX, R_EAX );
1154 store_reg( R_EAX, Rn );
1155 sh4_x86.tstate = TSTATE_NONE;
1157 MOV.B @(disp, GBR), R0 {:
1158 load_spreg( R_EAX, R_GBR );
1159 ADD_imm32_r32( disp, R_EAX );
1160 MMU_TRANSLATE_READ( R_EAX );
1161 MEM_READ_BYTE( R_EAX, R_EAX );
1162 store_reg( R_EAX, 0 );
1163 sh4_x86.tstate = TSTATE_NONE;
1165 MOV.B @(disp, Rm), R0 {:
1166 load_reg( R_EAX, Rm );
1167 ADD_imm32_r32( disp, R_EAX );
1168 MMU_TRANSLATE_READ( R_EAX );
1169 MEM_READ_BYTE( R_EAX, R_EAX );
1170 store_reg( R_EAX, 0 );
1171 sh4_x86.tstate = TSTATE_NONE;
1174 load_reg( R_EAX, Rn );
1175 check_walign32(R_EAX);
1176 MMU_TRANSLATE_WRITE( R_EAX );
1177 load_reg( R_EDX, Rm );
1178 MEM_WRITE_LONG( R_EAX, R_EDX );
1179 sh4_x86.tstate = TSTATE_NONE;
1182 load_reg( R_EAX, Rn );
1183 ADD_imm8s_r32( -4, R_EAX );
1184 check_walign32( R_EAX );
1185 MMU_TRANSLATE_WRITE( R_EAX );
1186 load_reg( R_EDX, Rm );
1187 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1188 MEM_WRITE_LONG( R_EAX, R_EDX );
1189 sh4_x86.tstate = TSTATE_NONE;
1191 MOV.L Rm, @(R0, Rn) {:
1192 load_reg( R_EAX, 0 );
1193 load_reg( R_ECX, Rn );
1194 ADD_r32_r32( R_ECX, R_EAX );
1195 check_walign32( R_EAX );
1196 MMU_TRANSLATE_WRITE( R_EAX );
1197 load_reg( R_EDX, Rm );
1198 MEM_WRITE_LONG( R_EAX, R_EDX );
1199 sh4_x86.tstate = TSTATE_NONE;
1201 MOV.L R0, @(disp, GBR) {:
1202 load_spreg( R_EAX, R_GBR );
1203 ADD_imm32_r32( disp, R_EAX );
1204 check_walign32( R_EAX );
1205 MMU_TRANSLATE_WRITE( R_EAX );
1206 load_reg( R_EDX, 0 );
1207 MEM_WRITE_LONG( R_EAX, R_EDX );
1208 sh4_x86.tstate = TSTATE_NONE;
1210 MOV.L Rm, @(disp, Rn) {:
1211 load_reg( R_EAX, Rn );
1212 ADD_imm32_r32( disp, R_EAX );
1213 check_walign32( R_EAX );
1214 MMU_TRANSLATE_WRITE( R_EAX );
1215 load_reg( R_EDX, Rm );
1216 MEM_WRITE_LONG( R_EAX, R_EDX );
1217 sh4_x86.tstate = TSTATE_NONE;
1220 load_reg( R_EAX, Rm );
1221 check_ralign32( R_EAX );
1222 MMU_TRANSLATE_READ( R_EAX );
1223 MEM_READ_LONG( R_EAX, R_EAX );
1224 store_reg( R_EAX, Rn );
1225 sh4_x86.tstate = TSTATE_NONE;
1228 load_reg( R_EAX, Rm );
1229 check_ralign32( R_EAX );
1230 MMU_TRANSLATE_READ( R_EAX );
1231 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1232 MEM_READ_LONG( R_EAX, R_EAX );
1233 store_reg( R_EAX, Rn );
1234 sh4_x86.tstate = TSTATE_NONE;
1236 MOV.L @(R0, Rm), Rn {:
1237 load_reg( R_EAX, 0 );
1238 load_reg( R_ECX, Rm );
1239 ADD_r32_r32( R_ECX, R_EAX );
1240 check_ralign32( R_EAX );
1241 MMU_TRANSLATE_READ( R_EAX );
1242 MEM_READ_LONG( R_EAX, R_EAX );
1243 store_reg( R_EAX, Rn );
1244 sh4_x86.tstate = TSTATE_NONE;
1246 MOV.L @(disp, GBR), R0 {:
1247 load_spreg( R_EAX, R_GBR );
1248 ADD_imm32_r32( disp, R_EAX );
1249 check_ralign32( R_EAX );
1250 MMU_TRANSLATE_READ( R_EAX );
1251 MEM_READ_LONG( R_EAX, R_EAX );
1252 store_reg( R_EAX, 0 );
1253 sh4_x86.tstate = TSTATE_NONE;
1255 MOV.L @(disp, PC), Rn {:
1256 if( sh4_x86.in_delay_slot ) {
1259 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
1260 if( IS_IN_ICACHE(target) ) {
1261 // If the target address is in the same page as the code, it's
1262 // pretty safe to just ref it directly and circumvent the whole
1263 // memory subsystem. (this is a big performance win)
1265 // FIXME: There's a corner-case that's not handled here when
1266 // the current code-page is in the ITLB but not in the UTLB.
1267 // (should generate a TLB miss although need to test SH4
1268 // behaviour to confirm) Unlikely to be anyone depending on this
1269 // behaviour though.
1270 sh4ptr_t ptr = GET_ICACHE_PTR(target);
1271 MOV_moff32_EAX( ptr );
1273 // Note: we use sh4r.pc for the calc as we could be running at a
1274 // different virtual address than the translation was done with,
1275 // but we can safely assume that the low bits are the same.
1276 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1277 ADD_sh4r_r32( R_PC, R_EAX );
1278 MMU_TRANSLATE_READ( R_EAX );
1279 MEM_READ_LONG( R_EAX, R_EAX );
1280 sh4_x86.tstate = TSTATE_NONE;
1282 store_reg( R_EAX, Rn );
1285 MOV.L @(disp, Rm), Rn {:
1286 load_reg( R_EAX, Rm );
1287 ADD_imm8s_r32( disp, R_EAX );
1288 check_ralign32( R_EAX );
1289 MMU_TRANSLATE_READ( R_EAX );
1290 MEM_READ_LONG( R_EAX, R_EAX );
1291 store_reg( R_EAX, Rn );
1292 sh4_x86.tstate = TSTATE_NONE;
1295 load_reg( R_EAX, Rn );
1296 check_walign16( R_EAX );
1297 MMU_TRANSLATE_WRITE( R_EAX )
1298 load_reg( R_EDX, Rm );
1299 MEM_WRITE_WORD( R_EAX, R_EDX );
1300 sh4_x86.tstate = TSTATE_NONE;
1303 load_reg( R_EAX, Rn );
1304 ADD_imm8s_r32( -2, R_EAX );
1305 check_walign16( R_EAX );
1306 MMU_TRANSLATE_WRITE( R_EAX );
1307 load_reg( R_EDX, Rm );
1308 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
1309 MEM_WRITE_WORD( R_EAX, R_EDX );
1310 sh4_x86.tstate = TSTATE_NONE;
1312 MOV.W Rm, @(R0, Rn) {:
1313 load_reg( R_EAX, 0 );
1314 load_reg( R_ECX, Rn );
1315 ADD_r32_r32( R_ECX, R_EAX );
1316 check_walign16( R_EAX );
1317 MMU_TRANSLATE_WRITE( R_EAX );
1318 load_reg( R_EDX, Rm );
1319 MEM_WRITE_WORD( R_EAX, R_EDX );
1320 sh4_x86.tstate = TSTATE_NONE;
1322 MOV.W R0, @(disp, GBR) {:
1323 load_spreg( R_EAX, R_GBR );
1324 ADD_imm32_r32( disp, R_EAX );
1325 check_walign16( R_EAX );
1326 MMU_TRANSLATE_WRITE( R_EAX );
1327 load_reg( R_EDX, 0 );
1328 MEM_WRITE_WORD( R_EAX, R_EDX );
1329 sh4_x86.tstate = TSTATE_NONE;
1331 MOV.W R0, @(disp, Rn) {:
1332 load_reg( R_EAX, Rn );
1333 ADD_imm32_r32( disp, R_EAX );
1334 check_walign16( R_EAX );
1335 MMU_TRANSLATE_WRITE( R_EAX );
1336 load_reg( R_EDX, 0 );
1337 MEM_WRITE_WORD( R_EAX, R_EDX );
1338 sh4_x86.tstate = TSTATE_NONE;
1341 load_reg( R_EAX, Rm );
1342 check_ralign16( R_EAX );
1343 MMU_TRANSLATE_READ( R_EAX );
1344 MEM_READ_WORD( R_EAX, R_EAX );
1345 store_reg( R_EAX, Rn );
1346 sh4_x86.tstate = TSTATE_NONE;
1349 load_reg( R_EAX, Rm );
1350 check_ralign16( R_EAX );
1351 MMU_TRANSLATE_READ( R_EAX );
1352 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1353 MEM_READ_WORD( R_EAX, R_EAX );
1354 store_reg( R_EAX, Rn );
1355 sh4_x86.tstate = TSTATE_NONE;
1357 MOV.W @(R0, Rm), Rn {:
1358 load_reg( R_EAX, 0 );
1359 load_reg( R_ECX, Rm );
1360 ADD_r32_r32( R_ECX, R_EAX );
1361 check_ralign16( R_EAX );
1362 MMU_TRANSLATE_READ( R_EAX );
1363 MEM_READ_WORD( R_EAX, R_EAX );
1364 store_reg( R_EAX, Rn );
1365 sh4_x86.tstate = TSTATE_NONE;
1367 MOV.W @(disp, GBR), R0 {:
1368 load_spreg( R_EAX, R_GBR );
1369 ADD_imm32_r32( disp, R_EAX );
1370 check_ralign16( R_EAX );
1371 MMU_TRANSLATE_READ( R_EAX );
1372 MEM_READ_WORD( R_EAX, R_EAX );
1373 store_reg( R_EAX, 0 );
1374 sh4_x86.tstate = TSTATE_NONE;
1376 MOV.W @(disp, PC), Rn {:
1377 if( sh4_x86.in_delay_slot ) {
1380 // See comments for MOV.L @(disp, PC), Rn
1381 uint32_t target = pc + disp + 4;
1382 if( IS_IN_ICACHE(target) ) {
1383 sh4ptr_t ptr = GET_ICACHE_PTR(target);
1384 MOV_moff32_EAX( ptr );
1385 MOVSX_r16_r32( R_EAX, R_EAX );
1387 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1388 ADD_sh4r_r32( R_PC, R_EAX );
1389 MMU_TRANSLATE_READ( R_EAX );
1390 MEM_READ_WORD( R_EAX, R_EAX );
1391 sh4_x86.tstate = TSTATE_NONE;
1393 store_reg( R_EAX, Rn );
1396 MOV.W @(disp, Rm), R0 {:
1397 load_reg( R_EAX, Rm );
1398 ADD_imm32_r32( disp, R_EAX );
1399 check_ralign16( R_EAX );
1400 MMU_TRANSLATE_READ( R_EAX );
1401 MEM_READ_WORD( R_EAX, R_EAX );
1402 store_reg( R_EAX, 0 );
1403 sh4_x86.tstate = TSTATE_NONE;
1405 MOVA @(disp, PC), R0 {:
1406 if( sh4_x86.in_delay_slot ) {
1409 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1410 ADD_sh4r_r32( R_PC, R_ECX );
1411 store_reg( R_ECX, 0 );
1412 sh4_x86.tstate = TSTATE_NONE;
1416 load_reg( R_EAX, Rn );
1417 check_walign32( R_EAX );
1418 MMU_TRANSLATE_WRITE( R_EAX );
1419 load_reg( R_EDX, 0 );
1420 MEM_WRITE_LONG( R_EAX, R_EDX );
1421 sh4_x86.tstate = TSTATE_NONE;
1424 /* Control transfer instructions */
1426 if( sh4_x86.in_delay_slot ) {
1429 sh4vma_t target = disp + pc + 4;
1430 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1431 exit_block_rel(target, pc+2 );
1432 JMP_TARGET(nottaken);
1437 if( sh4_x86.in_delay_slot ) {
1440 sh4_x86.in_delay_slot = DELAY_PC;
1441 if( UNTRANSLATABLE(pc+2) ) {
1442 load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );
1443 JT_rel8(6,nottaken);
1444 ADD_imm32_r32( disp, R_EAX );
1445 JMP_TARGET(nottaken);
1446 ADD_sh4r_r32( R_PC, R_EAX );
1447 store_spreg( R_EAX, R_NEW_PC );
1448 exit_block_emu(pc+2);
1449 sh4_x86.branch_taken = TRUE;
1452 if( sh4_x86.tstate == TSTATE_NONE ) {
1453 CMP_imm8s_sh4r( 1, R_T );
1454 sh4_x86.tstate = TSTATE_E;
1456 sh4vma_t target = disp + pc + 4;
1457 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JT rel32
1458 sh4_translate_instruction(pc+2);
1459 exit_block_rel( target, pc+4 );
1462 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1463 sh4_translate_instruction(pc+2);
1469 if( sh4_x86.in_delay_slot ) {
1472 sh4_x86.in_delay_slot = DELAY_PC;
1473 sh4_x86.branch_taken = TRUE;
1474 if( UNTRANSLATABLE(pc+2) ) {
1475 load_spreg( R_EAX, R_PC );
1476 ADD_imm32_r32( pc + disp + 4 - sh4_x86.block_start_pc, R_EAX );
1477 store_spreg( R_EAX, R_NEW_PC );
1478 exit_block_emu(pc+2);
1481 sh4_translate_instruction( pc + 2 );
1482 exit_block_rel( disp + pc + 4, pc+4 );
1488 if( sh4_x86.in_delay_slot ) {
1491 load_spreg( R_EAX, R_PC );
1492 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1493 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
1494 store_spreg( R_EAX, R_NEW_PC );
1495 sh4_x86.in_delay_slot = DELAY_PC;
1496 sh4_x86.tstate = TSTATE_NONE;
1497 sh4_x86.branch_taken = TRUE;
1498 if( UNTRANSLATABLE(pc+2) ) {
1499 exit_block_emu(pc+2);
1502 sh4_translate_instruction( pc + 2 );
1503 exit_block_newpcset(pc+2);
1509 if( sh4_x86.in_delay_slot ) {
1512 load_spreg( R_EAX, R_PC );
1513 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1514 store_spreg( R_EAX, R_PR );
1515 sh4_x86.in_delay_slot = DELAY_PC;
1516 sh4_x86.branch_taken = TRUE;
1517 sh4_x86.tstate = TSTATE_NONE;
1518 if( UNTRANSLATABLE(pc+2) ) {
1519 ADD_imm32_r32( disp, R_EAX );
1520 store_spreg( R_EAX, R_NEW_PC );
1521 exit_block_emu(pc+2);
1524 sh4_translate_instruction( pc + 2 );
1525 exit_block_rel( disp + pc + 4, pc+4 );
1531 if( sh4_x86.in_delay_slot ) {
1534 load_spreg( R_EAX, R_PC );
1535 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1536 store_spreg( R_EAX, R_PR );
1537 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
1538 store_spreg( R_EAX, R_NEW_PC );
1540 sh4_x86.in_delay_slot = DELAY_PC;
1541 sh4_x86.tstate = TSTATE_NONE;
1542 sh4_x86.branch_taken = TRUE;
1543 if( UNTRANSLATABLE(pc+2) ) {
1544 exit_block_emu(pc+2);
1547 sh4_translate_instruction( pc + 2 );
1548 exit_block_newpcset(pc+2);
1554 if( sh4_x86.in_delay_slot ) {
1557 sh4vma_t target = disp + pc + 4;
1558 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1559 exit_block_rel(target, pc+2 );
1560 JMP_TARGET(nottaken);
1565 if( sh4_x86.in_delay_slot ) {
1568 sh4_x86.in_delay_slot = DELAY_PC;
1569 if( UNTRANSLATABLE(pc+2) ) {
1570 load_imm32( R_EAX, pc + 4 - sh4_x86.block_start_pc );
1571 JF_rel8(6,nottaken);
1572 ADD_imm32_r32( disp, R_EAX );
1573 JMP_TARGET(nottaken);
1574 ADD_sh4r_r32( R_PC, R_EAX );
1575 store_spreg( R_EAX, R_NEW_PC );
1576 exit_block_emu(pc+2);
1577 sh4_x86.branch_taken = TRUE;
1580 if( sh4_x86.tstate == TSTATE_NONE ) {
1581 CMP_imm8s_sh4r( 1, R_T );
1582 sh4_x86.tstate = TSTATE_E;
1584 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JF rel32
1585 sh4_translate_instruction(pc+2);
1586 exit_block_rel( disp + pc + 4, pc+4 );
1588 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1589 sh4_translate_instruction(pc+2);
1595 if( sh4_x86.in_delay_slot ) {
1598 load_reg( R_ECX, Rn );
1599 store_spreg( R_ECX, R_NEW_PC );
1600 sh4_x86.in_delay_slot = DELAY_PC;
1601 sh4_x86.branch_taken = TRUE;
1602 if( UNTRANSLATABLE(pc+2) ) {
1603 exit_block_emu(pc+2);
1606 sh4_translate_instruction(pc+2);
1607 exit_block_newpcset(pc+2);
1613 if( sh4_x86.in_delay_slot ) {
1616 load_spreg( R_EAX, R_PC );
1617 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1618 store_spreg( R_EAX, R_PR );
1619 load_reg( R_ECX, Rn );
1620 store_spreg( R_ECX, R_NEW_PC );
1621 sh4_x86.in_delay_slot = DELAY_PC;
1622 sh4_x86.branch_taken = TRUE;
1623 sh4_x86.tstate = TSTATE_NONE;
1624 if( UNTRANSLATABLE(pc+2) ) {
1625 exit_block_emu(pc+2);
1628 sh4_translate_instruction(pc+2);
1629 exit_block_newpcset(pc+2);
1635 if( sh4_x86.in_delay_slot ) {
1639 load_spreg( R_ECX, R_SPC );
1640 store_spreg( R_ECX, R_NEW_PC );
1641 load_spreg( R_EAX, R_SSR );
1642 call_func1( sh4_write_sr, R_EAX );
1643 sh4_x86.in_delay_slot = DELAY_PC;
1644 sh4_x86.priv_checked = FALSE;
1645 sh4_x86.fpuen_checked = FALSE;
1646 sh4_x86.tstate = TSTATE_NONE;
1647 sh4_x86.branch_taken = TRUE;
1648 if( UNTRANSLATABLE(pc+2) ) {
1649 exit_block_emu(pc+2);
1652 sh4_translate_instruction(pc+2);
1653 exit_block_newpcset(pc+2);
1659 if( sh4_x86.in_delay_slot ) {
1662 load_spreg( R_ECX, R_PR );
1663 store_spreg( R_ECX, R_NEW_PC );
1664 sh4_x86.in_delay_slot = DELAY_PC;
1665 sh4_x86.branch_taken = TRUE;
1666 if( UNTRANSLATABLE(pc+2) ) {
1667 exit_block_emu(pc+2);
1670 sh4_translate_instruction(pc+2);
1671 exit_block_newpcset(pc+2);
1677 if( sh4_x86.in_delay_slot ) {
1680 load_imm32( R_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
1681 ADD_r32_sh4r( R_ECX, R_PC );
1682 load_imm32( R_EAX, imm );
1683 call_func1( sh4_raise_trap, R_EAX );
1684 sh4_x86.tstate = TSTATE_NONE;
1685 exit_block_pcset(pc);
1686 sh4_x86.branch_taken = TRUE;
1691 if( sh4_x86.in_delay_slot ) {
1694 JMP_exc(EXC_ILLEGAL);
1700 XOR_r32_r32(R_EAX, R_EAX);
1701 store_spreg( R_EAX, R_MACL );
1702 store_spreg( R_EAX, R_MACH );
1703 sh4_x86.tstate = TSTATE_NONE;
1708 sh4_x86.tstate = TSTATE_C;
1713 sh4_x86.tstate = TSTATE_C;
1718 sh4_x86.tstate = TSTATE_C;
1723 sh4_x86.tstate = TSTATE_C;
1726 /* Floating point moves */
1728 /* As horrible as this looks, it's actually covering 5 separate cases:
1729 * 1. 32-bit fr-to-fr (PR=0)
1730 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
1731 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
1732 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
1733 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
1736 load_spreg( R_ECX, R_FPSCR );
1737 load_fr_bank( R_EDX );
1738 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1739 JNE_rel8(8, doublesize);
1740 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
1741 store_fr( R_EDX, R_EAX, FRn );
1744 JMP_TARGET(doublesize);
1745 load_xf_bank( R_ECX );
1746 load_fr( R_ECX, R_EAX, FRm-1 );
1748 load_fr( R_ECX, R_EDX, FRm );
1749 store_fr( R_ECX, R_EAX, FRn-1 );
1750 store_fr( R_ECX, R_EDX, FRn );
1751 } else /* FRn&1 == 0 */ {
1752 load_fr( R_ECX, R_ECX, FRm );
1753 store_fr( R_EDX, R_EAX, FRn );
1754 store_fr( R_EDX, R_ECX, FRn+1 );
1757 } else /* FRm&1 == 0 */ {
1760 load_xf_bank( R_ECX );
1761 load_fr( R_EDX, R_EAX, FRm );
1762 load_fr( R_EDX, R_EDX, FRm+1 );
1763 store_fr( R_ECX, R_EAX, FRn-1 );
1764 store_fr( R_ECX, R_EDX, FRn );
1766 } else /* FRn&1 == 0 */ {
1768 load_fr( R_EDX, R_EAX, FRm );
1769 load_fr( R_EDX, R_ECX, FRm+1 );
1770 store_fr( R_EDX, R_EAX, FRn );
1771 store_fr( R_EDX, R_ECX, FRn+1 );
1775 sh4_x86.tstate = TSTATE_NONE;
1779 load_reg( R_EAX, Rn );
1780 check_walign32( R_EAX );
1781 MMU_TRANSLATE_WRITE( R_EAX );
1782 load_spreg( R_EDX, R_FPSCR );
1783 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1784 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1785 load_fr_bank( R_EDX );
1786 load_fr( R_EDX, R_ECX, FRm );
1787 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1789 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1790 JMP_TARGET(doublesize);
1791 load_xf_bank( R_EDX );
1792 load_fr( R_EDX, R_ECX, FRm&0x0E );
1793 load_fr( R_EDX, R_EDX, FRm|0x01 );
1794 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1797 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1798 JMP_TARGET(doublesize);
1799 load_fr_bank( R_EDX );
1800 load_fr( R_EDX, R_ECX, FRm&0x0E );
1801 load_fr( R_EDX, R_EDX, FRm|0x01 );
1802 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1805 sh4_x86.tstate = TSTATE_NONE;
1809 load_reg( R_EAX, Rm );
1810 check_ralign32( R_EAX );
1811 MMU_TRANSLATE_READ( R_EAX );
1812 load_spreg( R_EDX, R_FPSCR );
1813 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1814 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1815 MEM_READ_LONG( R_EAX, R_EAX );
1816 load_fr_bank( R_EDX );
1817 store_fr( R_EDX, R_EAX, FRn );
1819 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1820 JMP_TARGET(doublesize);
1821 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1822 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1823 load_xf_bank( R_EDX );
1824 store_fr( R_EDX, R_ECX, FRn&0x0E );
1825 store_fr( R_EDX, R_EAX, FRn|0x01 );
1828 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1829 JMP_TARGET(doublesize);
1830 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1831 load_fr_bank( R_EDX );
1832 store_fr( R_EDX, R_ECX, FRn&0x0E );
1833 store_fr( R_EDX, R_EAX, FRn|0x01 );
1836 sh4_x86.tstate = TSTATE_NONE;
1840 load_reg( R_EAX, Rn );
1841 check_walign32( R_EAX );
1842 load_spreg( R_EDX, R_FPSCR );
1843 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1844 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
1845 ADD_imm8s_r32( -4, R_EAX );
1846 MMU_TRANSLATE_WRITE( R_EAX );
1847 load_fr_bank( R_EDX );
1848 load_fr( R_EDX, R_ECX, FRm );
1849 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
1850 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1852 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1853 JMP_TARGET(doublesize);
1854 ADD_imm8s_r32(-8,R_EAX);
1855 MMU_TRANSLATE_WRITE( R_EAX );
1856 load_xf_bank( R_EDX );
1857 load_fr( R_EDX, R_ECX, FRm&0x0E );
1858 load_fr( R_EDX, R_EDX, FRm|0x01 );
1859 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1860 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1863 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1864 JMP_TARGET(doublesize);
1865 ADD_imm8s_r32(-8,R_EAX);
1866 MMU_TRANSLATE_WRITE( R_EAX );
1867 load_fr_bank( R_EDX );
1868 load_fr( R_EDX, R_ECX, FRm&0x0E );
1869 load_fr( R_EDX, R_EDX, FRm|0x01 );
1870 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1871 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1874 sh4_x86.tstate = TSTATE_NONE;
1878 load_reg( R_EAX, Rm );
1879 check_ralign32( R_EAX );
1880 MMU_TRANSLATE_READ( R_EAX );
1881 load_spreg( R_EDX, R_FPSCR );
1882 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1883 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
1884 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1885 MEM_READ_LONG( R_EAX, R_EAX );
1886 load_fr_bank( R_EDX );
1887 store_fr( R_EDX, R_EAX, FRn );
1889 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
1890 JMP_TARGET(doublesize);
1891 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1892 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1893 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1894 load_xf_bank( R_EDX );
1895 store_fr( R_EDX, R_ECX, FRn&0x0E );
1896 store_fr( R_EDX, R_EAX, FRn|0x01 );
1899 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
1900 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1901 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1902 load_fr_bank( R_EDX );
1903 store_fr( R_EDX, R_ECX, FRn&0x0E );
1904 store_fr( R_EDX, R_EAX, FRn|0x01 );
1907 sh4_x86.tstate = TSTATE_NONE;
1909 FMOV FRm, @(R0, Rn) {:
1911 load_reg( R_EAX, Rn );
1912 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1913 check_walign32( R_EAX );
1914 MMU_TRANSLATE_WRITE( R_EAX );
1915 load_spreg( R_EDX, R_FPSCR );
1916 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1917 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1918 load_fr_bank( R_EDX );
1919 load_fr( R_EDX, R_ECX, FRm );
1920 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1922 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1923 JMP_TARGET(doublesize);
1924 load_xf_bank( R_EDX );
1925 load_fr( R_EDX, R_ECX, FRm&0x0E );
1926 load_fr( R_EDX, R_EDX, FRm|0x01 );
1927 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1930 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1931 JMP_TARGET(doublesize);
1932 load_fr_bank( R_EDX );
1933 load_fr( R_EDX, R_ECX, FRm&0x0E );
1934 load_fr( R_EDX, R_EDX, FRm|0x01 );
1935 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1938 sh4_x86.tstate = TSTATE_NONE;
1940 FMOV @(R0, Rm), FRn {:
1942 load_reg( R_EAX, Rm );
1943 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1944 check_ralign32( R_EAX );
1945 MMU_TRANSLATE_READ( R_EAX );
1946 load_spreg( R_EDX, R_FPSCR );
1947 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1948 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1949 MEM_READ_LONG( R_EAX, R_EAX );
1950 load_fr_bank( R_EDX );
1951 store_fr( R_EDX, R_EAX, FRn );
1953 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1954 JMP_TARGET(doublesize);
1955 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1956 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1957 load_xf_bank( R_EDX );
1958 store_fr( R_EDX, R_ECX, FRn&0x0E );
1959 store_fr( R_EDX, R_EAX, FRn|0x01 );
1962 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1963 JMP_TARGET(doublesize);
1964 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1965 load_fr_bank( R_EDX );
1966 store_fr( R_EDX, R_ECX, FRn&0x0E );
1967 store_fr( R_EDX, R_EAX, FRn|0x01 );
1970 sh4_x86.tstate = TSTATE_NONE;
1972 FLDI0 FRn {: /* IFF PR=0 */
1974 load_spreg( R_ECX, R_FPSCR );
1975 TEST_imm32_r32( FPSCR_PR, R_ECX );
1977 XOR_r32_r32( R_EAX, R_EAX );
1978 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1979 store_fr( R_ECX, R_EAX, FRn );
1981 sh4_x86.tstate = TSTATE_NONE;
1983 FLDI1 FRn {: /* IFF PR=0 */
1985 load_spreg( R_ECX, R_FPSCR );
1986 TEST_imm32_r32( FPSCR_PR, R_ECX );
1988 load_imm32(R_EAX, 0x3F800000);
1989 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1990 store_fr( R_ECX, R_EAX, FRn );
1992 sh4_x86.tstate = TSTATE_NONE;
1997 load_spreg( R_ECX, R_FPSCR );
1998 load_spreg(R_EDX, REG_OFFSET(fr_bank));
2000 TEST_imm32_r32( FPSCR_PR, R_ECX );
2001 JNE_rel8(5, doubleprec);
2002 pop_fr( R_EDX, FRn );
2004 JMP_TARGET(doubleprec);
2005 pop_dr( R_EDX, FRn );
2007 sh4_x86.tstate = TSTATE_NONE;
2011 load_spreg( R_ECX, R_FPSCR );
2012 load_fr_bank( R_EDX );
2013 TEST_imm32_r32( FPSCR_PR, R_ECX );
2014 JNE_rel8(5, doubleprec);
2015 push_fr( R_EDX, FRm );
2017 JMP_TARGET(doubleprec);
2018 push_dr( R_EDX, FRm );
2020 load_imm32( R_ECX, (uint32_t)&max_int );
2021 FILD_r32ind( R_ECX );
2023 JNA_rel8( 32, sat );
2024 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
2025 FILD_r32ind( R_ECX ); // 2
2027 JAE_rel8( 21, sat2 ); // 2
2028 load_imm32( R_EAX, (uint32_t)&save_fcw );
2029 FNSTCW_r32ind( R_EAX );
2030 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
2031 FLDCW_r32ind( R_EDX );
2032 FISTP_sh4r(R_FPUL); // 3
2033 FLDCW_r32ind( R_EAX );
2034 JMP_rel8( 9, end ); // 2
2038 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
2039 store_spreg( R_ECX, R_FPUL );
2042 sh4_x86.tstate = TSTATE_NONE;
2046 load_fr_bank( R_ECX );
2047 load_fr( R_ECX, R_EAX, FRm );
2048 store_spreg( R_EAX, R_FPUL );
2049 sh4_x86.tstate = TSTATE_NONE;
2053 load_fr_bank( R_ECX );
2054 load_spreg( R_EAX, R_FPUL );
2055 store_fr( R_ECX, R_EAX, FRn );
2056 sh4_x86.tstate = TSTATE_NONE;
2060 load_spreg( R_ECX, R_FPSCR );
2061 TEST_imm32_r32( FPSCR_PR, R_ECX );
2062 JE_rel8(9, end); // only when PR=1
2063 load_fr_bank( R_ECX );
2064 push_dr( R_ECX, FRm );
2067 sh4_x86.tstate = TSTATE_NONE;
2071 load_spreg( R_ECX, R_FPSCR );
2072 TEST_imm32_r32( FPSCR_PR, R_ECX );
2073 JE_rel8(9, end); // only when PR=1
2074 load_fr_bank( R_ECX );
2076 pop_dr( R_ECX, FRn );
2078 sh4_x86.tstate = TSTATE_NONE;
2081 /* Floating point instructions */
2084 load_spreg( R_ECX, R_FPSCR );
2085 load_fr_bank( R_EDX );
2086 TEST_imm32_r32( FPSCR_PR, R_ECX );
2087 JNE_rel8(10, doubleprec);
2088 push_fr(R_EDX, FRn); // 3
2090 pop_fr( R_EDX, FRn); //3
2091 JMP_rel8(8,end); // 2
2092 JMP_TARGET(doubleprec);
2093 push_dr(R_EDX, FRn);
2097 sh4_x86.tstate = TSTATE_NONE;
2101 load_spreg( R_ECX, R_FPSCR );
2102 TEST_imm32_r32( FPSCR_PR, R_ECX );
2103 load_fr_bank( R_EDX );
2104 JNE_rel8(13,doubleprec);
2105 push_fr(R_EDX, FRm);
2106 push_fr(R_EDX, FRn);
2110 JMP_TARGET(doubleprec);
2111 push_dr(R_EDX, FRm);
2112 push_dr(R_EDX, FRn);
2116 sh4_x86.tstate = TSTATE_NONE;
2120 load_spreg( R_ECX, R_FPSCR );
2121 TEST_imm32_r32( FPSCR_PR, R_ECX );
2122 load_fr_bank( R_EDX );
2123 JNE_rel8(13, doubleprec);
2124 push_fr(R_EDX, FRn);
2125 push_fr(R_EDX, FRm);
2129 JMP_TARGET(doubleprec);
2130 push_dr(R_EDX, FRn);
2131 push_dr(R_EDX, FRm);
2135 sh4_x86.tstate = TSTATE_NONE;
2137 FMAC FR0, FRm, FRn {:
2139 load_spreg( R_ECX, R_FPSCR );
2140 load_spreg( R_EDX, REG_OFFSET(fr_bank));
2141 TEST_imm32_r32( FPSCR_PR, R_ECX );
2142 JNE_rel8(18, doubleprec);
2143 push_fr( R_EDX, 0 );
2144 push_fr( R_EDX, FRm );
2146 push_fr( R_EDX, FRn );
2148 pop_fr( R_EDX, FRn );
2150 JMP_TARGET(doubleprec);
2151 push_dr( R_EDX, 0 );
2152 push_dr( R_EDX, FRm );
2154 push_dr( R_EDX, FRn );
2156 pop_dr( R_EDX, FRn );
2158 sh4_x86.tstate = TSTATE_NONE;
2163 load_spreg( R_ECX, R_FPSCR );
2164 TEST_imm32_r32( FPSCR_PR, R_ECX );
2165 load_fr_bank( R_EDX );
2166 JNE_rel8(13, doubleprec);
2167 push_fr(R_EDX, FRm);
2168 push_fr(R_EDX, FRn);
2172 JMP_TARGET(doubleprec);
2173 push_dr(R_EDX, FRm);
2174 push_dr(R_EDX, FRn);
2178 sh4_x86.tstate = TSTATE_NONE;
2182 load_spreg( R_ECX, R_FPSCR );
2183 TEST_imm32_r32( FPSCR_PR, R_ECX );
2184 load_fr_bank( R_EDX );
2185 JNE_rel8(10, doubleprec);
2186 push_fr(R_EDX, FRn);
2190 JMP_TARGET(doubleprec);
2191 push_dr(R_EDX, FRn);
2195 sh4_x86.tstate = TSTATE_NONE;
2199 load_spreg( R_ECX, R_FPSCR );
2200 TEST_imm32_r32( FPSCR_PR, R_ECX );
2201 load_fr_bank( R_EDX );
2202 JNE_rel8(12, end); // PR=0 only
2204 push_fr(R_EDX, FRn);
2209 sh4_x86.tstate = TSTATE_NONE;
2213 load_spreg( R_ECX, R_FPSCR );
2214 TEST_imm32_r32( FPSCR_PR, R_ECX );
2215 load_fr_bank( R_EDX );
2216 JNE_rel8(10, doubleprec);
2217 push_fr(R_EDX, FRn);
2221 JMP_TARGET(doubleprec);
2222 push_dr(R_EDX, FRn);
2226 sh4_x86.tstate = TSTATE_NONE;
2230 load_spreg( R_ECX, R_FPSCR );
2231 TEST_imm32_r32( FPSCR_PR, R_ECX );
2232 load_fr_bank( R_EDX );
2233 JNE_rel8(13, doubleprec);
2234 push_fr(R_EDX, FRn);
2235 push_fr(R_EDX, FRm);
2239 JMP_TARGET(doubleprec);
2240 push_dr(R_EDX, FRn);
2241 push_dr(R_EDX, FRm);
2245 sh4_x86.tstate = TSTATE_NONE;
2250 load_spreg( R_ECX, R_FPSCR );
2251 TEST_imm32_r32( FPSCR_PR, R_ECX );
2252 load_fr_bank( R_EDX );
2253 JNE_rel8(8, doubleprec);
2254 push_fr(R_EDX, FRm);
2255 push_fr(R_EDX, FRn);
2257 JMP_TARGET(doubleprec);
2258 push_dr(R_EDX, FRm);
2259 push_dr(R_EDX, FRn);
2264 sh4_x86.tstate = TSTATE_NONE;
2268 load_spreg( R_ECX, R_FPSCR );
2269 TEST_imm32_r32( FPSCR_PR, R_ECX );
2270 load_fr_bank( R_EDX );
2271 JNE_rel8(8, doubleprec);
2272 push_fr(R_EDX, FRm);
2273 push_fr(R_EDX, FRn);
2275 JMP_TARGET(doubleprec);
2276 push_dr(R_EDX, FRm);
2277 push_dr(R_EDX, FRn);
2282 sh4_x86.tstate = TSTATE_NONE;
2287 load_spreg( R_ECX, R_FPSCR );
2288 TEST_imm32_r32( FPSCR_PR, R_ECX );
2289 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
2290 load_fr_bank( R_ECX );
2291 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
2292 load_spreg( R_EDX, R_FPUL );
2293 call_func2( sh4_fsca, R_EDX, R_ECX );
2294 JMP_TARGET(doubleprec);
2295 sh4_x86.tstate = TSTATE_NONE;
2299 load_spreg( R_ECX, R_FPSCR );
2300 TEST_imm32_r32( FPSCR_PR, R_ECX );
2301 JNE_rel8(44, doubleprec);
2303 load_fr_bank( R_ECX );
2304 push_fr( R_ECX, FVm<<2 );
2305 push_fr( R_ECX, FVn<<2 );
2307 push_fr( R_ECX, (FVm<<2)+1);
2308 push_fr( R_ECX, (FVn<<2)+1);
2311 push_fr( R_ECX, (FVm<<2)+2);
2312 push_fr( R_ECX, (FVn<<2)+2);
2315 push_fr( R_ECX, (FVm<<2)+3);
2316 push_fr( R_ECX, (FVn<<2)+3);
2319 pop_fr( R_ECX, (FVn<<2)+3);
2320 JMP_TARGET(doubleprec);
2321 sh4_x86.tstate = TSTATE_NONE;
2325 load_spreg( R_ECX, R_FPSCR );
2326 TEST_imm32_r32( FPSCR_PR, R_ECX );
2327 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
2328 load_fr_bank( R_EDX ); // 3
2329 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
2330 load_xf_bank( R_ECX ); // 12
2331 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
2332 JMP_TARGET(doubleprec);
2333 sh4_x86.tstate = TSTATE_NONE;
2338 load_spreg( R_ECX, R_FPSCR );
2339 XOR_imm32_r32( FPSCR_FR, R_ECX );
2340 store_spreg( R_ECX, R_FPSCR );
2341 update_fr_bank( R_ECX );
2342 sh4_x86.tstate = TSTATE_NONE;
2346 load_spreg( R_ECX, R_FPSCR );
2347 XOR_imm32_r32( FPSCR_SZ, R_ECX );
2348 store_spreg( R_ECX, R_FPSCR );
2349 sh4_x86.tstate = TSTATE_NONE;
2352 /* Processor control instructions */
2354 if( sh4_x86.in_delay_slot ) {
2358 load_reg( R_EAX, Rm );
2359 call_func1( sh4_write_sr, R_EAX );
2360 sh4_x86.priv_checked = FALSE;
2361 sh4_x86.fpuen_checked = FALSE;
2362 sh4_x86.tstate = TSTATE_NONE;
2366 load_reg( R_EAX, Rm );
2367 store_spreg( R_EAX, R_GBR );
2371 load_reg( R_EAX, Rm );
2372 store_spreg( R_EAX, R_VBR );
2373 sh4_x86.tstate = TSTATE_NONE;
2377 load_reg( R_EAX, Rm );
2378 store_spreg( R_EAX, R_SSR );
2379 sh4_x86.tstate = TSTATE_NONE;
2383 load_reg( R_EAX, Rm );
2384 store_spreg( R_EAX, R_SGR );
2385 sh4_x86.tstate = TSTATE_NONE;
2389 load_reg( R_EAX, Rm );
2390 store_spreg( R_EAX, R_SPC );
2391 sh4_x86.tstate = TSTATE_NONE;
2395 load_reg( R_EAX, Rm );
2396 store_spreg( R_EAX, R_DBR );
2397 sh4_x86.tstate = TSTATE_NONE;
2401 load_reg( R_EAX, Rm );
2402 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2403 sh4_x86.tstate = TSTATE_NONE;
2406 load_reg( R_EAX, Rm );
2407 check_ralign32( R_EAX );
2408 MMU_TRANSLATE_READ( R_EAX );
2409 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2410 MEM_READ_LONG( R_EAX, R_EAX );
2411 store_spreg( R_EAX, R_GBR );
2412 sh4_x86.tstate = TSTATE_NONE;
2415 if( sh4_x86.in_delay_slot ) {
2419 load_reg( R_EAX, Rm );
2420 check_ralign32( R_EAX );
2421 MMU_TRANSLATE_READ( R_EAX );
2422 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2423 MEM_READ_LONG( R_EAX, R_EAX );
2424 call_func1( sh4_write_sr, R_EAX );
2425 sh4_x86.priv_checked = FALSE;
2426 sh4_x86.fpuen_checked = FALSE;
2427 sh4_x86.tstate = TSTATE_NONE;
2432 load_reg( R_EAX, Rm );
2433 check_ralign32( R_EAX );
2434 MMU_TRANSLATE_READ( R_EAX );
2435 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2436 MEM_READ_LONG( R_EAX, R_EAX );
2437 store_spreg( R_EAX, R_VBR );
2438 sh4_x86.tstate = TSTATE_NONE;
2442 load_reg( R_EAX, Rm );
2443 check_ralign32( R_EAX );
2444 MMU_TRANSLATE_READ( R_EAX );
2445 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2446 MEM_READ_LONG( R_EAX, R_EAX );
2447 store_spreg( R_EAX, R_SSR );
2448 sh4_x86.tstate = TSTATE_NONE;
2452 load_reg( R_EAX, Rm );
2453 check_ralign32( R_EAX );
2454 MMU_TRANSLATE_READ( R_EAX );
2455 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2456 MEM_READ_LONG( R_EAX, R_EAX );
2457 store_spreg( R_EAX, R_SGR );
2458 sh4_x86.tstate = TSTATE_NONE;
2462 load_reg( R_EAX, Rm );
2463 check_ralign32( R_EAX );
2464 MMU_TRANSLATE_READ( R_EAX );
2465 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2466 MEM_READ_LONG( R_EAX, R_EAX );
2467 store_spreg( R_EAX, R_SPC );
2468 sh4_x86.tstate = TSTATE_NONE;
2472 load_reg( R_EAX, Rm );
2473 check_ralign32( R_EAX );
2474 MMU_TRANSLATE_READ( R_EAX );
2475 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2476 MEM_READ_LONG( R_EAX, R_EAX );
2477 store_spreg( R_EAX, R_DBR );
2478 sh4_x86.tstate = TSTATE_NONE;
2480 LDC.L @Rm+, Rn_BANK {:
2482 load_reg( R_EAX, Rm );
2483 check_ralign32( R_EAX );
2484 MMU_TRANSLATE_READ( R_EAX );
2485 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2486 MEM_READ_LONG( R_EAX, R_EAX );
2487 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2488 sh4_x86.tstate = TSTATE_NONE;
2491 load_reg( R_EAX, Rm );
2492 store_spreg( R_EAX, R_FPSCR );
2493 update_fr_bank( R_EAX );
2494 sh4_x86.tstate = TSTATE_NONE;
2496 LDS.L @Rm+, FPSCR {:
2497 load_reg( R_EAX, Rm );
2498 check_ralign32( R_EAX );
2499 MMU_TRANSLATE_READ( R_EAX );
2500 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2501 MEM_READ_LONG( R_EAX, R_EAX );
2502 store_spreg( R_EAX, R_FPSCR );
2503 update_fr_bank( R_EAX );
2504 sh4_x86.tstate = TSTATE_NONE;
2507 load_reg( R_EAX, Rm );
2508 store_spreg( R_EAX, R_FPUL );
2511 load_reg( R_EAX, Rm );
2512 check_ralign32( R_EAX );
2513 MMU_TRANSLATE_READ( R_EAX );
2514 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2515 MEM_READ_LONG( R_EAX, R_EAX );
2516 store_spreg( R_EAX, R_FPUL );
2517 sh4_x86.tstate = TSTATE_NONE;
2520 load_reg( R_EAX, Rm );
2521 store_spreg( R_EAX, R_MACH );
2524 load_reg( R_EAX, Rm );
2525 check_ralign32( R_EAX );
2526 MMU_TRANSLATE_READ( R_EAX );
2527 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2528 MEM_READ_LONG( R_EAX, R_EAX );
2529 store_spreg( R_EAX, R_MACH );
2530 sh4_x86.tstate = TSTATE_NONE;
2533 load_reg( R_EAX, Rm );
2534 store_spreg( R_EAX, R_MACL );
2537 load_reg( R_EAX, Rm );
2538 check_ralign32( R_EAX );
2539 MMU_TRANSLATE_READ( R_EAX );
2540 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2541 MEM_READ_LONG( R_EAX, R_EAX );
2542 store_spreg( R_EAX, R_MACL );
2543 sh4_x86.tstate = TSTATE_NONE;
2546 load_reg( R_EAX, Rm );
2547 store_spreg( R_EAX, R_PR );
2550 load_reg( R_EAX, Rm );
2551 check_ralign32( R_EAX );
2552 MMU_TRANSLATE_READ( R_EAX );
2553 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2554 MEM_READ_LONG( R_EAX, R_EAX );
2555 store_spreg( R_EAX, R_PR );
2556 sh4_x86.tstate = TSTATE_NONE;
2559 call_func0( MMU_ldtlb );
2565 load_reg( R_EAX, Rn );
2566 MOV_r32_r32( R_EAX, R_ECX );
2567 AND_imm32_r32( 0xFC000000, R_EAX );
2568 CMP_imm32_r32( 0xE0000000, R_EAX );
2569 JNE_rel8(8+CALL_FUNC1_SIZE, end);
2570 call_func1( sh4_flush_store_queue, R_ECX );
2571 TEST_r32_r32( R_EAX, R_EAX );
2574 sh4_x86.tstate = TSTATE_NONE;
2578 call_func0( sh4_sleep );
2579 sh4_x86.tstate = TSTATE_NONE;
2580 sh4_x86.in_delay_slot = DELAY_NONE;
2585 call_func0(sh4_read_sr);
2586 store_reg( R_EAX, Rn );
2587 sh4_x86.tstate = TSTATE_NONE;
2590 load_spreg( R_EAX, R_GBR );
2591 store_reg( R_EAX, Rn );
2595 load_spreg( R_EAX, R_VBR );
2596 store_reg( R_EAX, Rn );
2597 sh4_x86.tstate = TSTATE_NONE;
2601 load_spreg( R_EAX, R_SSR );
2602 store_reg( R_EAX, Rn );
2603 sh4_x86.tstate = TSTATE_NONE;
2607 load_spreg( R_EAX, R_SPC );
2608 store_reg( R_EAX, Rn );
2609 sh4_x86.tstate = TSTATE_NONE;
2613 load_spreg( R_EAX, R_SGR );
2614 store_reg( R_EAX, Rn );
2615 sh4_x86.tstate = TSTATE_NONE;
2619 load_spreg( R_EAX, R_DBR );
2620 store_reg( R_EAX, Rn );
2621 sh4_x86.tstate = TSTATE_NONE;
2625 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
2626 store_reg( R_EAX, Rn );
2627 sh4_x86.tstate = TSTATE_NONE;
2631 load_reg( R_EAX, Rn );
2632 check_walign32( R_EAX );
2633 ADD_imm8s_r32( -4, R_EAX );
2634 MMU_TRANSLATE_WRITE( R_EAX );
2635 PUSH_realigned_r32( R_EAX );
2636 call_func0( sh4_read_sr );
2637 POP_realigned_r32( R_ECX );
2638 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2639 MEM_WRITE_LONG( R_ECX, R_EAX );
2640 sh4_x86.tstate = TSTATE_NONE;
2644 load_reg( R_EAX, Rn );
2645 check_walign32( R_EAX );
2646 ADD_imm8s_r32( -4, R_EAX );
2647 MMU_TRANSLATE_WRITE( R_EAX );
2648 load_spreg( R_EDX, R_VBR );
2649 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2650 MEM_WRITE_LONG( R_EAX, R_EDX );
2651 sh4_x86.tstate = TSTATE_NONE;
2655 load_reg( R_EAX, Rn );
2656 check_walign32( R_EAX );
2657 ADD_imm8s_r32( -4, R_EAX );
2658 MMU_TRANSLATE_WRITE( R_EAX );
2659 load_spreg( R_EDX, R_SSR );
2660 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2661 MEM_WRITE_LONG( R_EAX, R_EDX );
2662 sh4_x86.tstate = TSTATE_NONE;
2666 load_reg( R_EAX, Rn );
2667 check_walign32( R_EAX );
2668 ADD_imm8s_r32( -4, R_EAX );
2669 MMU_TRANSLATE_WRITE( R_EAX );
2670 load_spreg( R_EDX, R_SPC );
2671 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2672 MEM_WRITE_LONG( R_EAX, R_EDX );
2673 sh4_x86.tstate = TSTATE_NONE;
2677 load_reg( R_EAX, Rn );
2678 check_walign32( R_EAX );
2679 ADD_imm8s_r32( -4, R_EAX );
2680 MMU_TRANSLATE_WRITE( R_EAX );
2681 load_spreg( R_EDX, R_SGR );
2682 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2683 MEM_WRITE_LONG( R_EAX, R_EDX );
2684 sh4_x86.tstate = TSTATE_NONE;
2688 load_reg( R_EAX, Rn );
2689 check_walign32( R_EAX );
2690 ADD_imm8s_r32( -4, R_EAX );
2691 MMU_TRANSLATE_WRITE( R_EAX );
2692 load_spreg( R_EDX, R_DBR );
2693 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2694 MEM_WRITE_LONG( R_EAX, R_EDX );
2695 sh4_x86.tstate = TSTATE_NONE;
2697 STC.L Rm_BANK, @-Rn {:
2699 load_reg( R_EAX, Rn );
2700 check_walign32( R_EAX );
2701 ADD_imm8s_r32( -4, R_EAX );
2702 MMU_TRANSLATE_WRITE( R_EAX );
2703 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
2704 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2705 MEM_WRITE_LONG( R_EAX, R_EDX );
2706 sh4_x86.tstate = TSTATE_NONE;
2709 load_reg( R_EAX, Rn );
2710 check_walign32( R_EAX );
2711 ADD_imm8s_r32( -4, R_EAX );
2712 MMU_TRANSLATE_WRITE( R_EAX );
2713 load_spreg( R_EDX, R_GBR );
2714 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2715 MEM_WRITE_LONG( R_EAX, R_EDX );
2716 sh4_x86.tstate = TSTATE_NONE;
2719 load_spreg( R_EAX, R_FPSCR );
2720 store_reg( R_EAX, Rn );
2722 STS.L FPSCR, @-Rn {:
2723 load_reg( R_EAX, Rn );
2724 check_walign32( R_EAX );
2725 ADD_imm8s_r32( -4, R_EAX );
2726 MMU_TRANSLATE_WRITE( R_EAX );
2727 load_spreg( R_EDX, R_FPSCR );
2728 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2729 MEM_WRITE_LONG( R_EAX, R_EDX );
2730 sh4_x86.tstate = TSTATE_NONE;
2733 load_spreg( R_EAX, R_FPUL );
2734 store_reg( R_EAX, Rn );
2737 load_reg( R_EAX, Rn );
2738 check_walign32( R_EAX );
2739 ADD_imm8s_r32( -4, R_EAX );
2740 MMU_TRANSLATE_WRITE( R_EAX );
2741 load_spreg( R_EDX, R_FPUL );
2742 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2743 MEM_WRITE_LONG( R_EAX, R_EDX );
2744 sh4_x86.tstate = TSTATE_NONE;
2747 load_spreg( R_EAX, R_MACH );
2748 store_reg( R_EAX, Rn );
2751 load_reg( R_EAX, Rn );
2752 check_walign32( R_EAX );
2753 ADD_imm8s_r32( -4, R_EAX );
2754 MMU_TRANSLATE_WRITE( R_EAX );
2755 load_spreg( R_EDX, R_MACH );
2756 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2757 MEM_WRITE_LONG( R_EAX, R_EDX );
2758 sh4_x86.tstate = TSTATE_NONE;
2761 load_spreg( R_EAX, R_MACL );
2762 store_reg( R_EAX, Rn );
2765 load_reg( R_EAX, Rn );
2766 check_walign32( R_EAX );
2767 ADD_imm8s_r32( -4, R_EAX );
2768 MMU_TRANSLATE_WRITE( R_EAX );
2769 load_spreg( R_EDX, R_MACL );
2770 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2771 MEM_WRITE_LONG( R_EAX, R_EDX );
2772 sh4_x86.tstate = TSTATE_NONE;
2775 load_spreg( R_EAX, R_PR );
2776 store_reg( R_EAX, Rn );
2779 load_reg( R_EAX, Rn );
2780 check_walign32( R_EAX );
2781 ADD_imm8s_r32( -4, R_EAX );
2782 MMU_TRANSLATE_WRITE( R_EAX );
2783 load_spreg( R_EDX, R_PR );
2784 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2785 MEM_WRITE_LONG( R_EAX, R_EDX );
2786 sh4_x86.tstate = TSTATE_NONE;
2789 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
2791 sh4_x86.in_delay_slot = DELAY_NONE;
.