2 * $Id: sh4x86.c,v 1.3 2007-09-04 08:40:23 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.
23 #include "sh4/sh4core.h"
24 #include "sh4/sh4trans.h"
25 #include "sh4/x86op.h"
28 #define DEFAULT_BACKPATCH_SIZE 4096
31 * Struct to manage internal translation state. This state is not saved -
32 * it is only valid between calls to sh4_translate_begin_block() and
33 * sh4_translate_end_block()
35 struct sh4_x86_state {
36 gboolean in_delay_slot;
37 gboolean priv_checked; /* true if we've already checked the cpu mode. */
38 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
40 /* Allocated memory for the (block-wide) back-patch list */
41 uint32_t **backpatch_list;
42 uint32_t backpatch_posn;
43 uint32_t backpatch_size;
46 #define EXIT_DATA_ADDR_READ 0
47 #define EXIT_DATA_ADDR_WRITE 7
48 #define EXIT_ILLEGAL 14
49 #define EXIT_SLOT_ILLEGAL 21
50 #define EXIT_FPU_DISABLED 28
51 #define EXIT_SLOT_FPU_DISABLED 35
53 static struct sh4_x86_state sh4_x86;
57 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
58 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
62 static void sh4_x86_add_backpatch( uint8_t *ptr )
64 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
65 sh4_x86.backpatch_size <<= 1;
66 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
67 assert( sh4_x86.backpatch_list != NULL );
69 sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
72 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
75 for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
76 *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]));
81 #define MARK_JMP(x,n) uint8_t *_mark_jmp_##x = xlat_output + n
82 #define CHECK_JMP(x) assert( _mark_jmp_##x == xlat_output )
90 * Emit an instruction to load an SH4 reg into a real register
92 static inline void load_reg( int x86reg, int sh4reg )
96 OP(0x45 + (x86reg<<3));
97 OP(REG_OFFSET(r[sh4reg]));
101 * Load the SR register into an x86 register
103 static inline void read_sr( int x86reg )
105 MOV_ebp_r32( R_M, x86reg );
107 OR_ebp_r32( R_Q, x86reg );
108 SHL_imm8_r32( 7, x86reg );
109 OR_ebp_r32( R_S, x86reg );
111 OR_ebp_r32( R_T, x86reg );
112 OR_ebp_r32( R_SR, x86reg );
115 static inline void write_sr( int x86reg )
117 TEST_imm32_r32( SR_M, x86reg );
119 TEST_imm32_r32( SR_Q, x86reg );
121 TEST_imm32_r32( SR_S, x86reg );
123 TEST_imm32_r32( SR_T, x86reg );
125 AND_imm32_r32( SR_MQSTMASK, x86reg );
126 MOV_r32_ebp( x86reg, R_SR );
130 static inline void load_spreg( int x86reg, int regoffset )
132 /* mov [bp+n], reg */
134 OP(0x45 + (x86reg<<3));
139 * Emit an instruction to load an immediate value into a register
141 static inline void load_imm32( int x86reg, uint32_t value ) {
142 /* mov #value, reg */
148 * Emit an instruction to store an SH4 reg (RN)
150 void static inline store_reg( int x86reg, int sh4reg ) {
151 /* mov reg, [bp+n] */
153 OP(0x45 + (x86reg<<3));
154 OP(REG_OFFSET(r[sh4reg]));
156 void static inline store_spreg( int x86reg, int regoffset ) {
157 /* mov reg, [bp+n] */
159 OP(0x45 + (x86reg<<3));
164 * Note: clobbers EAX to make the indirect call - this isn't usually
165 * a problem since the callee will usually clobber it anyway.
167 static inline void call_func0( void *ptr )
169 load_imm32(R_EAX, (uint32_t)ptr);
173 static inline void call_func1( void *ptr, int arg1 )
177 ADD_imm8s_r32( -4, R_ESP );
180 static inline void call_func2( void *ptr, int arg1, int arg2 )
185 ADD_imm8s_r32( -4, R_ESP );
188 /* Exception checks - Note that all exception checks will clobber EAX */
189 static void check_priv( )
191 if( !sh4_x86.priv_checked ) {
192 sh4_x86.priv_checked = TRUE;
193 load_spreg( R_EAX, R_SR );
194 AND_imm32_r32( SR_MD, R_EAX );
195 if( sh4_x86.in_delay_slot ) {
196 JE_exit( EXIT_SLOT_ILLEGAL );
198 JE_exit( EXIT_ILLEGAL );
203 static void check_fpuen( )
205 if( !sh4_x86.fpuen_checked ) {
206 sh4_x86.fpuen_checked = TRUE;
207 load_spreg( R_EAX, R_SR );
208 AND_imm32_r32( SR_FD, R_EAX );
209 if( sh4_x86.in_delay_slot ) {
210 JNE_exit(EXIT_SLOT_FPU_DISABLED);
212 JNE_exit(EXIT_FPU_DISABLED);
217 static void check_ralign16( int x86reg )
219 TEST_imm32_r32( 0x00000001, x86reg );
220 JNE_exit(EXIT_DATA_ADDR_READ);
223 static void check_walign16( int x86reg )
225 TEST_imm32_r32( 0x00000001, x86reg );
226 JNE_exit(EXIT_DATA_ADDR_WRITE);
229 static void check_ralign32( int x86reg )
231 TEST_imm32_r32( 0x00000003, x86reg );
232 JNE_exit(EXIT_DATA_ADDR_READ);
234 static void check_walign32( int x86reg )
236 TEST_imm32_r32( 0x00000003, x86reg );
237 JNE_exit(EXIT_DATA_ADDR_WRITE);
242 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
243 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
244 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
245 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
246 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
247 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
248 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
250 #define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);
251 #define CHECKSLOTILLEGAL() if(sh4_x86.in_delay_slot) RAISE_EXCEPTION(EXC_SLOT_ILLEGAL)
256 * Emit the 'start of block' assembly. Sets up the stack frame and save
259 void sh4_translate_begin_block()
264 load_imm32( R_EBP, (uint32_t)&sh4r );
267 sh4_x86.in_delay_slot = FALSE;
268 sh4_x86.priv_checked = FALSE;
269 sh4_x86.fpuen_checked = FALSE;
270 sh4_x86.backpatch_posn = 0;
274 * Exit the block early (ie branch out), conditionally or otherwise
276 void exit_block( uint32_t pc )
278 load_imm32( R_ECX, pc );
279 store_spreg( R_ECX, REG_OFFSET(pc) );
280 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
281 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
283 ADD_r32_r32( R_EAX, R_ECX );
284 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
285 XOR_r32_r32( R_EAX, R_EAX );
290 * Flush any open regs back to memory, restore SI/DI/, update PC, etc
292 void sh4_translate_end_block( sh4addr_t pc ) {
293 assert( !sh4_x86.in_delay_slot ); // should never stop here
294 // Normal termination - save PC, cycle count
297 uint8_t *end_ptr = xlat_output;
298 // Exception termination. Jump block for various exception codes:
299 PUSH_imm32( EXC_DATA_ADDR_READ );
301 PUSH_imm32( EXC_DATA_ADDR_WRITE );
303 PUSH_imm32( EXC_ILLEGAL );
305 PUSH_imm32( EXC_SLOT_ILLEGAL );
307 PUSH_imm32( EXC_FPU_DISABLED );
309 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
311 load_spreg( R_ECX, REG_OFFSET(pc) );
312 ADD_r32_r32( R_ESI, R_ECX );
313 ADD_r32_r32( R_ESI, R_ECX );
314 store_spreg( R_ECX, REG_OFFSET(pc) );
315 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
316 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
318 ADD_r32_r32( R_EAX, R_ECX );
319 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
321 load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
322 CALL_r32( R_EAX ); // 2
326 sh4_x86_do_backpatch( end_ptr );
330 * Translate a single instruction. Delayed branches are handled specially
331 * by translating both branch and delayed instruction as a single unit (as
334 * @return true if the instruction marks the end of a basic block
337 uint32_t sh4_x86_translate_instruction( uint32_t pc )
339 uint16_t ir = sh4_read_word( pc );
341 switch( (ir&0xF000) >> 12 ) {
345 switch( (ir&0x80) >> 7 ) {
347 switch( (ir&0x70) >> 4 ) {
350 uint32_t Rn = ((ir>>8)&0xF);
352 store_reg( R_EAX, Rn );
357 uint32_t Rn = ((ir>>8)&0xF);
358 load_spreg( R_EAX, R_GBR );
359 store_reg( R_EAX, Rn );
364 uint32_t Rn = ((ir>>8)&0xF);
365 load_spreg( R_EAX, R_VBR );
366 store_reg( R_EAX, Rn );
371 uint32_t Rn = ((ir>>8)&0xF);
372 load_spreg( R_EAX, R_SSR );
373 store_reg( R_EAX, Rn );
378 uint32_t Rn = ((ir>>8)&0xF);
379 load_spreg( R_EAX, R_SPC );
380 store_reg( R_EAX, Rn );
389 { /* STC Rm_BANK, Rn */
390 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
397 switch( (ir&0xF0) >> 4 ) {
400 uint32_t Rn = ((ir>>8)&0xF);
405 uint32_t Rn = ((ir>>8)&0xF);
410 uint32_t Rn = ((ir>>8)&0xF);
415 uint32_t Rn = ((ir>>8)&0xF);
420 uint32_t Rn = ((ir>>8)&0xF);
425 uint32_t Rn = ((ir>>8)&0xF);
429 { /* MOVCA.L R0, @Rn */
430 uint32_t Rn = ((ir>>8)&0xF);
431 load_reg( R_EAX, 0 );
432 load_reg( R_ECX, Rn );
433 MEM_WRITE_LONG( R_ECX, R_EAX );
442 { /* MOV.B Rm, @(R0, Rn) */
443 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
444 load_reg( R_EAX, 0 );
445 load_reg( R_ECX, Rn );
446 ADD_r32_r32( R_EAX, R_ECX );
447 load_reg( R_EAX, Rm );
448 MEM_WRITE_BYTE( R_ECX, R_EAX );
452 { /* MOV.W Rm, @(R0, Rn) */
453 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
454 load_reg( R_EAX, 0 );
455 load_reg( R_ECX, Rn );
456 ADD_r32_r32( R_EAX, R_ECX );
457 load_reg( R_EAX, Rm );
458 MEM_WRITE_WORD( R_ECX, R_EAX );
462 { /* MOV.L Rm, @(R0, Rn) */
463 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
464 load_reg( R_EAX, 0 );
465 load_reg( R_ECX, Rn );
466 ADD_r32_r32( R_EAX, R_ECX );
467 load_reg( R_EAX, Rm );
468 MEM_WRITE_LONG( R_ECX, R_EAX );
473 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
474 load_reg( R_EAX, Rm );
475 load_reg( R_ECX, Rn );
477 store_spreg( R_EAX, R_MACL );
481 switch( (ir&0xFF0) >> 4 ) {
512 switch( (ir&0xF0) >> 4 ) {
515 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
520 XOR_r32_r32( R_EAX, R_EAX );
521 store_spreg( R_EAX, R_Q );
522 store_spreg( R_EAX, R_M );
523 store_spreg( R_EAX, R_T );
528 uint32_t Rn = ((ir>>8)&0xF);
529 load_spreg( R_EAX, R_T );
530 store_reg( R_EAX, Rn );
539 switch( (ir&0xF0) >> 4 ) {
542 uint32_t Rn = ((ir>>8)&0xF);
543 load_spreg( R_EAX, R_MACH );
544 store_reg( R_EAX, Rn );
549 uint32_t Rn = ((ir>>8)&0xF);
550 load_spreg( R_EAX, R_MACL );
551 store_reg( R_EAX, Rn );
556 uint32_t Rn = ((ir>>8)&0xF);
557 load_spreg( R_EAX, R_PR );
558 store_reg( R_EAX, Rn );
563 uint32_t Rn = ((ir>>8)&0xF);
564 load_spreg( R_EAX, R_SGR );
565 store_reg( R_EAX, Rn );
570 uint32_t Rn = ((ir>>8)&0xF);
571 load_spreg( R_EAX, R_FPUL );
572 store_reg( R_EAX, Rn );
576 { /* STS FPSCR, Rn */
577 uint32_t Rn = ((ir>>8)&0xF);
578 load_spreg( R_EAX, R_FPSCR );
579 store_reg( R_EAX, Rn );
584 uint32_t Rn = ((ir>>8)&0xF);
585 load_spreg( R_EAX, R_DBR );
586 store_reg( R_EAX, Rn );
595 switch( (ir&0xFF0) >> 4 ) {
614 { /* MOV.B @(R0, Rm), Rn */
615 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
616 load_reg( R_EAX, 0 );
617 load_reg( R_ECX, Rm );
618 ADD_r32_r32( R_EAX, R_ECX );
619 MEM_READ_BYTE( R_ECX, R_EAX );
620 store_reg( R_EAX, Rn );
624 { /* MOV.W @(R0, Rm), Rn */
625 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
626 load_reg( R_EAX, 0 );
627 load_reg( R_ECX, Rm );
628 ADD_r32_r32( R_EAX, R_ECX );
629 MEM_READ_WORD( R_ECX, R_EAX );
630 store_reg( R_EAX, Rn );
634 { /* MOV.L @(R0, Rm), Rn */
635 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
636 load_reg( R_EAX, 0 );
637 load_reg( R_ECX, Rm );
638 ADD_r32_r32( R_EAX, R_ECX );
639 MEM_READ_LONG( R_ECX, R_EAX );
640 store_reg( R_EAX, Rn );
644 { /* MAC.L @Rm+, @Rn+ */
645 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
654 { /* MOV.L Rm, @(disp, Rn) */
655 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
656 load_reg( R_ECX, Rn );
657 load_reg( R_EAX, Rm );
658 ADD_imm32_r32( disp, R_ECX );
659 MEM_WRITE_LONG( R_ECX, R_EAX );
665 { /* MOV.B Rm, @Rn */
666 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
667 load_reg( R_EAX, Rm );
668 load_reg( R_ECX, Rn );
669 MEM_WRITE_BYTE( R_ECX, R_EAX );
673 { /* MOV.W Rm, @Rn */
674 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
675 load_reg( R_ECX, Rn );
676 MEM_READ_WORD( R_ECX, R_EAX );
677 store_reg( R_EAX, Rn );
681 { /* MOV.L Rm, @Rn */
682 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
683 load_reg( R_EAX, Rm );
684 load_reg( R_ECX, Rn );
685 MEM_WRITE_LONG( R_ECX, R_EAX );
689 { /* MOV.B Rm, @-Rn */
690 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
691 load_reg( R_EAX, Rm );
692 load_reg( R_ECX, Rn );
693 ADD_imm8s_r32( -1, Rn );
694 store_reg( R_ECX, Rn );
695 MEM_WRITE_BYTE( R_ECX, R_EAX );
699 { /* MOV.W Rm, @-Rn */
700 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
701 load_reg( R_ECX, Rn );
702 load_reg( R_EAX, Rm );
703 ADD_imm8s_r32( -2, R_ECX );
704 MEM_WRITE_WORD( R_ECX, R_EAX );
708 { /* MOV.L Rm, @-Rn */
709 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
710 load_reg( R_EAX, Rm );
711 load_reg( R_ECX, Rn );
712 ADD_imm8s_r32( -4, R_ECX );
713 store_reg( R_ECX, Rn );
714 MEM_WRITE_LONG( R_ECX, R_EAX );
719 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
720 load_reg( R_EAX, Rm );
721 load_reg( R_ECX, Rm );
722 SHR_imm8_r32( 31, R_EAX );
723 SHR_imm8_r32( 31, R_ECX );
724 store_spreg( R_EAX, R_M );
725 store_spreg( R_ECX, R_Q );
726 CMP_r32_r32( R_EAX, R_ECX );
732 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
733 load_reg( R_EAX, Rm );
734 load_reg( R_ECX, Rn );
735 TEST_r32_r32( R_EAX, R_ECX );
741 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
742 load_reg( R_EAX, Rm );
743 load_reg( R_ECX, Rn );
744 AND_r32_r32( R_EAX, R_ECX );
745 store_reg( R_ECX, Rn );
750 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
751 load_reg( R_EAX, Rm );
752 load_reg( R_ECX, Rn );
753 XOR_r32_r32( R_EAX, R_ECX );
754 store_reg( R_ECX, Rn );
759 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
760 load_reg( R_EAX, Rm );
761 load_reg( R_ECX, Rn );
762 OR_r32_r32( R_EAX, R_ECX );
763 store_reg( R_ECX, Rn );
767 { /* CMP/STR Rm, Rn */
768 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
769 load_reg( R_EAX, Rm );
770 load_reg( R_ECX, Rn );
771 XOR_r32_r32( R_ECX, R_EAX );
772 TEST_r8_r8( R_AL, R_AL );
774 TEST_r8_r8( R_AH, R_AH ); // 2
776 SHR_imm8_r32( 16, R_EAX ); // 3
777 TEST_r8_r8( R_AL, R_AL ); // 2
779 TEST_r8_r8( R_AH, R_AH ); // 2
785 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
786 load_reg( R_EAX, Rm );
787 MOV_r32_r32( R_EAX, R_ECX );
788 SHR_imm8_r32( 16, R_EAX );
789 SHL_imm8_r32( 16, R_ECX );
790 OR_r32_r32( R_EAX, R_ECX );
791 store_reg( R_ECX, Rn );
795 { /* MULU.W Rm, Rn */
796 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
800 { /* MULS.W Rm, Rn */
801 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
812 { /* CMP/EQ Rm, Rn */
813 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
814 load_reg( R_EAX, Rm );
815 load_reg( R_ECX, Rn );
816 CMP_r32_r32( R_EAX, R_ECX );
821 { /* CMP/HS Rm, Rn */
822 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
823 load_reg( R_EAX, Rm );
824 load_reg( R_ECX, Rn );
825 CMP_r32_r32( R_EAX, R_ECX );
830 { /* CMP/GE Rm, Rn */
831 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
832 load_reg( R_EAX, Rm );
833 load_reg( R_ECX, Rn );
834 CMP_r32_r32( R_EAX, R_ECX );
840 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
844 { /* DMULU.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 );
849 store_spreg( R_EDX, R_MACH );
850 store_spreg( R_EAX, R_MACL );
854 { /* CMP/HI Rm, Rn */
855 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
856 load_reg( R_EAX, Rm );
857 load_reg( R_ECX, Rn );
858 CMP_r32_r32( R_EAX, R_ECX );
863 { /* CMP/GT Rm, Rn */
864 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
865 load_reg( R_EAX, Rm );
866 load_reg( R_ECX, Rn );
867 CMP_r32_r32( R_EAX, R_ECX );
873 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
874 load_reg( R_EAX, Rm );
875 load_reg( R_ECX, Rn );
876 SUB_r32_r32( R_EAX, R_ECX );
877 store_reg( R_ECX, Rn );
882 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
883 load_reg( R_EAX, Rm );
884 load_reg( R_ECX, Rn );
886 SBB_r32_r32( R_EAX, R_ECX );
887 store_reg( R_ECX, Rn );
892 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
893 load_reg( R_EAX, Rm );
894 load_reg( R_ECX, Rn );
895 SUB_r32_r32( R_EAX, R_ECX );
896 store_reg( R_ECX, Rn );
902 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
903 load_reg( R_EAX, Rm );
904 load_reg( R_ECX, Rn );
905 ADD_r32_r32( R_EAX, R_ECX );
906 store_reg( R_ECX, Rn );
910 { /* DMULS.L Rm, Rn */
911 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
912 load_reg( R_EAX, Rm );
913 load_reg( R_ECX, Rn );
915 store_spreg( R_EDX, R_MACH );
916 store_spreg( R_EAX, R_MACL );
921 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
922 load_reg( R_EAX, Rm );
923 load_reg( R_ECX, Rn );
925 ADC_r32_r32( R_EAX, R_ECX );
926 store_reg( R_ECX, Rn );
932 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
933 load_reg( R_EAX, Rm );
934 load_reg( R_ECX, Rn );
935 ADD_r32_r32( R_EAX, R_ECX );
936 store_reg( R_ECX, Rn );
948 switch( (ir&0xF0) >> 4 ) {
951 uint32_t Rn = ((ir>>8)&0xF);
952 load_reg( R_EAX, Rn );
954 store_reg( R_EAX, Rn );
959 uint32_t Rn = ((ir>>8)&0xF);
960 load_reg( R_EAX, Rn );
961 ADD_imm8s_r32( -1, Rn );
962 store_reg( R_EAX, Rn );
968 uint32_t Rn = ((ir>>8)&0xF);
969 load_reg( R_EAX, Rn );
971 store_reg( R_EAX, Rn );
980 switch( (ir&0xF0) >> 4 ) {
983 uint32_t Rn = ((ir>>8)&0xF);
984 load_reg( R_EAX, Rn );
986 store_reg( R_EAX, Rn );
991 uint32_t Rn = ((ir>>8)&0xF);
992 load_reg( R_EAX, Rn );
993 CMP_imm8s_r32( 0, R_EAX );
999 uint32_t Rn = ((ir>>8)&0xF);
1000 load_reg( R_EAX, Rn );
1002 store_reg( R_EAX, Rn );
1011 switch( (ir&0xF0) >> 4 ) {
1013 { /* STS.L MACH, @-Rn */
1014 uint32_t Rn = ((ir>>8)&0xF);
1015 load_reg( R_ECX, Rn );
1016 ADD_imm8s_r32( -4, Rn );
1017 store_reg( R_ECX, Rn );
1018 load_spreg( R_EAX, R_MACH );
1019 MEM_WRITE_LONG( R_ECX, R_EAX );
1023 { /* STS.L MACL, @-Rn */
1024 uint32_t Rn = ((ir>>8)&0xF);
1025 load_reg( R_ECX, Rn );
1026 ADD_imm8s_r32( -4, Rn );
1027 store_reg( R_ECX, Rn );
1028 load_spreg( R_EAX, R_MACL );
1029 MEM_WRITE_LONG( R_ECX, R_EAX );
1033 { /* STS.L PR, @-Rn */
1034 uint32_t Rn = ((ir>>8)&0xF);
1035 load_reg( R_ECX, Rn );
1036 ADD_imm8s_r32( -4, Rn );
1037 store_reg( R_ECX, Rn );
1038 load_spreg( R_EAX, R_PR );
1039 MEM_WRITE_LONG( R_ECX, R_EAX );
1043 { /* STC.L SGR, @-Rn */
1044 uint32_t Rn = ((ir>>8)&0xF);
1045 load_reg( R_ECX, Rn );
1046 ADD_imm8s_r32( -4, Rn );
1047 store_reg( R_ECX, Rn );
1048 load_spreg( R_EAX, R_SGR );
1049 MEM_WRITE_LONG( R_ECX, R_EAX );
1053 { /* STS.L FPUL, @-Rn */
1054 uint32_t Rn = ((ir>>8)&0xF);
1055 load_reg( R_ECX, Rn );
1056 ADD_imm8s_r32( -4, Rn );
1057 store_reg( R_ECX, Rn );
1058 load_spreg( R_EAX, R_FPUL );
1059 MEM_WRITE_LONG( R_ECX, R_EAX );
1063 { /* STS.L FPSCR, @-Rn */
1064 uint32_t Rn = ((ir>>8)&0xF);
1065 load_reg( R_ECX, Rn );
1066 ADD_imm8s_r32( -4, Rn );
1067 store_reg( R_ECX, Rn );
1068 load_spreg( R_EAX, R_FPSCR );
1069 MEM_WRITE_LONG( R_ECX, R_EAX );
1073 { /* STC.L DBR, @-Rn */
1074 uint32_t Rn = ((ir>>8)&0xF);
1075 load_reg( R_ECX, Rn );
1076 ADD_imm8s_r32( -4, Rn );
1077 store_reg( R_ECX, Rn );
1078 load_spreg( R_EAX, R_DBR );
1079 MEM_WRITE_LONG( R_ECX, R_EAX );
1088 switch( (ir&0x80) >> 7 ) {
1090 switch( (ir&0x70) >> 4 ) {
1092 { /* STC.L SR, @-Rn */
1093 uint32_t Rn = ((ir>>8)&0xF);
1095 load_reg( R_ECX, Rn );
1096 ADD_imm8s_r32( -4, Rn );
1097 store_reg( R_ECX, Rn );
1099 MEM_WRITE_LONG( R_ECX, R_EAX );
1103 { /* STC.L GBR, @-Rn */
1104 uint32_t Rn = ((ir>>8)&0xF);
1105 load_reg( R_ECX, Rn );
1106 ADD_imm8s_r32( -4, Rn );
1107 store_reg( R_ECX, Rn );
1108 load_spreg( R_EAX, R_GBR );
1109 MEM_WRITE_LONG( R_ECX, R_EAX );
1113 { /* STC.L VBR, @-Rn */
1114 uint32_t Rn = ((ir>>8)&0xF);
1115 load_reg( R_ECX, Rn );
1116 ADD_imm8s_r32( -4, Rn );
1117 store_reg( R_ECX, Rn );
1118 load_spreg( R_EAX, R_VBR );
1119 MEM_WRITE_LONG( R_ECX, R_EAX );
1123 { /* STC.L SSR, @-Rn */
1124 uint32_t Rn = ((ir>>8)&0xF);
1125 load_reg( R_ECX, Rn );
1126 ADD_imm8s_r32( -4, Rn );
1127 store_reg( R_ECX, Rn );
1128 load_spreg( R_EAX, R_SSR );
1129 MEM_WRITE_LONG( R_ECX, R_EAX );
1133 { /* STC.L SPC, @-Rn */
1134 uint32_t Rn = ((ir>>8)&0xF);
1135 load_reg( R_ECX, Rn );
1136 ADD_imm8s_r32( -4, Rn );
1137 store_reg( R_ECX, Rn );
1138 load_spreg( R_EAX, R_SPC );
1139 MEM_WRITE_LONG( R_ECX, R_EAX );
1148 { /* STC.L Rm_BANK, @-Rn */
1149 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1155 switch( (ir&0xF0) >> 4 ) {
1158 uint32_t Rn = ((ir>>8)&0xF);
1159 load_reg( R_EAX, Rn );
1161 store_reg( R_EAX, Rn );
1167 uint32_t Rn = ((ir>>8)&0xF);
1168 load_reg( R_EAX, Rn );
1171 store_reg( R_EAX, Rn );
1181 switch( (ir&0xF0) >> 4 ) {
1184 uint32_t Rn = ((ir>>8)&0xF);
1185 load_reg( R_EAX, Rn );
1187 store_reg( R_EAX, Rn );
1193 uint32_t Rn = ((ir>>8)&0xF);
1194 load_reg( R_EAX, Rn );
1195 CMP_imm8s_r32( 0, R_EAX );
1201 uint32_t Rn = ((ir>>8)&0xF);
1202 load_reg( R_EAX, Rn );
1205 store_reg( R_EAX, Rn );
1215 switch( (ir&0xF0) >> 4 ) {
1217 { /* LDS.L @Rm+, MACH */
1218 uint32_t Rm = ((ir>>8)&0xF);
1219 load_reg( R_EAX, Rm );
1220 MOV_r32_r32( R_EAX, R_ECX );
1221 ADD_imm8s_r32( 4, R_EAX );
1222 store_reg( R_EAX, Rm );
1223 MEM_READ_LONG( R_ECX, R_EAX );
1224 store_spreg( R_EAX, R_MACH );
1228 { /* LDS.L @Rm+, MACL */
1229 uint32_t Rm = ((ir>>8)&0xF);
1230 load_reg( R_EAX, Rm );
1231 MOV_r32_r32( R_EAX, R_ECX );
1232 ADD_imm8s_r32( 4, R_EAX );
1233 store_reg( R_EAX, Rm );
1234 MEM_READ_LONG( R_ECX, R_EAX );
1235 store_spreg( R_EAX, R_MACL );
1239 { /* LDS.L @Rm+, PR */
1240 uint32_t Rm = ((ir>>8)&0xF);
1241 load_reg( R_EAX, Rm );
1242 MOV_r32_r32( R_EAX, R_ECX );
1243 ADD_imm8s_r32( 4, R_EAX );
1244 store_reg( R_EAX, Rm );
1245 MEM_READ_LONG( R_ECX, R_EAX );
1246 store_spreg( R_EAX, R_PR );
1250 { /* LDC.L @Rm+, SGR */
1251 uint32_t Rm = ((ir>>8)&0xF);
1252 load_reg( R_EAX, Rm );
1253 MOV_r32_r32( R_EAX, R_ECX );
1254 ADD_imm8s_r32( 4, R_EAX );
1255 store_reg( R_EAX, Rm );
1256 MEM_READ_LONG( R_ECX, R_EAX );
1257 store_spreg( R_EAX, R_SGR );
1261 { /* LDS.L @Rm+, FPUL */
1262 uint32_t Rm = ((ir>>8)&0xF);
1263 load_reg( R_EAX, Rm );
1264 MOV_r32_r32( R_EAX, R_ECX );
1265 ADD_imm8s_r32( 4, R_EAX );
1266 store_reg( R_EAX, Rm );
1267 MEM_READ_LONG( R_ECX, R_EAX );
1268 store_spreg( R_EAX, R_FPUL );
1272 { /* LDS.L @Rm+, FPSCR */
1273 uint32_t Rm = ((ir>>8)&0xF);
1274 load_reg( R_EAX, Rm );
1275 MOV_r32_r32( R_EAX, R_ECX );
1276 ADD_imm8s_r32( 4, R_EAX );
1277 store_reg( R_EAX, Rm );
1278 MEM_READ_LONG( R_ECX, R_EAX );
1279 store_spreg( R_EAX, R_FPSCR );
1283 { /* LDC.L @Rm+, DBR */
1284 uint32_t Rm = ((ir>>8)&0xF);
1285 load_reg( R_EAX, Rm );
1286 MOV_r32_r32( R_EAX, R_ECX );
1287 ADD_imm8s_r32( 4, R_EAX );
1288 store_reg( R_EAX, Rm );
1289 MEM_READ_LONG( R_ECX, R_EAX );
1290 store_spreg( R_EAX, R_DBR );
1299 switch( (ir&0x80) >> 7 ) {
1301 switch( (ir&0x70) >> 4 ) {
1303 { /* LDC.L @Rm+, SR */
1304 uint32_t Rm = ((ir>>8)&0xF);
1305 load_reg( R_EAX, Rm );
1306 MOV_r32_r32( R_EAX, R_ECX );
1307 ADD_imm8s_r32( 4, R_EAX );
1308 store_reg( R_EAX, Rm );
1309 MEM_READ_LONG( R_ECX, R_EAX );
1314 { /* LDC.L @Rm+, GBR */
1315 uint32_t Rm = ((ir>>8)&0xF);
1316 load_reg( R_EAX, Rm );
1317 MOV_r32_r32( R_EAX, R_ECX );
1318 ADD_imm8s_r32( 4, R_EAX );
1319 store_reg( R_EAX, Rm );
1320 MEM_READ_LONG( R_ECX, R_EAX );
1321 store_spreg( R_EAX, R_GBR );
1325 { /* LDC.L @Rm+, VBR */
1326 uint32_t Rm = ((ir>>8)&0xF);
1327 load_reg( R_EAX, Rm );
1328 MOV_r32_r32( R_EAX, R_ECX );
1329 ADD_imm8s_r32( 4, R_EAX );
1330 store_reg( R_EAX, Rm );
1331 MEM_READ_LONG( R_ECX, R_EAX );
1332 store_spreg( R_EAX, R_VBR );
1336 { /* LDC.L @Rm+, SSR */
1337 uint32_t Rm = ((ir>>8)&0xF);
1338 load_reg( R_EAX, Rm );
1339 MOV_r32_r32( R_EAX, R_ECX );
1340 ADD_imm8s_r32( 4, R_EAX );
1341 store_reg( R_EAX, Rm );
1342 MEM_READ_LONG( R_ECX, R_EAX );
1343 store_spreg( R_EAX, R_SSR );
1347 { /* LDC.L @Rm+, SPC */
1348 uint32_t Rm = ((ir>>8)&0xF);
1349 load_reg( R_EAX, Rm );
1350 MOV_r32_r32( R_EAX, R_ECX );
1351 ADD_imm8s_r32( 4, R_EAX );
1352 store_reg( R_EAX, Rm );
1353 MEM_READ_LONG( R_ECX, R_EAX );
1354 store_spreg( R_EAX, R_SPC );
1363 { /* LDC.L @Rm+, Rn_BANK */
1364 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1370 switch( (ir&0xF0) >> 4 ) {
1373 uint32_t Rn = ((ir>>8)&0xF);
1374 load_reg( R_EAX, Rn );
1375 SHL_imm8_r32( 2, R_EAX );
1376 store_reg( R_EAX, Rn );
1381 uint32_t Rn = ((ir>>8)&0xF);
1382 load_reg( R_EAX, Rn );
1383 SHL_imm8_r32( 8, R_EAX );
1384 store_reg( R_EAX, Rn );
1389 uint32_t Rn = ((ir>>8)&0xF);
1390 load_reg( R_EAX, Rn );
1391 SHL_imm8_r32( 16, R_EAX );
1392 store_reg( R_EAX, Rn );
1401 switch( (ir&0xF0) >> 4 ) {
1404 uint32_t Rn = ((ir>>8)&0xF);
1405 load_reg( R_EAX, Rn );
1406 SHR_imm8_r32( 2, R_EAX );
1407 store_reg( R_EAX, Rn );
1412 uint32_t Rn = ((ir>>8)&0xF);
1413 load_reg( R_EAX, Rn );
1414 SHR_imm8_r32( 8, R_EAX );
1415 store_reg( R_EAX, Rn );
1420 uint32_t Rn = ((ir>>8)&0xF);
1421 load_reg( R_EAX, Rn );
1422 SHR_imm8_r32( 16, R_EAX );
1423 store_reg( R_EAX, Rn );
1432 switch( (ir&0xF0) >> 4 ) {
1434 { /* LDS Rm, MACH */
1435 uint32_t Rm = ((ir>>8)&0xF);
1436 load_reg( R_EAX, Rm );
1437 store_spreg( R_EAX, R_MACH );
1441 { /* LDS Rm, MACL */
1442 uint32_t Rm = ((ir>>8)&0xF);
1443 load_reg( R_EAX, Rm );
1444 store_spreg( R_EAX, R_MACL );
1449 uint32_t Rm = ((ir>>8)&0xF);
1450 load_reg( R_EAX, Rm );
1451 store_spreg( R_EAX, R_PR );
1456 uint32_t Rm = ((ir>>8)&0xF);
1457 load_reg( R_EAX, Rm );
1458 store_spreg( R_EAX, R_SGR );
1462 { /* LDS Rm, FPUL */
1463 uint32_t Rm = ((ir>>8)&0xF);
1464 load_reg( R_EAX, Rm );
1465 store_spreg( R_EAX, R_FPUL );
1469 { /* LDS Rm, FPSCR */
1470 uint32_t Rm = ((ir>>8)&0xF);
1471 load_reg( R_EAX, Rm );
1472 store_spreg( R_EAX, R_FPSCR );
1477 uint32_t Rm = ((ir>>8)&0xF);
1478 load_reg( R_EAX, Rm );
1479 store_spreg( R_EAX, R_DBR );
1488 switch( (ir&0xF0) >> 4 ) {
1491 uint32_t Rn = ((ir>>8)&0xF);
1496 uint32_t Rn = ((ir>>8)&0xF);
1497 load_reg( R_ECX, Rn );
1498 MEM_READ_BYTE( R_ECX, R_EAX );
1499 TEST_r8_r8( R_AL, R_AL );
1501 OR_imm8_r8( 0x80, R_AL );
1502 MEM_WRITE_BYTE( R_ECX, R_EAX );
1507 uint32_t Rn = ((ir>>8)&0xF);
1517 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1518 /* Annoyingly enough, not directly convertible */
1519 load_reg( R_EAX, Rn );
1520 load_reg( R_ECX, Rm );
1521 CMP_imm32_r32( 0, R_ECX );
1524 NEG_r32( R_ECX ); // 2
1525 AND_imm8_r8( 0x1F, R_CL ); // 3
1526 SAR_r32_CL( R_EAX ); // 2
1529 AND_imm8_r8( 0x1F, R_CL ); // 3
1530 SHL_r32_CL( R_EAX ); // 2
1532 store_reg( R_EAX, Rn );
1537 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1538 load_reg( R_EAX, Rn );
1539 load_reg( R_ECX, Rm );
1541 MOV_r32_r32( R_EAX, R_EDX );
1542 SHL_r32_CL( R_EAX );
1544 SHR_r32_CL( R_EDX );
1545 CMP_imm8s_r32( 0, R_ECX );
1546 CMOVAE_r32_r32( R_EDX, R_EAX );
1547 store_reg( R_EAX, Rn );
1551 switch( (ir&0x80) >> 7 ) {
1553 switch( (ir&0x70) >> 4 ) {
1556 uint32_t Rm = ((ir>>8)&0xF);
1557 load_reg( R_EAX, Rm );
1563 uint32_t Rm = ((ir>>8)&0xF);
1564 load_reg( R_EAX, Rm );
1565 store_spreg( R_EAX, R_GBR );
1570 uint32_t Rm = ((ir>>8)&0xF);
1571 load_reg( R_EAX, Rm );
1572 store_spreg( R_EAX, R_VBR );
1577 uint32_t Rm = ((ir>>8)&0xF);
1578 load_reg( R_EAX, Rm );
1579 store_spreg( R_EAX, R_SSR );
1584 uint32_t Rm = ((ir>>8)&0xF);
1585 load_reg( R_EAX, Rm );
1586 store_spreg( R_EAX, R_SPC );
1595 { /* LDC Rm, Rn_BANK */
1596 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
1602 { /* MAC.W @Rm+, @Rn+ */
1603 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1609 { /* MOV.L @(disp, Rm), Rn */
1610 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1611 load_reg( R_ECX, Rm );
1612 ADD_imm8s_r32( disp, R_ECX );
1613 MEM_READ_LONG( R_ECX, R_EAX );
1614 store_reg( R_EAX, Rn );
1620 { /* MOV.B @Rm, Rn */
1621 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1622 load_reg( R_ECX, Rm );
1623 MEM_READ_BYTE( R_ECX, R_EAX );
1624 store_reg( R_ECX, Rn );
1628 { /* MOV.W @Rm, Rn */
1629 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1630 load_reg( R_ECX, Rm );
1631 MEM_READ_WORD( R_ECX, R_EAX );
1632 store_reg( R_EAX, Rn );
1636 { /* MOV.L @Rm, Rn */
1637 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1638 load_reg( R_ECX, Rm );
1639 MEM_READ_LONG( R_ECX, R_EAX );
1640 store_reg( R_EAX, Rn );
1645 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1646 load_reg( R_EAX, Rm );
1647 store_reg( R_EAX, Rn );
1651 { /* MOV.B @Rm+, Rn */
1652 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1653 load_reg( R_ECX, Rm );
1654 MOV_r32_r32( R_ECX, R_EAX );
1655 ADD_imm8s_r32( 1, R_EAX );
1656 store_reg( R_EAX, Rm );
1657 MEM_READ_BYTE( R_ECX, R_EAX );
1658 store_reg( R_EAX, Rn );
1662 { /* MOV.W @Rm+, Rn */
1663 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1664 load_reg( R_EAX, Rm );
1665 MOV_r32_r32( R_EAX, R_ECX );
1666 ADD_imm8s_r32( 2, R_EAX );
1667 store_reg( R_EAX, Rm );
1668 MEM_READ_WORD( R_ECX, R_EAX );
1669 store_reg( R_EAX, Rn );
1673 { /* MOV.L @Rm+, Rn */
1674 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1675 load_reg( R_EAX, Rm );
1676 MOV_r32_r32( R_EAX, R_ECX );
1677 ADD_imm8s_r32( 4, R_EAX );
1678 store_reg( R_EAX, Rm );
1679 MEM_READ_LONG( R_ECX, R_EAX );
1680 store_reg( R_EAX, Rn );
1685 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1686 load_reg( R_EAX, Rm );
1688 store_reg( R_EAX, Rn );
1692 { /* SWAP.B Rm, Rn */
1693 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1694 load_reg( R_EAX, Rm );
1695 XCHG_r8_r8( R_AL, R_AH );
1696 store_reg( R_EAX, Rn );
1700 { /* SWAP.W Rm, Rn */
1701 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1702 load_reg( R_EAX, Rm );
1703 MOV_r32_r32( R_EAX, R_ECX );
1704 SHL_imm8_r32( 16, R_ECX );
1705 SHR_imm8_r32( 16, R_EAX );
1706 OR_r32_r32( R_EAX, R_ECX );
1707 store_reg( R_ECX, Rn );
1712 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1713 load_reg( R_EAX, Rm );
1714 XOR_r32_r32( R_ECX, R_ECX );
1716 SBB_r32_r32( R_EAX, R_ECX );
1717 store_reg( R_ECX, Rn );
1723 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1724 load_reg( R_EAX, Rm );
1726 store_reg( R_EAX, Rn );
1730 { /* EXTU.B Rm, Rn */
1731 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1732 load_reg( R_EAX, Rm );
1733 MOVZX_r8_r32( R_EAX, R_EAX );
1734 store_reg( R_EAX, Rn );
1738 { /* EXTU.W Rm, Rn */
1739 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1740 load_reg( R_EAX, Rm );
1741 MOVZX_r16_r32( R_EAX, R_EAX );
1742 store_reg( R_EAX, Rn );
1746 { /* EXTS.B Rm, Rn */
1747 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1748 load_reg( R_EAX, Rm );
1749 MOVSX_r8_r32( R_EAX, R_EAX );
1750 store_reg( R_EAX, Rn );
1754 { /* EXTS.W Rm, Rn */
1755 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1756 load_reg( R_EAX, Rm );
1757 MOVSX_r16_r32( R_EAX, R_EAX );
1758 store_reg( R_EAX, Rn );
1764 { /* ADD #imm, Rn */
1765 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
1766 load_reg( R_EAX, Rn );
1767 ADD_imm8s_r32( imm, R_EAX );
1768 store_reg( R_EAX, Rn );
1772 switch( (ir&0xF00) >> 8 ) {
1774 { /* MOV.B R0, @(disp, Rn) */
1775 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1776 load_reg( R_EAX, 0 );
1777 load_reg( R_ECX, Rn );
1778 ADD_imm32_r32( disp, R_ECX );
1779 MEM_WRITE_BYTE( R_ECX, R_EAX );
1783 { /* MOV.W R0, @(disp, Rn) */
1784 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1785 load_reg( R_ECX, Rn );
1786 load_reg( R_EAX, 0 );
1787 ADD_imm32_r32( disp, R_ECX );
1788 MEM_WRITE_WORD( R_ECX, R_EAX );
1792 { /* MOV.B @(disp, Rm), R0 */
1793 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
1794 load_reg( R_ECX, Rm );
1795 ADD_imm32_r32( disp, R_ECX );
1796 MEM_READ_BYTE( R_ECX, R_EAX );
1797 store_reg( R_EAX, 0 );
1801 { /* MOV.W @(disp, Rm), R0 */
1802 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
1803 load_reg( R_ECX, Rm );
1804 ADD_imm32_r32( disp, R_ECX );
1805 MEM_READ_WORD( R_ECX, R_EAX );
1806 store_reg( R_EAX, 0 );
1810 { /* CMP/EQ #imm, R0 */
1811 int32_t imm = SIGNEXT8(ir&0xFF);
1812 load_reg( R_EAX, 0 );
1813 CMP_imm8s_r32(imm, R_EAX);
1819 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1820 /* If true, result PC += 4 + disp. else result PC = pc+2 */
1826 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1827 CMP_imm8s_ebp( 0, R_T );
1829 exit_block( disp + pc + 4 );
1835 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1841 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
1842 CMP_imm8s_ebp( 0, R_T );
1844 exit_block( disp + pc + 4 );
1845 sh4_x86.in_delay_slot = TRUE;
1854 { /* MOV.W @(disp, PC), Rn */
1855 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
1856 load_imm32( R_ECX, pc + disp + 4 );
1857 MEM_READ_WORD( R_ECX, R_EAX );
1858 store_reg( R_EAX, Rn );
1863 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1864 exit_block( disp + pc + 4 );
1869 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
1873 switch( (ir&0xF00) >> 8 ) {
1875 { /* MOV.B R0, @(disp, GBR) */
1876 uint32_t disp = (ir&0xFF);
1877 load_reg( R_EAX, 0 );
1878 load_spreg( R_ECX, R_GBR );
1879 ADD_imm32_r32( disp, R_ECX );
1880 MEM_WRITE_BYTE( R_ECX, R_EAX );
1884 { /* MOV.W R0, @(disp, GBR) */
1885 uint32_t disp = (ir&0xFF)<<1;
1886 load_spreg( R_ECX, R_GBR );
1887 load_reg( R_EAX, 0 );
1888 ADD_imm32_r32( disp, R_ECX );
1889 MEM_WRITE_WORD( R_ECX, R_EAX );
1893 { /* MOV.L R0, @(disp, GBR) */
1894 uint32_t disp = (ir&0xFF)<<2;
1895 load_spreg( R_ECX, R_GBR );
1896 load_reg( R_EAX, 0 );
1897 ADD_imm32_r32( disp, R_ECX );
1898 MEM_WRITE_LONG( R_ECX, R_EAX );
1903 uint32_t imm = (ir&0xFF);
1907 { /* MOV.B @(disp, GBR), R0 */
1908 uint32_t disp = (ir&0xFF);
1909 load_spreg( R_ECX, R_GBR );
1910 ADD_imm32_r32( disp, R_ECX );
1911 MEM_READ_BYTE( R_ECX, R_EAX );
1912 store_reg( R_EAX, 0 );
1916 { /* MOV.W @(disp, GBR), R0 */
1917 uint32_t disp = (ir&0xFF)<<1;
1918 load_spreg( R_ECX, R_GBR );
1919 ADD_imm32_r32( disp, R_ECX );
1920 MEM_READ_WORD( R_ECX, R_EAX );
1921 store_reg( R_EAX, 0 );
1925 { /* MOV.L @(disp, GBR), R0 */
1926 uint32_t disp = (ir&0xFF)<<2;
1927 load_spreg( R_ECX, R_GBR );
1928 ADD_imm32_r32( disp, R_ECX );
1929 MEM_READ_LONG( R_ECX, R_EAX );
1930 store_reg( R_EAX, 0 );
1934 { /* MOVA @(disp, PC), R0 */
1935 uint32_t disp = (ir&0xFF)<<2;
1936 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
1937 store_reg( R_ECX, 0 );
1941 { /* TST #imm, R0 */
1942 uint32_t imm = (ir&0xFF);
1943 load_reg( R_EAX, 0 );
1944 TEST_imm32_r32( imm, R_EAX );
1949 { /* AND #imm, R0 */
1950 uint32_t imm = (ir&0xFF);
1951 load_reg( R_EAX, 0 );
1952 AND_imm32_r32(imm, R_EAX);
1953 store_reg( R_EAX, 0 );
1957 { /* XOR #imm, R0 */
1958 uint32_t imm = (ir&0xFF);
1959 load_reg( R_EAX, 0 );
1960 XOR_imm32_r32( imm, R_EAX );
1961 store_reg( R_EAX, 0 );
1966 uint32_t imm = (ir&0xFF);
1967 load_reg( R_EAX, 0 );
1968 OR_imm32_r32(imm, R_EAX);
1969 store_reg( R_EAX, 0 );
1973 { /* TST.B #imm, @(R0, GBR) */
1974 uint32_t imm = (ir&0xFF);
1975 load_reg( R_EAX, 0);
1976 load_reg( R_ECX, R_GBR);
1977 ADD_r32_r32( R_EAX, R_ECX );
1978 MEM_READ_BYTE( R_ECX, R_EAX );
1979 TEST_imm8_r8( imm, R_EAX );
1984 { /* AND.B #imm, @(R0, GBR) */
1985 uint32_t imm = (ir&0xFF);
1986 load_reg( R_EAX, 0 );
1987 load_spreg( R_ECX, R_GBR );
1988 ADD_r32_r32( R_EAX, R_EBX );
1989 MEM_READ_BYTE( R_ECX, R_EAX );
1990 AND_imm32_r32(imm, R_ECX );
1991 MEM_WRITE_BYTE( R_ECX, R_EAX );
1995 { /* XOR.B #imm, @(R0, GBR) */
1996 uint32_t imm = (ir&0xFF);
1997 load_reg( R_EAX, 0 );
1998 load_spreg( R_ECX, R_GBR );
1999 ADD_r32_r32( R_EAX, R_ECX );
2000 MEM_READ_BYTE( R_ECX, R_EAX );
2001 XOR_imm32_r32( imm, R_EAX );
2002 MEM_WRITE_BYTE( R_ECX, R_EAX );
2006 { /* OR.B #imm, @(R0, GBR) */
2007 uint32_t imm = (ir&0xFF);
2013 { /* MOV.L @(disp, PC), Rn */
2014 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2015 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2016 MEM_READ_LONG( R_ECX, R_EAX );
2017 store_reg( R_EAX, 0 );
2021 { /* MOV #imm, Rn */
2022 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2023 load_imm32( R_EAX, imm );
2024 store_reg( R_EAX, Rn );
2030 { /* FADD FRm, FRn */
2031 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2035 { /* FSUB FRm, FRn */
2036 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2040 { /* FMUL FRm, FRn */
2041 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2045 { /* FDIV FRm, FRn */
2046 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2050 { /* FCMP/EQ FRm, FRn */
2051 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2055 { /* FCMP/GT FRm, FRn */
2056 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2060 { /* FMOV @(R0, Rm), FRn */
2061 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2065 { /* FMOV FRm, @(R0, Rn) */
2066 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2070 { /* FMOV @Rm, FRn */
2071 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2075 { /* FMOV @Rm+, FRn */
2076 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2080 { /* FMOV FRm, @Rn */
2081 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2085 { /* FMOV FRm, @-Rn */
2086 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2090 { /* FMOV FRm, FRn */
2091 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
2095 switch( (ir&0xF0) >> 4 ) {
2097 { /* FSTS FPUL, FRn */
2098 uint32_t FRn = ((ir>>8)&0xF);
2102 { /* FLDS FRm, FPUL */
2103 uint32_t FRm = ((ir>>8)&0xF);
2107 { /* FLOAT FPUL, FRn */
2108 uint32_t FRn = ((ir>>8)&0xF);
2112 { /* FTRC FRm, FPUL */
2113 uint32_t FRm = ((ir>>8)&0xF);
2118 uint32_t FRn = ((ir>>8)&0xF);
2123 uint32_t FRn = ((ir>>8)&0xF);
2128 uint32_t FRn = ((ir>>8)&0xF);
2133 uint32_t FRn = ((ir>>8)&0xF);
2138 uint32_t FRn = ((ir>>8)&0xF);
2143 uint32_t FRn = ((ir>>8)&0xF);
2147 { /* FCNVSD FPUL, FRn */
2148 uint32_t FRn = ((ir>>8)&0xF);
2152 { /* FCNVDS FRm, FPUL */
2153 uint32_t FRm = ((ir>>8)&0xF);
2157 { /* FIPR FVm, FVn */
2158 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
2162 switch( (ir&0x100) >> 8 ) {
2164 { /* FSCA FPUL, FRn */
2165 uint32_t FRn = ((ir>>9)&0x7)<<1;
2169 switch( (ir&0x200) >> 9 ) {
2171 { /* FTRV XMTRX, FVn */
2172 uint32_t FVn = ((ir>>10)&0x3);
2176 switch( (ir&0xC00) >> 10 ) {
2204 { /* FMAC FR0, FRm, FRn */
2205 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
.