4 * SH4 => x86 translation. This version does no real optimization, it just
5 * outputs straight-line x86 code - it mainly exists to provide a baseline
6 * to test the optimizing versions against.
8 * Copyright (c) 2007 Nathan Keynes.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
28 #include "sh4/xltcache.h"
29 #include "sh4/sh4core.h"
30 #include "sh4/sh4trans.h"
31 #include "sh4/sh4mmio.h"
32 #include "sh4/x86op.h"
35 #define DEFAULT_BACKPATCH_SIZE 4096
37 struct backpatch_record {
39 uint32_t fixup_icount;
43 #define MAX_RECOVERY_SIZE 2048
50 * Struct to manage internal translation state. This state is not saved -
51 * it is only valid between calls to sh4_translate_begin_block() and
52 * sh4_translate_end_block()
54 struct sh4_x86_state {
56 gboolean priv_checked; /* true if we've already checked the cpu mode. */
57 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
58 gboolean branch_taken; /* true if we branched unconditionally */
59 uint32_t block_start_pc;
60 uint32_t stack_posn; /* Trace stack height for alignment purposes */
64 gboolean tlb_on; /* True if tlb translation is active */
66 /* Allocated memory for the (block-wide) back-patch list */
67 struct backpatch_record *backpatch_list;
68 uint32_t backpatch_posn;
69 uint32_t backpatch_size;
70 struct xlat_recovery_record recovery_list[MAX_RECOVERY_SIZE];
71 uint32_t recovery_posn;
74 #define TSTATE_NONE -1
84 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
85 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
86 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
87 OP(0x70+sh4_x86.tstate); OP(rel8); \
89 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
90 #define JF_rel8(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^1)); OP(rel8); \
95 static struct sh4_x86_state sh4_x86;
97 static uint32_t max_int = 0x7FFFFFFF;
98 static uint32_t min_int = 0x80000000;
99 static uint32_t save_fcw; /* save value for fpu control word */
100 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
104 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
105 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
109 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
111 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
112 sh4_x86.backpatch_size <<= 1;
113 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list,
114 sh4_x86.backpatch_size * sizeof(struct backpatch_record));
115 assert( sh4_x86.backpatch_list != NULL );
117 if( sh4_x86.in_delay_slot ) {
120 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_addr = (uint32_t *)fixup_addr;
121 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
122 sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
123 sh4_x86.backpatch_posn++;
126 void sh4_x86_add_recovery( uint32_t pc )
128 xlat_recovery[xlat_recovery_posn].xlat_pc = (uintptr_t)xlat_output;
129 xlat_recovery[xlat_recovery_posn].sh4_icount = (pc - sh4_x86.block_start_pc)>>1;
130 xlat_recovery_posn++;
134 * Emit an instruction to load an SH4 reg into a real register
136 static inline void load_reg( int x86reg, int sh4reg )
138 /* mov [bp+n], reg */
140 OP(0x45 + (x86reg<<3));
141 OP(REG_OFFSET(r[sh4reg]));
144 static inline void load_reg16s( int x86reg, int sh4reg )
148 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
151 static inline void load_reg16u( int x86reg, int sh4reg )
155 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
159 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
160 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
162 * Emit an instruction to load an immediate value into a register
164 static inline void load_imm32( int x86reg, uint32_t value ) {
165 /* mov #value, reg */
171 * Load an immediate 64-bit quantity (note: x86-64 only)
173 static inline void load_imm64( int x86reg, uint32_t value ) {
174 /* mov #value, reg */
182 * Emit an instruction to store an SH4 reg (RN)
184 void static inline store_reg( int x86reg, int sh4reg ) {
185 /* mov reg, [bp+n] */
187 OP(0x45 + (x86reg<<3));
188 OP(REG_OFFSET(r[sh4reg]));
191 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
194 * Load an FR register (single-precision floating point) into an integer x86
195 * register (eg for register-to-register moves)
197 void static inline load_fr( int bankreg, int x86reg, int frm )
199 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
203 * Store an FR register (single-precision floating point) into an integer x86
204 * register (eg for register-to-register moves)
206 void static inline store_fr( int bankreg, int x86reg, int frn )
208 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
213 * Load a pointer to the back fp back into the specified x86 register. The
214 * bankreg must have been previously loaded with FPSCR.
217 static inline void load_xf_bank( int bankreg )
220 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
221 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
222 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
226 * Update the fr_bank pointer based on the current fpscr value.
228 static inline void update_fr_bank( int fpscrreg )
230 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
231 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
232 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
233 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
236 * Push FPUL (as a 32-bit float) onto the FPU stack
238 static inline void push_fpul( )
240 OP(0xD9); OP(0x45); OP(R_FPUL);
244 * Pop FPUL (as a 32-bit float) from the FPU stack
246 static inline void pop_fpul( )
248 OP(0xD9); OP(0x5D); OP(R_FPUL);
252 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
253 * with the location of the current fp bank.
255 static inline void push_fr( int bankreg, int frm )
257 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
261 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
262 * with bankreg previously loaded with the location of the current fp bank.
264 static inline void pop_fr( int bankreg, int frm )
266 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
270 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
271 * with the location of the current fp bank.
273 static inline void push_dr( int bankreg, int frm )
275 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
278 static inline void pop_dr( int bankreg, int frm )
280 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
283 /* Exception checks - Note that all exception checks will clobber EAX */
285 #define check_priv( ) \
286 if( !sh4_x86.priv_checked ) { \
287 sh4_x86.priv_checked = TRUE;\
288 load_spreg( R_EAX, R_SR );\
289 AND_imm32_r32( SR_MD, R_EAX );\
290 if( sh4_x86.in_delay_slot ) {\
291 JE_exc( EXC_SLOT_ILLEGAL );\
293 JE_exc( EXC_ILLEGAL );\
297 #define check_fpuen( ) \
298 if( !sh4_x86.fpuen_checked ) {\
299 sh4_x86.fpuen_checked = TRUE;\
300 load_spreg( R_EAX, R_SR );\
301 AND_imm32_r32( SR_FD, R_EAX );\
302 if( sh4_x86.in_delay_slot ) {\
303 JNE_exc(EXC_SLOT_FPU_DISABLED);\
305 JNE_exc(EXC_FPU_DISABLED);\
309 #define check_ralign16( x86reg ) \
310 TEST_imm32_r32( 0x00000001, x86reg ); \
311 JNE_exc(EXC_DATA_ADDR_READ)
313 #define check_walign16( x86reg ) \
314 TEST_imm32_r32( 0x00000001, x86reg ); \
315 JNE_exc(EXC_DATA_ADDR_WRITE);
317 #define check_ralign32( x86reg ) \
318 TEST_imm32_r32( 0x00000003, x86reg ); \
319 JNE_exc(EXC_DATA_ADDR_READ)
321 #define check_walign32( x86reg ) \
322 TEST_imm32_r32( 0x00000003, x86reg ); \
323 JNE_exc(EXC_DATA_ADDR_WRITE);
326 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
327 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
328 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
329 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
330 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
331 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
332 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
335 * Perform MMU translation on the address in addr_reg for a read operation, iff the TLB is turned
336 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
338 #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); }
340 * Perform MMU translation on the address in addr_reg for a write operation, iff the TLB is turned
341 * on, otherwise do nothing. Clobbers EAX, ECX and EDX. May raise a TLB exception or address error.
343 #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); }
345 #define MEM_READ_SIZE (CALL_FUNC1_SIZE)
346 #define MEM_WRITE_SIZE (CALL_FUNC2_SIZE)
347 #define MMU_TRANSLATE_SIZE (sh4_x86.tlb_on ? (CALL_FUNC1_SIZE + 12) : 0 )
349 #define SLOTILLEGAL() JMP_exc(EXC_SLOT_ILLEGAL); sh4_x86.in_delay_slot = DELAY_NONE; return 1;
351 /****** Import appropriate calling conventions ******/
352 #if SH4_TRANSLATOR == TARGET_X86_64
353 #include "sh4/ia64abi.h"
354 #else /* SH4_TRANSLATOR == TARGET_X86 */
356 #include "sh4/ia32mac.h"
358 #include "sh4/ia32abi.h"
362 uint32_t sh4_translate_end_block_size()
364 return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*12);
369 * Embed a breakpoint into the generated code
371 void sh4_translate_emit_breakpoint( sh4vma_t pc )
373 load_imm32( R_EAX, pc );
374 call_func1( sh4_translate_breakpoint_hit, R_EAX );
378 * Embed a call to sh4_execute_instruction for situations that we
379 * can't translate (mainly page-crossing delay slots at the moment).
380 * Caller is responsible for setting new_pc.
382 void sh4_emulator_exit( sh4vma_t endpc )
384 load_imm32( R_ECX, endpc - sh4_x86.block_start_pc ); // 5
385 ADD_r32_sh4r( R_ECX, R_PC );
387 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
388 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
389 load_imm32( R_ECX, sh4_x86.in_delay_slot ? 1 : 0 );
390 store_spreg( R_ECX, REG_OFFSET(in_delay_slot) );
392 call_func0( sh4_execute_instruction );
393 load_imm32( R_EAX, R_PC );
394 if( sh4_x86.tlb_on ) {
395 call_func1(xlat_get_code_by_vma,R_EAX);
397 call_func1(xlat_get_code,R_EAX);
399 AND_imm8s_r32( 0xFC, R_EAX ); // 3
405 * Translate a single instruction. Delayed branches are handled specially
406 * by translating both branch and delayed instruction as a single unit (as
408 * The instruction MUST be in the icache (assert check)
410 * @return true if the instruction marks the end of a basic block
413 uint32_t sh4_translate_instruction( sh4vma_t pc )
416 /* Read instruction from icache */
417 assert( IS_IN_ICACHE(pc) );
418 ir = *(uint16_t *)GET_ICACHE_PTR(pc);
420 /* PC is not in the current icache - this usually means we're running
421 * with MMU on, and we've gone past the end of the page. And since
422 * sh4_translate_block is pretty careful about this, it means we're
423 * almost certainly in a delay slot.
425 * Since we can't assume the page is present (and we can't fault it in
426 * at this point, inline a call to sh4_execute_instruction (with a few
427 * small repairs to cope with the different environment).
430 if( !sh4_x86.in_delay_slot ) {
431 sh4_x86_add_recovery(pc);
436 load_reg( R_EAX, Rm );
437 load_reg( R_ECX, Rn );
438 ADD_r32_r32( R_EAX, R_ECX );
439 store_reg( R_ECX, Rn );
440 sh4_x86.tstate = TSTATE_NONE;
443 load_reg( R_EAX, Rn );
444 ADD_imm8s_r32( imm, R_EAX );
445 store_reg( R_EAX, Rn );
446 sh4_x86.tstate = TSTATE_NONE;
449 if( sh4_x86.tstate != TSTATE_C ) {
452 load_reg( R_EAX, Rm );
453 load_reg( R_ECX, Rn );
454 ADC_r32_r32( R_EAX, R_ECX );
455 store_reg( R_ECX, Rn );
457 sh4_x86.tstate = TSTATE_C;
460 load_reg( R_EAX, Rm );
461 load_reg( R_ECX, Rn );
462 ADD_r32_r32( R_EAX, R_ECX );
463 store_reg( R_ECX, Rn );
465 sh4_x86.tstate = TSTATE_O;
468 load_reg( R_EAX, Rm );
469 load_reg( R_ECX, Rn );
470 AND_r32_r32( R_EAX, R_ECX );
471 store_reg( R_ECX, Rn );
472 sh4_x86.tstate = TSTATE_NONE;
475 load_reg( R_EAX, 0 );
476 AND_imm32_r32(imm, R_EAX);
477 store_reg( R_EAX, 0 );
478 sh4_x86.tstate = TSTATE_NONE;
480 AND.B #imm, @(R0, GBR) {:
481 load_reg( R_EAX, 0 );
482 load_spreg( R_ECX, R_GBR );
483 ADD_r32_r32( R_ECX, R_EAX );
484 MMU_TRANSLATE_WRITE( R_EAX );
485 PUSH_realigned_r32(R_EAX);
486 MEM_READ_BYTE( R_EAX, R_EAX );
487 POP_realigned_r32(R_ECX);
488 AND_imm32_r32(imm, R_EAX );
489 MEM_WRITE_BYTE( R_ECX, R_EAX );
490 sh4_x86.tstate = TSTATE_NONE;
493 load_reg( R_EAX, Rm );
494 load_reg( R_ECX, Rn );
495 CMP_r32_r32( R_EAX, R_ECX );
497 sh4_x86.tstate = TSTATE_E;
500 load_reg( R_EAX, 0 );
501 CMP_imm8s_r32(imm, R_EAX);
503 sh4_x86.tstate = TSTATE_E;
506 load_reg( R_EAX, Rm );
507 load_reg( R_ECX, Rn );
508 CMP_r32_r32( R_EAX, R_ECX );
510 sh4_x86.tstate = TSTATE_GE;
513 load_reg( R_EAX, Rm );
514 load_reg( R_ECX, Rn );
515 CMP_r32_r32( R_EAX, R_ECX );
517 sh4_x86.tstate = TSTATE_G;
520 load_reg( R_EAX, Rm );
521 load_reg( R_ECX, Rn );
522 CMP_r32_r32( R_EAX, R_ECX );
524 sh4_x86.tstate = TSTATE_A;
527 load_reg( R_EAX, Rm );
528 load_reg( R_ECX, Rn );
529 CMP_r32_r32( R_EAX, R_ECX );
531 sh4_x86.tstate = TSTATE_AE;
534 load_reg( R_EAX, Rn );
535 CMP_imm8s_r32( 0, R_EAX );
537 sh4_x86.tstate = TSTATE_G;
540 load_reg( R_EAX, Rn );
541 CMP_imm8s_r32( 0, R_EAX );
543 sh4_x86.tstate = TSTATE_GE;
546 load_reg( R_EAX, Rm );
547 load_reg( R_ECX, Rn );
548 XOR_r32_r32( R_ECX, R_EAX );
549 TEST_r8_r8( R_AL, R_AL );
550 JE_rel8(13, target1);
551 TEST_r8_r8( R_AH, R_AH ); // 2
553 SHR_imm8_r32( 16, R_EAX ); // 3
554 TEST_r8_r8( R_AL, R_AL ); // 2
556 TEST_r8_r8( R_AH, R_AH ); // 2
561 sh4_x86.tstate = TSTATE_E;
564 load_reg( R_EAX, Rm );
565 load_reg( R_ECX, Rn );
566 SHR_imm8_r32( 31, R_EAX );
567 SHR_imm8_r32( 31, R_ECX );
568 store_spreg( R_EAX, R_M );
569 store_spreg( R_ECX, R_Q );
570 CMP_r32_r32( R_EAX, R_ECX );
572 sh4_x86.tstate = TSTATE_NE;
575 XOR_r32_r32( R_EAX, R_EAX );
576 store_spreg( R_EAX, R_Q );
577 store_spreg( R_EAX, R_M );
578 store_spreg( R_EAX, R_T );
579 sh4_x86.tstate = TSTATE_C; // works for DIV1
582 load_spreg( R_ECX, R_M );
583 load_reg( R_EAX, Rn );
584 if( sh4_x86.tstate != TSTATE_C ) {
588 SETC_r8( R_DL ); // Q'
589 CMP_sh4r_r32( R_Q, R_ECX );
591 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
594 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
596 store_reg( R_EAX, Rn ); // Done with Rn now
597 SETC_r8(R_AL); // tmp1
598 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
599 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
600 store_spreg( R_ECX, R_Q );
601 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
602 MOVZX_r8_r32( R_AL, R_EAX );
603 store_spreg( R_EAX, R_T );
604 sh4_x86.tstate = TSTATE_NONE;
607 load_reg( R_EAX, Rm );
608 load_reg( R_ECX, Rn );
610 store_spreg( R_EDX, R_MACH );
611 store_spreg( R_EAX, R_MACL );
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, Rn );
624 ADD_imm8s_r32( -1, R_EAX );
625 store_reg( R_EAX, Rn );
627 sh4_x86.tstate = TSTATE_E;
630 load_reg( R_EAX, Rm );
631 MOVSX_r8_r32( R_EAX, R_EAX );
632 store_reg( R_EAX, Rn );
635 load_reg( R_EAX, Rm );
636 MOVSX_r16_r32( R_EAX, R_EAX );
637 store_reg( R_EAX, Rn );
640 load_reg( R_EAX, Rm );
641 MOVZX_r8_r32( R_EAX, R_EAX );
642 store_reg( R_EAX, Rn );
645 load_reg( R_EAX, Rm );
646 MOVZX_r16_r32( R_EAX, R_EAX );
647 store_reg( R_EAX, Rn );
651 load_reg( R_EAX, Rm );
652 check_ralign32( R_EAX );
653 MMU_TRANSLATE_READ( R_EAX );
654 PUSH_realigned_r32( R_EAX );
655 load_reg( R_EAX, Rn );
656 ADD_imm8s_r32( 4, R_EAX );
657 MMU_TRANSLATE_READ( R_EAX );
658 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rn]) );
659 // Note translate twice in case of page boundaries. Maybe worth
660 // adding a page-boundary check to skip the second translation
662 load_reg( R_EAX, Rm );
663 check_ralign32( R_EAX );
664 MMU_TRANSLATE_READ( R_EAX );
665 PUSH_realigned_r32( R_EAX );
666 load_reg( R_EAX, Rn );
667 check_ralign32( R_EAX );
668 MMU_TRANSLATE_READ( R_EAX );
669 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
670 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
672 MEM_READ_LONG( R_EAX, R_EAX );
675 MEM_READ_LONG( R_ECX, R_EAX );
676 POP_realigned_r32( R_ECX );
679 ADD_r32_sh4r( R_EAX, R_MACL );
680 ADC_r32_sh4r( R_EDX, R_MACH );
682 load_spreg( R_ECX, R_S );
683 TEST_r32_r32(R_ECX, R_ECX);
684 JE_rel8( CALL_FUNC0_SIZE, nosat );
685 call_func0( signsat48 );
687 sh4_x86.tstate = TSTATE_NONE;
691 load_reg( R_EAX, Rm );
692 check_ralign16( R_EAX );
693 MMU_TRANSLATE_READ( R_EAX );
694 PUSH_realigned_r32( R_EAX );
695 load_reg( R_EAX, Rn );
696 ADD_imm8s_r32( 2, R_EAX );
697 MMU_TRANSLATE_READ( R_EAX );
698 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
699 // Note translate twice in case of page boundaries. Maybe worth
700 // adding a page-boundary check to skip the second translation
702 load_reg( R_EAX, Rm );
703 check_ralign16( R_EAX );
704 MMU_TRANSLATE_READ( R_EAX );
705 PUSH_realigned_r32( R_EAX );
706 load_reg( R_EAX, Rn );
707 check_ralign16( R_EAX );
708 MMU_TRANSLATE_READ( R_EAX );
709 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
710 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
712 MEM_READ_WORD( R_EAX, R_EAX );
715 MEM_READ_WORD( R_ECX, R_EAX );
716 POP_realigned_r32( R_ECX );
719 load_spreg( R_ECX, R_S );
720 TEST_r32_r32( R_ECX, R_ECX );
721 JE_rel8( 47, nosat );
723 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
724 JNO_rel8( 51, end ); // 2
725 load_imm32( R_EDX, 1 ); // 5
726 store_spreg( R_EDX, R_MACH ); // 6
727 JS_rel8( 13, positive ); // 2
728 load_imm32( R_EAX, 0x80000000 );// 5
729 store_spreg( R_EAX, R_MACL ); // 6
730 JMP_rel8( 25, end2 ); // 2
732 JMP_TARGET(positive);
733 load_imm32( R_EAX, 0x7FFFFFFF );// 5
734 store_spreg( R_EAX, R_MACL ); // 6
735 JMP_rel8( 12, end3); // 2
738 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
739 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
743 sh4_x86.tstate = TSTATE_NONE;
746 load_spreg( R_EAX, R_T );
747 store_reg( R_EAX, Rn );
750 load_reg( R_EAX, Rm );
751 load_reg( R_ECX, Rn );
753 store_spreg( R_EAX, R_MACL );
754 sh4_x86.tstate = TSTATE_NONE;
757 load_reg16s( R_EAX, Rm );
758 load_reg16s( R_ECX, Rn );
760 store_spreg( R_EAX, R_MACL );
761 sh4_x86.tstate = TSTATE_NONE;
764 load_reg16u( R_EAX, Rm );
765 load_reg16u( R_ECX, Rn );
767 store_spreg( R_EAX, R_MACL );
768 sh4_x86.tstate = TSTATE_NONE;
771 load_reg( R_EAX, Rm );
773 store_reg( R_EAX, Rn );
774 sh4_x86.tstate = TSTATE_NONE;
777 load_reg( R_EAX, Rm );
778 XOR_r32_r32( R_ECX, R_ECX );
780 SBB_r32_r32( R_EAX, R_ECX );
781 store_reg( R_ECX, Rn );
783 sh4_x86.tstate = TSTATE_C;
786 load_reg( R_EAX, Rm );
788 store_reg( R_EAX, Rn );
789 sh4_x86.tstate = TSTATE_NONE;
792 load_reg( R_EAX, Rm );
793 load_reg( R_ECX, Rn );
794 OR_r32_r32( R_EAX, R_ECX );
795 store_reg( R_ECX, Rn );
796 sh4_x86.tstate = TSTATE_NONE;
799 load_reg( R_EAX, 0 );
800 OR_imm32_r32(imm, R_EAX);
801 store_reg( R_EAX, 0 );
802 sh4_x86.tstate = TSTATE_NONE;
804 OR.B #imm, @(R0, GBR) {:
805 load_reg( R_EAX, 0 );
806 load_spreg( R_ECX, R_GBR );
807 ADD_r32_r32( R_ECX, R_EAX );
808 MMU_TRANSLATE_WRITE( R_EAX );
809 PUSH_realigned_r32(R_EAX);
810 MEM_READ_BYTE( R_EAX, R_EAX );
811 POP_realigned_r32(R_ECX);
812 OR_imm32_r32(imm, R_EAX );
813 MEM_WRITE_BYTE( R_ECX, R_EAX );
814 sh4_x86.tstate = TSTATE_NONE;
817 load_reg( R_EAX, Rn );
818 if( sh4_x86.tstate != TSTATE_C ) {
822 store_reg( R_EAX, Rn );
824 sh4_x86.tstate = TSTATE_C;
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 );
839 store_reg( R_EAX, Rn );
841 sh4_x86.tstate = TSTATE_C;
844 load_reg( R_EAX, Rn );
846 store_reg( R_EAX, Rn );
848 sh4_x86.tstate = TSTATE_C;
851 /* Annoyingly enough, not directly convertible */
852 load_reg( R_EAX, Rn );
853 load_reg( R_ECX, Rm );
854 CMP_imm32_r32( 0, R_ECX );
857 NEG_r32( R_ECX ); // 2
858 AND_imm8_r8( 0x1F, R_CL ); // 3
859 JE_rel8( 4, emptysar); // 2
860 SAR_r32_CL( R_EAX ); // 2
861 JMP_rel8(10, end); // 2
863 JMP_TARGET(emptysar);
864 SAR_imm8_r32(31, R_EAX ); // 3
868 AND_imm8_r8( 0x1F, R_CL ); // 3
869 SHL_r32_CL( R_EAX ); // 2
872 store_reg( R_EAX, Rn );
873 sh4_x86.tstate = TSTATE_NONE;
876 load_reg( R_EAX, Rn );
877 load_reg( R_ECX, Rm );
878 CMP_imm32_r32( 0, R_ECX );
881 NEG_r32( R_ECX ); // 2
882 AND_imm8_r8( 0x1F, R_CL ); // 3
883 JE_rel8( 4, emptyshr );
884 SHR_r32_CL( R_EAX ); // 2
885 JMP_rel8(9, end); // 2
887 JMP_TARGET(emptyshr);
888 XOR_r32_r32( R_EAX, R_EAX );
892 AND_imm8_r8( 0x1F, R_CL ); // 3
893 SHL_r32_CL( R_EAX ); // 2
896 store_reg( R_EAX, Rn );
897 sh4_x86.tstate = TSTATE_NONE;
900 load_reg( R_EAX, Rn );
903 store_reg( R_EAX, Rn );
904 sh4_x86.tstate = TSTATE_C;
907 load_reg( R_EAX, Rn );
910 store_reg( R_EAX, Rn );
911 sh4_x86.tstate = TSTATE_C;
914 load_reg( R_EAX, Rn );
917 store_reg( R_EAX, Rn );
918 sh4_x86.tstate = TSTATE_C;
921 load_reg( R_EAX, Rn );
922 SHL_imm8_r32( 2, R_EAX );
923 store_reg( R_EAX, Rn );
924 sh4_x86.tstate = TSTATE_NONE;
927 load_reg( R_EAX, Rn );
928 SHL_imm8_r32( 8, R_EAX );
929 store_reg( R_EAX, Rn );
930 sh4_x86.tstate = TSTATE_NONE;
933 load_reg( R_EAX, Rn );
934 SHL_imm8_r32( 16, R_EAX );
935 store_reg( R_EAX, Rn );
936 sh4_x86.tstate = TSTATE_NONE;
939 load_reg( R_EAX, Rn );
942 store_reg( R_EAX, Rn );
943 sh4_x86.tstate = TSTATE_C;
946 load_reg( R_EAX, Rn );
947 SHR_imm8_r32( 2, R_EAX );
948 store_reg( R_EAX, Rn );
949 sh4_x86.tstate = TSTATE_NONE;
952 load_reg( R_EAX, Rn );
953 SHR_imm8_r32( 8, R_EAX );
954 store_reg( R_EAX, Rn );
955 sh4_x86.tstate = TSTATE_NONE;
958 load_reg( R_EAX, Rn );
959 SHR_imm8_r32( 16, R_EAX );
960 store_reg( R_EAX, Rn );
961 sh4_x86.tstate = TSTATE_NONE;
964 load_reg( R_EAX, Rm );
965 load_reg( R_ECX, Rn );
966 SUB_r32_r32( R_EAX, R_ECX );
967 store_reg( R_ECX, Rn );
968 sh4_x86.tstate = TSTATE_NONE;
971 load_reg( R_EAX, Rm );
972 load_reg( R_ECX, Rn );
973 if( sh4_x86.tstate != TSTATE_C ) {
976 SBB_r32_r32( R_EAX, R_ECX );
977 store_reg( R_ECX, Rn );
979 sh4_x86.tstate = TSTATE_C;
982 load_reg( R_EAX, Rm );
983 load_reg( R_ECX, Rn );
984 SUB_r32_r32( R_EAX, R_ECX );
985 store_reg( R_ECX, Rn );
987 sh4_x86.tstate = TSTATE_O;
990 load_reg( R_EAX, Rm );
991 XCHG_r8_r8( R_AL, R_AH );
992 store_reg( R_EAX, Rn );
995 load_reg( R_EAX, Rm );
996 MOV_r32_r32( R_EAX, R_ECX );
997 SHL_imm8_r32( 16, R_ECX );
998 SHR_imm8_r32( 16, R_EAX );
999 OR_r32_r32( R_EAX, R_ECX );
1000 store_reg( R_ECX, Rn );
1001 sh4_x86.tstate = TSTATE_NONE;
1004 load_reg( R_EAX, Rn );
1005 MMU_TRANSLATE_WRITE( R_EAX );
1006 PUSH_realigned_r32( R_EAX );
1007 MEM_READ_BYTE( R_EAX, R_EAX );
1008 TEST_r8_r8( R_AL, R_AL );
1010 OR_imm8_r8( 0x80, R_AL );
1011 POP_realigned_r32( R_ECX );
1012 MEM_WRITE_BYTE( R_ECX, R_EAX );
1013 sh4_x86.tstate = TSTATE_NONE;
1016 load_reg( R_EAX, Rm );
1017 load_reg( R_ECX, Rn );
1018 TEST_r32_r32( R_EAX, R_ECX );
1020 sh4_x86.tstate = TSTATE_E;
1023 load_reg( R_EAX, 0 );
1024 TEST_imm32_r32( imm, R_EAX );
1026 sh4_x86.tstate = TSTATE_E;
1028 TST.B #imm, @(R0, GBR) {:
1029 load_reg( R_EAX, 0);
1030 load_reg( R_ECX, R_GBR);
1031 ADD_r32_r32( R_ECX, R_EAX );
1032 MMU_TRANSLATE_READ( R_EAX );
1033 MEM_READ_BYTE( R_EAX, R_EAX );
1034 TEST_imm8_r8( imm, R_AL );
1036 sh4_x86.tstate = TSTATE_E;
1039 load_reg( R_EAX, Rm );
1040 load_reg( R_ECX, Rn );
1041 XOR_r32_r32( R_EAX, R_ECX );
1042 store_reg( R_ECX, Rn );
1043 sh4_x86.tstate = TSTATE_NONE;
1046 load_reg( R_EAX, 0 );
1047 XOR_imm32_r32( imm, R_EAX );
1048 store_reg( R_EAX, 0 );
1049 sh4_x86.tstate = TSTATE_NONE;
1051 XOR.B #imm, @(R0, GBR) {:
1052 load_reg( R_EAX, 0 );
1053 load_spreg( R_ECX, R_GBR );
1054 ADD_r32_r32( R_ECX, R_EAX );
1055 MMU_TRANSLATE_WRITE( R_EAX );
1056 PUSH_realigned_r32(R_EAX);
1057 MEM_READ_BYTE(R_EAX, R_EAX);
1058 POP_realigned_r32(R_ECX);
1059 XOR_imm32_r32( imm, R_EAX );
1060 MEM_WRITE_BYTE( R_ECX, R_EAX );
1061 sh4_x86.tstate = TSTATE_NONE;
1064 load_reg( R_EAX, Rm );
1065 load_reg( R_ECX, Rn );
1066 SHL_imm8_r32( 16, R_EAX );
1067 SHR_imm8_r32( 16, R_ECX );
1068 OR_r32_r32( R_EAX, R_ECX );
1069 store_reg( R_ECX, Rn );
1070 sh4_x86.tstate = TSTATE_NONE;
1073 /* Data move instructions */
1075 load_reg( R_EAX, Rm );
1076 store_reg( R_EAX, Rn );
1079 load_imm32( R_EAX, imm );
1080 store_reg( R_EAX, Rn );
1083 load_reg( R_EAX, Rn );
1084 MMU_TRANSLATE_WRITE( R_EAX );
1085 load_reg( R_EDX, Rm );
1086 MEM_WRITE_BYTE( R_EAX, R_EDX );
1087 sh4_x86.tstate = TSTATE_NONE;
1090 load_reg( R_EAX, Rn );
1091 ADD_imm8s_r32( -1, R_EAX );
1092 MMU_TRANSLATE_WRITE( R_EAX );
1093 load_reg( R_EDX, Rm );
1094 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );
1095 MEM_WRITE_BYTE( R_EAX, R_EDX );
1096 sh4_x86.tstate = TSTATE_NONE;
1098 MOV.B Rm, @(R0, Rn) {:
1099 load_reg( R_EAX, 0 );
1100 load_reg( R_ECX, Rn );
1101 ADD_r32_r32( R_ECX, R_EAX );
1102 MMU_TRANSLATE_WRITE( R_EAX );
1103 load_reg( R_EDX, Rm );
1104 MEM_WRITE_BYTE( R_EAX, R_EDX );
1105 sh4_x86.tstate = TSTATE_NONE;
1107 MOV.B R0, @(disp, GBR) {:
1108 load_spreg( R_EAX, R_GBR );
1109 ADD_imm32_r32( disp, R_EAX );
1110 MMU_TRANSLATE_WRITE( R_EAX );
1111 load_reg( R_EDX, 0 );
1112 MEM_WRITE_BYTE( R_EAX, R_EDX );
1113 sh4_x86.tstate = TSTATE_NONE;
1115 MOV.B R0, @(disp, Rn) {:
1116 load_reg( R_EAX, Rn );
1117 ADD_imm32_r32( disp, R_EAX );
1118 MMU_TRANSLATE_WRITE( R_EAX );
1119 load_reg( R_EDX, 0 );
1120 MEM_WRITE_BYTE( R_EAX, R_EDX );
1121 sh4_x86.tstate = TSTATE_NONE;
1124 load_reg( R_EAX, Rm );
1125 MMU_TRANSLATE_READ( R_EAX );
1126 MEM_READ_BYTE( R_EAX, R_EAX );
1127 store_reg( R_EAX, Rn );
1128 sh4_x86.tstate = TSTATE_NONE;
1131 load_reg( R_EAX, Rm );
1132 MMU_TRANSLATE_READ( R_EAX );
1133 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );
1134 MEM_READ_BYTE( R_EAX, R_EAX );
1135 store_reg( R_EAX, Rn );
1136 sh4_x86.tstate = TSTATE_NONE;
1138 MOV.B @(R0, Rm), Rn {:
1139 load_reg( R_EAX, 0 );
1140 load_reg( R_ECX, Rm );
1141 ADD_r32_r32( R_ECX, R_EAX );
1142 MMU_TRANSLATE_READ( R_EAX )
1143 MEM_READ_BYTE( R_EAX, R_EAX );
1144 store_reg( R_EAX, Rn );
1145 sh4_x86.tstate = TSTATE_NONE;
1147 MOV.B @(disp, GBR), R0 {:
1148 load_spreg( R_EAX, R_GBR );
1149 ADD_imm32_r32( disp, R_EAX );
1150 MMU_TRANSLATE_READ( R_EAX );
1151 MEM_READ_BYTE( R_EAX, R_EAX );
1152 store_reg( R_EAX, 0 );
1153 sh4_x86.tstate = TSTATE_NONE;
1155 MOV.B @(disp, Rm), R0 {:
1156 load_reg( R_EAX, Rm );
1157 ADD_imm32_r32( disp, R_EAX );
1158 MMU_TRANSLATE_READ( R_EAX );
1159 MEM_READ_BYTE( R_EAX, R_EAX );
1160 store_reg( R_EAX, 0 );
1161 sh4_x86.tstate = TSTATE_NONE;
1164 load_reg( R_EAX, Rn );
1165 check_walign32(R_EAX);
1166 MMU_TRANSLATE_WRITE( R_EAX );
1167 load_reg( R_EDX, Rm );
1168 MEM_WRITE_LONG( R_EAX, R_EDX );
1169 sh4_x86.tstate = TSTATE_NONE;
1172 load_reg( R_EAX, Rn );
1173 ADD_imm8s_r32( -4, R_EAX );
1174 check_walign32( R_EAX );
1175 MMU_TRANSLATE_WRITE( R_EAX );
1176 load_reg( R_EDX, Rm );
1177 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
1178 MEM_WRITE_LONG( R_EAX, R_EDX );
1179 sh4_x86.tstate = TSTATE_NONE;
1181 MOV.L Rm, @(R0, Rn) {:
1182 load_reg( R_EAX, 0 );
1183 load_reg( R_ECX, Rn );
1184 ADD_r32_r32( R_ECX, R_EAX );
1185 check_walign32( R_EAX );
1186 MMU_TRANSLATE_WRITE( R_EAX );
1187 load_reg( R_EDX, Rm );
1188 MEM_WRITE_LONG( R_EAX, R_EDX );
1189 sh4_x86.tstate = TSTATE_NONE;
1191 MOV.L R0, @(disp, GBR) {:
1192 load_spreg( R_EAX, R_GBR );
1193 ADD_imm32_r32( disp, R_EAX );
1194 check_walign32( R_EAX );
1195 MMU_TRANSLATE_WRITE( R_EAX );
1196 load_reg( R_EDX, 0 );
1197 MEM_WRITE_LONG( R_EAX, R_EDX );
1198 sh4_x86.tstate = TSTATE_NONE;
1200 MOV.L Rm, @(disp, Rn) {:
1201 load_reg( R_EAX, Rn );
1202 ADD_imm32_r32( disp, R_EAX );
1203 check_walign32( R_EAX );
1204 MMU_TRANSLATE_WRITE( R_EAX );
1205 load_reg( R_EDX, Rm );
1206 MEM_WRITE_LONG( R_EAX, R_EDX );
1207 sh4_x86.tstate = TSTATE_NONE;
1210 load_reg( R_EAX, Rm );
1211 check_ralign32( R_EAX );
1212 MMU_TRANSLATE_READ( R_EAX );
1213 MEM_READ_LONG( R_EAX, R_EAX );
1214 store_reg( R_EAX, Rn );
1215 sh4_x86.tstate = TSTATE_NONE;
1218 load_reg( R_EAX, Rm );
1219 check_ralign32( R_EAX );
1220 MMU_TRANSLATE_READ( R_EAX );
1221 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1222 MEM_READ_LONG( R_EAX, R_EAX );
1223 store_reg( R_EAX, Rn );
1224 sh4_x86.tstate = TSTATE_NONE;
1226 MOV.L @(R0, Rm), Rn {:
1227 load_reg( R_EAX, 0 );
1228 load_reg( R_ECX, Rm );
1229 ADD_r32_r32( R_ECX, R_EAX );
1230 check_ralign32( R_EAX );
1231 MMU_TRANSLATE_READ( R_EAX );
1232 MEM_READ_LONG( R_EAX, R_EAX );
1233 store_reg( R_EAX, Rn );
1234 sh4_x86.tstate = TSTATE_NONE;
1236 MOV.L @(disp, GBR), R0 {:
1237 load_spreg( R_EAX, R_GBR );
1238 ADD_imm32_r32( disp, R_EAX );
1239 check_ralign32( R_EAX );
1240 MMU_TRANSLATE_READ( R_EAX );
1241 MEM_READ_LONG( R_EAX, R_EAX );
1242 store_reg( R_EAX, 0 );
1243 sh4_x86.tstate = TSTATE_NONE;
1245 MOV.L @(disp, PC), Rn {:
1246 if( sh4_x86.in_delay_slot ) {
1249 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
1250 if( IS_IN_ICACHE(target) ) {
1251 // If the target address is in the same page as the code, it's
1252 // pretty safe to just ref it directly and circumvent the whole
1253 // memory subsystem. (this is a big performance win)
1255 // FIXME: There's a corner-case that's not handled here when
1256 // the current code-page is in the ITLB but not in the UTLB.
1257 // (should generate a TLB miss although need to test SH4
1258 // behaviour to confirm) Unlikely to be anyone depending on this
1259 // behaviour though.
1260 sh4ptr_t ptr = GET_ICACHE_PTR(target);
1261 MOV_moff32_EAX( ptr );
1263 // Note: we use sh4r.pc for the calc as we could be running at a
1264 // different virtual address than the translation was done with,
1265 // but we can safely assume that the low bits are the same.
1266 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1267 ADD_sh4r_r32( R_PC, R_EAX );
1268 MMU_TRANSLATE_READ( R_EAX );
1269 MEM_READ_LONG( R_EAX, R_EAX );
1270 sh4_x86.tstate = TSTATE_NONE;
1272 store_reg( R_EAX, Rn );
1275 MOV.L @(disp, Rm), Rn {:
1276 load_reg( R_EAX, Rm );
1277 ADD_imm8s_r32( disp, R_EAX );
1278 check_ralign32( R_EAX );
1279 MMU_TRANSLATE_READ( R_EAX );
1280 MEM_READ_LONG( R_EAX, R_EAX );
1281 store_reg( R_EAX, Rn );
1282 sh4_x86.tstate = TSTATE_NONE;
1285 load_reg( R_EAX, Rn );
1286 check_walign16( R_EAX );
1287 MMU_TRANSLATE_WRITE( R_EAX )
1288 load_reg( R_EDX, Rm );
1289 MEM_WRITE_WORD( R_EAX, R_EDX );
1290 sh4_x86.tstate = TSTATE_NONE;
1293 load_reg( R_EAX, Rn );
1294 ADD_imm8s_r32( -2, R_EAX );
1295 check_walign16( R_EAX );
1296 MMU_TRANSLATE_WRITE( R_EAX );
1297 load_reg( R_EDX, Rm );
1298 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );
1299 MEM_WRITE_WORD( R_EAX, R_EDX );
1300 sh4_x86.tstate = TSTATE_NONE;
1302 MOV.W Rm, @(R0, Rn) {:
1303 load_reg( R_EAX, 0 );
1304 load_reg( R_ECX, Rn );
1305 ADD_r32_r32( R_ECX, R_EAX );
1306 check_walign16( R_EAX );
1307 MMU_TRANSLATE_WRITE( R_EAX );
1308 load_reg( R_EDX, Rm );
1309 MEM_WRITE_WORD( R_EAX, R_EDX );
1310 sh4_x86.tstate = TSTATE_NONE;
1312 MOV.W R0, @(disp, GBR) {:
1313 load_spreg( R_EAX, R_GBR );
1314 ADD_imm32_r32( disp, R_EAX );
1315 check_walign16( R_EAX );
1316 MMU_TRANSLATE_WRITE( R_EAX );
1317 load_reg( R_EDX, 0 );
1318 MEM_WRITE_WORD( R_EAX, R_EDX );
1319 sh4_x86.tstate = TSTATE_NONE;
1321 MOV.W R0, @(disp, Rn) {:
1322 load_reg( R_EAX, Rn );
1323 ADD_imm32_r32( disp, R_EAX );
1324 check_walign16( R_EAX );
1325 MMU_TRANSLATE_WRITE( R_EAX );
1326 load_reg( R_EDX, 0 );
1327 MEM_WRITE_WORD( R_EAX, R_EDX );
1328 sh4_x86.tstate = TSTATE_NONE;
1331 load_reg( R_EAX, Rm );
1332 check_ralign16( R_EAX );
1333 MMU_TRANSLATE_READ( R_EAX );
1334 MEM_READ_WORD( R_EAX, R_EAX );
1335 store_reg( R_EAX, Rn );
1336 sh4_x86.tstate = TSTATE_NONE;
1339 load_reg( R_EAX, Rm );
1340 check_ralign16( R_EAX );
1341 MMU_TRANSLATE_READ( R_EAX );
1342 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
1343 MEM_READ_WORD( R_EAX, R_EAX );
1344 store_reg( R_EAX, Rn );
1345 sh4_x86.tstate = TSTATE_NONE;
1347 MOV.W @(R0, Rm), Rn {:
1348 load_reg( R_EAX, 0 );
1349 load_reg( R_ECX, Rm );
1350 ADD_r32_r32( R_ECX, R_EAX );
1351 check_ralign16( R_EAX );
1352 MMU_TRANSLATE_READ( R_EAX );
1353 MEM_READ_WORD( R_EAX, R_EAX );
1354 store_reg( R_EAX, Rn );
1355 sh4_x86.tstate = TSTATE_NONE;
1357 MOV.W @(disp, GBR), R0 {:
1358 load_spreg( R_EAX, R_GBR );
1359 ADD_imm32_r32( disp, R_EAX );
1360 check_ralign16( R_EAX );
1361 MMU_TRANSLATE_READ( R_EAX );
1362 MEM_READ_WORD( R_EAX, R_EAX );
1363 store_reg( R_EAX, 0 );
1364 sh4_x86.tstate = TSTATE_NONE;
1366 MOV.W @(disp, PC), Rn {:
1367 if( sh4_x86.in_delay_slot ) {
1370 // See comments for MOV.L @(disp, PC), Rn
1371 uint32_t target = pc + disp + 4;
1372 if( IS_IN_ICACHE(target) ) {
1373 sh4ptr_t ptr = GET_ICACHE_PTR(target);
1374 MOV_moff32_EAX( ptr );
1375 MOVSX_r16_r32( R_EAX, R_EAX );
1377 load_imm32( R_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1378 ADD_sh4r_r32( R_PC, R_EAX );
1379 MMU_TRANSLATE_READ( R_EAX );
1380 MEM_READ_WORD( R_EAX, R_EAX );
1381 sh4_x86.tstate = TSTATE_NONE;
1383 store_reg( R_EAX, Rn );
1386 MOV.W @(disp, Rm), R0 {:
1387 load_reg( R_EAX, Rm );
1388 ADD_imm32_r32( disp, R_EAX );
1389 check_ralign16( R_EAX );
1390 MMU_TRANSLATE_READ( R_EAX );
1391 MEM_READ_WORD( R_EAX, R_EAX );
1392 store_reg( R_EAX, 0 );
1393 sh4_x86.tstate = TSTATE_NONE;
1395 MOVA @(disp, PC), R0 {:
1396 if( sh4_x86.in_delay_slot ) {
1399 load_imm32( R_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1400 ADD_sh4r_r32( R_PC, R_ECX );
1401 store_reg( R_ECX, 0 );
1402 sh4_x86.tstate = TSTATE_NONE;
1406 load_reg( R_EAX, Rn );
1407 check_walign32( R_EAX );
1408 MMU_TRANSLATE_WRITE( R_EAX );
1409 load_reg( R_EDX, 0 );
1410 MEM_WRITE_LONG( R_EAX, R_EDX );
1411 sh4_x86.tstate = TSTATE_NONE;
1414 /* Control transfer instructions */
1416 if( sh4_x86.in_delay_slot ) {
1419 sh4vma_t target = disp + pc + 4;
1420 JT_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1421 exit_block_rel(target, pc+2 );
1422 JMP_TARGET(nottaken);
1427 if( sh4_x86.in_delay_slot ) {
1430 sh4vma_t target = disp + pc + 4;
1431 sh4_x86.in_delay_slot = DELAY_PC;
1432 if( sh4_x86.tstate == TSTATE_NONE ) {
1433 CMP_imm8s_sh4r( 1, R_T );
1434 sh4_x86.tstate = TSTATE_E;
1436 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
1437 sh4_translate_instruction(pc+2);
1438 exit_block_rel( target, pc+4 );
1440 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1441 sh4_translate_instruction(pc+2);
1446 if( sh4_x86.in_delay_slot ) {
1449 sh4_x86.in_delay_slot = DELAY_PC;
1450 sh4_translate_instruction( pc + 2 );
1451 exit_block_rel( disp + pc + 4, pc+4 );
1452 sh4_x86.branch_taken = TRUE;
1457 if( sh4_x86.in_delay_slot ) {
1460 load_spreg( R_EAX, R_PC );
1461 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1462 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
1463 store_spreg( R_EAX, R_NEW_PC );
1464 sh4_x86.in_delay_slot = DELAY_PC;
1465 sh4_x86.tstate = TSTATE_NONE;
1466 sh4_translate_instruction( pc + 2 );
1467 exit_block_newpcset(pc+2);
1468 sh4_x86.branch_taken = TRUE;
1473 if( sh4_x86.in_delay_slot ) {
1476 load_spreg( R_EAX, R_PC );
1477 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1478 store_spreg( R_EAX, R_PR );
1479 sh4_x86.in_delay_slot = DELAY_PC;
1480 sh4_translate_instruction( pc + 2 );
1481 exit_block_rel( disp + pc + 4, pc+4 );
1482 sh4_x86.branch_taken = TRUE;
1487 if( sh4_x86.in_delay_slot ) {
1490 load_spreg( R_EAX, R_PC );
1491 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1492 store_spreg( R_EAX, R_PR );
1493 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_EAX );
1494 store_spreg( R_EAX, R_NEW_PC );
1496 sh4_x86.tstate = TSTATE_NONE;
1497 sh4_translate_instruction( pc + 2 );
1498 exit_block_newpcset(pc+2);
1499 sh4_x86.branch_taken = TRUE;
1504 if( sh4_x86.in_delay_slot ) {
1507 sh4vma_t target = disp + pc + 4;
1508 JF_rel8( EXIT_BLOCK_REL_SIZE(target), nottaken );
1509 exit_block_rel(target, pc+2 );
1510 JMP_TARGET(nottaken);
1515 if( sh4_x86.in_delay_slot ) {
1518 sh4_x86.in_delay_slot = DELAY_PC;
1519 if( sh4_x86.tstate == TSTATE_NONE ) {
1520 CMP_imm8s_sh4r( 1, R_T );
1521 sh4_x86.tstate = TSTATE_E;
1523 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
1524 sh4_translate_instruction(pc+2);
1525 exit_block_rel( disp + pc + 4, pc+4 );
1527 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
1528 sh4_translate_instruction(pc+2);
1533 if( sh4_x86.in_delay_slot ) {
1536 load_reg( R_ECX, Rn );
1537 store_spreg( R_ECX, R_NEW_PC );
1538 sh4_x86.in_delay_slot = DELAY_PC;
1539 sh4_translate_instruction(pc+2);
1540 exit_block_newpcset(pc+2);
1541 sh4_x86.branch_taken = TRUE;
1546 if( sh4_x86.in_delay_slot ) {
1549 load_spreg( R_EAX, R_PC );
1550 ADD_imm32_r32( pc + 4 - sh4_x86.block_start_pc, R_EAX );
1551 store_spreg( R_EAX, R_PR );
1552 load_reg( R_ECX, Rn );
1553 store_spreg( R_ECX, R_NEW_PC );
1554 sh4_translate_instruction(pc+2);
1555 exit_block_newpcset(pc+2);
1556 sh4_x86.branch_taken = TRUE;
1561 if( sh4_x86.in_delay_slot ) {
1565 load_spreg( R_ECX, R_SPC );
1566 store_spreg( R_ECX, R_NEW_PC );
1567 load_spreg( R_EAX, R_SSR );
1568 call_func1( sh4_write_sr, R_EAX );
1569 sh4_x86.in_delay_slot = DELAY_PC;
1570 sh4_x86.priv_checked = FALSE;
1571 sh4_x86.fpuen_checked = FALSE;
1572 sh4_x86.tstate = TSTATE_NONE;
1573 sh4_translate_instruction(pc+2);
1574 exit_block_newpcset(pc+2);
1575 sh4_x86.branch_taken = TRUE;
1580 if( sh4_x86.in_delay_slot ) {
1583 load_spreg( R_ECX, R_PR );
1584 store_spreg( R_ECX, R_NEW_PC );
1585 sh4_x86.in_delay_slot = DELAY_PC;
1586 sh4_translate_instruction(pc+2);
1587 exit_block_newpcset(pc+2);
1588 sh4_x86.branch_taken = TRUE;
1593 if( sh4_x86.in_delay_slot ) {
1596 load_imm32( R_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
1597 ADD_r32_sh4r( R_ECX, R_PC );
1598 load_imm32( R_EAX, imm );
1599 call_func1( sh4_raise_trap, R_EAX );
1600 sh4_x86.tstate = TSTATE_NONE;
1601 exit_block_pcset(pc);
1602 sh4_x86.branch_taken = TRUE;
1607 if( sh4_x86.in_delay_slot ) {
1610 JMP_exc(EXC_ILLEGAL);
1616 XOR_r32_r32(R_EAX, R_EAX);
1617 store_spreg( R_EAX, R_MACL );
1618 store_spreg( R_EAX, R_MACH );
1619 sh4_x86.tstate = TSTATE_NONE;
1624 sh4_x86.tstate = TSTATE_C;
1629 sh4_x86.tstate = TSTATE_C;
1634 sh4_x86.tstate = TSTATE_C;
1639 sh4_x86.tstate = TSTATE_C;
1642 /* Floating point moves */
1644 /* As horrible as this looks, it's actually covering 5 separate cases:
1645 * 1. 32-bit fr-to-fr (PR=0)
1646 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
1647 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
1648 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
1649 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
1652 load_spreg( R_ECX, R_FPSCR );
1653 load_fr_bank( R_EDX );
1654 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1655 JNE_rel8(8, doublesize);
1656 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
1657 store_fr( R_EDX, R_EAX, FRn );
1660 JMP_TARGET(doublesize);
1661 load_xf_bank( R_ECX );
1662 load_fr( R_ECX, R_EAX, FRm-1 );
1664 load_fr( R_ECX, R_EDX, FRm );
1665 store_fr( R_ECX, R_EAX, FRn-1 );
1666 store_fr( R_ECX, R_EDX, FRn );
1667 } else /* FRn&1 == 0 */ {
1668 load_fr( R_ECX, R_ECX, FRm );
1669 store_fr( R_EDX, R_EAX, FRn );
1670 store_fr( R_EDX, R_ECX, FRn+1 );
1673 } else /* FRm&1 == 0 */ {
1676 load_xf_bank( R_ECX );
1677 load_fr( R_EDX, R_EAX, FRm );
1678 load_fr( R_EDX, R_EDX, FRm+1 );
1679 store_fr( R_ECX, R_EAX, FRn-1 );
1680 store_fr( R_ECX, R_EDX, FRn );
1682 } else /* FRn&1 == 0 */ {
1684 load_fr( R_EDX, R_EAX, FRm );
1685 load_fr( R_EDX, R_ECX, FRm+1 );
1686 store_fr( R_EDX, R_EAX, FRn );
1687 store_fr( R_EDX, R_ECX, FRn+1 );
1691 sh4_x86.tstate = TSTATE_NONE;
1695 load_reg( R_EAX, Rn );
1696 check_walign32( R_EAX );
1697 MMU_TRANSLATE_WRITE( R_EAX );
1698 load_spreg( R_EDX, R_FPSCR );
1699 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1700 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1701 load_fr_bank( R_EDX );
1702 load_fr( R_EDX, R_ECX, FRm );
1703 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1705 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1706 JMP_TARGET(doublesize);
1707 load_xf_bank( R_EDX );
1708 load_fr( R_EDX, R_ECX, FRm&0x0E );
1709 load_fr( R_EDX, R_EDX, FRm|0x01 );
1710 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1713 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1714 JMP_TARGET(doublesize);
1715 load_fr_bank( R_EDX );
1716 load_fr( R_EDX, R_ECX, FRm&0x0E );
1717 load_fr( R_EDX, R_EDX, FRm|0x01 );
1718 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1721 sh4_x86.tstate = TSTATE_NONE;
1725 load_reg( R_EAX, Rm );
1726 check_ralign32( R_EAX );
1727 MMU_TRANSLATE_READ( R_EAX );
1728 load_spreg( R_EDX, R_FPSCR );
1729 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1730 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1731 MEM_READ_LONG( R_EAX, R_EAX );
1732 load_fr_bank( R_EDX );
1733 store_fr( R_EDX, R_EAX, FRn );
1735 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1736 JMP_TARGET(doublesize);
1737 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1738 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1739 load_xf_bank( R_EDX );
1740 store_fr( R_EDX, R_ECX, FRn&0x0E );
1741 store_fr( R_EDX, R_EAX, FRn|0x01 );
1744 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1745 JMP_TARGET(doublesize);
1746 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1747 load_fr_bank( R_EDX );
1748 store_fr( R_EDX, R_ECX, FRn&0x0E );
1749 store_fr( R_EDX, R_EAX, FRn|0x01 );
1752 sh4_x86.tstate = TSTATE_NONE;
1756 load_reg( R_EAX, Rn );
1757 check_walign32( R_EAX );
1758 load_spreg( R_EDX, R_FPSCR );
1759 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1760 JNE_rel8(15 + MEM_WRITE_SIZE + MMU_TRANSLATE_SIZE, doublesize);
1761 ADD_imm8s_r32( -4, R_EAX );
1762 MMU_TRANSLATE_WRITE( R_EAX );
1763 load_fr_bank( R_EDX );
1764 load_fr( R_EDX, R_ECX, FRm );
1765 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));
1766 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1768 JMP_rel8( 25 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1769 JMP_TARGET(doublesize);
1770 ADD_imm8s_r32(-8,R_EAX);
1771 MMU_TRANSLATE_WRITE( R_EAX );
1772 load_xf_bank( R_EDX );
1773 load_fr( R_EDX, R_ECX, FRm&0x0E );
1774 load_fr( R_EDX, R_EDX, FRm|0x01 );
1775 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1776 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1779 JMP_rel8( 16 + MEM_WRITE_DOUBLE_SIZE + MMU_TRANSLATE_SIZE, end );
1780 JMP_TARGET(doublesize);
1781 ADD_imm8s_r32(-8,R_EAX);
1782 MMU_TRANSLATE_WRITE( R_EAX );
1783 load_fr_bank( R_EDX );
1784 load_fr( R_EDX, R_ECX, FRm&0x0E );
1785 load_fr( R_EDX, R_EDX, FRm|0x01 );
1786 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));
1787 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1790 sh4_x86.tstate = TSTATE_NONE;
1794 load_reg( R_EAX, Rm );
1795 check_ralign32( R_EAX );
1796 MMU_TRANSLATE_READ( R_EAX );
1797 load_spreg( R_EDX, R_FPSCR );
1798 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1799 JNE_rel8(12 + MEM_READ_SIZE, doublesize);
1800 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1801 MEM_READ_LONG( R_EAX, R_EAX );
1802 load_fr_bank( R_EDX );
1803 store_fr( R_EDX, R_EAX, FRn );
1805 JMP_rel8(25 + MEM_READ_DOUBLE_SIZE, end);
1806 JMP_TARGET(doublesize);
1807 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1808 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1809 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1810 load_xf_bank( R_EDX );
1811 store_fr( R_EDX, R_ECX, FRn&0x0E );
1812 store_fr( R_EDX, R_EAX, FRn|0x01 );
1815 JMP_rel8(13 + MEM_READ_DOUBLE_SIZE, end);
1816 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );
1817 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1818 load_fr_bank( R_EDX );
1819 store_fr( R_EDX, R_ECX, FRn&0x0E );
1820 store_fr( R_EDX, R_EAX, FRn|0x01 );
1823 sh4_x86.tstate = TSTATE_NONE;
1825 FMOV FRm, @(R0, Rn) {:
1827 load_reg( R_EAX, Rn );
1828 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1829 check_walign32( R_EAX );
1830 MMU_TRANSLATE_WRITE( R_EAX );
1831 load_spreg( R_EDX, R_FPSCR );
1832 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1833 JNE_rel8(8 + MEM_WRITE_SIZE, doublesize);
1834 load_fr_bank( R_EDX );
1835 load_fr( R_EDX, R_ECX, FRm );
1836 MEM_WRITE_LONG( R_EAX, R_ECX ); // 12
1838 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
1839 JMP_TARGET(doublesize);
1840 load_xf_bank( R_EDX );
1841 load_fr( R_EDX, R_ECX, FRm&0x0E );
1842 load_fr( R_EDX, R_EDX, FRm|0x01 );
1843 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1846 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
1847 JMP_TARGET(doublesize);
1848 load_fr_bank( R_EDX );
1849 load_fr( R_EDX, R_ECX, FRm&0x0E );
1850 load_fr( R_EDX, R_EDX, FRm|0x01 );
1851 MEM_WRITE_DOUBLE( R_EAX, R_ECX, R_EDX );
1854 sh4_x86.tstate = TSTATE_NONE;
1856 FMOV @(R0, Rm), FRn {:
1858 load_reg( R_EAX, Rm );
1859 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EAX );
1860 check_ralign32( R_EAX );
1861 MMU_TRANSLATE_READ( R_EAX );
1862 load_spreg( R_EDX, R_FPSCR );
1863 TEST_imm32_r32( FPSCR_SZ, R_EDX );
1864 JNE_rel8(8 + MEM_READ_SIZE, doublesize);
1865 MEM_READ_LONG( R_EAX, R_EAX );
1866 load_fr_bank( R_EDX );
1867 store_fr( R_EDX, R_EAX, FRn );
1869 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
1870 JMP_TARGET(doublesize);
1871 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1872 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
1873 load_xf_bank( R_EDX );
1874 store_fr( R_EDX, R_ECX, FRn&0x0E );
1875 store_fr( R_EDX, R_EAX, FRn|0x01 );
1878 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
1879 JMP_TARGET(doublesize);
1880 MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );
1881 load_fr_bank( R_EDX );
1882 store_fr( R_EDX, R_ECX, FRn&0x0E );
1883 store_fr( R_EDX, R_EAX, FRn|0x01 );
1886 sh4_x86.tstate = TSTATE_NONE;
1888 FLDI0 FRn {: /* IFF PR=0 */
1890 load_spreg( R_ECX, R_FPSCR );
1891 TEST_imm32_r32( FPSCR_PR, R_ECX );
1893 XOR_r32_r32( R_EAX, R_EAX );
1894 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1895 store_fr( R_ECX, R_EAX, FRn );
1897 sh4_x86.tstate = TSTATE_NONE;
1899 FLDI1 FRn {: /* IFF PR=0 */
1901 load_spreg( R_ECX, R_FPSCR );
1902 TEST_imm32_r32( FPSCR_PR, R_ECX );
1904 load_imm32(R_EAX, 0x3F800000);
1905 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1906 store_fr( R_ECX, R_EAX, FRn );
1908 sh4_x86.tstate = TSTATE_NONE;
1913 load_spreg( R_ECX, R_FPSCR );
1914 load_spreg(R_EDX, REG_OFFSET(fr_bank));
1916 TEST_imm32_r32( FPSCR_PR, R_ECX );
1917 JNE_rel8(5, doubleprec);
1918 pop_fr( R_EDX, FRn );
1920 JMP_TARGET(doubleprec);
1921 pop_dr( R_EDX, FRn );
1923 sh4_x86.tstate = TSTATE_NONE;
1927 load_spreg( R_ECX, R_FPSCR );
1928 load_fr_bank( R_EDX );
1929 TEST_imm32_r32( FPSCR_PR, R_ECX );
1930 JNE_rel8(5, doubleprec);
1931 push_fr( R_EDX, FRm );
1933 JMP_TARGET(doubleprec);
1934 push_dr( R_EDX, FRm );
1936 load_imm32( R_ECX, (uint32_t)&max_int );
1937 FILD_r32ind( R_ECX );
1939 JNA_rel8( 32, sat );
1940 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
1941 FILD_r32ind( R_ECX ); // 2
1943 JAE_rel8( 21, sat2 ); // 2
1944 load_imm32( R_EAX, (uint32_t)&save_fcw );
1945 FNSTCW_r32ind( R_EAX );
1946 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
1947 FLDCW_r32ind( R_EDX );
1948 FISTP_sh4r(R_FPUL); // 3
1949 FLDCW_r32ind( R_EAX );
1950 JMP_rel8( 9, end ); // 2
1954 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
1955 store_spreg( R_ECX, R_FPUL );
1958 sh4_x86.tstate = TSTATE_NONE;
1962 load_fr_bank( R_ECX );
1963 load_fr( R_ECX, R_EAX, FRm );
1964 store_spreg( R_EAX, R_FPUL );
1965 sh4_x86.tstate = TSTATE_NONE;
1969 load_fr_bank( R_ECX );
1970 load_spreg( R_EAX, R_FPUL );
1971 store_fr( R_ECX, R_EAX, FRn );
1972 sh4_x86.tstate = TSTATE_NONE;
1976 load_spreg( R_ECX, R_FPSCR );
1977 TEST_imm32_r32( FPSCR_PR, R_ECX );
1978 JE_rel8(9, end); // only when PR=1
1979 load_fr_bank( R_ECX );
1980 push_dr( R_ECX, FRm );
1983 sh4_x86.tstate = TSTATE_NONE;
1987 load_spreg( R_ECX, R_FPSCR );
1988 TEST_imm32_r32( FPSCR_PR, R_ECX );
1989 JE_rel8(9, end); // only when PR=1
1990 load_fr_bank( R_ECX );
1992 pop_dr( R_ECX, FRn );
1994 sh4_x86.tstate = TSTATE_NONE;
1997 /* Floating point instructions */
2000 load_spreg( R_ECX, R_FPSCR );
2001 load_fr_bank( R_EDX );
2002 TEST_imm32_r32( FPSCR_PR, R_ECX );
2003 JNE_rel8(10, doubleprec);
2004 push_fr(R_EDX, FRn); // 3
2006 pop_fr( R_EDX, FRn); //3
2007 JMP_rel8(8,end); // 2
2008 JMP_TARGET(doubleprec);
2009 push_dr(R_EDX, FRn);
2013 sh4_x86.tstate = TSTATE_NONE;
2017 load_spreg( R_ECX, R_FPSCR );
2018 TEST_imm32_r32( FPSCR_PR, R_ECX );
2019 load_fr_bank( R_EDX );
2020 JNE_rel8(13,doubleprec);
2021 push_fr(R_EDX, FRm);
2022 push_fr(R_EDX, FRn);
2026 JMP_TARGET(doubleprec);
2027 push_dr(R_EDX, FRm);
2028 push_dr(R_EDX, FRn);
2032 sh4_x86.tstate = TSTATE_NONE;
2036 load_spreg( R_ECX, R_FPSCR );
2037 TEST_imm32_r32( FPSCR_PR, R_ECX );
2038 load_fr_bank( R_EDX );
2039 JNE_rel8(13, doubleprec);
2040 push_fr(R_EDX, FRn);
2041 push_fr(R_EDX, FRm);
2045 JMP_TARGET(doubleprec);
2046 push_dr(R_EDX, FRn);
2047 push_dr(R_EDX, FRm);
2051 sh4_x86.tstate = TSTATE_NONE;
2053 FMAC FR0, FRm, FRn {:
2055 load_spreg( R_ECX, R_FPSCR );
2056 load_spreg( R_EDX, REG_OFFSET(fr_bank));
2057 TEST_imm32_r32( FPSCR_PR, R_ECX );
2058 JNE_rel8(18, doubleprec);
2059 push_fr( R_EDX, 0 );
2060 push_fr( R_EDX, FRm );
2062 push_fr( R_EDX, FRn );
2064 pop_fr( R_EDX, FRn );
2066 JMP_TARGET(doubleprec);
2067 push_dr( R_EDX, 0 );
2068 push_dr( R_EDX, FRm );
2070 push_dr( R_EDX, FRn );
2072 pop_dr( R_EDX, FRn );
2074 sh4_x86.tstate = TSTATE_NONE;
2079 load_spreg( R_ECX, R_FPSCR );
2080 TEST_imm32_r32( FPSCR_PR, R_ECX );
2081 load_fr_bank( R_EDX );
2082 JNE_rel8(13, doubleprec);
2083 push_fr(R_EDX, FRm);
2084 push_fr(R_EDX, FRn);
2088 JMP_TARGET(doubleprec);
2089 push_dr(R_EDX, FRm);
2090 push_dr(R_EDX, FRn);
2094 sh4_x86.tstate = TSTATE_NONE;
2098 load_spreg( R_ECX, R_FPSCR );
2099 TEST_imm32_r32( FPSCR_PR, R_ECX );
2100 load_fr_bank( R_EDX );
2101 JNE_rel8(10, doubleprec);
2102 push_fr(R_EDX, FRn);
2106 JMP_TARGET(doubleprec);
2107 push_dr(R_EDX, FRn);
2111 sh4_x86.tstate = TSTATE_NONE;
2115 load_spreg( R_ECX, R_FPSCR );
2116 TEST_imm32_r32( FPSCR_PR, R_ECX );
2117 load_fr_bank( R_EDX );
2118 JNE_rel8(12, end); // PR=0 only
2120 push_fr(R_EDX, FRn);
2125 sh4_x86.tstate = TSTATE_NONE;
2129 load_spreg( R_ECX, R_FPSCR );
2130 TEST_imm32_r32( FPSCR_PR, R_ECX );
2131 load_fr_bank( R_EDX );
2132 JNE_rel8(10, doubleprec);
2133 push_fr(R_EDX, FRn);
2137 JMP_TARGET(doubleprec);
2138 push_dr(R_EDX, FRn);
2142 sh4_x86.tstate = TSTATE_NONE;
2146 load_spreg( R_ECX, R_FPSCR );
2147 TEST_imm32_r32( FPSCR_PR, R_ECX );
2148 load_fr_bank( R_EDX );
2149 JNE_rel8(13, doubleprec);
2150 push_fr(R_EDX, FRn);
2151 push_fr(R_EDX, FRm);
2155 JMP_TARGET(doubleprec);
2156 push_dr(R_EDX, FRn);
2157 push_dr(R_EDX, FRm);
2161 sh4_x86.tstate = TSTATE_NONE;
2166 load_spreg( R_ECX, R_FPSCR );
2167 TEST_imm32_r32( FPSCR_PR, R_ECX );
2168 load_fr_bank( R_EDX );
2169 JNE_rel8(8, doubleprec);
2170 push_fr(R_EDX, FRm);
2171 push_fr(R_EDX, FRn);
2173 JMP_TARGET(doubleprec);
2174 push_dr(R_EDX, FRm);
2175 push_dr(R_EDX, FRn);
2180 sh4_x86.tstate = TSTATE_NONE;
2184 load_spreg( R_ECX, R_FPSCR );
2185 TEST_imm32_r32( FPSCR_PR, R_ECX );
2186 load_fr_bank( R_EDX );
2187 JNE_rel8(8, doubleprec);
2188 push_fr(R_EDX, FRm);
2189 push_fr(R_EDX, FRn);
2191 JMP_TARGET(doubleprec);
2192 push_dr(R_EDX, FRm);
2193 push_dr(R_EDX, FRn);
2198 sh4_x86.tstate = TSTATE_NONE;
2203 load_spreg( R_ECX, R_FPSCR );
2204 TEST_imm32_r32( FPSCR_PR, R_ECX );
2205 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
2206 load_fr_bank( R_ECX );
2207 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
2208 load_spreg( R_EDX, R_FPUL );
2209 call_func2( sh4_fsca, R_EDX, R_ECX );
2210 JMP_TARGET(doubleprec);
2211 sh4_x86.tstate = TSTATE_NONE;
2215 load_spreg( R_ECX, R_FPSCR );
2216 TEST_imm32_r32( FPSCR_PR, R_ECX );
2217 JNE_rel8(44, doubleprec);
2219 load_fr_bank( R_ECX );
2220 push_fr( R_ECX, FVm<<2 );
2221 push_fr( R_ECX, FVn<<2 );
2223 push_fr( R_ECX, (FVm<<2)+1);
2224 push_fr( R_ECX, (FVn<<2)+1);
2227 push_fr( R_ECX, (FVm<<2)+2);
2228 push_fr( R_ECX, (FVn<<2)+2);
2231 push_fr( R_ECX, (FVm<<2)+3);
2232 push_fr( R_ECX, (FVn<<2)+3);
2235 pop_fr( R_ECX, (FVn<<2)+3);
2236 JMP_TARGET(doubleprec);
2237 sh4_x86.tstate = TSTATE_NONE;
2241 load_spreg( R_ECX, R_FPSCR );
2242 TEST_imm32_r32( FPSCR_PR, R_ECX );
2243 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
2244 load_fr_bank( R_EDX ); // 3
2245 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
2246 load_xf_bank( R_ECX ); // 12
2247 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
2248 JMP_TARGET(doubleprec);
2249 sh4_x86.tstate = TSTATE_NONE;
2254 load_spreg( R_ECX, R_FPSCR );
2255 XOR_imm32_r32( FPSCR_FR, R_ECX );
2256 store_spreg( R_ECX, R_FPSCR );
2257 update_fr_bank( R_ECX );
2258 sh4_x86.tstate = TSTATE_NONE;
2262 load_spreg( R_ECX, R_FPSCR );
2263 XOR_imm32_r32( FPSCR_SZ, R_ECX );
2264 store_spreg( R_ECX, R_FPSCR );
2265 sh4_x86.tstate = TSTATE_NONE;
2268 /* Processor control instructions */
2270 if( sh4_x86.in_delay_slot ) {
2274 load_reg( R_EAX, Rm );
2275 call_func1( sh4_write_sr, R_EAX );
2276 sh4_x86.priv_checked = FALSE;
2277 sh4_x86.fpuen_checked = FALSE;
2278 sh4_x86.tstate = TSTATE_NONE;
2282 load_reg( R_EAX, Rm );
2283 store_spreg( R_EAX, R_GBR );
2287 load_reg( R_EAX, Rm );
2288 store_spreg( R_EAX, R_VBR );
2289 sh4_x86.tstate = TSTATE_NONE;
2293 load_reg( R_EAX, Rm );
2294 store_spreg( R_EAX, R_SSR );
2295 sh4_x86.tstate = TSTATE_NONE;
2299 load_reg( R_EAX, Rm );
2300 store_spreg( R_EAX, R_SGR );
2301 sh4_x86.tstate = TSTATE_NONE;
2305 load_reg( R_EAX, Rm );
2306 store_spreg( R_EAX, R_SPC );
2307 sh4_x86.tstate = TSTATE_NONE;
2311 load_reg( R_EAX, Rm );
2312 store_spreg( R_EAX, R_DBR );
2313 sh4_x86.tstate = TSTATE_NONE;
2317 load_reg( R_EAX, Rm );
2318 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2319 sh4_x86.tstate = TSTATE_NONE;
2322 load_reg( R_EAX, Rm );
2323 check_ralign32( R_EAX );
2324 MMU_TRANSLATE_READ( R_EAX );
2325 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2326 MEM_READ_LONG( R_EAX, R_EAX );
2327 store_spreg( R_EAX, R_GBR );
2328 sh4_x86.tstate = TSTATE_NONE;
2331 if( sh4_x86.in_delay_slot ) {
2335 load_reg( R_EAX, Rm );
2336 check_ralign32( R_EAX );
2337 MMU_TRANSLATE_READ( R_EAX );
2338 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2339 MEM_READ_LONG( R_EAX, R_EAX );
2340 call_func1( sh4_write_sr, R_EAX );
2341 sh4_x86.priv_checked = FALSE;
2342 sh4_x86.fpuen_checked = FALSE;
2343 sh4_x86.tstate = TSTATE_NONE;
2348 load_reg( R_EAX, Rm );
2349 check_ralign32( R_EAX );
2350 MMU_TRANSLATE_READ( R_EAX );
2351 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2352 MEM_READ_LONG( R_EAX, R_EAX );
2353 store_spreg( R_EAX, R_VBR );
2354 sh4_x86.tstate = TSTATE_NONE;
2358 load_reg( R_EAX, Rm );
2359 check_ralign32( R_EAX );
2360 MMU_TRANSLATE_READ( R_EAX );
2361 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2362 MEM_READ_LONG( R_EAX, R_EAX );
2363 store_spreg( R_EAX, R_SSR );
2364 sh4_x86.tstate = TSTATE_NONE;
2368 load_reg( R_EAX, Rm );
2369 check_ralign32( R_EAX );
2370 MMU_TRANSLATE_READ( R_EAX );
2371 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2372 MEM_READ_LONG( R_EAX, R_EAX );
2373 store_spreg( R_EAX, R_SGR );
2374 sh4_x86.tstate = TSTATE_NONE;
2378 load_reg( R_EAX, Rm );
2379 check_ralign32( R_EAX );
2380 MMU_TRANSLATE_READ( R_EAX );
2381 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2382 MEM_READ_LONG( R_EAX, R_EAX );
2383 store_spreg( R_EAX, R_SPC );
2384 sh4_x86.tstate = TSTATE_NONE;
2388 load_reg( R_EAX, Rm );
2389 check_ralign32( R_EAX );
2390 MMU_TRANSLATE_READ( R_EAX );
2391 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2392 MEM_READ_LONG( R_EAX, R_EAX );
2393 store_spreg( R_EAX, R_DBR );
2394 sh4_x86.tstate = TSTATE_NONE;
2396 LDC.L @Rm+, Rn_BANK {:
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_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2404 sh4_x86.tstate = TSTATE_NONE;
2407 load_reg( R_EAX, Rm );
2408 store_spreg( R_EAX, R_FPSCR );
2409 update_fr_bank( R_EAX );
2410 sh4_x86.tstate = TSTATE_NONE;
2412 LDS.L @Rm+, FPSCR {:
2413 load_reg( R_EAX, Rm );
2414 check_ralign32( R_EAX );
2415 MMU_TRANSLATE_READ( R_EAX );
2416 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2417 MEM_READ_LONG( R_EAX, R_EAX );
2418 store_spreg( R_EAX, R_FPSCR );
2419 update_fr_bank( R_EAX );
2420 sh4_x86.tstate = TSTATE_NONE;
2423 load_reg( R_EAX, Rm );
2424 store_spreg( R_EAX, R_FPUL );
2427 load_reg( R_EAX, Rm );
2428 check_ralign32( R_EAX );
2429 MMU_TRANSLATE_READ( R_EAX );
2430 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2431 MEM_READ_LONG( R_EAX, R_EAX );
2432 store_spreg( R_EAX, R_FPUL );
2433 sh4_x86.tstate = TSTATE_NONE;
2436 load_reg( R_EAX, Rm );
2437 store_spreg( R_EAX, R_MACH );
2440 load_reg( R_EAX, Rm );
2441 check_ralign32( R_EAX );
2442 MMU_TRANSLATE_READ( R_EAX );
2443 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2444 MEM_READ_LONG( R_EAX, R_EAX );
2445 store_spreg( R_EAX, R_MACH );
2446 sh4_x86.tstate = TSTATE_NONE;
2449 load_reg( R_EAX, Rm );
2450 store_spreg( R_EAX, R_MACL );
2453 load_reg( R_EAX, Rm );
2454 check_ralign32( R_EAX );
2455 MMU_TRANSLATE_READ( R_EAX );
2456 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2457 MEM_READ_LONG( R_EAX, R_EAX );
2458 store_spreg( R_EAX, R_MACL );
2459 sh4_x86.tstate = TSTATE_NONE;
2462 load_reg( R_EAX, Rm );
2463 store_spreg( R_EAX, R_PR );
2466 load_reg( R_EAX, Rm );
2467 check_ralign32( R_EAX );
2468 MMU_TRANSLATE_READ( R_EAX );
2469 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
2470 MEM_READ_LONG( R_EAX, R_EAX );
2471 store_spreg( R_EAX, R_PR );
2472 sh4_x86.tstate = TSTATE_NONE;
2475 call_func0( MMU_ldtlb );
2481 load_reg( R_EAX, Rn );
2482 MOV_r32_r32( R_EAX, R_ECX );
2483 AND_imm32_r32( 0xFC000000, R_EAX );
2484 CMP_imm32_r32( 0xE0000000, R_EAX );
2485 JNE_rel8(8+CALL_FUNC1_SIZE, end);
2486 call_func1( sh4_flush_store_queue, R_ECX );
2487 TEST_r32_r32( R_EAX, R_EAX );
2490 sh4_x86.tstate = TSTATE_NONE;
2494 call_func0( sh4_sleep );
2495 sh4_x86.tstate = TSTATE_NONE;
2496 sh4_x86.in_delay_slot = DELAY_NONE;
2501 call_func0(sh4_read_sr);
2502 store_reg( R_EAX, Rn );
2503 sh4_x86.tstate = TSTATE_NONE;
2506 load_spreg( R_EAX, R_GBR );
2507 store_reg( R_EAX, Rn );
2511 load_spreg( R_EAX, R_VBR );
2512 store_reg( R_EAX, Rn );
2513 sh4_x86.tstate = TSTATE_NONE;
2517 load_spreg( R_EAX, R_SSR );
2518 store_reg( R_EAX, Rn );
2519 sh4_x86.tstate = TSTATE_NONE;
2523 load_spreg( R_EAX, R_SPC );
2524 store_reg( R_EAX, Rn );
2525 sh4_x86.tstate = TSTATE_NONE;
2529 load_spreg( R_EAX, R_SGR );
2530 store_reg( R_EAX, Rn );
2531 sh4_x86.tstate = TSTATE_NONE;
2535 load_spreg( R_EAX, R_DBR );
2536 store_reg( R_EAX, Rn );
2537 sh4_x86.tstate = TSTATE_NONE;
2541 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
2542 store_reg( R_EAX, Rn );
2543 sh4_x86.tstate = TSTATE_NONE;
2547 load_reg( R_EAX, Rn );
2548 check_walign32( R_EAX );
2549 ADD_imm8s_r32( -4, R_EAX );
2550 MMU_TRANSLATE_WRITE( R_EAX );
2551 PUSH_realigned_r32( R_EAX );
2552 call_func0( sh4_read_sr );
2553 POP_realigned_r32( R_ECX );
2554 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2555 MEM_WRITE_LONG( R_ECX, R_EAX );
2556 sh4_x86.tstate = TSTATE_NONE;
2560 load_reg( R_EAX, Rn );
2561 check_walign32( R_EAX );
2562 ADD_imm8s_r32( -4, R_EAX );
2563 MMU_TRANSLATE_WRITE( R_EAX );
2564 load_spreg( R_EDX, R_VBR );
2565 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2566 MEM_WRITE_LONG( R_EAX, R_EDX );
2567 sh4_x86.tstate = TSTATE_NONE;
2571 load_reg( R_EAX, Rn );
2572 check_walign32( R_EAX );
2573 ADD_imm8s_r32( -4, R_EAX );
2574 MMU_TRANSLATE_WRITE( R_EAX );
2575 load_spreg( R_EDX, R_SSR );
2576 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2577 MEM_WRITE_LONG( R_EAX, R_EDX );
2578 sh4_x86.tstate = TSTATE_NONE;
2582 load_reg( R_EAX, Rn );
2583 check_walign32( R_EAX );
2584 ADD_imm8s_r32( -4, R_EAX );
2585 MMU_TRANSLATE_WRITE( R_EAX );
2586 load_spreg( R_EDX, R_SPC );
2587 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2588 MEM_WRITE_LONG( R_EAX, R_EDX );
2589 sh4_x86.tstate = TSTATE_NONE;
2593 load_reg( R_EAX, Rn );
2594 check_walign32( R_EAX );
2595 ADD_imm8s_r32( -4, R_EAX );
2596 MMU_TRANSLATE_WRITE( R_EAX );
2597 load_spreg( R_EDX, R_SGR );
2598 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2599 MEM_WRITE_LONG( R_EAX, R_EDX );
2600 sh4_x86.tstate = TSTATE_NONE;
2604 load_reg( R_EAX, Rn );
2605 check_walign32( R_EAX );
2606 ADD_imm8s_r32( -4, R_EAX );
2607 MMU_TRANSLATE_WRITE( R_EAX );
2608 load_spreg( R_EDX, R_DBR );
2609 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2610 MEM_WRITE_LONG( R_EAX, R_EDX );
2611 sh4_x86.tstate = TSTATE_NONE;
2613 STC.L Rm_BANK, @-Rn {:
2615 load_reg( R_EAX, Rn );
2616 check_walign32( R_EAX );
2617 ADD_imm8s_r32( -4, R_EAX );
2618 MMU_TRANSLATE_WRITE( R_EAX );
2619 load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
2620 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2621 MEM_WRITE_LONG( R_EAX, R_EDX );
2622 sh4_x86.tstate = TSTATE_NONE;
2625 load_reg( R_EAX, Rn );
2626 check_walign32( R_EAX );
2627 ADD_imm8s_r32( -4, R_EAX );
2628 MMU_TRANSLATE_WRITE( R_EAX );
2629 load_spreg( R_EDX, R_GBR );
2630 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2631 MEM_WRITE_LONG( R_EAX, R_EDX );
2632 sh4_x86.tstate = TSTATE_NONE;
2635 load_spreg( R_EAX, R_FPSCR );
2636 store_reg( R_EAX, Rn );
2638 STS.L FPSCR, @-Rn {:
2639 load_reg( R_EAX, Rn );
2640 check_walign32( R_EAX );
2641 ADD_imm8s_r32( -4, R_EAX );
2642 MMU_TRANSLATE_WRITE( R_EAX );
2643 load_spreg( R_EDX, R_FPSCR );
2644 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2645 MEM_WRITE_LONG( R_EAX, R_EDX );
2646 sh4_x86.tstate = TSTATE_NONE;
2649 load_spreg( R_EAX, R_FPUL );
2650 store_reg( R_EAX, Rn );
2653 load_reg( R_EAX, Rn );
2654 check_walign32( R_EAX );
2655 ADD_imm8s_r32( -4, R_EAX );
2656 MMU_TRANSLATE_WRITE( R_EAX );
2657 load_spreg( R_EDX, R_FPUL );
2658 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2659 MEM_WRITE_LONG( R_EAX, R_EDX );
2660 sh4_x86.tstate = TSTATE_NONE;
2663 load_spreg( R_EAX, R_MACH );
2664 store_reg( R_EAX, Rn );
2667 load_reg( R_EAX, Rn );
2668 check_walign32( R_EAX );
2669 ADD_imm8s_r32( -4, R_EAX );
2670 MMU_TRANSLATE_WRITE( R_EAX );
2671 load_spreg( R_EDX, R_MACH );
2672 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2673 MEM_WRITE_LONG( R_EAX, R_EDX );
2674 sh4_x86.tstate = TSTATE_NONE;
2677 load_spreg( R_EAX, R_MACL );
2678 store_reg( R_EAX, Rn );
2681 load_reg( R_EAX, Rn );
2682 check_walign32( R_EAX );
2683 ADD_imm8s_r32( -4, R_EAX );
2684 MMU_TRANSLATE_WRITE( R_EAX );
2685 load_spreg( R_EDX, R_MACL );
2686 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2687 MEM_WRITE_LONG( R_EAX, R_EDX );
2688 sh4_x86.tstate = TSTATE_NONE;
2691 load_spreg( R_EAX, R_PR );
2692 store_reg( R_EAX, Rn );
2695 load_reg( R_EAX, Rn );
2696 check_walign32( R_EAX );
2697 ADD_imm8s_r32( -4, R_EAX );
2698 MMU_TRANSLATE_WRITE( R_EAX );
2699 load_spreg( R_EDX, R_PR );
2700 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );
2701 MEM_WRITE_LONG( R_EAX, R_EDX );
2702 sh4_x86.tstate = TSTATE_NONE;
2705 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
2707 sh4_x86.in_delay_slot = DELAY_NONE;
.