2 * $Id: sh4x86.c,v 1.18 2007-10-04 08:47:27 nkeynes Exp $
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
38 * Struct to manage internal translation state. This state is not saved -
39 * it is only valid between calls to sh4_translate_begin_block() and
40 * sh4_translate_end_block()
42 struct sh4_x86_state {
43 gboolean in_delay_slot;
44 gboolean priv_checked; /* true if we've already checked the cpu mode. */
45 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
46 gboolean branch_taken; /* true if we branched unconditionally */
47 uint32_t block_start_pc;
50 /* Allocated memory for the (block-wide) back-patch list */
51 uint32_t **backpatch_list;
52 uint32_t backpatch_posn;
53 uint32_t backpatch_size;
56 #define TSTATE_NONE -1
66 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
67 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
68 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
69 OP(0x70+sh4_x86.tstate); OP(rel8); \
71 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
72 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
73 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
74 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
78 #define EXIT_DATA_ADDR_READ 0
79 #define EXIT_DATA_ADDR_WRITE 7
80 #define EXIT_ILLEGAL 14
81 #define EXIT_SLOT_ILLEGAL 21
82 #define EXIT_FPU_DISABLED 28
83 #define EXIT_SLOT_FPU_DISABLED 35
85 static struct sh4_x86_state sh4_x86;
87 static uint32_t max_int = 0x7FFFFFFF;
88 static uint32_t min_int = 0x80000000;
89 static uint32_t save_fcw; /* save value for fpu control word */
90 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
94 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
95 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
99 static void sh4_x86_add_backpatch( uint8_t *ptr )
101 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
102 sh4_x86.backpatch_size <<= 1;
103 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
104 assert( sh4_x86.backpatch_list != NULL );
106 sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
109 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
112 for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
113 *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
118 * Emit an instruction to load an SH4 reg into a real register
120 static inline void load_reg( int x86reg, int sh4reg )
122 /* mov [bp+n], reg */
124 OP(0x45 + (x86reg<<3));
125 OP(REG_OFFSET(r[sh4reg]));
128 static inline void load_reg16s( int x86reg, int sh4reg )
132 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
135 static inline void load_reg16u( int x86reg, int sh4reg )
139 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
143 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
144 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
146 * Emit an instruction to load an immediate value into a register
148 static inline void load_imm32( int x86reg, uint32_t value ) {
149 /* mov #value, reg */
155 * Emit an instruction to store an SH4 reg (RN)
157 void static inline store_reg( int x86reg, int sh4reg ) {
158 /* mov reg, [bp+n] */
160 OP(0x45 + (x86reg<<3));
161 OP(REG_OFFSET(r[sh4reg]));
164 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
167 * Load an FR register (single-precision floating point) into an integer x86
168 * register (eg for register-to-register moves)
170 void static inline load_fr( int bankreg, int x86reg, int frm )
172 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
176 * Store an FR register (single-precision floating point) into an integer x86
177 * register (eg for register-to-register moves)
179 void static inline store_fr( int bankreg, int x86reg, int frn )
181 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
186 * Load a pointer to the back fp back into the specified x86 register. The
187 * bankreg must have been previously loaded with FPSCR.
190 static inline void load_xf_bank( int bankreg )
193 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
194 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
195 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
199 * Update the fr_bank pointer based on the current fpscr value.
201 static inline void update_fr_bank( int fpscrreg )
203 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
204 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
205 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
206 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
209 * Push FPUL (as a 32-bit float) onto the FPU stack
211 static inline void push_fpul( )
213 OP(0xD9); OP(0x45); OP(R_FPUL);
217 * Pop FPUL (as a 32-bit float) from the FPU stack
219 static inline void pop_fpul( )
221 OP(0xD9); OP(0x5D); OP(R_FPUL);
225 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
226 * with the location of the current fp bank.
228 static inline void push_fr( int bankreg, int frm )
230 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
234 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
235 * with bankreg previously loaded with the location of the current fp bank.
237 static inline void pop_fr( int bankreg, int frm )
239 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
243 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
244 * with the location of the current fp bank.
246 static inline void push_dr( int bankreg, int frm )
248 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
251 static inline void pop_dr( int bankreg, int frm )
253 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
257 * Note: clobbers EAX to make the indirect call - this isn't usually
258 * a problem since the callee will usually clobber it anyway.
260 static inline void call_func0( void *ptr )
262 load_imm32(R_EAX, (uint32_t)ptr);
266 static inline void call_func1( void *ptr, int arg1 )
270 ADD_imm8s_r32( 4, R_ESP );
273 static inline void call_func2( void *ptr, int arg1, int arg2 )
278 ADD_imm8s_r32( 8, R_ESP );
282 * Write a double (64-bit) value into memory, with the first word in arg2a, and
283 * the second in arg2b
286 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
288 ADD_imm8s_r32( 4, addr );
291 ADD_imm8s_r32( -4, addr );
294 call_func0(sh4_write_long);
295 ADD_imm8s_r32( 8, R_ESP );
296 call_func0(sh4_write_long);
297 ADD_imm8s_r32( 8, R_ESP );
301 * Read a double (64-bit) value from memory, writing the first word into arg2a
302 * and the second into arg2b. The addr must not be in EAX
305 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
308 call_func0(sh4_read_long);
311 ADD_imm8s_r32( 4, addr );
313 call_func0(sh4_read_long);
314 ADD_imm8s_r32( 4, R_ESP );
315 MOV_r32_r32( R_EAX, arg2b );
319 /* Exception checks - Note that all exception checks will clobber EAX */
320 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
322 #define check_priv( ) \
323 if( !sh4_x86.priv_checked ) { \
324 sh4_x86.priv_checked = TRUE;\
326 load_spreg( R_EAX, R_SR );\
327 AND_imm32_r32( SR_MD, R_EAX );\
328 if( sh4_x86.in_delay_slot ) {\
329 JE_exit( EXIT_SLOT_ILLEGAL );\
331 JE_exit( EXIT_ILLEGAL );\
336 static void check_priv_no_precheck()
338 if( !sh4_x86.priv_checked ) {
339 sh4_x86.priv_checked = TRUE;
340 load_spreg( R_EAX, R_SR );
341 AND_imm32_r32( SR_MD, R_EAX );
342 if( sh4_x86.in_delay_slot ) {
343 JE_exit( EXIT_SLOT_ILLEGAL );
345 JE_exit( EXIT_ILLEGAL );
350 #define check_fpuen( ) \
351 if( !sh4_x86.fpuen_checked ) {\
352 sh4_x86.fpuen_checked = TRUE;\
354 load_spreg( R_EAX, R_SR );\
355 AND_imm32_r32( SR_FD, R_EAX );\
356 if( sh4_x86.in_delay_slot ) {\
357 JNE_exit(EXIT_SLOT_FPU_DISABLED);\
359 JNE_exit(EXIT_FPU_DISABLED);\
363 static void check_fpuen_no_precheck()
365 if( !sh4_x86.fpuen_checked ) {
366 sh4_x86.fpuen_checked = TRUE;
367 load_spreg( R_EAX, R_SR );
368 AND_imm32_r32( SR_FD, R_EAX );
369 if( sh4_x86.in_delay_slot ) {
370 JNE_exit(EXIT_SLOT_FPU_DISABLED);
372 JNE_exit(EXIT_FPU_DISABLED);
378 static void check_ralign16( int x86reg )
380 TEST_imm32_r32( 0x00000001, x86reg );
381 JNE_exit(EXIT_DATA_ADDR_READ);
384 static void check_walign16( int x86reg )
386 TEST_imm32_r32( 0x00000001, x86reg );
387 JNE_exit(EXIT_DATA_ADDR_WRITE);
390 static void check_ralign32( int x86reg )
392 TEST_imm32_r32( 0x00000003, x86reg );
393 JNE_exit(EXIT_DATA_ADDR_READ);
395 static void check_walign32( int x86reg )
397 TEST_imm32_r32( 0x00000003, x86reg );
398 JNE_exit(EXIT_DATA_ADDR_WRITE);
402 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
403 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
404 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
405 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
406 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
407 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
408 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
410 #define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
415 * Emit the 'start of block' assembly. Sets up the stack frame and save
418 void sh4_translate_begin_block( sh4addr_t pc )
422 load_imm32( R_EBP, (uint32_t)&sh4r );
424 sh4_x86.in_delay_slot = FALSE;
425 sh4_x86.priv_checked = FALSE;
426 sh4_x86.fpuen_checked = FALSE;
427 sh4_x86.branch_taken = FALSE;
428 sh4_x86.backpatch_posn = 0;
429 sh4_x86.block_start_pc = pc;
430 sh4_x86.tstate = TSTATE_NONE;
434 * Exit the block to an absolute PC
437 void exit_block( sh4addr_t pc, sh4addr_t endpc )
439 load_imm32( R_ECX, pc ); // 5
440 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
441 MOV_moff32_EAX( (uint32_t)xlat_get_lut_entry(pc) ); // 5
442 AND_imm8s_r32( 0xFC, R_EAX ); // 3
443 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
444 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
450 * Exit the block with sh4r.pc already written
453 void exit_block_pcset( pc )
455 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
456 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
457 load_spreg( R_EAX, REG_OFFSET(pc) );
458 call_func1(xlat_get_code,R_EAX);
464 * Write the block trailer (exception handling block)
466 void sh4_translate_end_block( sh4addr_t pc ) {
467 if( sh4_x86.branch_taken == FALSE ) {
468 // Didn't exit unconditionally already, so write the termination here
469 exit_block( pc, pc );
471 if( sh4_x86.backpatch_posn != 0 ) {
472 uint8_t *end_ptr = xlat_output;
473 // Exception termination. Jump block for various exception codes:
474 PUSH_imm32( EXC_DATA_ADDR_READ );
475 JMP_rel8( 33, target1 );
476 PUSH_imm32( EXC_DATA_ADDR_WRITE );
477 JMP_rel8( 26, target2 );
478 PUSH_imm32( EXC_ILLEGAL );
479 JMP_rel8( 19, target3 );
480 PUSH_imm32( EXC_SLOT_ILLEGAL );
481 JMP_rel8( 12, target4 );
482 PUSH_imm32( EXC_FPU_DISABLED );
483 JMP_rel8( 5, target5 );
484 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
492 load_spreg( R_ECX, REG_OFFSET(pc) );
493 ADD_r32_r32( R_EDX, R_ECX );
494 ADD_r32_r32( R_EDX, R_ECX );
495 store_spreg( R_ECX, REG_OFFSET(pc) );
496 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
498 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
500 load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
501 CALL_r32( R_EAX ); // 2
502 ADD_imm8s_r32( 4, R_ESP );
503 load_spreg( R_EAX, REG_OFFSET(pc) );
504 call_func1(xlat_get_code,R_EAX);
508 sh4_x86_do_backpatch( end_ptr );
514 extern uint16_t *sh4_icache;
515 extern uint32_t sh4_icache_addr;
518 * Translate a single instruction. Delayed branches are handled specially
519 * by translating both branch and delayed instruction as a single unit (as
522 * @return true if the instruction marks the end of a basic block
525 uint32_t sh4_x86_translate_instruction( sh4addr_t pc )
528 /* Read instruction */
529 uint32_t pageaddr = pc >> 12;
530 if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
531 ir = sh4_icache[(pc&0xFFF)>>1];
533 sh4_icache = (uint16_t *)mem_get_page(pc);
534 if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
535 /* If someone's actually been so daft as to try to execute out of an IO
536 * region, fallback on the full-blown memory read
539 ir = sh4_read_word(pc);
541 sh4_icache_addr = pageaddr;
542 ir = sh4_icache[(pc&0xFFF)>>1];
546 switch( (ir&0xF000) >> 12 ) {
550 switch( (ir&0x80) >> 7 ) {
552 switch( (ir&0x70) >> 4 ) {
555 uint32_t Rn = ((ir>>8)&0xF);
557 call_func0(sh4_read_sr);
558 store_reg( R_EAX, Rn );
559 sh4_x86.tstate = TSTATE_NONE;
564 uint32_t Rn = ((ir>>8)&0xF);
565 load_spreg( R_EAX, R_GBR );
566 store_reg( R_EAX, Rn );
571 uint32_t Rn = ((ir>>8)&0xF);
573 load_spreg( R_EAX, R_VBR );
574 store_reg( R_EAX, Rn );
575 sh4_x86.tstate = TSTATE_NONE;
580 uint32_t Rn = ((ir>>8)&0xF);
582 load_spreg( R_EAX, R_SSR );
583 store_reg( R_EAX, Rn );
584 sh4_x86.tstate = TSTATE_NONE;
589 uint32_t Rn = ((ir>>8)&0xF);
591 load_spreg( R_EAX, R_SPC );
592 store_reg( R_EAX, Rn );
593 sh4_x86.tstate = TSTATE_NONE;
602 { /* STC Rm_BANK, Rn */
603 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
605 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
606 store_reg( R_EAX, Rn );
607 sh4_x86.tstate = TSTATE_NONE;
613 switch( (ir&0xF0) >> 4 ) {
616 uint32_t Rn = ((ir>>8)&0xF);
617 if( sh4_x86.in_delay_slot ) {
620 load_imm32( R_ECX, pc + 4 );
621 store_spreg( R_ECX, R_PR );
622 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_ECX );
623 store_spreg( R_ECX, REG_OFFSET(pc) );
624 sh4_x86.in_delay_slot = TRUE;
625 sh4_x86.tstate = TSTATE_NONE;
626 sh4_x86_translate_instruction( pc + 2 );
627 exit_block_pcset(pc+2);
628 sh4_x86.branch_taken = TRUE;
635 uint32_t Rn = ((ir>>8)&0xF);
636 if( sh4_x86.in_delay_slot ) {
639 load_reg( R_EAX, Rn );
640 ADD_imm32_r32( pc + 4, R_EAX );
641 store_spreg( R_EAX, REG_OFFSET(pc) );
642 sh4_x86.in_delay_slot = TRUE;
643 sh4_x86.tstate = TSTATE_NONE;
644 sh4_x86_translate_instruction( pc + 2 );
645 exit_block_pcset(pc+2);
646 sh4_x86.branch_taken = TRUE;
653 uint32_t Rn = ((ir>>8)&0xF);
654 load_reg( R_EAX, Rn );
656 AND_imm32_r32( 0xFC000000, R_EAX );
657 CMP_imm32_r32( 0xE0000000, R_EAX );
659 call_func0( sh4_flush_store_queue );
661 ADD_imm8s_r32( 4, R_ESP );
662 sh4_x86.tstate = TSTATE_NONE;
667 uint32_t Rn = ((ir>>8)&0xF);
672 uint32_t Rn = ((ir>>8)&0xF);
677 uint32_t Rn = ((ir>>8)&0xF);
681 { /* MOVCA.L R0, @Rn */
682 uint32_t Rn = ((ir>>8)&0xF);
683 load_reg( R_EAX, 0 );
684 load_reg( R_ECX, Rn );
686 check_walign32( R_ECX );
687 MEM_WRITE_LONG( R_ECX, R_EAX );
688 sh4_x86.tstate = TSTATE_NONE;
697 { /* MOV.B Rm, @(R0, Rn) */
698 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
699 load_reg( R_EAX, 0 );
700 load_reg( R_ECX, Rn );
701 ADD_r32_r32( R_EAX, R_ECX );
702 load_reg( R_EAX, Rm );
703 MEM_WRITE_BYTE( R_ECX, R_EAX );
704 sh4_x86.tstate = TSTATE_NONE;
708 { /* MOV.W Rm, @(R0, Rn) */
709 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
710 load_reg( R_EAX, 0 );
711 load_reg( R_ECX, Rn );
712 ADD_r32_r32( R_EAX, R_ECX );
714 check_walign16( R_ECX );
715 load_reg( R_EAX, Rm );
716 MEM_WRITE_WORD( R_ECX, R_EAX );
717 sh4_x86.tstate = TSTATE_NONE;
721 { /* MOV.L Rm, @(R0, Rn) */
722 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
723 load_reg( R_EAX, 0 );
724 load_reg( R_ECX, Rn );
725 ADD_r32_r32( R_EAX, R_ECX );
727 check_walign32( R_ECX );
728 load_reg( R_EAX, Rm );
729 MEM_WRITE_LONG( R_ECX, R_EAX );
730 sh4_x86.tstate = TSTATE_NONE;
735 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
736 load_reg( R_EAX, Rm );
737 load_reg( R_ECX, Rn );
739 store_spreg( R_EAX, R_MACL );
740 sh4_x86.tstate = TSTATE_NONE;
744 switch( (ir&0xFF0) >> 4 ) {
749 sh4_x86.tstate = TSTATE_C;
756 sh4_x86.tstate = TSTATE_C;
761 XOR_r32_r32(R_EAX, R_EAX);
762 store_spreg( R_EAX, R_MACL );
763 store_spreg( R_EAX, R_MACH );
764 sh4_x86.tstate = TSTATE_NONE;
775 sh4_x86.tstate = TSTATE_C;
782 sh4_x86.tstate = TSTATE_C;
791 switch( (ir&0xF0) >> 4 ) {
794 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
799 XOR_r32_r32( R_EAX, R_EAX );
800 store_spreg( R_EAX, R_Q );
801 store_spreg( R_EAX, R_M );
802 store_spreg( R_EAX, R_T );
803 sh4_x86.tstate = TSTATE_C; // works for DIV1
808 uint32_t Rn = ((ir>>8)&0xF);
809 load_spreg( R_EAX, R_T );
810 store_reg( R_EAX, Rn );
819 switch( (ir&0xF0) >> 4 ) {
822 uint32_t Rn = ((ir>>8)&0xF);
823 load_spreg( R_EAX, R_MACH );
824 store_reg( R_EAX, Rn );
829 uint32_t Rn = ((ir>>8)&0xF);
830 load_spreg( R_EAX, R_MACL );
831 store_reg( R_EAX, Rn );
836 uint32_t Rn = ((ir>>8)&0xF);
837 load_spreg( R_EAX, R_PR );
838 store_reg( R_EAX, Rn );
843 uint32_t Rn = ((ir>>8)&0xF);
845 load_spreg( R_EAX, R_SGR );
846 store_reg( R_EAX, Rn );
847 sh4_x86.tstate = TSTATE_NONE;
852 uint32_t Rn = ((ir>>8)&0xF);
853 load_spreg( R_EAX, R_FPUL );
854 store_reg( R_EAX, Rn );
858 { /* STS FPSCR, Rn */
859 uint32_t Rn = ((ir>>8)&0xF);
860 load_spreg( R_EAX, R_FPSCR );
861 store_reg( R_EAX, Rn );
866 uint32_t Rn = ((ir>>8)&0xF);
868 load_spreg( R_EAX, R_DBR );
869 store_reg( R_EAX, Rn );
870 sh4_x86.tstate = TSTATE_NONE;
879 switch( (ir&0xFF0) >> 4 ) {
882 if( sh4_x86.in_delay_slot ) {
885 load_spreg( R_ECX, R_PR );
886 store_spreg( R_ECX, REG_OFFSET(pc) );
887 sh4_x86.in_delay_slot = TRUE;
888 sh4_x86_translate_instruction(pc+2);
889 exit_block_pcset(pc+2);
890 sh4_x86.branch_taken = TRUE;
898 call_func0( sh4_sleep );
899 sh4_x86.tstate = TSTATE_NONE;
900 sh4_x86.in_delay_slot = FALSE;
906 if( sh4_x86.in_delay_slot ) {
910 load_spreg( R_ECX, R_SPC );
911 store_spreg( R_ECX, REG_OFFSET(pc) );
912 load_spreg( R_EAX, R_SSR );
913 call_func1( sh4_write_sr, R_EAX );
914 sh4_x86.in_delay_slot = TRUE;
915 sh4_x86.priv_checked = FALSE;
916 sh4_x86.fpuen_checked = FALSE;
917 sh4_x86.tstate = TSTATE_NONE;
918 sh4_x86_translate_instruction(pc+2);
919 exit_block_pcset(pc+2);
920 sh4_x86.branch_taken = TRUE;
931 { /* MOV.B @(R0, Rm), Rn */
932 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
933 load_reg( R_EAX, 0 );
934 load_reg( R_ECX, Rm );
935 ADD_r32_r32( R_EAX, R_ECX );
936 MEM_READ_BYTE( R_ECX, R_EAX );
937 store_reg( R_EAX, Rn );
938 sh4_x86.tstate = TSTATE_NONE;
942 { /* MOV.W @(R0, Rm), Rn */
943 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
944 load_reg( R_EAX, 0 );
945 load_reg( R_ECX, Rm );
946 ADD_r32_r32( R_EAX, R_ECX );
948 check_ralign16( R_ECX );
949 MEM_READ_WORD( R_ECX, R_EAX );
950 store_reg( R_EAX, Rn );
951 sh4_x86.tstate = TSTATE_NONE;
955 { /* MOV.L @(R0, Rm), Rn */
956 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
957 load_reg( R_EAX, 0 );
958 load_reg( R_ECX, Rm );
959 ADD_r32_r32( R_EAX, R_ECX );
961 check_ralign32( R_ECX );
962 MEM_READ_LONG( R_ECX, R_EAX );
963 store_reg( R_EAX, Rn );
964 sh4_x86.tstate = TSTATE_NONE;
968 { /* MAC.L @Rm+, @Rn+ */
969 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
970 load_reg( R_ECX, Rm );
972 check_ralign32( R_ECX );
973 load_reg( R_ECX, Rn );
974 check_ralign32( R_ECX );
975 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
976 MEM_READ_LONG( R_ECX, R_EAX );
978 load_reg( R_ECX, Rm );
979 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
980 MEM_READ_LONG( R_ECX, R_EAX );
983 ADD_r32_sh4r( R_EAX, R_MACL );
984 ADC_r32_sh4r( R_EDX, R_MACH );
986 load_spreg( R_ECX, R_S );
987 TEST_r32_r32(R_ECX, R_ECX);
989 call_func0( signsat48 );
991 sh4_x86.tstate = TSTATE_NONE;
1000 { /* MOV.L Rm, @(disp, Rn) */
1001 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1002 load_reg( R_ECX, Rn );
1003 load_reg( R_EAX, Rm );
1004 ADD_imm32_r32( disp, R_ECX );
1006 check_walign32( R_ECX );
1007 MEM_WRITE_LONG( R_ECX, R_EAX );
1008 sh4_x86.tstate = TSTATE_NONE;
1014 { /* MOV.B Rm, @Rn */
1015 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1016 load_reg( R_EAX, Rm );
1017 load_reg( R_ECX, Rn );
1018 MEM_WRITE_BYTE( R_ECX, R_EAX );
1019 sh4_x86.tstate = TSTATE_NONE;
1023 { /* MOV.W Rm, @Rn */
1024 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1025 load_reg( R_ECX, Rn );
1027 check_walign16( R_ECX );
1028 load_reg( R_EAX, Rm );
1029 MEM_WRITE_WORD( R_ECX, R_EAX );
1030 sh4_x86.tstate = TSTATE_NONE;
1034 { /* MOV.L Rm, @Rn */
1035 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1036 load_reg( R_EAX, Rm );
1037 load_reg( R_ECX, Rn );
1039 check_walign32(R_ECX);
1040 MEM_WRITE_LONG( R_ECX, R_EAX );
1041 sh4_x86.tstate = TSTATE_NONE;
1045 { /* MOV.B Rm, @-Rn */
1046 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1047 load_reg( R_EAX, Rm );
1048 load_reg( R_ECX, Rn );
1049 ADD_imm8s_r32( -1, R_ECX );
1050 store_reg( R_ECX, Rn );
1051 MEM_WRITE_BYTE( R_ECX, R_EAX );
1052 sh4_x86.tstate = TSTATE_NONE;
1056 { /* MOV.W Rm, @-Rn */
1057 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1058 load_reg( R_ECX, Rn );
1060 check_walign16( R_ECX );
1061 load_reg( R_EAX, Rm );
1062 ADD_imm8s_r32( -2, R_ECX );
1063 store_reg( R_ECX, Rn );
1064 MEM_WRITE_WORD( R_ECX, R_EAX );
1065 sh4_x86.tstate = TSTATE_NONE;
1069 { /* MOV.L Rm, @-Rn */
1070 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1071 load_reg( R_EAX, Rm );
1072 load_reg( R_ECX, Rn );
1074 check_walign32( R_ECX );
1075 ADD_imm8s_r32( -4, R_ECX );
1076 store_reg( R_ECX, Rn );
1077 MEM_WRITE_LONG( R_ECX, R_EAX );
1078 sh4_x86.tstate = TSTATE_NONE;
1082 { /* DIV0S Rm, Rn */
1083 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1084 load_reg( R_EAX, Rm );
1085 load_reg( R_ECX, Rn );
1086 SHR_imm8_r32( 31, R_EAX );
1087 SHR_imm8_r32( 31, R_ECX );
1088 store_spreg( R_EAX, R_M );
1089 store_spreg( R_ECX, R_Q );
1090 CMP_r32_r32( R_EAX, R_ECX );
1092 sh4_x86.tstate = TSTATE_NE;
1097 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1098 load_reg( R_EAX, Rm );
1099 load_reg( R_ECX, Rn );
1100 TEST_r32_r32( R_EAX, R_ECX );
1102 sh4_x86.tstate = TSTATE_E;
1107 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1108 load_reg( R_EAX, Rm );
1109 load_reg( R_ECX, Rn );
1110 AND_r32_r32( R_EAX, R_ECX );
1111 store_reg( R_ECX, Rn );
1112 sh4_x86.tstate = TSTATE_NONE;
1117 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1118 load_reg( R_EAX, Rm );
1119 load_reg( R_ECX, Rn );
1120 XOR_r32_r32( R_EAX, R_ECX );
1121 store_reg( R_ECX, Rn );
1122 sh4_x86.tstate = TSTATE_NONE;
1127 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1128 load_reg( R_EAX, Rm );
1129 load_reg( R_ECX, Rn );
1130 OR_r32_r32( R_EAX, R_ECX );
1131 store_reg( R_ECX, Rn );
1132 sh4_x86.tstate = TSTATE_NONE;
1136 { /* CMP/STR Rm, Rn */
1137 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1138 load_reg( R_EAX, Rm );
1139 load_reg( R_ECX, Rn );
1140 XOR_r32_r32( R_ECX, R_EAX );
1141 TEST_r8_r8( R_AL, R_AL );
1142 JE_rel8(13, target1);
1143 TEST_r8_r8( R_AH, R_AH ); // 2
1144 JE_rel8(9, target2);
1145 SHR_imm8_r32( 16, R_EAX ); // 3
1146 TEST_r8_r8( R_AL, R_AL ); // 2
1147 JE_rel8(2, target3);
1148 TEST_r8_r8( R_AH, R_AH ); // 2
1149 JMP_TARGET(target1);
1150 JMP_TARGET(target2);
1151 JMP_TARGET(target3);
1153 sh4_x86.tstate = TSTATE_E;
1157 { /* XTRCT Rm, Rn */
1158 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1159 load_reg( R_EAX, Rm );
1160 load_reg( R_ECX, Rn );
1161 SHL_imm8_r32( 16, R_EAX );
1162 SHR_imm8_r32( 16, R_ECX );
1163 OR_r32_r32( R_EAX, R_ECX );
1164 store_reg( R_ECX, Rn );
1165 sh4_x86.tstate = TSTATE_NONE;
1169 { /* MULU.W Rm, Rn */
1170 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1171 load_reg16u( R_EAX, Rm );
1172 load_reg16u( R_ECX, Rn );
1174 store_spreg( R_EAX, R_MACL );
1175 sh4_x86.tstate = TSTATE_NONE;
1179 { /* MULS.W Rm, Rn */
1180 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1181 load_reg16s( R_EAX, Rm );
1182 load_reg16s( R_ECX, Rn );
1184 store_spreg( R_EAX, R_MACL );
1185 sh4_x86.tstate = TSTATE_NONE;
1196 { /* CMP/EQ Rm, Rn */
1197 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1198 load_reg( R_EAX, Rm );
1199 load_reg( R_ECX, Rn );
1200 CMP_r32_r32( R_EAX, R_ECX );
1202 sh4_x86.tstate = TSTATE_E;
1206 { /* CMP/HS Rm, Rn */
1207 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1208 load_reg( R_EAX, Rm );
1209 load_reg( R_ECX, Rn );
1210 CMP_r32_r32( R_EAX, R_ECX );
1212 sh4_x86.tstate = TSTATE_AE;
1216 { /* CMP/GE Rm, Rn */
1217 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1218 load_reg( R_EAX, Rm );
1219 load_reg( R_ECX, Rn );
1220 CMP_r32_r32( R_EAX, R_ECX );
1222 sh4_x86.tstate = TSTATE_GE;
1227 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1228 load_spreg( R_ECX, R_M );
1229 load_reg( R_EAX, Rn );
1230 if( sh4_x86.tstate != TSTATE_C ) {
1234 SETC_r8( R_DL ); // Q'
1235 CMP_sh4r_r32( R_Q, R_ECX );
1236 JE_rel8(5, mqequal);
1237 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1239 JMP_TARGET(mqequal);
1240 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1242 store_reg( R_EAX, Rn ); // Done with Rn now
1243 SETC_r8(R_AL); // tmp1
1244 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1245 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1246 store_spreg( R_ECX, R_Q );
1247 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1248 MOVZX_r8_r32( R_AL, R_EAX );
1249 store_spreg( R_EAX, R_T );
1250 sh4_x86.tstate = TSTATE_NONE;
1254 { /* DMULU.L Rm, Rn */
1255 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1256 load_reg( R_EAX, Rm );
1257 load_reg( R_ECX, Rn );
1259 store_spreg( R_EDX, R_MACH );
1260 store_spreg( R_EAX, R_MACL );
1261 sh4_x86.tstate = TSTATE_NONE;
1265 { /* CMP/HI Rm, Rn */
1266 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1267 load_reg( R_EAX, Rm );
1268 load_reg( R_ECX, Rn );
1269 CMP_r32_r32( R_EAX, R_ECX );
1271 sh4_x86.tstate = TSTATE_A;
1275 { /* CMP/GT Rm, Rn */
1276 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1277 load_reg( R_EAX, Rm );
1278 load_reg( R_ECX, Rn );
1279 CMP_r32_r32( R_EAX, R_ECX );
1281 sh4_x86.tstate = TSTATE_G;
1286 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1287 load_reg( R_EAX, Rm );
1288 load_reg( R_ECX, Rn );
1289 SUB_r32_r32( R_EAX, R_ECX );
1290 store_reg( R_ECX, Rn );
1291 sh4_x86.tstate = TSTATE_NONE;
1296 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1297 load_reg( R_EAX, Rm );
1298 load_reg( R_ECX, Rn );
1299 if( sh4_x86.tstate != TSTATE_C ) {
1302 SBB_r32_r32( R_EAX, R_ECX );
1303 store_reg( R_ECX, Rn );
1305 sh4_x86.tstate = TSTATE_C;
1310 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1311 load_reg( R_EAX, Rm );
1312 load_reg( R_ECX, Rn );
1313 SUB_r32_r32( R_EAX, R_ECX );
1314 store_reg( R_ECX, Rn );
1316 sh4_x86.tstate = TSTATE_O;
1321 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1322 load_reg( R_EAX, Rm );
1323 load_reg( R_ECX, Rn );
1324 ADD_r32_r32( R_EAX, R_ECX );
1325 store_reg( R_ECX, Rn );
1326 sh4_x86.tstate = TSTATE_NONE;
1330 { /* DMULS.L Rm, Rn */
1331 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1332 load_reg( R_EAX, Rm );
1333 load_reg( R_ECX, Rn );
1335 store_spreg( R_EDX, R_MACH );
1336 store_spreg( R_EAX, R_MACL );
1337 sh4_x86.tstate = TSTATE_NONE;
1342 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1343 if( sh4_x86.tstate != TSTATE_C ) {
1346 load_reg( R_EAX, Rm );
1347 load_reg( R_ECX, Rn );
1348 ADC_r32_r32( R_EAX, R_ECX );
1349 store_reg( R_ECX, Rn );
1351 sh4_x86.tstate = TSTATE_C;
1356 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1357 load_reg( R_EAX, Rm );
1358 load_reg( R_ECX, Rn );
1359 ADD_r32_r32( R_EAX, R_ECX );
1360 store_reg( R_ECX, Rn );
1362 sh4_x86.tstate = TSTATE_O;
1373 switch( (ir&0xF0) >> 4 ) {
1376 uint32_t Rn = ((ir>>8)&0xF);
1377 load_reg( R_EAX, Rn );
1380 store_reg( R_EAX, Rn );
1381 sh4_x86.tstate = TSTATE_C;
1386 uint32_t Rn = ((ir>>8)&0xF);
1387 load_reg( R_EAX, Rn );
1388 ADD_imm8s_r32( -1, R_EAX );
1389 store_reg( R_EAX, Rn );
1391 sh4_x86.tstate = TSTATE_E;
1396 uint32_t Rn = ((ir>>8)&0xF);
1397 load_reg( R_EAX, Rn );
1400 store_reg( R_EAX, Rn );
1401 sh4_x86.tstate = TSTATE_C;
1410 switch( (ir&0xF0) >> 4 ) {
1413 uint32_t Rn = ((ir>>8)&0xF);
1414 load_reg( R_EAX, Rn );
1417 store_reg( R_EAX, Rn );
1418 sh4_x86.tstate = TSTATE_C;
1423 uint32_t Rn = ((ir>>8)&0xF);
1424 load_reg( R_EAX, Rn );
1425 CMP_imm8s_r32( 0, R_EAX );
1427 sh4_x86.tstate = TSTATE_GE;
1432 uint32_t Rn = ((ir>>8)&0xF);
1433 load_reg( R_EAX, Rn );
1436 store_reg( R_EAX, Rn );
1437 sh4_x86.tstate = TSTATE_C;
1446 switch( (ir&0xF0) >> 4 ) {
1448 { /* STS.L MACH, @-Rn */
1449 uint32_t Rn = ((ir>>8)&0xF);
1450 load_reg( R_ECX, Rn );
1452 check_walign32( R_ECX );
1453 ADD_imm8s_r32( -4, R_ECX );
1454 store_reg( R_ECX, Rn );
1455 load_spreg( R_EAX, R_MACH );
1456 MEM_WRITE_LONG( R_ECX, R_EAX );
1457 sh4_x86.tstate = TSTATE_NONE;
1461 { /* STS.L MACL, @-Rn */
1462 uint32_t Rn = ((ir>>8)&0xF);
1463 load_reg( R_ECX, Rn );
1465 check_walign32( R_ECX );
1466 ADD_imm8s_r32( -4, R_ECX );
1467 store_reg( R_ECX, Rn );
1468 load_spreg( R_EAX, R_MACL );
1469 MEM_WRITE_LONG( R_ECX, R_EAX );
1470 sh4_x86.tstate = TSTATE_NONE;
1474 { /* STS.L PR, @-Rn */
1475 uint32_t Rn = ((ir>>8)&0xF);
1476 load_reg( R_ECX, Rn );
1478 check_walign32( R_ECX );
1479 ADD_imm8s_r32( -4, R_ECX );
1480 store_reg( R_ECX, Rn );
1481 load_spreg( R_EAX, R_PR );
1482 MEM_WRITE_LONG( R_ECX, R_EAX );
1483 sh4_x86.tstate = TSTATE_NONE;
1487 { /* STC.L SGR, @-Rn */
1488 uint32_t Rn = ((ir>>8)&0xF);
1490 check_priv_no_precheck();
1491 load_reg( R_ECX, Rn );
1492 check_walign32( R_ECX );
1493 ADD_imm8s_r32( -4, R_ECX );
1494 store_reg( R_ECX, Rn );
1495 load_spreg( R_EAX, R_SGR );
1496 MEM_WRITE_LONG( R_ECX, R_EAX );
1497 sh4_x86.tstate = TSTATE_NONE;
1501 { /* STS.L FPUL, @-Rn */
1502 uint32_t Rn = ((ir>>8)&0xF);
1503 load_reg( R_ECX, Rn );
1505 check_walign32( R_ECX );
1506 ADD_imm8s_r32( -4, R_ECX );
1507 store_reg( R_ECX, Rn );
1508 load_spreg( R_EAX, R_FPUL );
1509 MEM_WRITE_LONG( R_ECX, R_EAX );
1510 sh4_x86.tstate = TSTATE_NONE;
1514 { /* STS.L FPSCR, @-Rn */
1515 uint32_t Rn = ((ir>>8)&0xF);
1516 load_reg( R_ECX, Rn );
1518 check_walign32( R_ECX );
1519 ADD_imm8s_r32( -4, R_ECX );
1520 store_reg( R_ECX, Rn );
1521 load_spreg( R_EAX, R_FPSCR );
1522 MEM_WRITE_LONG( R_ECX, R_EAX );
1523 sh4_x86.tstate = TSTATE_NONE;
1527 { /* STC.L DBR, @-Rn */
1528 uint32_t Rn = ((ir>>8)&0xF);
1530 check_priv_no_precheck();
1531 load_reg( R_ECX, Rn );
1532 check_walign32( R_ECX );
1533 ADD_imm8s_r32( -4, R_ECX );
1534 store_reg( R_ECX, Rn );
1535 load_spreg( R_EAX, R_DBR );
1536 MEM_WRITE_LONG( R_ECX, R_EAX );
1537 sh4_x86.tstate = TSTATE_NONE;
1546 switch( (ir&0x80) >> 7 ) {
1548 switch( (ir&0x70) >> 4 ) {
1550 { /* STC.L SR, @-Rn */
1551 uint32_t Rn = ((ir>>8)&0xF);
1553 check_priv_no_precheck();
1554 call_func0( sh4_read_sr );
1555 load_reg( R_ECX, Rn );
1556 check_walign32( R_ECX );
1557 ADD_imm8s_r32( -4, R_ECX );
1558 store_reg( R_ECX, Rn );
1559 MEM_WRITE_LONG( R_ECX, R_EAX );
1560 sh4_x86.tstate = TSTATE_NONE;
1564 { /* STC.L GBR, @-Rn */
1565 uint32_t Rn = ((ir>>8)&0xF);
1566 load_reg( R_ECX, Rn );
1568 check_walign32( R_ECX );
1569 ADD_imm8s_r32( -4, R_ECX );
1570 store_reg( R_ECX, Rn );
1571 load_spreg( R_EAX, R_GBR );
1572 MEM_WRITE_LONG( R_ECX, R_EAX );
1573 sh4_x86.tstate = TSTATE_NONE;
1577 { /* STC.L VBR, @-Rn */
1578 uint32_t Rn = ((ir>>8)&0xF);
1580 check_priv_no_precheck();
1581 load_reg( R_ECX, Rn );
1582 check_walign32( R_ECX );
1583 ADD_imm8s_r32( -4, R_ECX );
1584 store_reg( R_ECX, Rn );
1585 load_spreg( R_EAX, R_VBR );
1586 MEM_WRITE_LONG( R_ECX, R_EAX );
1587 sh4_x86.tstate = TSTATE_NONE;
1591 { /* STC.L SSR, @-Rn */
1592 uint32_t Rn = ((ir>>8)&0xF);
1594 check_priv_no_precheck();
1595 load_reg( R_ECX, Rn );
1596 check_walign32( R_ECX );
1597 ADD_imm8s_r32( -4, R_ECX );
1598 store_reg( R_ECX, Rn );
1599 load_spreg( R_EAX, R_SSR );
1600 MEM_WRITE_LONG( R_ECX, R_EAX );
1601 sh4_x86.tstate = TSTATE_NONE;
1605 { /* STC.L SPC, @-Rn */
1606 uint32_t Rn = ((ir>>8)&0xF);
1608 check_priv_no_precheck();
1609 load_reg( R_ECX, Rn );
1610 check_walign32( R_ECX );
1611 ADD_imm8s_r32( -4, R_ECX );
1612 store_reg( R_ECX, Rn );
1613 load_spreg( R_EAX, R_SPC );
1614 MEM_WRITE_LONG( R_ECX, R_EAX );
1615 sh4_x86.tstate = TSTATE_NONE;
1624 { /* STC.L Rm_BANK, @-Rn */
1625 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1627 check_priv_no_precheck();
1628 load_reg( R_ECX, Rn );
1629 check_walign32( R_ECX );
1630 ADD_imm8s_r32( -4, R_ECX );
1631 store_reg( R_ECX, Rn );
1632 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1633 MEM_WRITE_LONG( R_ECX, R_EAX );
1634 sh4_x86.tstate = TSTATE_NONE;
1640 switch( (ir&0xF0) >> 4 ) {
1643 uint32_t Rn = ((ir>>8)&0xF);
1644 load_reg( R_EAX, Rn );
1646 store_reg( R_EAX, Rn );
1648 sh4_x86.tstate = TSTATE_C;
1653 uint32_t Rn = ((ir>>8)&0xF);
1654 load_reg( R_EAX, Rn );
1655 if( sh4_x86.tstate != TSTATE_C ) {
1659 store_reg( R_EAX, Rn );
1661 sh4_x86.tstate = TSTATE_C;
1670 switch( (ir&0xF0) >> 4 ) {
1673 uint32_t Rn = ((ir>>8)&0xF);
1674 load_reg( R_EAX, Rn );
1676 store_reg( R_EAX, Rn );
1678 sh4_x86.tstate = TSTATE_C;
1683 uint32_t Rn = ((ir>>8)&0xF);
1684 load_reg( R_EAX, Rn );
1685 CMP_imm8s_r32( 0, R_EAX );
1687 sh4_x86.tstate = TSTATE_G;
1692 uint32_t Rn = ((ir>>8)&0xF);
1693 load_reg( R_EAX, Rn );
1694 if( sh4_x86.tstate != TSTATE_C ) {
1698 store_reg( R_EAX, Rn );
1700 sh4_x86.tstate = TSTATE_C;
1709 switch( (ir&0xF0) >> 4 ) {
1711 { /* LDS.L @Rm+, MACH */
1712 uint32_t Rm = ((ir>>8)&0xF);
1713 load_reg( R_EAX, Rm );
1715 check_ralign32( R_EAX );
1716 MOV_r32_r32( R_EAX, R_ECX );
1717 ADD_imm8s_r32( 4, R_EAX );
1718 store_reg( R_EAX, Rm );
1719 MEM_READ_LONG( R_ECX, R_EAX );
1720 store_spreg( R_EAX, R_MACH );
1721 sh4_x86.tstate = TSTATE_NONE;
1725 { /* LDS.L @Rm+, MACL */
1726 uint32_t Rm = ((ir>>8)&0xF);
1727 load_reg( R_EAX, Rm );
1729 check_ralign32( R_EAX );
1730 MOV_r32_r32( R_EAX, R_ECX );
1731 ADD_imm8s_r32( 4, R_EAX );
1732 store_reg( R_EAX, Rm );
1733 MEM_READ_LONG( R_ECX, R_EAX );
1734 store_spreg( R_EAX, R_MACL );
1735 sh4_x86.tstate = TSTATE_NONE;
1739 { /* LDS.L @Rm+, PR */
1740 uint32_t Rm = ((ir>>8)&0xF);
1741 load_reg( R_EAX, Rm );
1743 check_ralign32( R_EAX );
1744 MOV_r32_r32( R_EAX, R_ECX );
1745 ADD_imm8s_r32( 4, R_EAX );
1746 store_reg( R_EAX, Rm );
1747 MEM_READ_LONG( R_ECX, R_EAX );
1748 store_spreg( R_EAX, R_PR );
1749 sh4_x86.tstate = TSTATE_NONE;
1753 { /* LDC.L @Rm+, SGR */
1754 uint32_t Rm = ((ir>>8)&0xF);
1756 check_priv_no_precheck();
1757 load_reg( R_EAX, Rm );
1758 check_ralign32( R_EAX );
1759 MOV_r32_r32( R_EAX, R_ECX );
1760 ADD_imm8s_r32( 4, R_EAX );
1761 store_reg( R_EAX, Rm );
1762 MEM_READ_LONG( R_ECX, R_EAX );
1763 store_spreg( R_EAX, R_SGR );
1764 sh4_x86.tstate = TSTATE_NONE;
1768 { /* LDS.L @Rm+, FPUL */
1769 uint32_t Rm = ((ir>>8)&0xF);
1770 load_reg( R_EAX, Rm );
1772 check_ralign32( R_EAX );
1773 MOV_r32_r32( R_EAX, R_ECX );
1774 ADD_imm8s_r32( 4, R_EAX );
1775 store_reg( R_EAX, Rm );
1776 MEM_READ_LONG( R_ECX, R_EAX );
1777 store_spreg( R_EAX, R_FPUL );
1778 sh4_x86.tstate = TSTATE_NONE;
1782 { /* LDS.L @Rm+, FPSCR */
1783 uint32_t Rm = ((ir>>8)&0xF);
1784 load_reg( R_EAX, Rm );
1786 check_ralign32( R_EAX );
1787 MOV_r32_r32( R_EAX, R_ECX );
1788 ADD_imm8s_r32( 4, R_EAX );
1789 store_reg( R_EAX, Rm );
1790 MEM_READ_LONG( R_ECX, R_EAX );
1791 store_spreg( R_EAX, R_FPSCR );
1792 update_fr_bank( R_EAX );
1793 sh4_x86.tstate = TSTATE_NONE;
1797 { /* LDC.L @Rm+, DBR */
1798 uint32_t Rm = ((ir>>8)&0xF);
1800 check_priv_no_precheck();
1801 load_reg( R_EAX, Rm );
1802 check_ralign32( R_EAX );
1803 MOV_r32_r32( R_EAX, R_ECX );
1804 ADD_imm8s_r32( 4, R_EAX );
1805 store_reg( R_EAX, Rm );
1806 MEM_READ_LONG( R_ECX, R_EAX );
1807 store_spreg( R_EAX, R_DBR );
1808 sh4_x86.tstate = TSTATE_NONE;
1817 switch( (ir&0x80) >> 7 ) {
1819 switch( (ir&0x70) >> 4 ) {
1821 { /* LDC.L @Rm+, SR */
1822 uint32_t Rm = ((ir>>8)&0xF);
1823 if( sh4_x86.in_delay_slot ) {
1827 check_priv_no_precheck();
1828 load_reg( R_EAX, Rm );
1829 check_ralign32( R_EAX );
1830 MOV_r32_r32( R_EAX, R_ECX );
1831 ADD_imm8s_r32( 4, R_EAX );
1832 store_reg( R_EAX, Rm );
1833 MEM_READ_LONG( R_ECX, R_EAX );
1834 call_func1( sh4_write_sr, R_EAX );
1835 sh4_x86.priv_checked = FALSE;
1836 sh4_x86.fpuen_checked = FALSE;
1837 sh4_x86.tstate = TSTATE_NONE;
1842 { /* LDC.L @Rm+, GBR */
1843 uint32_t Rm = ((ir>>8)&0xF);
1844 load_reg( R_EAX, Rm );
1846 check_ralign32( R_EAX );
1847 MOV_r32_r32( R_EAX, R_ECX );
1848 ADD_imm8s_r32( 4, R_EAX );
1849 store_reg( R_EAX, Rm );
1850 MEM_READ_LONG( R_ECX, R_EAX );
1851 store_spreg( R_EAX, R_GBR );
1852 sh4_x86.tstate = TSTATE_NONE;
1856 { /* LDC.L @Rm+, VBR */
1857 uint32_t Rm = ((ir>>8)&0xF);
1859 check_priv_no_precheck();
1860 load_reg( R_EAX, Rm );
1861 check_ralign32( R_EAX );
1862 MOV_r32_r32( R_EAX, R_ECX );
1863 ADD_imm8s_r32( 4, R_EAX );
1864 store_reg( R_EAX, Rm );
1865 MEM_READ_LONG( R_ECX, R_EAX );
1866 store_spreg( R_EAX, R_VBR );
1867 sh4_x86.tstate = TSTATE_NONE;
1871 { /* LDC.L @Rm+, SSR */
1872 uint32_t Rm = ((ir>>8)&0xF);
1874 check_priv_no_precheck();
1875 load_reg( R_EAX, Rm );
1876 check_ralign32( R_EAX );
1877 MOV_r32_r32( R_EAX, R_ECX );
1878 ADD_imm8s_r32( 4, R_EAX );
1879 store_reg( R_EAX, Rm );
1880 MEM_READ_LONG( R_ECX, R_EAX );
1881 store_spreg( R_EAX, R_SSR );
1882 sh4_x86.tstate = TSTATE_NONE;
1886 { /* LDC.L @Rm+, SPC */
1887 uint32_t Rm = ((ir>>8)&0xF);
1889 check_priv_no_precheck();
1890 load_reg( R_EAX, Rm );
1891 check_ralign32( R_EAX );
1892 MOV_r32_r32( R_EAX, R_ECX );
1893 ADD_imm8s_r32( 4, R_EAX );
1894 store_reg( R_EAX, Rm );
1895 MEM_READ_LONG( R_ECX, R_EAX );
1896 store_spreg( R_EAX, R_SPC );
1897 sh4_x86.tstate = TSTATE_NONE;
1906 { /* LDC.L @Rm+, Rn_BANK */
1907 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1909 check_priv_no_precheck();
1910 load_reg( R_EAX, Rm );
1911 check_ralign32( R_EAX );
1912 MOV_r32_r32( R_EAX, R_ECX );
1913 ADD_imm8s_r32( 4, R_EAX );
1914 store_reg( R_EAX, Rm );
1915 MEM_READ_LONG( R_ECX, R_EAX );
1916 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1917 sh4_x86.tstate = TSTATE_NONE;
1923 switch( (ir&0xF0) >> 4 ) {
1926 uint32_t Rn = ((ir>>8)&0xF);
1927 load_reg( R_EAX, Rn );
1928 SHL_imm8_r32( 2, R_EAX );
1929 store_reg( R_EAX, Rn );
1930 sh4_x86.tstate = TSTATE_NONE;
1935 uint32_t Rn = ((ir>>8)&0xF);
1936 load_reg( R_EAX, Rn );
1937 SHL_imm8_r32( 8, R_EAX );
1938 store_reg( R_EAX, Rn );
1939 sh4_x86.tstate = TSTATE_NONE;
1944 uint32_t Rn = ((ir>>8)&0xF);
1945 load_reg( R_EAX, Rn );
1946 SHL_imm8_r32( 16, R_EAX );
1947 store_reg( R_EAX, Rn );
1948 sh4_x86.tstate = TSTATE_NONE;
1957 switch( (ir&0xF0) >> 4 ) {
1960 uint32_t Rn = ((ir>>8)&0xF);
1961 load_reg( R_EAX, Rn );
1962 SHR_imm8_r32( 2, R_EAX );
1963 store_reg( R_EAX, Rn );
1964 sh4_x86.tstate = TSTATE_NONE;
1969 uint32_t Rn = ((ir>>8)&0xF);
1970 load_reg( R_EAX, Rn );
1971 SHR_imm8_r32( 8, R_EAX );
1972 store_reg( R_EAX, Rn );
1973 sh4_x86.tstate = TSTATE_NONE;
1978 uint32_t Rn = ((ir>>8)&0xF);
1979 load_reg( R_EAX, Rn );
1980 SHR_imm8_r32( 16, R_EAX );
1981 store_reg( R_EAX, Rn );
1982 sh4_x86.tstate = TSTATE_NONE;
1991 switch( (ir&0xF0) >> 4 ) {
1993 { /* LDS Rm, MACH */
1994 uint32_t Rm = ((ir>>8)&0xF);
1995 load_reg( R_EAX, Rm );
1996 store_spreg( R_EAX, R_MACH );
2000 { /* LDS Rm, MACL */
2001 uint32_t Rm = ((ir>>8)&0xF);
2002 load_reg( R_EAX, Rm );
2003 store_spreg( R_EAX, R_MACL );
2008 uint32_t Rm = ((ir>>8)&0xF);
2009 load_reg( R_EAX, Rm );
2010 store_spreg( R_EAX, R_PR );
2015 uint32_t Rm = ((ir>>8)&0xF);
2017 load_reg( R_EAX, Rm );
2018 store_spreg( R_EAX, R_SGR );
2019 sh4_x86.tstate = TSTATE_NONE;
2023 { /* LDS Rm, FPUL */
2024 uint32_t Rm = ((ir>>8)&0xF);
2025 load_reg( R_EAX, Rm );
2026 store_spreg( R_EAX, R_FPUL );
2030 { /* LDS Rm, FPSCR */
2031 uint32_t Rm = ((ir>>8)&0xF);
2032 load_reg( R_EAX, Rm );
2033 store_spreg( R_EAX, R_FPSCR );
2034 update_fr_bank( R_EAX );
2035 sh4_x86.tstate = TSTATE_NONE;
2040 uint32_t Rm = ((ir>>8)&0xF);
2042 load_reg( R_EAX, Rm );
2043 store_spreg( R_EAX, R_DBR );
2044 sh4_x86.tstate = TSTATE_NONE;
2053 switch( (ir&0xF0) >> 4 ) {
2056 uint32_t Rn = ((ir>>8)&0xF);
2057 if( sh4_x86.in_delay_slot ) {
2060 load_imm32( R_EAX, pc + 4 );
2061 store_spreg( R_EAX, R_PR );
2062 load_reg( R_ECX, Rn );
2063 store_spreg( R_ECX, REG_OFFSET(pc) );
2064 sh4_x86.in_delay_slot = TRUE;
2065 sh4_x86_translate_instruction(pc+2);
2066 exit_block_pcset(pc+2);
2067 sh4_x86.branch_taken = TRUE;
2074 uint32_t Rn = ((ir>>8)&0xF);
2075 load_reg( R_ECX, Rn );
2076 MEM_READ_BYTE( R_ECX, R_EAX );
2077 TEST_r8_r8( R_AL, R_AL );
2079 OR_imm8_r8( 0x80, R_AL );
2080 load_reg( R_ECX, Rn );
2081 MEM_WRITE_BYTE( R_ECX, R_EAX );
2082 sh4_x86.tstate = TSTATE_NONE;
2087 uint32_t Rn = ((ir>>8)&0xF);
2088 if( sh4_x86.in_delay_slot ) {
2091 load_reg( R_ECX, Rn );
2092 store_spreg( R_ECX, REG_OFFSET(pc) );
2093 sh4_x86.in_delay_slot = TRUE;
2094 sh4_x86_translate_instruction(pc+2);
2095 exit_block_pcset(pc+2);
2096 sh4_x86.branch_taken = TRUE;
2108 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2109 /* Annoyingly enough, not directly convertible */
2110 load_reg( R_EAX, Rn );
2111 load_reg( R_ECX, Rm );
2112 CMP_imm32_r32( 0, R_ECX );
2113 JGE_rel8(16, doshl);
2115 NEG_r32( R_ECX ); // 2
2116 AND_imm8_r8( 0x1F, R_CL ); // 3
2117 JE_rel8( 4, emptysar); // 2
2118 SAR_r32_CL( R_EAX ); // 2
2119 JMP_rel8(10, end); // 2
2121 JMP_TARGET(emptysar);
2122 SAR_imm8_r32(31, R_EAX ); // 3
2126 AND_imm8_r8( 0x1F, R_CL ); // 3
2127 SHL_r32_CL( R_EAX ); // 2
2130 store_reg( R_EAX, Rn );
2131 sh4_x86.tstate = TSTATE_NONE;
2136 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2137 load_reg( R_EAX, Rn );
2138 load_reg( R_ECX, Rm );
2139 CMP_imm32_r32( 0, R_ECX );
2140 JGE_rel8(15, doshl);
2142 NEG_r32( R_ECX ); // 2
2143 AND_imm8_r8( 0x1F, R_CL ); // 3
2144 JE_rel8( 4, emptyshr );
2145 SHR_r32_CL( R_EAX ); // 2
2146 JMP_rel8(9, end); // 2
2148 JMP_TARGET(emptyshr);
2149 XOR_r32_r32( R_EAX, R_EAX );
2153 AND_imm8_r8( 0x1F, R_CL ); // 3
2154 SHL_r32_CL( R_EAX ); // 2
2157 store_reg( R_EAX, Rn );
2158 sh4_x86.tstate = TSTATE_NONE;
2162 switch( (ir&0x80) >> 7 ) {
2164 switch( (ir&0x70) >> 4 ) {
2167 uint32_t Rm = ((ir>>8)&0xF);
2168 if( sh4_x86.in_delay_slot ) {
2172 load_reg( R_EAX, Rm );
2173 call_func1( sh4_write_sr, R_EAX );
2174 sh4_x86.priv_checked = FALSE;
2175 sh4_x86.fpuen_checked = FALSE;
2176 sh4_x86.tstate = TSTATE_NONE;
2182 uint32_t Rm = ((ir>>8)&0xF);
2183 load_reg( R_EAX, Rm );
2184 store_spreg( R_EAX, R_GBR );
2189 uint32_t Rm = ((ir>>8)&0xF);
2191 load_reg( R_EAX, Rm );
2192 store_spreg( R_EAX, R_VBR );
2193 sh4_x86.tstate = TSTATE_NONE;
2198 uint32_t Rm = ((ir>>8)&0xF);
2200 load_reg( R_EAX, Rm );
2201 store_spreg( R_EAX, R_SSR );
2202 sh4_x86.tstate = TSTATE_NONE;
2207 uint32_t Rm = ((ir>>8)&0xF);
2209 load_reg( R_EAX, Rm );
2210 store_spreg( R_EAX, R_SPC );
2211 sh4_x86.tstate = TSTATE_NONE;
2220 { /* LDC Rm, Rn_BANK */
2221 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2223 load_reg( R_EAX, Rm );
2224 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2225 sh4_x86.tstate = TSTATE_NONE;
2231 { /* MAC.W @Rm+, @Rn+ */
2232 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2233 load_reg( R_ECX, Rm );
2235 check_ralign16( R_ECX );
2236 load_reg( R_ECX, Rn );
2237 check_ralign16( R_ECX );
2238 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2239 MEM_READ_WORD( R_ECX, R_EAX );
2241 load_reg( R_ECX, Rm );
2242 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2243 MEM_READ_WORD( R_ECX, R_EAX );
2247 load_spreg( R_ECX, R_S );
2248 TEST_r32_r32( R_ECX, R_ECX );
2249 JE_rel8( 47, nosat );
2251 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2252 JNO_rel8( 51, end ); // 2
2253 load_imm32( R_EDX, 1 ); // 5
2254 store_spreg( R_EDX, R_MACH ); // 6
2255 JS_rel8( 13, positive ); // 2
2256 load_imm32( R_EAX, 0x80000000 );// 5
2257 store_spreg( R_EAX, R_MACL ); // 6
2258 JMP_rel8( 25, end2 ); // 2
2260 JMP_TARGET(positive);
2261 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2262 store_spreg( R_EAX, R_MACL ); // 6
2263 JMP_rel8( 12, end3); // 2
2266 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2267 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2271 sh4_x86.tstate = TSTATE_NONE;
2277 { /* MOV.L @(disp, Rm), Rn */
2278 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2279 load_reg( R_ECX, Rm );
2280 ADD_imm8s_r32( disp, R_ECX );
2282 check_ralign32( R_ECX );
2283 MEM_READ_LONG( R_ECX, R_EAX );
2284 store_reg( R_EAX, Rn );
2285 sh4_x86.tstate = TSTATE_NONE;
2291 { /* MOV.B @Rm, Rn */
2292 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2293 load_reg( R_ECX, Rm );
2294 MEM_READ_BYTE( R_ECX, R_EAX );
2295 store_reg( R_EAX, Rn );
2296 sh4_x86.tstate = TSTATE_NONE;
2300 { /* MOV.W @Rm, Rn */
2301 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2302 load_reg( R_ECX, Rm );
2304 check_ralign16( R_ECX );
2305 MEM_READ_WORD( R_ECX, R_EAX );
2306 store_reg( R_EAX, Rn );
2307 sh4_x86.tstate = TSTATE_NONE;
2311 { /* MOV.L @Rm, Rn */
2312 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2313 load_reg( R_ECX, Rm );
2315 check_ralign32( R_ECX );
2316 MEM_READ_LONG( R_ECX, R_EAX );
2317 store_reg( R_EAX, Rn );
2318 sh4_x86.tstate = TSTATE_NONE;
2323 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2324 load_reg( R_EAX, Rm );
2325 store_reg( R_EAX, Rn );
2329 { /* MOV.B @Rm+, Rn */
2330 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2331 load_reg( R_ECX, Rm );
2332 MOV_r32_r32( R_ECX, R_EAX );
2333 ADD_imm8s_r32( 1, R_EAX );
2334 store_reg( R_EAX, Rm );
2335 MEM_READ_BYTE( R_ECX, R_EAX );
2336 store_reg( R_EAX, Rn );
2337 sh4_x86.tstate = TSTATE_NONE;
2341 { /* MOV.W @Rm+, Rn */
2342 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2343 load_reg( R_EAX, Rm );
2345 check_ralign16( R_EAX );
2346 MOV_r32_r32( R_EAX, R_ECX );
2347 ADD_imm8s_r32( 2, R_EAX );
2348 store_reg( R_EAX, Rm );
2349 MEM_READ_WORD( R_ECX, R_EAX );
2350 store_reg( R_EAX, Rn );
2351 sh4_x86.tstate = TSTATE_NONE;
2355 { /* MOV.L @Rm+, Rn */
2356 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2357 load_reg( R_EAX, Rm );
2359 check_ralign32( R_EAX );
2360 MOV_r32_r32( R_EAX, R_ECX );
2361 ADD_imm8s_r32( 4, R_EAX );
2362 store_reg( R_EAX, Rm );
2363 MEM_READ_LONG( R_ECX, R_EAX );
2364 store_reg( R_EAX, Rn );
2365 sh4_x86.tstate = TSTATE_NONE;
2370 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2371 load_reg( R_EAX, Rm );
2373 store_reg( R_EAX, Rn );
2374 sh4_x86.tstate = TSTATE_NONE;
2378 { /* SWAP.B Rm, Rn */
2379 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2380 load_reg( R_EAX, Rm );
2381 XCHG_r8_r8( R_AL, R_AH );
2382 store_reg( R_EAX, Rn );
2386 { /* SWAP.W Rm, Rn */
2387 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2388 load_reg( R_EAX, Rm );
2389 MOV_r32_r32( R_EAX, R_ECX );
2390 SHL_imm8_r32( 16, R_ECX );
2391 SHR_imm8_r32( 16, R_EAX );
2392 OR_r32_r32( R_EAX, R_ECX );
2393 store_reg( R_ECX, Rn );
2394 sh4_x86.tstate = TSTATE_NONE;
2399 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2400 load_reg( R_EAX, Rm );
2401 XOR_r32_r32( R_ECX, R_ECX );
2403 SBB_r32_r32( R_EAX, R_ECX );
2404 store_reg( R_ECX, Rn );
2406 sh4_x86.tstate = TSTATE_C;
2411 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2412 load_reg( R_EAX, Rm );
2414 store_reg( R_EAX, Rn );
2415 sh4_x86.tstate = TSTATE_NONE;
2419 { /* EXTU.B Rm, Rn */
2420 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2421 load_reg( R_EAX, Rm );
2422 MOVZX_r8_r32( R_EAX, R_EAX );
2423 store_reg( R_EAX, Rn );
2427 { /* EXTU.W Rm, Rn */
2428 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2429 load_reg( R_EAX, Rm );
2430 MOVZX_r16_r32( R_EAX, R_EAX );
2431 store_reg( R_EAX, Rn );
2435 { /* EXTS.B Rm, Rn */
2436 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2437 load_reg( R_EAX, Rm );
2438 MOVSX_r8_r32( R_EAX, R_EAX );
2439 store_reg( R_EAX, Rn );
2443 { /* EXTS.W Rm, Rn */
2444 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2445 load_reg( R_EAX, Rm );
2446 MOVSX_r16_r32( R_EAX, R_EAX );
2447 store_reg( R_EAX, Rn );
2453 { /* ADD #imm, Rn */
2454 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2455 load_reg( R_EAX, Rn );
2456 ADD_imm8s_r32( imm, R_EAX );
2457 store_reg( R_EAX, Rn );
2458 sh4_x86.tstate = TSTATE_NONE;
2462 switch( (ir&0xF00) >> 8 ) {
2464 { /* MOV.B R0, @(disp, Rn) */
2465 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2466 load_reg( R_EAX, 0 );
2467 load_reg( R_ECX, Rn );
2468 ADD_imm32_r32( disp, R_ECX );
2469 MEM_WRITE_BYTE( R_ECX, R_EAX );
2470 sh4_x86.tstate = TSTATE_NONE;
2474 { /* MOV.W R0, @(disp, Rn) */
2475 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2476 load_reg( R_ECX, Rn );
2477 load_reg( R_EAX, 0 );
2478 ADD_imm32_r32( disp, R_ECX );
2480 check_walign16( R_ECX );
2481 MEM_WRITE_WORD( R_ECX, R_EAX );
2482 sh4_x86.tstate = TSTATE_NONE;
2486 { /* MOV.B @(disp, Rm), R0 */
2487 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2488 load_reg( R_ECX, Rm );
2489 ADD_imm32_r32( disp, R_ECX );
2490 MEM_READ_BYTE( R_ECX, R_EAX );
2491 store_reg( R_EAX, 0 );
2492 sh4_x86.tstate = TSTATE_NONE;
2496 { /* MOV.W @(disp, Rm), R0 */
2497 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2498 load_reg( R_ECX, Rm );
2499 ADD_imm32_r32( disp, R_ECX );
2501 check_ralign16( R_ECX );
2502 MEM_READ_WORD( R_ECX, R_EAX );
2503 store_reg( R_EAX, 0 );
2504 sh4_x86.tstate = TSTATE_NONE;
2508 { /* CMP/EQ #imm, R0 */
2509 int32_t imm = SIGNEXT8(ir&0xFF);
2510 load_reg( R_EAX, 0 );
2511 CMP_imm8s_r32(imm, R_EAX);
2513 sh4_x86.tstate = TSTATE_E;
2518 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2519 if( sh4_x86.in_delay_slot ) {
2522 JF_rel8( 29, nottaken );
2523 exit_block( disp + pc + 4, pc+2 );
2524 JMP_TARGET(nottaken);
2531 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2532 if( sh4_x86.in_delay_slot ) {
2535 JT_rel8( 29, nottaken );
2536 exit_block( disp + pc + 4, pc+2 );
2537 JMP_TARGET(nottaken);
2544 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2545 if( sh4_x86.in_delay_slot ) {
2548 sh4_x86.in_delay_slot = TRUE;
2549 if( sh4_x86.tstate == TSTATE_NONE ) {
2550 CMP_imm8s_sh4r( 1, R_T );
2551 sh4_x86.tstate = TSTATE_E;
2553 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2554 sh4_x86_translate_instruction(pc+2);
2555 exit_block( disp + pc + 4, pc+4 );
2557 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2558 sh4_x86_translate_instruction(pc+2);
2565 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2566 if( sh4_x86.in_delay_slot ) {
2569 sh4_x86.in_delay_slot = TRUE;
2570 if( sh4_x86.tstate == TSTATE_NONE ) {
2571 CMP_imm8s_sh4r( 1, R_T );
2572 sh4_x86.tstate = TSTATE_E;
2574 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2575 sh4_x86_translate_instruction(pc+2);
2576 exit_block( disp + pc + 4, pc+4 );
2578 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2579 sh4_x86_translate_instruction(pc+2);
2590 { /* MOV.W @(disp, PC), Rn */
2591 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2592 if( sh4_x86.in_delay_slot ) {
2595 load_imm32( R_ECX, pc + disp + 4 );
2596 MEM_READ_WORD( R_ECX, R_EAX );
2597 store_reg( R_EAX, Rn );
2598 sh4_x86.tstate = TSTATE_NONE;
2604 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2605 if( sh4_x86.in_delay_slot ) {
2608 sh4_x86.in_delay_slot = TRUE;
2609 sh4_x86_translate_instruction( pc + 2 );
2610 exit_block( disp + pc + 4, pc+4 );
2611 sh4_x86.branch_taken = TRUE;
2618 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2619 if( sh4_x86.in_delay_slot ) {
2622 load_imm32( R_EAX, pc + 4 );
2623 store_spreg( R_EAX, R_PR );
2624 sh4_x86.in_delay_slot = TRUE;
2625 sh4_x86_translate_instruction( pc + 2 );
2626 exit_block( disp + pc + 4, pc+4 );
2627 sh4_x86.branch_taken = TRUE;
2633 switch( (ir&0xF00) >> 8 ) {
2635 { /* MOV.B R0, @(disp, GBR) */
2636 uint32_t disp = (ir&0xFF);
2637 load_reg( R_EAX, 0 );
2638 load_spreg( R_ECX, R_GBR );
2639 ADD_imm32_r32( disp, R_ECX );
2640 MEM_WRITE_BYTE( R_ECX, R_EAX );
2641 sh4_x86.tstate = TSTATE_NONE;
2645 { /* MOV.W R0, @(disp, GBR) */
2646 uint32_t disp = (ir&0xFF)<<1;
2647 load_spreg( R_ECX, R_GBR );
2648 load_reg( R_EAX, 0 );
2649 ADD_imm32_r32( disp, R_ECX );
2651 check_walign16( R_ECX );
2652 MEM_WRITE_WORD( R_ECX, R_EAX );
2653 sh4_x86.tstate = TSTATE_NONE;
2657 { /* MOV.L R0, @(disp, GBR) */
2658 uint32_t disp = (ir&0xFF)<<2;
2659 load_spreg( R_ECX, R_GBR );
2660 load_reg( R_EAX, 0 );
2661 ADD_imm32_r32( disp, R_ECX );
2663 check_walign32( R_ECX );
2664 MEM_WRITE_LONG( R_ECX, R_EAX );
2665 sh4_x86.tstate = TSTATE_NONE;
2670 uint32_t imm = (ir&0xFF);
2671 if( sh4_x86.in_delay_slot ) {
2675 call_func0( sh4_raise_trap );
2676 ADD_imm8s_r32( 4, R_ESP );
2677 sh4_x86.tstate = TSTATE_NONE;
2678 exit_block_pcset(pc);
2679 sh4_x86.branch_taken = TRUE;
2685 { /* MOV.B @(disp, GBR), R0 */
2686 uint32_t disp = (ir&0xFF);
2687 load_spreg( R_ECX, R_GBR );
2688 ADD_imm32_r32( disp, R_ECX );
2689 MEM_READ_BYTE( R_ECX, R_EAX );
2690 store_reg( R_EAX, 0 );
2691 sh4_x86.tstate = TSTATE_NONE;
2695 { /* MOV.W @(disp, GBR), R0 */
2696 uint32_t disp = (ir&0xFF)<<1;
2697 load_spreg( R_ECX, R_GBR );
2698 ADD_imm32_r32( disp, R_ECX );
2700 check_ralign16( R_ECX );
2701 MEM_READ_WORD( R_ECX, R_EAX );
2702 store_reg( R_EAX, 0 );
2703 sh4_x86.tstate = TSTATE_NONE;
2707 { /* MOV.L @(disp, GBR), R0 */
2708 uint32_t disp = (ir&0xFF)<<2;
2709 load_spreg( R_ECX, R_GBR );
2710 ADD_imm32_r32( disp, R_ECX );
2712 check_ralign32( R_ECX );
2713 MEM_READ_LONG( R_ECX, R_EAX );
2714 store_reg( R_EAX, 0 );
2715 sh4_x86.tstate = TSTATE_NONE;
2719 { /* MOVA @(disp, PC), R0 */
2720 uint32_t disp = (ir&0xFF)<<2;
2721 if( sh4_x86.in_delay_slot ) {
2724 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2725 store_reg( R_ECX, 0 );
2730 { /* TST #imm, R0 */
2731 uint32_t imm = (ir&0xFF);
2732 load_reg( R_EAX, 0 );
2733 TEST_imm32_r32( imm, R_EAX );
2735 sh4_x86.tstate = TSTATE_E;
2739 { /* AND #imm, R0 */
2740 uint32_t imm = (ir&0xFF);
2741 load_reg( R_EAX, 0 );
2742 AND_imm32_r32(imm, R_EAX);
2743 store_reg( R_EAX, 0 );
2744 sh4_x86.tstate = TSTATE_NONE;
2748 { /* XOR #imm, R0 */
2749 uint32_t imm = (ir&0xFF);
2750 load_reg( R_EAX, 0 );
2751 XOR_imm32_r32( imm, R_EAX );
2752 store_reg( R_EAX, 0 );
2753 sh4_x86.tstate = TSTATE_NONE;
2758 uint32_t imm = (ir&0xFF);
2759 load_reg( R_EAX, 0 );
2760 OR_imm32_r32(imm, R_EAX);
2761 store_reg( R_EAX, 0 );
2762 sh4_x86.tstate = TSTATE_NONE;
2766 { /* TST.B #imm, @(R0, GBR) */
2767 uint32_t imm = (ir&0xFF);
2768 load_reg( R_EAX, 0);
2769 load_reg( R_ECX, R_GBR);
2770 ADD_r32_r32( R_EAX, R_ECX );
2771 MEM_READ_BYTE( R_ECX, R_EAX );
2772 TEST_imm8_r8( imm, R_AL );
2774 sh4_x86.tstate = TSTATE_E;
2778 { /* AND.B #imm, @(R0, GBR) */
2779 uint32_t imm = (ir&0xFF);
2780 load_reg( R_EAX, 0 );
2781 load_spreg( R_ECX, R_GBR );
2782 ADD_r32_r32( R_EAX, R_ECX );
2784 call_func0(sh4_read_byte);
2786 AND_imm32_r32(imm, R_EAX );
2787 MEM_WRITE_BYTE( R_ECX, R_EAX );
2788 sh4_x86.tstate = TSTATE_NONE;
2792 { /* XOR.B #imm, @(R0, GBR) */
2793 uint32_t imm = (ir&0xFF);
2794 load_reg( R_EAX, 0 );
2795 load_spreg( R_ECX, R_GBR );
2796 ADD_r32_r32( R_EAX, R_ECX );
2798 call_func0(sh4_read_byte);
2800 XOR_imm32_r32( imm, R_EAX );
2801 MEM_WRITE_BYTE( R_ECX, R_EAX );
2802 sh4_x86.tstate = TSTATE_NONE;
2806 { /* OR.B #imm, @(R0, GBR) */
2807 uint32_t imm = (ir&0xFF);
2808 load_reg( R_EAX, 0 );
2809 load_spreg( R_ECX, R_GBR );
2810 ADD_r32_r32( R_EAX, R_ECX );
2812 call_func0(sh4_read_byte);
2814 OR_imm32_r32(imm, R_EAX );
2815 MEM_WRITE_BYTE( R_ECX, R_EAX );
2816 sh4_x86.tstate = TSTATE_NONE;
2822 { /* MOV.L @(disp, PC), Rn */
2823 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2824 if( sh4_x86.in_delay_slot ) {
2827 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2828 char *ptr = mem_get_region(target);
2830 MOV_moff32_EAX( (uint32_t)ptr );
2832 load_imm32( R_ECX, target );
2833 MEM_READ_LONG( R_ECX, R_EAX );
2835 store_reg( R_EAX, Rn );
2836 sh4_x86.tstate = TSTATE_NONE;
2841 { /* MOV #imm, Rn */
2842 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2843 load_imm32( R_EAX, imm );
2844 store_reg( R_EAX, Rn );
2850 { /* FADD FRm, FRn */
2851 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2853 load_spreg( R_ECX, R_FPSCR );
2854 TEST_imm32_r32( FPSCR_PR, R_ECX );
2855 load_fr_bank( R_EDX );
2856 JNE_rel8(13,doubleprec);
2857 push_fr(R_EDX, FRm);
2858 push_fr(R_EDX, FRn);
2862 JMP_TARGET(doubleprec);
2863 push_dr(R_EDX, FRm);
2864 push_dr(R_EDX, FRn);
2868 sh4_x86.tstate = TSTATE_NONE;
2872 { /* FSUB FRm, FRn */
2873 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2875 load_spreg( R_ECX, R_FPSCR );
2876 TEST_imm32_r32( FPSCR_PR, R_ECX );
2877 load_fr_bank( R_EDX );
2878 JNE_rel8(13, doubleprec);
2879 push_fr(R_EDX, FRn);
2880 push_fr(R_EDX, FRm);
2884 JMP_TARGET(doubleprec);
2885 push_dr(R_EDX, FRn);
2886 push_dr(R_EDX, FRm);
2890 sh4_x86.tstate = TSTATE_NONE;
2894 { /* FMUL FRm, FRn */
2895 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2897 load_spreg( R_ECX, R_FPSCR );
2898 TEST_imm32_r32( FPSCR_PR, R_ECX );
2899 load_fr_bank( R_EDX );
2900 JNE_rel8(13, doubleprec);
2901 push_fr(R_EDX, FRm);
2902 push_fr(R_EDX, FRn);
2906 JMP_TARGET(doubleprec);
2907 push_dr(R_EDX, FRm);
2908 push_dr(R_EDX, FRn);
2912 sh4_x86.tstate = TSTATE_NONE;
2916 { /* FDIV FRm, FRn */
2917 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2919 load_spreg( R_ECX, R_FPSCR );
2920 TEST_imm32_r32( FPSCR_PR, R_ECX );
2921 load_fr_bank( R_EDX );
2922 JNE_rel8(13, doubleprec);
2923 push_fr(R_EDX, FRn);
2924 push_fr(R_EDX, FRm);
2928 JMP_TARGET(doubleprec);
2929 push_dr(R_EDX, FRn);
2930 push_dr(R_EDX, FRm);
2934 sh4_x86.tstate = TSTATE_NONE;
2938 { /* FCMP/EQ FRm, FRn */
2939 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2941 load_spreg( R_ECX, R_FPSCR );
2942 TEST_imm32_r32( FPSCR_PR, R_ECX );
2943 load_fr_bank( R_EDX );
2944 JNE_rel8(8, doubleprec);
2945 push_fr(R_EDX, FRm);
2946 push_fr(R_EDX, FRn);
2948 JMP_TARGET(doubleprec);
2949 push_dr(R_EDX, FRm);
2950 push_dr(R_EDX, FRn);
2955 sh4_x86.tstate = TSTATE_NONE;
2959 { /* FCMP/GT FRm, FRn */
2960 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2962 load_spreg( R_ECX, R_FPSCR );
2963 TEST_imm32_r32( FPSCR_PR, R_ECX );
2964 load_fr_bank( R_EDX );
2965 JNE_rel8(8, doubleprec);
2966 push_fr(R_EDX, FRm);
2967 push_fr(R_EDX, FRn);
2969 JMP_TARGET(doubleprec);
2970 push_dr(R_EDX, FRm);
2971 push_dr(R_EDX, FRn);
2976 sh4_x86.tstate = TSTATE_NONE;
2980 { /* FMOV @(R0, Rm), FRn */
2981 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2983 check_fpuen_no_precheck();
2984 load_reg( R_ECX, Rm );
2985 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
2986 check_ralign32( R_ECX );
2987 load_spreg( R_EDX, R_FPSCR );
2988 TEST_imm32_r32( FPSCR_SZ, R_EDX );
2989 JNE_rel8(19, doublesize);
2990 MEM_READ_LONG( R_ECX, R_EAX );
2991 load_fr_bank( R_EDX );
2992 store_fr( R_EDX, R_EAX, FRn );
2995 JMP_TARGET(doublesize);
2996 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
2997 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
2998 load_xf_bank( R_EDX );
2999 store_fr( R_EDX, R_EAX, FRn&0x0E );
3000 store_fr( R_EDX, R_ECX, FRn|0x01 );
3004 JMP_TARGET(doublesize);
3005 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3006 load_fr_bank( R_EDX );
3007 store_fr( R_EDX, R_EAX, FRn&0x0E );
3008 store_fr( R_EDX, R_ECX, FRn|0x01 );
3011 sh4_x86.tstate = TSTATE_NONE;
3015 { /* FMOV FRm, @(R0, Rn) */
3016 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3018 check_fpuen_no_precheck();
3019 load_reg( R_ECX, Rn );
3020 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
3021 check_walign32( R_ECX );
3022 load_spreg( R_EDX, R_FPSCR );
3023 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3024 JNE_rel8(20, doublesize);
3025 load_fr_bank( R_EDX );
3026 load_fr( R_EDX, R_EAX, FRm );
3027 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3029 JMP_rel8( 48, end );
3030 JMP_TARGET(doublesize);
3031 load_xf_bank( R_EDX );
3032 load_fr( R_EDX, R_EAX, FRm&0x0E );
3033 load_fr( R_EDX, R_EDX, FRm|0x01 );
3034 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3037 JMP_rel8( 39, end );
3038 JMP_TARGET(doublesize);
3039 load_fr_bank( R_EDX );
3040 load_fr( R_EDX, R_EAX, FRm&0x0E );
3041 load_fr( R_EDX, R_EDX, FRm|0x01 );
3042 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3045 sh4_x86.tstate = TSTATE_NONE;
3049 { /* FMOV @Rm, FRn */
3050 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3052 check_fpuen_no_precheck();
3053 load_reg( R_ECX, Rm );
3054 check_ralign32( R_ECX );
3055 load_spreg( R_EDX, R_FPSCR );
3056 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3057 JNE_rel8(19, doublesize);
3058 MEM_READ_LONG( R_ECX, R_EAX );
3059 load_fr_bank( R_EDX );
3060 store_fr( R_EDX, R_EAX, FRn );
3063 JMP_TARGET(doublesize);
3064 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3065 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3066 load_xf_bank( R_EDX );
3067 store_fr( R_EDX, R_EAX, FRn&0x0E );
3068 store_fr( R_EDX, R_ECX, FRn|0x01 );
3072 JMP_TARGET(doublesize);
3073 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3074 load_fr_bank( R_EDX );
3075 store_fr( R_EDX, R_EAX, FRn&0x0E );
3076 store_fr( R_EDX, R_ECX, FRn|0x01 );
3079 sh4_x86.tstate = TSTATE_NONE;
3083 { /* FMOV @Rm+, FRn */
3084 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3086 check_fpuen_no_precheck();
3087 load_reg( R_ECX, Rm );
3088 check_ralign32( R_ECX );
3089 MOV_r32_r32( R_ECX, R_EAX );
3090 load_spreg( R_EDX, R_FPSCR );
3091 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3092 JNE_rel8(25, doublesize);
3093 ADD_imm8s_r32( 4, R_EAX );
3094 store_reg( R_EAX, Rm );
3095 MEM_READ_LONG( R_ECX, R_EAX );
3096 load_fr_bank( R_EDX );
3097 store_fr( R_EDX, R_EAX, FRn );
3100 JMP_TARGET(doublesize);
3101 ADD_imm8s_r32( 8, R_EAX );
3102 store_reg(R_EAX, Rm);
3103 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3104 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3105 load_xf_bank( R_EDX );
3106 store_fr( R_EDX, R_EAX, FRn&0x0E );
3107 store_fr( R_EDX, R_ECX, FRn|0x01 );
3111 ADD_imm8s_r32( 8, R_EAX );
3112 store_reg(R_EAX, Rm);
3113 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3114 load_fr_bank( R_EDX );
3115 store_fr( R_EDX, R_EAX, FRn&0x0E );
3116 store_fr( R_EDX, R_ECX, FRn|0x01 );
3119 sh4_x86.tstate = TSTATE_NONE;
3123 { /* FMOV FRm, @Rn */
3124 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3126 check_fpuen_no_precheck();
3127 load_reg( R_ECX, Rn );
3128 check_walign32( R_ECX );
3129 load_spreg( R_EDX, R_FPSCR );
3130 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3131 JNE_rel8(20, doublesize);
3132 load_fr_bank( R_EDX );
3133 load_fr( R_EDX, R_EAX, FRm );
3134 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3136 JMP_rel8( 48, end );
3137 JMP_TARGET(doublesize);
3138 load_xf_bank( R_EDX );
3139 load_fr( R_EDX, R_EAX, FRm&0x0E );
3140 load_fr( R_EDX, R_EDX, FRm|0x01 );
3141 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3144 JMP_rel8( 39, end );
3145 JMP_TARGET(doublesize);
3146 load_fr_bank( R_EDX );
3147 load_fr( R_EDX, R_EAX, FRm&0x0E );
3148 load_fr( R_EDX, R_EDX, FRm|0x01 );
3149 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3152 sh4_x86.tstate = TSTATE_NONE;
3156 { /* FMOV FRm, @-Rn */
3157 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3159 check_fpuen_no_precheck();
3160 load_reg( R_ECX, Rn );
3161 check_walign32( R_ECX );
3162 load_spreg( R_EDX, R_FPSCR );
3163 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3164 JNE_rel8(26, doublesize);
3165 load_fr_bank( R_EDX );
3166 load_fr( R_EDX, R_EAX, FRm );
3167 ADD_imm8s_r32(-4,R_ECX);
3168 store_reg( R_ECX, Rn );
3169 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3171 JMP_rel8( 54, end );
3172 JMP_TARGET(doublesize);
3173 load_xf_bank( R_EDX );
3174 load_fr( R_EDX, R_EAX, FRm&0x0E );
3175 load_fr( R_EDX, R_EDX, FRm|0x01 );
3176 ADD_imm8s_r32(-8,R_ECX);
3177 store_reg( R_ECX, Rn );
3178 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3181 JMP_rel8( 45, end );
3182 JMP_TARGET(doublesize);
3183 load_fr_bank( R_EDX );
3184 load_fr( R_EDX, R_EAX, FRm&0x0E );
3185 load_fr( R_EDX, R_EDX, FRm|0x01 );
3186 ADD_imm8s_r32(-8,R_ECX);
3187 store_reg( R_ECX, Rn );
3188 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3191 sh4_x86.tstate = TSTATE_NONE;
3195 { /* FMOV FRm, FRn */
3196 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3197 /* As horrible as this looks, it's actually covering 5 separate cases:
3198 * 1. 32-bit fr-to-fr (PR=0)
3199 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3200 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3201 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3202 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3205 load_spreg( R_ECX, R_FPSCR );
3206 load_fr_bank( R_EDX );
3207 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3208 JNE_rel8(8, doublesize);
3209 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3210 store_fr( R_EDX, R_EAX, FRn );
3213 JMP_TARGET(doublesize);
3214 load_xf_bank( R_ECX );
3215 load_fr( R_ECX, R_EAX, FRm-1 );
3217 load_fr( R_ECX, R_EDX, FRm );
3218 store_fr( R_ECX, R_EAX, FRn-1 );
3219 store_fr( R_ECX, R_EDX, FRn );
3220 } else /* FRn&1 == 0 */ {
3221 load_fr( R_ECX, R_ECX, FRm );
3222 store_fr( R_EDX, R_EAX, FRn );
3223 store_fr( R_EDX, R_ECX, FRn+1 );
3226 } else /* FRm&1 == 0 */ {
3229 load_xf_bank( R_ECX );
3230 load_fr( R_EDX, R_EAX, FRm );
3231 load_fr( R_EDX, R_EDX, FRm+1 );
3232 store_fr( R_ECX, R_EAX, FRn-1 );
3233 store_fr( R_ECX, R_EDX, FRn );
3235 } else /* FRn&1 == 0 */ {
3237 load_fr( R_EDX, R_EAX, FRm );
3238 load_fr( R_EDX, R_ECX, FRm+1 );
3239 store_fr( R_EDX, R_EAX, FRn );
3240 store_fr( R_EDX, R_ECX, FRn+1 );
3244 sh4_x86.tstate = TSTATE_NONE;
3248 switch( (ir&0xF0) >> 4 ) {
3250 { /* FSTS FPUL, FRn */
3251 uint32_t FRn = ((ir>>8)&0xF);
3253 load_fr_bank( R_ECX );
3254 load_spreg( R_EAX, R_FPUL );
3255 store_fr( R_ECX, R_EAX, FRn );
3256 sh4_x86.tstate = TSTATE_NONE;
3260 { /* FLDS FRm, FPUL */
3261 uint32_t FRm = ((ir>>8)&0xF);
3263 load_fr_bank( R_ECX );
3264 load_fr( R_ECX, R_EAX, FRm );
3265 store_spreg( R_EAX, R_FPUL );
3266 sh4_x86.tstate = TSTATE_NONE;
3270 { /* FLOAT FPUL, FRn */
3271 uint32_t FRn = ((ir>>8)&0xF);
3273 load_spreg( R_ECX, R_FPSCR );
3274 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3276 TEST_imm32_r32( FPSCR_PR, R_ECX );
3277 JNE_rel8(5, doubleprec);
3278 pop_fr( R_EDX, FRn );
3280 JMP_TARGET(doubleprec);
3281 pop_dr( R_EDX, FRn );
3283 sh4_x86.tstate = TSTATE_NONE;
3287 { /* FTRC FRm, FPUL */
3288 uint32_t FRm = ((ir>>8)&0xF);
3290 load_spreg( R_ECX, R_FPSCR );
3291 load_fr_bank( R_EDX );
3292 TEST_imm32_r32( FPSCR_PR, R_ECX );
3293 JNE_rel8(5, doubleprec);
3294 push_fr( R_EDX, FRm );
3296 JMP_TARGET(doubleprec);
3297 push_dr( R_EDX, FRm );
3299 load_imm32( R_ECX, (uint32_t)&max_int );
3300 FILD_r32ind( R_ECX );
3302 JNA_rel8( 32, sat );
3303 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3304 FILD_r32ind( R_ECX ); // 2
3306 JAE_rel8( 21, sat2 ); // 2
3307 load_imm32( R_EAX, (uint32_t)&save_fcw );
3308 FNSTCW_r32ind( R_EAX );
3309 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3310 FLDCW_r32ind( R_EDX );
3311 FISTP_sh4r(R_FPUL); // 3
3312 FLDCW_r32ind( R_EAX );
3313 JMP_rel8( 9, end ); // 2
3317 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3318 store_spreg( R_ECX, R_FPUL );
3321 sh4_x86.tstate = TSTATE_NONE;
3326 uint32_t FRn = ((ir>>8)&0xF);
3328 load_spreg( R_ECX, R_FPSCR );
3329 TEST_imm32_r32( FPSCR_PR, R_ECX );
3330 load_fr_bank( R_EDX );
3331 JNE_rel8(10, doubleprec);
3332 push_fr(R_EDX, FRn);
3336 JMP_TARGET(doubleprec);
3337 push_dr(R_EDX, FRn);
3341 sh4_x86.tstate = TSTATE_NONE;
3346 uint32_t FRn = ((ir>>8)&0xF);
3348 load_spreg( R_ECX, R_FPSCR );
3349 load_fr_bank( R_EDX );
3350 TEST_imm32_r32( FPSCR_PR, R_ECX );
3351 JNE_rel8(10, doubleprec);
3352 push_fr(R_EDX, FRn); // 3
3354 pop_fr( R_EDX, FRn); //3
3355 JMP_rel8(8,end); // 2
3356 JMP_TARGET(doubleprec);
3357 push_dr(R_EDX, FRn);
3361 sh4_x86.tstate = TSTATE_NONE;
3366 uint32_t FRn = ((ir>>8)&0xF);
3368 load_spreg( R_ECX, R_FPSCR );
3369 TEST_imm32_r32( FPSCR_PR, R_ECX );
3370 load_fr_bank( R_EDX );
3371 JNE_rel8(10, doubleprec);
3372 push_fr(R_EDX, FRn);
3376 JMP_TARGET(doubleprec);
3377 push_dr(R_EDX, FRn);
3381 sh4_x86.tstate = TSTATE_NONE;
3386 uint32_t FRn = ((ir>>8)&0xF);
3388 load_spreg( R_ECX, R_FPSCR );
3389 TEST_imm32_r32( FPSCR_PR, R_ECX );
3390 load_fr_bank( R_EDX );
3391 JNE_rel8(12, end); // PR=0 only
3393 push_fr(R_EDX, FRn);
3398 sh4_x86.tstate = TSTATE_NONE;
3403 uint32_t FRn = ((ir>>8)&0xF);
3406 load_spreg( R_ECX, R_FPSCR );
3407 TEST_imm32_r32( FPSCR_PR, R_ECX );
3409 XOR_r32_r32( R_EAX, R_EAX );
3410 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3411 store_fr( R_ECX, R_EAX, FRn );
3413 sh4_x86.tstate = TSTATE_NONE;
3418 uint32_t FRn = ((ir>>8)&0xF);
3421 load_spreg( R_ECX, R_FPSCR );
3422 TEST_imm32_r32( FPSCR_PR, R_ECX );
3424 load_imm32(R_EAX, 0x3F800000);
3425 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3426 store_fr( R_ECX, R_EAX, FRn );
3428 sh4_x86.tstate = TSTATE_NONE;
3432 { /* FCNVSD FPUL, FRn */
3433 uint32_t FRn = ((ir>>8)&0xF);
3435 load_spreg( R_ECX, R_FPSCR );
3436 TEST_imm32_r32( FPSCR_PR, R_ECX );
3437 JE_rel8(9, end); // only when PR=1
3438 load_fr_bank( R_ECX );
3440 pop_dr( R_ECX, FRn );
3442 sh4_x86.tstate = TSTATE_NONE;
3446 { /* FCNVDS FRm, FPUL */
3447 uint32_t FRm = ((ir>>8)&0xF);
3449 load_spreg( R_ECX, R_FPSCR );
3450 TEST_imm32_r32( FPSCR_PR, R_ECX );
3451 JE_rel8(9, end); // only when PR=1
3452 load_fr_bank( R_ECX );
3453 push_dr( R_ECX, FRm );
3456 sh4_x86.tstate = TSTATE_NONE;
3460 { /* FIPR FVm, FVn */
3461 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3463 load_spreg( R_ECX, R_FPSCR );
3464 TEST_imm32_r32( FPSCR_PR, R_ECX );
3465 JNE_rel8(44, doubleprec);
3467 load_fr_bank( R_ECX );
3468 push_fr( R_ECX, FVm<<2 );
3469 push_fr( R_ECX, FVn<<2 );
3471 push_fr( R_ECX, (FVm<<2)+1);
3472 push_fr( R_ECX, (FVn<<2)+1);
3475 push_fr( R_ECX, (FVm<<2)+2);
3476 push_fr( R_ECX, (FVn<<2)+2);
3479 push_fr( R_ECX, (FVm<<2)+3);
3480 push_fr( R_ECX, (FVn<<2)+3);
3483 pop_fr( R_ECX, (FVn<<2)+3);
3484 JMP_TARGET(doubleprec);
3485 sh4_x86.tstate = TSTATE_NONE;
3489 switch( (ir&0x100) >> 8 ) {
3491 { /* FSCA FPUL, FRn */
3492 uint32_t FRn = ((ir>>9)&0x7)<<1;
3494 load_spreg( R_ECX, R_FPSCR );
3495 TEST_imm32_r32( FPSCR_PR, R_ECX );
3496 JNE_rel8( 21, doubleprec );
3497 load_fr_bank( R_ECX );
3498 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3499 load_spreg( R_EDX, R_FPUL );
3500 call_func2( sh4_fsca, R_EDX, R_ECX );
3501 JMP_TARGET(doubleprec);
3502 sh4_x86.tstate = TSTATE_NONE;
3506 switch( (ir&0x200) >> 9 ) {
3508 { /* FTRV XMTRX, FVn */
3509 uint32_t FVn = ((ir>>10)&0x3);
3511 load_spreg( R_ECX, R_FPSCR );
3512 TEST_imm32_r32( FPSCR_PR, R_ECX );
3513 JNE_rel8( 30, doubleprec );
3514 load_fr_bank( R_EDX ); // 3
3515 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3516 load_xf_bank( R_ECX ); // 12
3517 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3518 JMP_TARGET(doubleprec);
3519 sh4_x86.tstate = TSTATE_NONE;
3523 switch( (ir&0xC00) >> 10 ) {
3527 load_spreg( R_ECX, R_FPSCR );
3528 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3529 store_spreg( R_ECX, R_FPSCR );
3530 sh4_x86.tstate = TSTATE_NONE;
3536 load_spreg( R_ECX, R_FPSCR );
3537 XOR_imm32_r32( FPSCR_FR, R_ECX );
3538 store_spreg( R_ECX, R_FPSCR );
3539 update_fr_bank( R_ECX );
3540 sh4_x86.tstate = TSTATE_NONE;
3545 if( sh4_x86.in_delay_slot ) {
3549 JMP_exit(EXIT_ILLEGAL);
3569 { /* FMAC FR0, FRm, FRn */
3570 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3572 load_spreg( R_ECX, R_FPSCR );
3573 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3574 TEST_imm32_r32( FPSCR_PR, R_ECX );
3575 JNE_rel8(18, doubleprec);
3576 push_fr( R_EDX, 0 );
3577 push_fr( R_EDX, FRm );
3579 push_fr( R_EDX, FRn );
3581 pop_fr( R_EDX, FRn );
3583 JMP_TARGET(doubleprec);
3584 push_dr( R_EDX, 0 );
3585 push_dr( R_EDX, FRm );
3587 push_dr( R_EDX, FRn );
3589 pop_dr( R_EDX, FRn );
3591 sh4_x86.tstate = TSTATE_NONE;
3601 sh4_x86.in_delay_slot = FALSE;
.