2 * $Id: sh4x86.c,v 1.8 2007-09-12 11:41:43 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.
27 #include "sh4/sh4core.h"
28 #include "sh4/sh4trans.h"
29 #include "sh4/x86op.h"
32 #define DEFAULT_BACKPATCH_SIZE 4096
35 * Struct to manage internal translation state. This state is not saved -
36 * it is only valid between calls to sh4_translate_begin_block() and
37 * sh4_translate_end_block()
39 struct sh4_x86_state {
40 gboolean in_delay_slot;
41 gboolean priv_checked; /* true if we've already checked the cpu mode. */
42 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
44 /* Allocated memory for the (block-wide) back-patch list */
45 uint32_t **backpatch_list;
46 uint32_t backpatch_posn;
47 uint32_t backpatch_size;
50 #define EXIT_DATA_ADDR_READ 0
51 #define EXIT_DATA_ADDR_WRITE 7
52 #define EXIT_ILLEGAL 14
53 #define EXIT_SLOT_ILLEGAL 21
54 #define EXIT_FPU_DISABLED 28
55 #define EXIT_SLOT_FPU_DISABLED 35
57 static struct sh4_x86_state sh4_x86;
61 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
62 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
66 static void sh4_x86_add_backpatch( uint8_t *ptr )
68 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
69 sh4_x86.backpatch_size <<= 1;
70 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
71 assert( sh4_x86.backpatch_list != NULL );
73 sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
76 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
79 for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
80 *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
85 * Emit an instruction to load an SH4 reg into a real register
87 static inline void load_reg( int x86reg, int sh4reg )
91 OP(0x45 + (x86reg<<3));
92 OP(REG_OFFSET(r[sh4reg]));
95 static inline void load_reg16s( int x86reg, int sh4reg )
99 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
102 static inline void load_reg16u( int x86reg, int sh4reg )
106 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
110 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
111 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
113 * Emit an instruction to load an immediate value into a register
115 static inline void load_imm32( int x86reg, uint32_t value ) {
116 /* mov #value, reg */
122 * Emit an instruction to store an SH4 reg (RN)
124 void static inline store_reg( int x86reg, int sh4reg ) {
125 /* mov reg, [bp+n] */
127 OP(0x45 + (x86reg<<3));
128 OP(REG_OFFSET(r[sh4reg]));
131 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
134 * Load an FR register (single-precision floating point) into an integer x86
135 * register (eg for register-to-register moves)
137 void static inline load_fr( int bankreg, int x86reg, int frm )
139 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
143 * Store an FR register (single-precision floating point) into an integer x86
144 * register (eg for register-to-register moves)
146 void static inline store_fr( int bankreg, int x86reg, int frn )
148 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
153 * Load a pointer to the back fp back into the specified x86 register. The
154 * bankreg must have been previously loaded with FPSCR.
157 static inline void load_xf_bank( int bankreg )
159 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
160 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
161 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
165 * Push FPUL (as a 32-bit float) onto the FPU stack
167 static inline void push_fpul( )
169 OP(0xD9); OP(0x45); OP(R_FPUL);
173 * Pop FPUL (as a 32-bit float) from the FPU stack
175 static inline void pop_fpul( )
177 OP(0xD9); OP(0x5D); OP(R_FPUL);
181 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
182 * with the location of the current fp bank.
184 static inline void push_fr( int bankreg, int frm )
186 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
190 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
191 * with bankreg previously loaded with the location of the current fp bank.
193 static inline void pop_fr( int bankreg, int frm )
195 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
199 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
200 * with the location of the current fp bank.
202 static inline void push_dr( int bankreg, int frm )
204 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
207 static inline void pop_dr( int bankreg, int frm )
209 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
213 * Note: clobbers EAX to make the indirect call - this isn't usually
214 * a problem since the callee will usually clobber it anyway.
216 static inline void call_func0( void *ptr )
218 load_imm32(R_EAX, (uint32_t)ptr);
222 static inline void call_func1( void *ptr, int arg1 )
226 ADD_imm8s_r32( 4, R_ESP );
229 static inline void call_func2( void *ptr, int arg1, int arg2 )
234 ADD_imm8s_r32( 8, R_ESP );
238 * Write a double (64-bit) value into memory, with the first word in arg2a, and
239 * the second in arg2b
242 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
244 ADD_imm8s_r32( 4, addr );
247 ADD_imm8s_r32( -4, addr );
250 call_func0(sh4_write_long);
251 ADD_imm8s_r32( 8, R_ESP );
252 call_func0(sh4_write_long);
253 ADD_imm8s_r32( 8, R_ESP );
257 * Read a double (64-bit) value from memory, writing the first word into arg2a
258 * and the second into arg2b. The addr must not be in EAX
261 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
264 call_func0(sh4_read_long);
267 ADD_imm8s_r32( 4, addr );
269 call_func0(sh4_read_long);
270 ADD_imm8s_r32( 4, R_ESP );
271 MOV_r32_r32( R_EAX, arg2b );
275 /* Exception checks - Note that all exception checks will clobber EAX */
276 static void check_priv( )
278 if( !sh4_x86.priv_checked ) {
279 sh4_x86.priv_checked = TRUE;
280 load_spreg( R_EAX, R_SR );
281 AND_imm32_r32( SR_MD, R_EAX );
282 if( sh4_x86.in_delay_slot ) {
283 JE_exit( EXIT_SLOT_ILLEGAL );
285 JE_exit( EXIT_ILLEGAL );
290 static void check_fpuen( )
292 if( !sh4_x86.fpuen_checked ) {
293 sh4_x86.fpuen_checked = TRUE;
294 load_spreg( R_EAX, R_SR );
295 AND_imm32_r32( SR_FD, R_EAX );
296 if( sh4_x86.in_delay_slot ) {
297 JNE_exit(EXIT_SLOT_FPU_DISABLED);
299 JNE_exit(EXIT_FPU_DISABLED);
304 static void check_ralign16( int x86reg )
306 TEST_imm32_r32( 0x00000001, x86reg );
307 JNE_exit(EXIT_DATA_ADDR_READ);
310 static void check_walign16( int x86reg )
312 TEST_imm32_r32( 0x00000001, x86reg );
313 JNE_exit(EXIT_DATA_ADDR_WRITE);
316 static void check_ralign32( int x86reg )
318 TEST_imm32_r32( 0x00000003, x86reg );
319 JNE_exit(EXIT_DATA_ADDR_READ);
321 static void check_walign32( int x86reg )
323 TEST_imm32_r32( 0x00000003, x86reg );
324 JNE_exit(EXIT_DATA_ADDR_WRITE);
329 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
330 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
331 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
332 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
333 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
334 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
335 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
337 #define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);
338 #define SLOTILLEGAL() RAISE_EXCEPTION(EXC_SLOT_ILLEGAL); return 1
343 * Emit the 'start of block' assembly. Sets up the stack frame and save
346 void sh4_translate_begin_block()
350 load_imm32( R_EBP, (uint32_t)&sh4r );
353 XOR_r32_r32(R_ESI, R_ESI);
355 sh4_x86.in_delay_slot = FALSE;
356 sh4_x86.priv_checked = FALSE;
357 sh4_x86.fpuen_checked = FALSE;
358 sh4_x86.backpatch_posn = 0;
362 * Exit the block early (ie branch out), conditionally or otherwise
366 store_spreg( R_EDI, REG_OFFSET(pc) );
367 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
368 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
370 ADD_r32_r32( R_EAX, R_ECX );
371 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
372 load_imm32( R_EAX, 1 );
380 * Flush any open regs back to memory, restore SI/DI/, update PC, etc
382 void sh4_translate_end_block( sh4addr_t pc ) {
383 assert( !sh4_x86.in_delay_slot ); // should never stop here
384 // Normal termination - save PC, cycle count
387 uint8_t *end_ptr = xlat_output;
388 // Exception termination. Jump block for various exception codes:
389 PUSH_imm32( EXC_DATA_ADDR_READ );
390 JMP_rel8( 33, target1 );
391 PUSH_imm32( EXC_DATA_ADDR_WRITE );
392 JMP_rel8( 26, target2 );
393 PUSH_imm32( EXC_ILLEGAL );
394 JMP_rel8( 19, target3 );
395 PUSH_imm32( EXC_SLOT_ILLEGAL );
396 JMP_rel8( 12, target4 );
397 PUSH_imm32( EXC_FPU_DISABLED );
398 JMP_rel8( 5, target5 );
399 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
406 load_spreg( R_ECX, REG_OFFSET(pc) );
407 ADD_r32_r32( R_ESI, R_ECX );
408 ADD_r32_r32( R_ESI, R_ECX );
409 store_spreg( R_ECX, REG_OFFSET(pc) );
410 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
411 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
413 ADD_r32_r32( R_EAX, R_ECX );
414 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
416 load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
417 CALL_r32( R_EAX ); // 2
421 sh4_x86_do_backpatch( end_ptr );
425 * Translate a single instruction. Delayed branches are handled specially
426 * by translating both branch and delayed instruction as a single unit (as
429 * @return true if the instruction marks the end of a basic block
432 uint32_t sh4_x86_translate_instruction( uint32_t pc )
434 uint16_t ir = sh4_read_word( pc );
436 switch( (ir&0xF000) >> 12 ) {
440 switch( (ir&0x80) >> 7 ) {
442 switch( (ir&0x70) >> 4 ) {
445 uint32_t Rn = ((ir>>8)&0xF);
446 call_func0(sh4_read_sr);
447 store_reg( R_EAX, Rn );
452 uint32_t Rn = ((ir>>8)&0xF);
453 load_spreg( R_EAX, R_GBR );
454 store_reg( R_EAX, Rn );
459 uint32_t Rn = ((ir>>8)&0xF);
460 load_spreg( R_EAX, R_VBR );
461 store_reg( R_EAX, Rn );
466 uint32_t Rn = ((ir>>8)&0xF);
467 load_spreg( R_EAX, R_SSR );
468 store_reg( R_EAX, Rn );
473 uint32_t Rn = ((ir>>8)&0xF);
474 load_spreg( R_EAX, R_SPC );
475 store_reg( R_EAX, Rn );
484 { /* STC Rm_BANK, Rn */
485 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
486 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
487 store_reg( R_EAX, Rn );
493 switch( (ir&0xF0) >> 4 ) {
496 uint32_t Rn = ((ir>>8)&0xF);
497 if( sh4_x86.in_delay_slot ) {
500 load_imm32( R_EAX, pc + 4 );
501 store_spreg( R_EAX, R_PR );
502 load_reg( R_EDI, Rn );
503 ADD_r32_r32( R_EAX, R_EDI );
504 sh4_x86.in_delay_slot = TRUE;
512 uint32_t Rn = ((ir>>8)&0xF);
513 if( sh4_x86.in_delay_slot ) {
516 load_reg( R_EDI, Rn );
517 sh4_x86.in_delay_slot = TRUE;
525 uint32_t Rn = ((ir>>8)&0xF);
526 load_reg( R_EAX, Rn );
528 AND_imm32_r32( 0xFC000000, R_EAX );
529 CMP_imm32_r32( 0xE0000000, R_EAX );
531 call_func0( sh4_flush_store_queue );
533 ADD_imm8s_r32( 4, R_ESP );
538 uint32_t Rn = ((ir>>8)&0xF);
543 uint32_t Rn = ((ir>>8)&0xF);
548 uint32_t Rn = ((ir>>8)&0xF);
552 { /* MOVCA.L R0, @Rn */
553 uint32_t Rn = ((ir>>8)&0xF);
554 load_reg( R_EAX, 0 );
555 load_reg( R_ECX, Rn );
556 check_walign32( R_ECX );
557 MEM_WRITE_LONG( R_ECX, R_EAX );
566 { /* MOV.B Rm, @(R0, Rn) */
567 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
568 load_reg( R_EAX, 0 );
569 load_reg( R_ECX, Rn );
570 ADD_r32_r32( R_EAX, R_ECX );
571 load_reg( R_EAX, Rm );
572 MEM_WRITE_BYTE( R_ECX, R_EAX );
576 { /* MOV.W Rm, @(R0, Rn) */
577 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
578 load_reg( R_EAX, 0 );
579 load_reg( R_ECX, Rn );
580 ADD_r32_r32( R_EAX, R_ECX );
581 check_walign16( R_ECX );
582 load_reg( R_EAX, Rm );
583 MEM_WRITE_WORD( R_ECX, R_EAX );
587 { /* MOV.L Rm, @(R0, Rn) */
588 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
589 load_reg( R_EAX, 0 );
590 load_reg( R_ECX, Rn );
591 ADD_r32_r32( R_EAX, R_ECX );
592 check_walign32( R_ECX );
593 load_reg( R_EAX, Rm );
594 MEM_WRITE_LONG( R_ECX, R_EAX );
599 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
600 load_reg( R_EAX, Rm );
601 load_reg( R_ECX, Rn );
603 store_spreg( R_EAX, R_MACL );
607 switch( (ir&0xFF0) >> 4 ) {
622 XOR_r32_r32(R_EAX, R_EAX);
623 store_spreg( R_EAX, R_MACL );
624 store_spreg( R_EAX, R_MACH );
649 switch( (ir&0xF0) >> 4 ) {
652 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
657 XOR_r32_r32( R_EAX, R_EAX );
658 store_spreg( R_EAX, R_Q );
659 store_spreg( R_EAX, R_M );
660 store_spreg( R_EAX, R_T );
665 uint32_t Rn = ((ir>>8)&0xF);
666 load_spreg( R_EAX, R_T );
667 store_reg( R_EAX, Rn );
676 switch( (ir&0xF0) >> 4 ) {
679 uint32_t Rn = ((ir>>8)&0xF);
680 load_spreg( R_EAX, R_MACH );
681 store_reg( R_EAX, Rn );
686 uint32_t Rn = ((ir>>8)&0xF);
687 load_spreg( R_EAX, R_MACL );
688 store_reg( R_EAX, Rn );
693 uint32_t Rn = ((ir>>8)&0xF);
694 load_spreg( R_EAX, R_PR );
695 store_reg( R_EAX, Rn );
700 uint32_t Rn = ((ir>>8)&0xF);
701 load_spreg( R_EAX, R_SGR );
702 store_reg( R_EAX, Rn );
707 uint32_t Rn = ((ir>>8)&0xF);
708 load_spreg( R_EAX, R_FPUL );
709 store_reg( R_EAX, Rn );
713 { /* STS FPSCR, Rn */
714 uint32_t Rn = ((ir>>8)&0xF);
715 load_spreg( R_EAX, R_FPSCR );
716 store_reg( R_EAX, Rn );
721 uint32_t Rn = ((ir>>8)&0xF);
722 load_spreg( R_EAX, R_DBR );
723 store_reg( R_EAX, Rn );
732 switch( (ir&0xFF0) >> 4 ) {
735 if( sh4_x86.in_delay_slot ) {
738 load_spreg( R_EDI, R_PR );
739 sh4_x86.in_delay_slot = TRUE;
753 if( sh4_x86.in_delay_slot ) {
756 load_spreg( R_EDI, R_PR );
757 load_spreg( R_EAX, R_SSR );
758 call_func1( sh4_write_sr, R_EAX );
759 sh4_x86.in_delay_slot = TRUE;
760 sh4_x86.priv_checked = FALSE;
761 sh4_x86.fpuen_checked = FALSE;
773 { /* MOV.B @(R0, Rm), Rn */
774 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
775 load_reg( R_EAX, 0 );
776 load_reg( R_ECX, Rm );
777 ADD_r32_r32( R_EAX, R_ECX );
778 MEM_READ_BYTE( R_ECX, R_EAX );
779 store_reg( R_EAX, Rn );
783 { /* MOV.W @(R0, Rm), Rn */
784 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
785 load_reg( R_EAX, 0 );
786 load_reg( R_ECX, Rm );
787 ADD_r32_r32( R_EAX, R_ECX );
788 check_ralign16( R_ECX );
789 MEM_READ_WORD( R_ECX, R_EAX );
790 store_reg( R_EAX, Rn );
794 { /* MOV.L @(R0, Rm), Rn */
795 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
796 load_reg( R_EAX, 0 );
797 load_reg( R_ECX, Rm );
798 ADD_r32_r32( R_EAX, R_ECX );
799 check_ralign32( R_ECX );
800 MEM_READ_LONG( R_ECX, R_EAX );
801 store_reg( R_EAX, Rn );
805 { /* MAC.L @Rm+, @Rn+ */
806 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
815 { /* MOV.L Rm, @(disp, Rn) */
816 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
817 load_reg( R_ECX, Rn );
818 load_reg( R_EAX, Rm );
819 ADD_imm32_r32( disp, R_ECX );
820 check_walign32( R_ECX );
821 MEM_WRITE_LONG( R_ECX, R_EAX );
827 { /* MOV.B Rm, @Rn */
828 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
829 load_reg( R_EAX, Rm );
830 load_reg( R_ECX, Rn );
831 MEM_WRITE_BYTE( R_ECX, R_EAX );
835 { /* MOV.W Rm, @Rn */
836 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
837 load_reg( R_ECX, Rn );
838 check_walign16( R_ECX );
839 MEM_READ_WORD( R_ECX, R_EAX );
840 store_reg( R_EAX, Rn );
844 { /* MOV.L Rm, @Rn */
845 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
846 load_reg( R_EAX, Rm );
847 load_reg( R_ECX, Rn );
848 check_walign32(R_ECX);
849 MEM_WRITE_LONG( R_ECX, R_EAX );
853 { /* MOV.B Rm, @-Rn */
854 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
855 load_reg( R_EAX, Rm );
856 load_reg( R_ECX, Rn );
857 ADD_imm8s_r32( -1, Rn );
858 store_reg( R_ECX, Rn );
859 MEM_WRITE_BYTE( R_ECX, R_EAX );
863 { /* MOV.W Rm, @-Rn */
864 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
865 load_reg( R_ECX, Rn );
866 check_walign16( R_ECX );
867 load_reg( R_EAX, Rm );
868 ADD_imm8s_r32( -2, R_ECX );
869 MEM_WRITE_WORD( R_ECX, R_EAX );
873 { /* MOV.L Rm, @-Rn */
874 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
875 load_reg( R_EAX, Rm );
876 load_reg( R_ECX, Rn );
877 check_walign32( R_ECX );
878 ADD_imm8s_r32( -4, R_ECX );
879 store_reg( R_ECX, Rn );
880 MEM_WRITE_LONG( R_ECX, R_EAX );
885 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
886 load_reg( R_EAX, Rm );
887 load_reg( R_ECX, Rm );
888 SHR_imm8_r32( 31, R_EAX );
889 SHR_imm8_r32( 31, R_ECX );
890 store_spreg( R_EAX, R_M );
891 store_spreg( R_ECX, R_Q );
892 CMP_r32_r32( R_EAX, R_ECX );
898 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
899 load_reg( R_EAX, Rm );
900 load_reg( R_ECX, Rn );
901 TEST_r32_r32( R_EAX, R_ECX );
907 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
908 load_reg( R_EAX, Rm );
909 load_reg( R_ECX, Rn );
910 AND_r32_r32( R_EAX, R_ECX );
911 store_reg( R_ECX, Rn );
916 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
917 load_reg( R_EAX, Rm );
918 load_reg( R_ECX, Rn );
919 XOR_r32_r32( R_EAX, R_ECX );
920 store_reg( R_ECX, Rn );
925 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
926 load_reg( R_EAX, Rm );
927 load_reg( R_ECX, Rn );
928 OR_r32_r32( R_EAX, R_ECX );
929 store_reg( R_ECX, Rn );
933 { /* CMP/STR Rm, Rn */
934 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
935 load_reg( R_EAX, Rm );
936 load_reg( R_ECX, Rn );
937 XOR_r32_r32( R_ECX, R_EAX );
938 TEST_r8_r8( R_AL, R_AL );
939 JE_rel8(13, target1);
940 TEST_r8_r8( R_AH, R_AH ); // 2
942 SHR_imm8_r32( 16, R_EAX ); // 3
943 TEST_r8_r8( R_AL, R_AL ); // 2
945 TEST_r8_r8( R_AH, R_AH ); // 2
954 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
955 load_reg( R_EAX, Rm );
956 MOV_r32_r32( R_EAX, R_ECX );
957 SHR_imm8_r32( 16, R_EAX );
958 SHL_imm8_r32( 16, R_ECX );
959 OR_r32_r32( R_EAX, R_ECX );
960 store_reg( R_ECX, Rn );
964 { /* MULU.W Rm, Rn */
965 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
966 load_reg16u( R_EAX, Rm );
967 load_reg16u( R_ECX, Rn );
969 store_spreg( R_EAX, R_MACL );
973 { /* MULS.W Rm, Rn */
974 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
975 load_reg16s( R_EAX, Rm );
976 load_reg16s( R_ECX, Rn );
978 store_spreg( R_EAX, R_MACL );
989 { /* CMP/EQ Rm, Rn */
990 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
991 load_reg( R_EAX, Rm );
992 load_reg( R_ECX, Rn );
993 CMP_r32_r32( R_EAX, R_ECX );
998 { /* CMP/HS Rm, Rn */
999 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1000 load_reg( R_EAX, Rm );
1001 load_reg( R_ECX, Rn );
1002 CMP_r32_r32( R_EAX, R_ECX );
1007 { /* CMP/GE Rm, Rn */
1008 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1009 load_reg( R_EAX, Rm );
1010 load_reg( R_ECX, Rn );
1011 CMP_r32_r32( R_EAX, R_ECX );
1017 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1018 load_reg( R_ECX, Rn );
1020 RCL1_r32( R_ECX ); // OP2
1021 SETC_r32( R_EDX ); // Q
1022 load_spreg( R_EAX, R_Q );
1023 CMP_sh4r_r32( R_M, R_EAX );
1025 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
1026 JMP_rel8(3, mqnotequal);
1027 JMP_TARGET(mqequal);
1028 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
1029 JMP_TARGET(mqnotequal);
1034 { /* DMULU.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 store_spreg( R_EDX, R_MACH );
1040 store_spreg( R_EAX, R_MACL );
1044 { /* CMP/HI Rm, Rn */
1045 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1046 load_reg( R_EAX, Rm );
1047 load_reg( R_ECX, Rn );
1048 CMP_r32_r32( R_EAX, R_ECX );
1053 { /* CMP/GT Rm, Rn */
1054 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1055 load_reg( R_EAX, Rm );
1056 load_reg( R_ECX, Rn );
1057 CMP_r32_r32( R_EAX, R_ECX );
1063 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1064 load_reg( R_EAX, Rm );
1065 load_reg( R_ECX, Rn );
1066 SUB_r32_r32( R_EAX, R_ECX );
1067 store_reg( R_ECX, Rn );
1072 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1073 load_reg( R_EAX, Rm );
1074 load_reg( R_ECX, Rn );
1076 SBB_r32_r32( R_EAX, R_ECX );
1077 store_reg( R_ECX, Rn );
1082 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1083 load_reg( R_EAX, Rm );
1084 load_reg( R_ECX, Rn );
1085 SUB_r32_r32( R_EAX, R_ECX );
1086 store_reg( R_ECX, Rn );
1092 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1093 load_reg( R_EAX, Rm );
1094 load_reg( R_ECX, Rn );
1095 ADD_r32_r32( R_EAX, R_ECX );
1096 store_reg( R_ECX, Rn );
1100 { /* DMULS.L Rm, Rn */
1101 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1102 load_reg( R_EAX, Rm );
1103 load_reg( R_ECX, Rn );
1105 store_spreg( R_EDX, R_MACH );
1106 store_spreg( R_EAX, R_MACL );
1111 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1112 load_reg( R_EAX, Rm );
1113 load_reg( R_ECX, Rn );
1115 ADC_r32_r32( R_EAX, R_ECX );
1116 store_reg( R_ECX, Rn );
1122 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1123 load_reg( R_EAX, Rm );
1124 load_reg( R_ECX, Rn );
1125 ADD_r32_r32( R_EAX, R_ECX );
1126 store_reg( R_ECX, Rn );
1138 switch( (ir&0xF0) >> 4 ) {
1141 uint32_t Rn = ((ir>>8)&0xF);
1142 load_reg( R_EAX, Rn );
1144 store_reg( R_EAX, Rn );
1149 uint32_t Rn = ((ir>>8)&0xF);
1150 load_reg( R_EAX, Rn );
1151 ADD_imm8s_r32( -1, Rn );
1152 store_reg( R_EAX, Rn );
1158 uint32_t Rn = ((ir>>8)&0xF);
1159 load_reg( R_EAX, Rn );
1161 store_reg( R_EAX, Rn );
1170 switch( (ir&0xF0) >> 4 ) {
1173 uint32_t Rn = ((ir>>8)&0xF);
1174 load_reg( R_EAX, Rn );
1176 store_reg( R_EAX, Rn );
1181 uint32_t Rn = ((ir>>8)&0xF);
1182 load_reg( R_EAX, Rn );
1183 CMP_imm8s_r32( 0, R_EAX );
1189 uint32_t Rn = ((ir>>8)&0xF);
1190 load_reg( R_EAX, Rn );
1192 store_reg( R_EAX, Rn );
1201 switch( (ir&0xF0) >> 4 ) {
1203 { /* STS.L MACH, @-Rn */
1204 uint32_t Rn = ((ir>>8)&0xF);
1205 load_reg( R_ECX, Rn );
1206 ADD_imm8s_r32( -4, Rn );
1207 store_reg( R_ECX, Rn );
1208 load_spreg( R_EAX, R_MACH );
1209 MEM_WRITE_LONG( R_ECX, R_EAX );
1213 { /* STS.L MACL, @-Rn */
1214 uint32_t Rn = ((ir>>8)&0xF);
1215 load_reg( R_ECX, Rn );
1216 ADD_imm8s_r32( -4, Rn );
1217 store_reg( R_ECX, Rn );
1218 load_spreg( R_EAX, R_MACL );
1219 MEM_WRITE_LONG( R_ECX, R_EAX );
1223 { /* STS.L PR, @-Rn */
1224 uint32_t Rn = ((ir>>8)&0xF);
1225 load_reg( R_ECX, Rn );
1226 ADD_imm8s_r32( -4, Rn );
1227 store_reg( R_ECX, Rn );
1228 load_spreg( R_EAX, R_PR );
1229 MEM_WRITE_LONG( R_ECX, R_EAX );
1233 { /* STC.L SGR, @-Rn */
1234 uint32_t Rn = ((ir>>8)&0xF);
1235 load_reg( R_ECX, Rn );
1236 ADD_imm8s_r32( -4, Rn );
1237 store_reg( R_ECX, Rn );
1238 load_spreg( R_EAX, R_SGR );
1239 MEM_WRITE_LONG( R_ECX, R_EAX );
1243 { /* STS.L FPUL, @-Rn */
1244 uint32_t Rn = ((ir>>8)&0xF);
1245 load_reg( R_ECX, Rn );
1246 ADD_imm8s_r32( -4, Rn );
1247 store_reg( R_ECX, Rn );
1248 load_spreg( R_EAX, R_FPUL );
1249 MEM_WRITE_LONG( R_ECX, R_EAX );
1253 { /* STS.L FPSCR, @-Rn */
1254 uint32_t Rn = ((ir>>8)&0xF);
1255 load_reg( R_ECX, Rn );
1256 ADD_imm8s_r32( -4, Rn );
1257 store_reg( R_ECX, Rn );
1258 load_spreg( R_EAX, R_FPSCR );
1259 MEM_WRITE_LONG( R_ECX, R_EAX );
1263 { /* STC.L DBR, @-Rn */
1264 uint32_t Rn = ((ir>>8)&0xF);
1265 load_reg( R_ECX, Rn );
1266 ADD_imm8s_r32( -4, Rn );
1267 store_reg( R_ECX, Rn );
1268 load_spreg( R_EAX, R_DBR );
1269 MEM_WRITE_LONG( R_ECX, R_EAX );
1278 switch( (ir&0x80) >> 7 ) {
1280 switch( (ir&0x70) >> 4 ) {
1282 { /* STC.L SR, @-Rn */
1283 uint32_t Rn = ((ir>>8)&0xF);
1284 load_reg( R_ECX, Rn );
1285 ADD_imm8s_r32( -4, Rn );
1286 store_reg( R_ECX, Rn );
1287 call_func0( sh4_read_sr );
1288 MEM_WRITE_LONG( R_ECX, R_EAX );
1292 { /* STC.L GBR, @-Rn */
1293 uint32_t Rn = ((ir>>8)&0xF);
1294 load_reg( R_ECX, Rn );
1295 ADD_imm8s_r32( -4, Rn );
1296 store_reg( R_ECX, Rn );
1297 load_spreg( R_EAX, R_GBR );
1298 MEM_WRITE_LONG( R_ECX, R_EAX );
1302 { /* STC.L VBR, @-Rn */
1303 uint32_t Rn = ((ir>>8)&0xF);
1304 load_reg( R_ECX, Rn );
1305 ADD_imm8s_r32( -4, Rn );
1306 store_reg( R_ECX, Rn );
1307 load_spreg( R_EAX, R_VBR );
1308 MEM_WRITE_LONG( R_ECX, R_EAX );
1312 { /* STC.L SSR, @-Rn */
1313 uint32_t Rn = ((ir>>8)&0xF);
1314 load_reg( R_ECX, Rn );
1315 ADD_imm8s_r32( -4, Rn );
1316 store_reg( R_ECX, Rn );
1317 load_spreg( R_EAX, R_SSR );
1318 MEM_WRITE_LONG( R_ECX, R_EAX );
1322 { /* STC.L SPC, @-Rn */
1323 uint32_t Rn = ((ir>>8)&0xF);
1324 load_reg( R_ECX, Rn );
1325 ADD_imm8s_r32( -4, Rn );
1326 store_reg( R_ECX, Rn );
1327 load_spreg( R_EAX, R_SPC );
1328 MEM_WRITE_LONG( R_ECX, R_EAX );
1337 { /* STC.L Rm_BANK, @-Rn */
1338 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1339 load_reg( R_ECX, Rn );
1340 ADD_imm8s_r32( -4, Rn );
1341 store_reg( R_ECX, Rn );
1342 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1343 MEM_WRITE_LONG( R_ECX, R_EAX );
1349 switch( (ir&0xF0) >> 4 ) {
1352 uint32_t Rn = ((ir>>8)&0xF);
1353 load_reg( R_EAX, Rn );
1355 store_reg( R_EAX, Rn );
1361 uint32_t Rn = ((ir>>8)&0xF);
1362 load_reg( R_EAX, Rn );
1365 store_reg( R_EAX, Rn );
1375 switch( (ir&0xF0) >> 4 ) {
1378 uint32_t Rn = ((ir>>8)&0xF);
1379 load_reg( R_EAX, Rn );
1381 store_reg( R_EAX, Rn );
1387 uint32_t Rn = ((ir>>8)&0xF);
1388 load_reg( R_EAX, Rn );
1389 CMP_imm8s_r32( 0, R_EAX );
1395 uint32_t Rn = ((ir>>8)&0xF);
1396 load_reg( R_EAX, Rn );
1399 store_reg( R_EAX, Rn );
1409 switch( (ir&0xF0) >> 4 ) {
1411 { /* LDS.L @Rm+, MACH */
1412 uint32_t Rm = ((ir>>8)&0xF);
1413 load_reg( R_EAX, Rm );
1414 MOV_r32_r32( R_EAX, R_ECX );
1415 ADD_imm8s_r32( 4, R_EAX );
1416 store_reg( R_EAX, Rm );
1417 MEM_READ_LONG( R_ECX, R_EAX );
1418 store_spreg( R_EAX, R_MACH );
1422 { /* LDS.L @Rm+, MACL */
1423 uint32_t Rm = ((ir>>8)&0xF);
1424 load_reg( R_EAX, Rm );
1425 MOV_r32_r32( R_EAX, R_ECX );
1426 ADD_imm8s_r32( 4, R_EAX );
1427 store_reg( R_EAX, Rm );
1428 MEM_READ_LONG( R_ECX, R_EAX );
1429 store_spreg( R_EAX, R_MACL );
1433 { /* LDS.L @Rm+, PR */
1434 uint32_t Rm = ((ir>>8)&0xF);
1435 load_reg( R_EAX, Rm );
1436 MOV_r32_r32( R_EAX, R_ECX );
1437 ADD_imm8s_r32( 4, R_EAX );
1438 store_reg( R_EAX, Rm );
1439 MEM_READ_LONG( R_ECX, R_EAX );
1440 store_spreg( R_EAX, R_PR );
1444 { /* LDC.L @Rm+, SGR */
1445 uint32_t Rm = ((ir>>8)&0xF);
1446 load_reg( R_EAX, Rm );
1447 MOV_r32_r32( R_EAX, R_ECX );
1448 ADD_imm8s_r32( 4, R_EAX );
1449 store_reg( R_EAX, Rm );
1450 MEM_READ_LONG( R_ECX, R_EAX );
1451 store_spreg( R_EAX, R_SGR );
1455 { /* LDS.L @Rm+, FPUL */
1456 uint32_t Rm = ((ir>>8)&0xF);
1457 load_reg( R_EAX, Rm );
1458 MOV_r32_r32( R_EAX, R_ECX );
1459 ADD_imm8s_r32( 4, R_EAX );
1460 store_reg( R_EAX, Rm );
1461 MEM_READ_LONG( R_ECX, R_EAX );
1462 store_spreg( R_EAX, R_FPUL );
1466 { /* LDS.L @Rm+, FPSCR */
1467 uint32_t Rm = ((ir>>8)&0xF);
1468 load_reg( R_EAX, Rm );
1469 MOV_r32_r32( R_EAX, R_ECX );
1470 ADD_imm8s_r32( 4, R_EAX );
1471 store_reg( R_EAX, Rm );
1472 MEM_READ_LONG( R_ECX, R_EAX );
1473 store_spreg( R_EAX, R_FPSCR );
1477 { /* LDC.L @Rm+, DBR */
1478 uint32_t Rm = ((ir>>8)&0xF);
1479 load_reg( R_EAX, Rm );
1480 MOV_r32_r32( R_EAX, R_ECX );
1481 ADD_imm8s_r32( 4, R_EAX );
1482 store_reg( R_EAX, Rm );
1483 MEM_READ_LONG( R_ECX, R_EAX );
1484 store_spreg( R_EAX, R_DBR );
1493 switch( (ir&0x80) >> 7 ) {
1495 switch( (ir&0x70) >> 4 ) {
1497 { /* LDC.L @Rm+, SR */
1498 uint32_t Rm = ((ir>>8)&0xF);
1499 load_reg( R_EAX, Rm );
1500 MOV_r32_r32( R_EAX, R_ECX );
1501 ADD_imm8s_r32( 4, R_EAX );
1502 store_reg( R_EAX, Rm );
1503 MEM_READ_LONG( R_ECX, R_EAX );
1504 call_func1( sh4_write_sr, R_EAX );
1505 sh4_x86.priv_checked = FALSE;
1506 sh4_x86.fpuen_checked = FALSE;
1510 { /* LDC.L @Rm+, GBR */
1511 uint32_t Rm = ((ir>>8)&0xF);
1512 load_reg( R_EAX, Rm );
1513 MOV_r32_r32( R_EAX, R_ECX );
1514 ADD_imm8s_r32( 4, R_EAX );
1515 store_reg( R_EAX, Rm );
1516 MEM_READ_LONG( R_ECX, R_EAX );
1517 store_spreg( R_EAX, R_GBR );
1521 { /* LDC.L @Rm+, VBR */
1522 uint32_t Rm = ((ir>>8)&0xF);
1523 load_reg( R_EAX, Rm );
1524 MOV_r32_r32( R_EAX, R_ECX );
1525 ADD_imm8s_r32( 4, R_EAX );
1526 store_reg( R_EAX, Rm );
1527 MEM_READ_LONG( R_ECX, R_EAX );
1528 store_spreg( R_EAX, R_VBR );
1532 { /* LDC.L @Rm+, SSR */
1533 uint32_t Rm = ((ir>>8)&0xF);
1534 load_reg( R_EAX, Rm );
1535 MOV_r32_r32( R_EAX, R_ECX );
1536 ADD_imm8s_r32( 4, R_EAX );
1537 store_reg( R_EAX, Rm );
1538 MEM_READ_LONG( R_ECX, R_EAX );
1539 store_spreg( R_EAX, R_SSR );
1543 { /* LDC.L @Rm+, SPC */
1544 uint32_t Rm = ((ir>>8)&0xF);
1545 load_reg( R_EAX, Rm );
1546 MOV_r32_r32( R_EAX, R_ECX );
1547 ADD_imm8s_r32( 4, R_EAX );
1548 store_reg( R_EAX, Rm );
1549 MEM_READ_LONG( R_ECX, R_EAX );
1550 store_spreg( R_EAX, R_SPC );
1559 { /* LDC.L @Rm+, Rn_BANK */
1560 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1561 load_reg( R_EAX, Rm );
1562 MOV_r32_r32( R_EAX, R_ECX );
1563 ADD_imm8s_r32( 4, R_EAX );
1564 store_reg( R_EAX, Rm );
1565 MEM_READ_LONG( R_ECX, R_EAX );
1566 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1572 switch( (ir&0xF0) >> 4 ) {
1575 uint32_t Rn = ((ir>>8)&0xF);
1576 load_reg( R_EAX, Rn );
1577 SHL_imm8_r32( 2, R_EAX );
1578 store_reg( R_EAX, Rn );
1583 uint32_t Rn = ((ir>>8)&0xF);
1584 load_reg( R_EAX, Rn );
1585 SHL_imm8_r32( 8, R_EAX );
1586 store_reg( R_EAX, Rn );
1591 uint32_t Rn = ((ir>>8)&0xF);
1592 load_reg( R_EAX, Rn );
1593 SHL_imm8_r32( 16, R_EAX );
1594 store_reg( R_EAX, Rn );
1603 switch( (ir&0xF0) >> 4 ) {
1606 uint32_t Rn = ((ir>>8)&0xF);
1607 load_reg( R_EAX, Rn );
1608 SHR_imm8_r32( 2, R_EAX );
1609 store_reg( R_EAX, Rn );
1614 uint32_t Rn = ((ir>>8)&0xF);
1615 load_reg( R_EAX, Rn );
1616 SHR_imm8_r32( 8, R_EAX );
1617 store_reg( R_EAX, Rn );
1622 uint32_t Rn = ((ir>>8)&0xF);
1623 load_reg( R_EAX, Rn );
1624 SHR_imm8_r32( 16, R_EAX );
1625 store_reg( R_EAX, Rn );
1634 switch( (ir&0xF0) >> 4 ) {
1636 { /* LDS Rm, MACH */
1637 uint32_t Rm = ((ir>>8)&0xF);
1638 load_reg( R_EAX, Rm );
1639 store_spreg( R_EAX, R_MACH );
1643 { /* LDS Rm, MACL */
1644 uint32_t Rm = ((ir>>8)&0xF);
1645 load_reg( R_EAX, Rm );
1646 store_spreg( R_EAX, R_MACL );
1651 uint32_t Rm = ((ir>>8)&0xF);
1652 load_reg( R_EAX, Rm );
1653 store_spreg( R_EAX, R_PR );
1658 uint32_t Rm = ((ir>>8)&0xF);
1659 load_reg( R_EAX, Rm );
1660 store_spreg( R_EAX, R_SGR );
1664 { /* LDS Rm, FPUL */
1665 uint32_t Rm = ((ir>>8)&0xF);
1666 load_reg( R_EAX, Rm );
1667 store_spreg( R_EAX, R_FPUL );
1671 { /* LDS Rm, FPSCR */
1672 uint32_t Rm = ((ir>>8)&0xF);
1673 load_reg( R_EAX, Rm );
1674 store_spreg( R_EAX, R_FPSCR );
1679 uint32_t Rm = ((ir>>8)&0xF);
1680 load_reg( R_EAX, Rm );
1681 store_spreg( R_EAX, R_DBR );
1690 switch( (ir&0xF0) >> 4 ) {
1693 uint32_t Rn = ((ir>>8)&0xF);
1694 if( sh4_x86.in_delay_slot ) {
1697 load_imm32( R_EAX, pc + 4 );
1698 store_spreg( R_EAX, R_PR );
1699 load_reg( R_EDI, Rn );
1700 sh4_x86.in_delay_slot = TRUE;
1708 uint32_t Rn = ((ir>>8)&0xF);
1709 load_reg( R_ECX, Rn );
1710 MEM_READ_BYTE( R_ECX, R_EAX );
1711 TEST_r8_r8( R_AL, R_AL );
1713 OR_imm8_r8( 0x80, R_AL );
1714 MEM_WRITE_BYTE( R_ECX, R_EAX );
1719 uint32_t Rn = ((ir>>8)&0xF);
1720 if( sh4_x86.in_delay_slot ) {
1723 load_reg( R_EDI, Rn );
1724 sh4_x86.in_delay_slot = TRUE;
1737 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1738 /* Annoyingly enough, not directly convertible */
1739 load_reg( R_EAX, Rn );
1740 load_reg( R_ECX, Rm );
1741 CMP_imm32_r32( 0, R_ECX );
1744 NEG_r32( R_ECX ); // 2
1745 AND_imm8_r8( 0x1F, R_CL ); // 3
1746 SAR_r32_CL( R_EAX ); // 2
1747 JMP_rel8(5, end); // 2
1749 AND_imm8_r8( 0x1F, R_CL ); // 3
1750 SHL_r32_CL( R_EAX ); // 2
1752 store_reg( R_EAX, Rn );
1757 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1758 load_reg( R_EAX, Rn );
1759 load_reg( R_ECX, Rm );
1761 MOV_r32_r32( R_EAX, R_EDX );
1762 SHL_r32_CL( R_EAX );
1764 SHR_r32_CL( R_EDX );
1765 CMP_imm8s_r32( 0, R_ECX );
1766 CMOVAE_r32_r32( R_EDX, R_EAX );
1767 store_reg( R_EAX, Rn );
1771 switch( (ir&0x80) >> 7 ) {
1773 switch( (ir&0x70) >> 4 ) {
1776 uint32_t Rm = ((ir>>8)&0xF);
1777 load_reg( R_EAX, Rm );
1778 call_func1( sh4_write_sr, R_EAX );
1779 sh4_x86.priv_checked = FALSE;
1780 sh4_x86.fpuen_checked = FALSE;
1785 uint32_t Rm = ((ir>>8)&0xF);
1786 load_reg( R_EAX, Rm );
1787 store_spreg( R_EAX, R_GBR );
1792 uint32_t Rm = ((ir>>8)&0xF);
1793 load_reg( R_EAX, Rm );
1794 store_spreg( R_EAX, R_VBR );
1799 uint32_t Rm = ((ir>>8)&0xF);
1800 load_reg( R_EAX, Rm );
1801 store_spreg( R_EAX, R_SSR );
1806 uint32_t Rm = ((ir>>8)&0xF);
1807 load_reg( R_EAX, Rm );
1808 store_spreg( R_EAX, R_SPC );
1817 { /* LDC Rm, Rn_BANK */
1818 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1819 load_reg( R_EAX, Rm );
1820 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1826 { /* MAC.W @Rm+, @Rn+ */
1827 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1833 { /* MOV.L @(disp, Rm), Rn */
1834 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1835 load_reg( R_ECX, Rm );
1836 ADD_imm8s_r32( disp, R_ECX );
1837 check_ralign32( R_ECX );
1838 MEM_READ_LONG( R_ECX, R_EAX );
1839 store_reg( R_EAX, Rn );
1845 { /* MOV.B @Rm, Rn */
1846 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1847 load_reg( R_ECX, Rm );
1848 MEM_READ_BYTE( R_ECX, R_EAX );
1849 store_reg( R_ECX, Rn );
1853 { /* MOV.W @Rm, Rn */
1854 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1855 load_reg( R_ECX, Rm );
1856 check_ralign16( R_ECX );
1857 MEM_READ_WORD( R_ECX, R_EAX );
1858 store_reg( R_EAX, Rn );
1862 { /* MOV.L @Rm, Rn */
1863 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1864 load_reg( R_ECX, Rm );
1865 check_ralign32( R_ECX );
1866 MEM_READ_LONG( R_ECX, R_EAX );
1867 store_reg( R_EAX, Rn );
1872 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1873 load_reg( R_EAX, Rm );
1874 store_reg( R_EAX, Rn );
1878 { /* MOV.B @Rm+, Rn */
1879 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1880 load_reg( R_ECX, Rm );
1881 MOV_r32_r32( R_ECX, R_EAX );
1882 ADD_imm8s_r32( 1, R_EAX );
1883 store_reg( R_EAX, Rm );
1884 MEM_READ_BYTE( R_ECX, R_EAX );
1885 store_reg( R_EAX, Rn );
1889 { /* MOV.W @Rm+, Rn */
1890 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1891 load_reg( R_EAX, Rm );
1892 check_ralign16( R_EAX );
1893 MOV_r32_r32( R_EAX, R_ECX );
1894 ADD_imm8s_r32( 2, R_EAX );
1895 store_reg( R_EAX, Rm );
1896 MEM_READ_WORD( R_ECX, R_EAX );
1897 store_reg( R_EAX, Rn );
1901 { /* MOV.L @Rm+, Rn */
1902 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1903 load_reg( R_EAX, Rm );
1904 check_ralign32( R_ECX );
1905 MOV_r32_r32( R_EAX, R_ECX );
1906 ADD_imm8s_r32( 4, R_EAX );
1907 store_reg( R_EAX, Rm );
1908 MEM_READ_LONG( R_ECX, R_EAX );
1909 store_reg( R_EAX, Rn );
1914 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1915 load_reg( R_EAX, Rm );
1917 store_reg( R_EAX, Rn );
1921 { /* SWAP.B Rm, Rn */
1922 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1923 load_reg( R_EAX, Rm );
1924 XCHG_r8_r8( R_AL, R_AH );
1925 store_reg( R_EAX, Rn );
1929 { /* SWAP.W Rm, Rn */
1930 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1931 load_reg( R_EAX, Rm );
1932 MOV_r32_r32( R_EAX, R_ECX );
1933 SHL_imm8_r32( 16, R_ECX );
1934 SHR_imm8_r32( 16, R_EAX );
1935 OR_r32_r32( R_EAX, R_ECX );
1936 store_reg( R_ECX, Rn );
1941 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1942 load_reg( R_EAX, Rm );
1943 XOR_r32_r32( R_ECX, R_ECX );
1945 SBB_r32_r32( R_EAX, R_ECX );
1946 store_reg( R_ECX, Rn );
1952 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1953 load_reg( R_EAX, Rm );
1955 store_reg( R_EAX, Rn );
1959 { /* EXTU.B Rm, Rn */
1960 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1961 load_reg( R_EAX, Rm );
1962 MOVZX_r8_r32( R_EAX, R_EAX );
1963 store_reg( R_EAX, Rn );
1967 { /* EXTU.W Rm, Rn */
1968 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1969 load_reg( R_EAX, Rm );
1970 MOVZX_r16_r32( R_EAX, R_EAX );
1971 store_reg( R_EAX, Rn );
1975 { /* EXTS.B Rm, Rn */
1976 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1977 load_reg( R_EAX, Rm );
1978 MOVSX_r8_r32( R_EAX, R_EAX );
1979 store_reg( R_EAX, Rn );
1983 { /* EXTS.W Rm, Rn */
1984 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1985 load_reg( R_EAX, Rm );
1986 MOVSX_r16_r32( R_EAX, R_EAX );
1987 store_reg( R_EAX, Rn );
1993 { /* ADD #imm, Rn */
1994 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1995 load_reg( R_EAX, Rn );
1996 ADD_imm8s_r32( imm, R_EAX );
1997 store_reg( R_EAX, Rn );
2001 switch( (ir&0xF00) >> 8 ) {
2003 { /* MOV.B R0, @(disp, Rn) */
2004 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2005 load_reg( R_EAX, 0 );
2006 load_reg( R_ECX, Rn );
2007 ADD_imm32_r32( disp, R_ECX );
2008 MEM_WRITE_BYTE( R_ECX, R_EAX );
2012 { /* MOV.W R0, @(disp, Rn) */
2013 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2014 load_reg( R_ECX, Rn );
2015 load_reg( R_EAX, 0 );
2016 ADD_imm32_r32( disp, R_ECX );
2017 check_walign16( R_ECX );
2018 MEM_WRITE_WORD( R_ECX, R_EAX );
2022 { /* MOV.B @(disp, Rm), R0 */
2023 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2024 load_reg( R_ECX, Rm );
2025 ADD_imm32_r32( disp, R_ECX );
2026 MEM_READ_BYTE( R_ECX, R_EAX );
2027 store_reg( R_EAX, 0 );
2031 { /* MOV.W @(disp, Rm), R0 */
2032 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2033 load_reg( R_ECX, Rm );
2034 ADD_imm32_r32( disp, R_ECX );
2035 check_ralign16( R_ECX );
2036 MEM_READ_WORD( R_ECX, R_EAX );
2037 store_reg( R_EAX, 0 );
2041 { /* CMP/EQ #imm, R0 */
2042 int32_t imm = SIGNEXT8(ir&0xFF);
2043 load_reg( R_EAX, 0 );
2044 CMP_imm8s_r32(imm, R_EAX);
2050 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2051 if( sh4_x86.in_delay_slot ) {
2054 load_imm32( R_EDI, pc + 2 );
2055 CMP_imm8s_sh4r( 0, R_T );
2056 JE_rel8( 5, nottaken );
2057 load_imm32( R_EDI, disp + pc + 4 );
2058 JMP_TARGET(nottaken);
2066 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2067 if( sh4_x86.in_delay_slot ) {
2070 load_imm32( R_EDI, pc + 2 );
2071 CMP_imm8s_sh4r( 0, R_T );
2072 JNE_rel8( 5, nottaken );
2073 load_imm32( R_EDI, disp + pc + 4 );
2074 JMP_TARGET(nottaken);
2082 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2083 if( sh4_x86.in_delay_slot ) {
2086 load_imm32( R_EDI, pc + 2 );
2087 CMP_imm8s_sh4r( 0, R_T );
2088 JE_rel8( 5, nottaken );
2089 load_imm32( R_EDI, disp + pc + 4 );
2090 JMP_TARGET(nottaken);
2091 sh4_x86.in_delay_slot = TRUE;
2099 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2100 if( sh4_x86.in_delay_slot ) {
2103 load_imm32( R_EDI, pc + 2 );
2104 CMP_imm8s_sh4r( 0, R_T );
2105 JNE_rel8( 5, nottaken );
2106 load_imm32( R_EDI, disp + pc + 4 );
2107 JMP_TARGET(nottaken);
2108 sh4_x86.in_delay_slot = TRUE;
2120 { /* MOV.W @(disp, PC), Rn */
2121 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2122 if( sh4_x86.in_delay_slot ) {
2125 load_imm32( R_ECX, pc + disp + 4 );
2126 MEM_READ_WORD( R_ECX, R_EAX );
2127 store_reg( R_EAX, Rn );
2133 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2134 if( sh4_x86.in_delay_slot ) {
2137 load_imm32( R_EDI, disp + pc + 4 );
2138 sh4_x86.in_delay_slot = TRUE;
2146 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2147 if( sh4_x86.in_delay_slot ) {
2150 load_imm32( R_EAX, pc + 4 );
2151 store_spreg( R_EAX, R_PR );
2152 load_imm32( R_EDI, disp + pc + 4 );
2153 sh4_x86.in_delay_slot = TRUE;
2160 switch( (ir&0xF00) >> 8 ) {
2162 { /* MOV.B R0, @(disp, GBR) */
2163 uint32_t disp = (ir&0xFF);
2164 load_reg( R_EAX, 0 );
2165 load_spreg( R_ECX, R_GBR );
2166 ADD_imm32_r32( disp, R_ECX );
2167 MEM_WRITE_BYTE( R_ECX, R_EAX );
2171 { /* MOV.W R0, @(disp, GBR) */
2172 uint32_t disp = (ir&0xFF)<<1;
2173 load_spreg( R_ECX, R_GBR );
2174 load_reg( R_EAX, 0 );
2175 ADD_imm32_r32( disp, R_ECX );
2176 check_walign16( R_ECX );
2177 MEM_WRITE_WORD( R_ECX, R_EAX );
2181 { /* MOV.L R0, @(disp, GBR) */
2182 uint32_t disp = (ir&0xFF)<<2;
2183 load_spreg( R_ECX, R_GBR );
2184 load_reg( R_EAX, 0 );
2185 ADD_imm32_r32( disp, R_ECX );
2186 check_walign32( R_ECX );
2187 MEM_WRITE_LONG( R_ECX, R_EAX );
2192 uint32_t imm = (ir&0xFF);
2193 if( sh4_x86.in_delay_slot ) {
2197 RAISE_EXCEPTION(EXC_TRAP);
2202 { /* MOV.B @(disp, GBR), R0 */
2203 uint32_t disp = (ir&0xFF);
2204 load_spreg( R_ECX, R_GBR );
2205 ADD_imm32_r32( disp, R_ECX );
2206 MEM_READ_BYTE( R_ECX, R_EAX );
2207 store_reg( R_EAX, 0 );
2211 { /* MOV.W @(disp, GBR), R0 */
2212 uint32_t disp = (ir&0xFF)<<1;
2213 load_spreg( R_ECX, R_GBR );
2214 ADD_imm32_r32( disp, R_ECX );
2215 check_ralign16( R_ECX );
2216 MEM_READ_WORD( R_ECX, R_EAX );
2217 store_reg( R_EAX, 0 );
2221 { /* MOV.L @(disp, GBR), R0 */
2222 uint32_t disp = (ir&0xFF)<<2;
2223 load_spreg( R_ECX, R_GBR );
2224 ADD_imm32_r32( disp, R_ECX );
2225 check_ralign32( R_ECX );
2226 MEM_READ_LONG( R_ECX, R_EAX );
2227 store_reg( R_EAX, 0 );
2231 { /* MOVA @(disp, PC), R0 */
2232 uint32_t disp = (ir&0xFF)<<2;
2233 if( sh4_x86.in_delay_slot ) {
2236 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2237 store_reg( R_ECX, 0 );
2242 { /* TST #imm, R0 */
2243 uint32_t imm = (ir&0xFF);
2244 load_reg( R_EAX, 0 );
2245 TEST_imm32_r32( imm, R_EAX );
2250 { /* AND #imm, R0 */
2251 uint32_t imm = (ir&0xFF);
2252 load_reg( R_EAX, 0 );
2253 AND_imm32_r32(imm, R_EAX);
2254 store_reg( R_EAX, 0 );
2258 { /* XOR #imm, R0 */
2259 uint32_t imm = (ir&0xFF);
2260 load_reg( R_EAX, 0 );
2261 XOR_imm32_r32( imm, R_EAX );
2262 store_reg( R_EAX, 0 );
2267 uint32_t imm = (ir&0xFF);
2268 load_reg( R_EAX, 0 );
2269 OR_imm32_r32(imm, R_EAX);
2270 store_reg( R_EAX, 0 );
2274 { /* TST.B #imm, @(R0, GBR) */
2275 uint32_t imm = (ir&0xFF);
2276 load_reg( R_EAX, 0);
2277 load_reg( R_ECX, R_GBR);
2278 ADD_r32_r32( R_EAX, R_ECX );
2279 MEM_READ_BYTE( R_ECX, R_EAX );
2280 TEST_imm8_r8( imm, R_EAX );
2285 { /* AND.B #imm, @(R0, GBR) */
2286 uint32_t imm = (ir&0xFF);
2287 load_reg( R_EAX, 0 );
2288 load_spreg( R_ECX, R_GBR );
2289 ADD_r32_r32( R_EAX, R_ECX );
2290 MEM_READ_BYTE( R_ECX, R_EAX );
2291 AND_imm32_r32(imm, R_ECX );
2292 MEM_WRITE_BYTE( R_ECX, R_EAX );
2296 { /* XOR.B #imm, @(R0, GBR) */
2297 uint32_t imm = (ir&0xFF);
2298 load_reg( R_EAX, 0 );
2299 load_spreg( R_ECX, R_GBR );
2300 ADD_r32_r32( R_EAX, R_ECX );
2301 MEM_READ_BYTE( R_ECX, R_EAX );
2302 XOR_imm32_r32( imm, R_EAX );
2303 MEM_WRITE_BYTE( R_ECX, R_EAX );
2307 { /* OR.B #imm, @(R0, GBR) */
2308 uint32_t imm = (ir&0xFF);
2309 load_reg( R_EAX, 0 );
2310 load_spreg( R_ECX, R_GBR );
2311 ADD_r32_r32( R_EAX, R_ECX );
2312 MEM_READ_BYTE( R_ECX, R_EAX );
2313 OR_imm32_r32(imm, R_ECX );
2314 MEM_WRITE_BYTE( R_ECX, R_EAX );
2320 { /* MOV.L @(disp, PC), Rn */
2321 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2322 if( sh4_x86.in_delay_slot ) {
2325 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2326 MEM_READ_LONG( R_ECX, R_EAX );
2327 store_reg( R_EAX, 0 );
2332 { /* MOV #imm, Rn */
2333 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2334 load_imm32( R_EAX, imm );
2335 store_reg( R_EAX, Rn );
2341 { /* FADD FRm, FRn */
2342 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2344 load_spreg( R_ECX, R_FPSCR );
2345 TEST_imm32_r32( FPSCR_PR, R_ECX );
2346 load_fr_bank( R_EDX );
2347 JNE_rel8(13,doubleprec);
2348 push_fr(R_EDX, FRm);
2349 push_fr(R_EDX, FRn);
2353 JMP_TARGET(doubleprec);
2354 push_dr(R_EDX, FRm);
2355 push_dr(R_EDX, FRn);
2362 { /* FSUB FRm, FRn */
2363 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2365 load_spreg( R_ECX, R_FPSCR );
2366 TEST_imm32_r32( FPSCR_PR, R_ECX );
2367 load_fr_bank( R_EDX );
2368 JNE_rel8(13, doubleprec);
2369 push_fr(R_EDX, FRn);
2370 push_fr(R_EDX, FRm);
2374 JMP_TARGET(doubleprec);
2375 push_dr(R_EDX, FRn);
2376 push_dr(R_EDX, FRm);
2383 { /* FMUL FRm, FRn */
2384 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2386 load_spreg( R_ECX, R_FPSCR );
2387 TEST_imm32_r32( FPSCR_PR, R_ECX );
2388 load_fr_bank( R_EDX );
2389 JNE_rel8(13, doubleprec);
2390 push_fr(R_EDX, FRm);
2391 push_fr(R_EDX, FRn);
2395 JMP_TARGET(doubleprec);
2396 push_dr(R_EDX, FRm);
2397 push_dr(R_EDX, FRn);
2404 { /* FDIV FRm, FRn */
2405 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2407 load_spreg( R_ECX, R_FPSCR );
2408 TEST_imm32_r32( FPSCR_PR, R_ECX );
2409 load_fr_bank( R_EDX );
2410 JNE_rel8(13, doubleprec);
2411 push_fr(R_EDX, FRn);
2412 push_fr(R_EDX, FRm);
2416 JMP_TARGET(doubleprec);
2417 push_dr(R_EDX, FRn);
2418 push_dr(R_EDX, FRm);
2425 { /* FCMP/EQ FRm, FRn */
2426 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2428 load_spreg( R_ECX, R_FPSCR );
2429 TEST_imm32_r32( FPSCR_PR, R_ECX );
2430 load_fr_bank( R_EDX );
2431 JNE_rel8(8, doubleprec);
2432 push_fr(R_EDX, FRm);
2433 push_fr(R_EDX, FRn);
2435 JMP_TARGET(doubleprec);
2436 push_dr(R_EDX, FRm);
2437 push_dr(R_EDX, FRn);
2445 { /* FCMP/GT FRm, FRn */
2446 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2448 load_spreg( R_ECX, R_FPSCR );
2449 TEST_imm32_r32( FPSCR_PR, R_ECX );
2450 load_fr_bank( R_EDX );
2451 JNE_rel8(8, doubleprec);
2452 push_fr(R_EDX, FRm);
2453 push_fr(R_EDX, FRn);
2455 JMP_TARGET(doubleprec);
2456 push_dr(R_EDX, FRm);
2457 push_dr(R_EDX, FRn);
2465 { /* FMOV @(R0, Rm), FRn */
2466 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2468 load_reg( R_EDX, Rm );
2469 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
2470 check_ralign32( R_EDX );
2471 load_spreg( R_ECX, R_FPSCR );
2472 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2473 JNE_rel8(19, doublesize);
2474 MEM_READ_LONG( R_EDX, R_EAX );
2475 load_fr_bank( R_ECX );
2476 store_fr( R_ECX, R_EAX, FRn );
2479 JMP_TARGET(doublesize);
2480 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2481 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
2482 load_xf_bank( R_ECX );
2483 store_fr( R_ECX, R_EAX, FRn&0x0E );
2484 store_fr( R_ECX, R_EDX, FRn|0x01 );
2488 JMP_TARGET(doublesize);
2489 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2490 load_fr_bank( R_ECX );
2491 store_fr( R_ECX, R_EAX, FRn&0x0E );
2492 store_fr( R_ECX, R_EDX, FRn|0x01 );
2498 { /* FMOV FRm, @(R0, Rn) */
2499 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2501 load_reg( R_EDX, Rn );
2502 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
2503 check_walign32( R_EDX );
2504 load_spreg( R_ECX, R_FPSCR );
2505 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2506 JNE_rel8(20, doublesize);
2507 load_fr_bank( R_ECX );
2508 load_fr( R_ECX, R_EAX, FRm );
2509 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
2511 JMP_rel8( 46, end );
2512 JMP_TARGET(doublesize);
2513 load_xf_bank( R_ECX );
2514 load_fr( R_ECX, R_EAX, FRm&0x0E );
2515 load_fr( R_ECX, R_ECX, FRm|0x01 );
2516 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2519 JMP_rel8( 39, end );
2520 JMP_TARGET(doublesize);
2521 load_fr_bank( R_ECX );
2522 load_fr( R_ECX, R_EAX, FRm&0x0E );
2523 load_fr( R_ECX, R_ECX, FRm|0x01 );
2524 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2530 { /* FMOV @Rm, FRn */
2531 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2533 load_reg( R_EDX, Rm );
2534 check_ralign32( R_EDX );
2535 load_spreg( R_ECX, R_FPSCR );
2536 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2537 JNE_rel8(19, doublesize);
2538 MEM_READ_LONG( R_EDX, R_EAX );
2539 load_fr_bank( R_ECX );
2540 store_fr( R_ECX, R_EAX, FRn );
2543 JMP_TARGET(doublesize);
2544 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2545 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
2546 load_xf_bank( R_ECX );
2547 store_fr( R_ECX, R_EAX, FRn&0x0E );
2548 store_fr( R_ECX, R_EDX, FRn|0x01 );
2552 JMP_TARGET(doublesize);
2553 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2554 load_fr_bank( R_ECX );
2555 store_fr( R_ECX, R_EAX, FRn&0x0E );
2556 store_fr( R_ECX, R_EDX, FRn|0x01 );
2562 { /* FMOV @Rm+, FRn */
2563 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2565 load_reg( R_EDX, Rm );
2566 check_ralign32( R_EDX );
2567 MOV_r32_r32( R_EDX, R_EAX );
2568 load_spreg( R_ECX, R_FPSCR );
2569 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2570 JNE_rel8(25, doublesize);
2571 ADD_imm8s_r32( 4, R_EAX );
2572 store_reg( R_EAX, Rm );
2573 MEM_READ_LONG( R_EDX, R_EAX );
2574 load_fr_bank( R_ECX );
2575 store_fr( R_ECX, R_EAX, FRn );
2578 JMP_TARGET(doublesize);
2579 ADD_imm8s_r32( 8, R_EAX );
2580 store_reg(R_EAX, Rm);
2581 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2582 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
2583 load_xf_bank( R_ECX );
2584 store_fr( R_ECX, R_EAX, FRn&0x0E );
2585 store_fr( R_ECX, R_EDX, FRn|0x01 );
2589 ADD_imm8s_r32( 8, R_EAX );
2590 store_reg(R_EAX, Rm);
2591 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
2592 load_fr_bank( R_ECX );
2593 store_fr( R_ECX, R_EAX, FRn&0x0E );
2594 store_fr( R_ECX, R_EDX, FRn|0x01 );
2600 { /* FMOV FRm, @Rn */
2601 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2603 load_reg( R_EDX, Rn );
2604 check_walign32( R_EDX );
2605 load_spreg( R_ECX, R_FPSCR );
2606 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2607 JNE_rel8(20, doublesize);
2608 load_fr_bank( R_ECX );
2609 load_fr( R_ECX, R_EAX, FRm );
2610 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
2612 JMP_rel8( 46, end );
2613 JMP_TARGET(doublesize);
2614 load_xf_bank( R_ECX );
2615 load_fr( R_ECX, R_EAX, FRm&0x0E );
2616 load_fr( R_ECX, R_ECX, FRm|0x01 );
2617 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2620 JMP_rel8( 39, end );
2621 JMP_TARGET(doublesize);
2622 load_fr_bank( R_ECX );
2623 load_fr( R_ECX, R_EAX, FRm&0x0E );
2624 load_fr( R_ECX, R_ECX, FRm|0x01 );
2625 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2631 { /* FMOV FRm, @-Rn */
2632 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2634 load_reg( R_EDX, Rn );
2635 check_walign32( R_EDX );
2636 load_spreg( R_ECX, R_FPSCR );
2637 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2638 JNE_rel8(20, doublesize);
2639 load_fr_bank( R_ECX );
2640 load_fr( R_ECX, R_EAX, FRm );
2641 ADD_imm8s_r32(-4,R_EDX);
2642 store_reg( R_EDX, Rn );
2643 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
2645 JMP_rel8( 46, end );
2646 JMP_TARGET(doublesize);
2647 load_xf_bank( R_ECX );
2648 load_fr( R_ECX, R_EAX, FRm&0x0E );
2649 load_fr( R_ECX, R_ECX, FRm|0x01 );
2650 ADD_imm8s_r32(-8,R_EDX);
2651 store_reg( R_EDX, Rn );
2652 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2655 JMP_rel8( 39, end );
2656 JMP_TARGET(doublesize);
2657 load_fr_bank( R_ECX );
2658 load_fr( R_ECX, R_EAX, FRm&0x0E );
2659 load_fr( R_ECX, R_ECX, FRm|0x01 );
2660 ADD_imm8s_r32(-8,R_EDX);
2661 store_reg( R_EDX, Rn );
2662 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
2668 { /* FMOV FRm, FRn */
2669 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2670 /* As horrible as this looks, it's actually covering 5 separate cases:
2671 * 1. 32-bit fr-to-fr (PR=0)
2672 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
2673 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
2674 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
2675 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
2678 load_spreg( R_ECX, R_FPSCR );
2679 load_fr_bank( R_EDX );
2680 TEST_imm32_r32( FPSCR_SZ, R_ECX );
2681 JNE_rel8(8, doublesize);
2682 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
2683 store_fr( R_EDX, R_EAX, FRn );
2686 JMP_TARGET(doublesize);
2687 load_xf_bank( R_ECX );
2688 load_fr( R_ECX, R_EAX, FRm-1 );
2690 load_fr( R_ECX, R_EDX, FRm );
2691 store_fr( R_ECX, R_EAX, FRn-1 );
2692 store_fr( R_ECX, R_EDX, FRn );
2693 } else /* FRn&1 == 0 */ {
2694 load_fr( R_ECX, R_ECX, FRm );
2695 store_fr( R_EDX, R_EAX, FRn-1 );
2696 store_fr( R_EDX, R_ECX, FRn );
2699 } else /* FRm&1 == 0 */ {
2702 load_xf_bank( R_ECX );
2703 load_fr( R_EDX, R_EAX, FRm );
2704 load_fr( R_EDX, R_EDX, FRm+1 );
2705 store_fr( R_ECX, R_EAX, FRn-1 );
2706 store_fr( R_ECX, R_EDX, FRn );
2708 } else /* FRn&1 == 0 */ {
2710 load_fr( R_EDX, R_EAX, FRm );
2711 load_fr( R_EDX, R_ECX, FRm+1 );
2712 store_fr( R_EDX, R_EAX, FRn );
2713 store_fr( R_EDX, R_ECX, FRn+1 );
2720 switch( (ir&0xF0) >> 4 ) {
2722 { /* FSTS FPUL, FRn */
2723 uint32_t FRn = ((ir>>8)&0xF);
2725 load_fr_bank( R_ECX );
2726 load_spreg( R_EAX, R_FPUL );
2727 store_fr( R_ECX, R_EAX, FRn );
2731 { /* FLDS FRm, FPUL */
2732 uint32_t FRm = ((ir>>8)&0xF);
2734 load_fr_bank( R_ECX );
2735 load_fr( R_ECX, R_EAX, FRm );
2736 store_spreg( R_EAX, R_FPUL );
2740 { /* FLOAT FPUL, FRn */
2741 uint32_t FRn = ((ir>>8)&0xF);
2743 load_spreg( R_ECX, R_FPSCR );
2744 load_spreg(R_EDX, REG_OFFSET(fr_bank));
2746 TEST_imm32_r32( FPSCR_PR, R_ECX );
2747 JNE_rel8(5, doubleprec);
2748 pop_fr( R_EDX, FRn );
2750 JMP_TARGET(doubleprec);
2751 pop_dr( R_EDX, FRn );
2756 { /* FTRC FRm, FPUL */
2757 uint32_t FRm = ((ir>>8)&0xF);
2764 uint32_t FRn = ((ir>>8)&0xF);
2766 load_spreg( R_ECX, R_FPSCR );
2767 TEST_imm32_r32( FPSCR_PR, R_ECX );
2768 load_fr_bank( R_EDX );
2769 JNE_rel8(10, doubleprec);
2770 push_fr(R_EDX, FRn);
2774 JMP_TARGET(doubleprec);
2775 push_dr(R_EDX, FRn);
2783 uint32_t FRn = ((ir>>8)&0xF);
2785 load_spreg( R_ECX, R_FPSCR );
2786 load_fr_bank( R_EDX );
2787 TEST_imm32_r32( FPSCR_PR, R_ECX );
2788 JNE_rel8(10, doubleprec);
2789 push_fr(R_EDX, FRn); // 3
2791 pop_fr( R_EDX, FRn); //3
2792 JMP_rel8(8,end); // 2
2793 JMP_TARGET(doubleprec);
2794 push_dr(R_EDX, FRn);
2802 uint32_t FRn = ((ir>>8)&0xF);
2804 load_spreg( R_ECX, R_FPSCR );
2805 TEST_imm32_r32( FPSCR_PR, R_ECX );
2806 load_fr_bank( R_EDX );
2807 JNE_rel8(10, doubleprec);
2808 push_fr(R_EDX, FRn);
2812 JMP_TARGET(doubleprec);
2813 push_dr(R_EDX, FRn);
2821 uint32_t FRn = ((ir>>8)&0xF);
2823 load_spreg( R_ECX, R_FPSCR );
2824 TEST_imm32_r32( FPSCR_PR, R_ECX );
2825 load_fr_bank( R_EDX );
2826 JNE_rel8(12, end); // PR=0 only
2828 push_fr(R_EDX, FRn);
2837 uint32_t FRn = ((ir>>8)&0xF);
2840 load_spreg( R_ECX, R_FPSCR );
2841 TEST_imm32_r32( FPSCR_PR, R_ECX );
2843 XOR_r32_r32( R_EAX, R_EAX );
2844 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
2845 store_fr( R_ECX, R_EAX, FRn );
2851 uint32_t FRn = ((ir>>8)&0xF);
2854 load_spreg( R_ECX, R_FPSCR );
2855 TEST_imm32_r32( FPSCR_PR, R_ECX );
2857 load_imm32(R_EAX, 0x3F800000);
2858 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
2859 store_fr( R_ECX, R_EAX, FRn );
2864 { /* FCNVSD FPUL, FRn */
2865 uint32_t FRn = ((ir>>8)&0xF);
2868 load_spreg( R_ECX, R_FPSCR );
2869 TEST_imm32_r32( FPSCR_PR, R_ECX );
2870 JE_rel8(9, end); // only when PR=1
2871 load_fr_bank( R_ECX );
2873 pop_dr( R_ECX, FRn );
2878 { /* FCNVDS FRm, FPUL */
2879 uint32_t FRm = ((ir>>8)&0xF);
2881 load_spreg( R_ECX, R_FPSCR );
2882 TEST_imm32_r32( FPSCR_PR, R_ECX );
2883 JE_rel8(9, end); // only when PR=1
2884 load_fr_bank( R_ECX );
2885 push_dr( R_ECX, FRm );
2891 { /* FIPR FVm, FVn */
2892 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
2897 switch( (ir&0x100) >> 8 ) {
2899 { /* FSCA FPUL, FRn */
2900 uint32_t FRn = ((ir>>9)&0x7)<<1;
2905 switch( (ir&0x200) >> 9 ) {
2907 { /* FTRV XMTRX, FVn */
2908 uint32_t FVn = ((ir>>10)&0x3);
2913 switch( (ir&0xC00) >> 10 ) {
2917 load_spreg( R_ECX, R_FPSCR );
2918 XOR_imm32_r32( FPSCR_SZ, R_ECX );
2919 store_spreg( R_ECX, R_FPSCR );
2925 load_spreg( R_ECX, R_FPSCR );
2926 XOR_imm32_r32( FPSCR_FR, R_ECX );
2927 store_spreg( R_ECX, R_FPSCR );
2932 if( sh4_x86.in_delay_slot ) {
2933 RAISE_EXCEPTION(EXC_SLOT_ILLEGAL);
2935 RAISE_EXCEPTION(EXC_ILLEGAL);
2955 { /* FMAC FR0, FRm, FRn */
2956 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2958 load_spreg( R_ECX, R_FPSCR );
2959 load_spreg( R_EDX, REG_OFFSET(fr_bank));
2960 TEST_imm32_r32( FPSCR_PR, R_ECX );
2961 JNE_rel8(18, doubleprec);
2962 push_fr( R_EDX, 0 );
2963 push_fr( R_EDX, FRm );
2965 push_fr( R_EDX, FRn );
2967 pop_fr( R_EDX, FRn );
2969 JMP_TARGET(doubleprec);
2970 push_dr( R_EDX, 0 );
2971 push_dr( R_EDX, FRm );
2973 push_dr( R_EDX, FRn );
2975 pop_dr( R_EDX, FRn );
2987 if( sh4_x86.in_delay_slot ) {
2988 sh4_x86.in_delay_slot = FALSE;
.