2 * $Id: sh4x86.in,v 1.20 2007-11-08 11:54:16 nkeynes Exp $
4 * SH4 => x86 translation. This version does no real optimization, it just
5 * outputs straight-line x86 code - it mainly exists to provide a baseline
6 * to test the optimizing versions against.
8 * Copyright (c) 2007 Nathan Keynes.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
28 #include "sh4/xltcache.h"
29 #include "sh4/sh4core.h"
30 #include "sh4/sh4trans.h"
31 #include "sh4/sh4mmio.h"
32 #include "sh4/x86op.h"
35 #define DEFAULT_BACKPATCH_SIZE 4096
38 * Struct to manage internal translation state. This state is not saved -
39 * it is only valid between calls to sh4_translate_begin_block() and
40 * sh4_translate_end_block()
42 struct sh4_x86_state {
43 gboolean in_delay_slot;
44 gboolean priv_checked; /* true if we've already checked the cpu mode. */
45 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
46 gboolean branch_taken; /* true if we branched unconditionally */
47 uint32_t block_start_pc;
50 /* Allocated memory for the (block-wide) back-patch list */
51 uint32_t **backpatch_list;
52 uint32_t backpatch_posn;
53 uint32_t backpatch_size;
56 #define TSTATE_NONE -1
66 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
67 #define JT_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
68 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
69 OP(0x70+sh4_x86.tstate); OP(rel8); \
71 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
72 #define JF_rel8(rel8,label) if( sh4_x86.tstate == TSTATE_NONE ) { \
73 CMP_imm8s_sh4r( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
74 OP(0x70+ (sh4_x86.tstate^1)); OP(rel8); \
78 #define EXIT_DATA_ADDR_READ 0
79 #define EXIT_DATA_ADDR_WRITE 7
80 #define EXIT_ILLEGAL 14
81 #define EXIT_SLOT_ILLEGAL 21
82 #define EXIT_FPU_DISABLED 28
83 #define EXIT_SLOT_FPU_DISABLED 35
85 static struct sh4_x86_state sh4_x86;
87 static uint32_t max_int = 0x7FFFFFFF;
88 static uint32_t min_int = 0x80000000;
89 static uint32_t save_fcw; /* save value for fpu control word */
90 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
94 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
95 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
99 static void sh4_x86_add_backpatch( uint8_t *ptr )
101 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
102 sh4_x86.backpatch_size <<= 1;
103 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
104 assert( sh4_x86.backpatch_list != NULL );
106 sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
109 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
112 for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
113 *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
118 * Emit an instruction to load an SH4 reg into a real register
120 static inline void load_reg( int x86reg, int sh4reg )
122 /* mov [bp+n], reg */
124 OP(0x45 + (x86reg<<3));
125 OP(REG_OFFSET(r[sh4reg]));
128 static inline void load_reg16s( int x86reg, int sh4reg )
132 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
135 static inline void load_reg16u( int x86reg, int sh4reg )
139 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
143 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
144 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
146 * Emit an instruction to load an immediate value into a register
148 static inline void load_imm32( int x86reg, uint32_t value ) {
149 /* mov #value, reg */
155 * Load an immediate 64-bit quantity (note: x86-64 only)
157 static inline void load_imm64( int x86reg, uint32_t value ) {
158 /* mov #value, reg */
166 * Emit an instruction to store an SH4 reg (RN)
168 void static inline store_reg( int x86reg, int sh4reg ) {
169 /* mov reg, [bp+n] */
171 OP(0x45 + (x86reg<<3));
172 OP(REG_OFFSET(r[sh4reg]));
175 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
178 * Load an FR register (single-precision floating point) into an integer x86
179 * register (eg for register-to-register moves)
181 void static inline load_fr( int bankreg, int x86reg, int frm )
183 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
187 * Store an FR register (single-precision floating point) into an integer x86
188 * register (eg for register-to-register moves)
190 void static inline store_fr( int bankreg, int x86reg, int frn )
192 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
197 * Load a pointer to the back fp back into the specified x86 register. The
198 * bankreg must have been previously loaded with FPSCR.
201 static inline void load_xf_bank( int bankreg )
204 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
205 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
206 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
210 * Update the fr_bank pointer based on the current fpscr value.
212 static inline void update_fr_bank( int fpscrreg )
214 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
215 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
216 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
217 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
220 * Push FPUL (as a 32-bit float) onto the FPU stack
222 static inline void push_fpul( )
224 OP(0xD9); OP(0x45); OP(R_FPUL);
228 * Pop FPUL (as a 32-bit float) from the FPU stack
230 static inline void pop_fpul( )
232 OP(0xD9); OP(0x5D); OP(R_FPUL);
236 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
237 * with the location of the current fp bank.
239 static inline void push_fr( int bankreg, int frm )
241 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
245 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
246 * with bankreg previously loaded with the location of the current fp bank.
248 static inline void pop_fr( int bankreg, int frm )
250 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
254 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
255 * with the location of the current fp bank.
257 static inline void push_dr( int bankreg, int frm )
259 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
262 static inline void pop_dr( int bankreg, int frm )
264 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
267 #if SH4_TRANSLATOR == TARGET_X86_64
268 /* X86-64 has different calling conventions... */
270 * Note: clobbers EAX to make the indirect call - this isn't usually
271 * a problem since the callee will usually clobber it anyway.
274 #define CALL_FUNC0_SIZE 12
275 static inline void call_func0( void *ptr )
277 load_imm64(R_EAX, (uint64_t)ptr);
281 #define CALL_FUNC1_SIZE 14
282 static inline void call_func1( void *ptr, int arg1 )
284 MOV_r32_r32(arg1, R_EDI);
288 #define CALL_FUNC2_SIZE 16
289 static inline void call_func2( void *ptr, int arg1, int arg2 )
291 MOV_r32_r32(arg1, R_EDI);
292 MOV_r32_r32(arg2, R_ESI);
296 #define MEM_WRITE_DOUBLE_SIZE 39
298 * Write a double (64-bit) value into memory, with the first word in arg2a, and
299 * the second in arg2b
301 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
304 MOV_r32_r32( addr, R_EDI );
305 MOV_r32_r32( arg2b, R_ESI );
306 REXW(); SHL_imm8_r32( 32, R_ESI );
307 REXW(); MOVZX_r16_r32( arg2a, arg2a );
308 REXW(); OR_r32_r32( arg2a, R_ESI );
309 call_func0(sh4_write_quad);
313 call_func2(sh4_write_long, addr, arg2a);
316 ADD_imm8s_r32(4, addr);
317 call_func2(sh4_write_long, addr, arg2b);
320 #define MEM_READ_DOUBLE_SIZE 35
322 * Read a double (64-bit) value from memory, writing the first word into arg2a
323 * and the second into arg2b. The addr must not be in EAX
325 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
328 MOV_r32_r32( addr, R_EDI );
329 call_func0(sh4_read_quad);
330 REXW(); MOV_r32_r32( R_EAX, arg2a );
331 REXW(); MOV_r32_r32( R_EAX, arg2b );
332 REXW(); SHR_imm8_r32( 32, arg2b );
335 call_func1(sh4_read_long, addr);
338 ADD_imm8s_r32(4, R_EDI);
339 call_func0(sh4_read_long);
340 MOV_r32_r32(R_EAX, arg2b);
344 #define EXIT_BLOCK_SIZE 35
346 * Exit the block to an absolute PC
348 void exit_block( sh4addr_t pc, sh4addr_t endpc )
350 load_imm32( R_ECX, pc ); // 5
351 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
352 REXW(); MOV_moff32_EAX( xlat_get_lut_entry(pc) );
353 REXW(); AND_imm8s_r32( 0xFC, R_EAX ); // 3
354 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
355 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
362 * Write the block trailer (exception handling block)
364 void sh4_translate_end_block( sh4addr_t pc ) {
365 if( sh4_x86.branch_taken == FALSE ) {
366 // Didn't exit unconditionally already, so write the termination here
367 exit_block( pc, pc );
369 if( sh4_x86.backpatch_posn != 0 ) {
370 uint8_t *end_ptr = xlat_output;
371 // Exception termination. Jump block for various exception codes:
372 load_imm32( R_EDI, EXC_DATA_ADDR_READ );
373 JMP_rel8( 33, target1 );
374 load_imm32( R_EDI, EXC_DATA_ADDR_WRITE );
375 JMP_rel8( 26, target2 );
376 load_imm32( R_EDI, EXC_ILLEGAL );
377 JMP_rel8( 19, target3 );
378 load_imm32( R_EDI, EXC_SLOT_ILLEGAL );
379 JMP_rel8( 12, target4 );
380 load_imm32( R_EDI, EXC_FPU_DISABLED );
381 JMP_rel8( 5, target5 );
382 load_imm32( R_EDI, EXC_SLOT_FPU_DISABLED );
390 load_spreg( R_ECX, REG_OFFSET(pc) );
391 ADD_r32_r32( R_EDX, R_ECX );
392 ADD_r32_r32( R_EDX, R_ECX );
393 store_spreg( R_ECX, REG_OFFSET(pc) );
394 MOV_moff32_EAX( &sh4_cpu_period );
396 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
398 call_func0( sh4_raise_exception );
399 load_spreg( R_EAX, REG_OFFSET(pc) );
400 call_func1(xlat_get_code,R_EAX);
404 sh4_x86_do_backpatch( end_ptr );
408 #else /* SH4_TRANSLATOR == TARGET_X86 */
411 * Note: clobbers EAX to make the indirect call - this isn't usually
412 * a problem since the callee will usually clobber it anyway.
414 #define CALL_FUNC0_SIZE 7
415 static inline void call_func0( void *ptr )
417 load_imm32(R_EAX, (uint32_t)ptr);
421 #define CALL_FUNC1_SIZE 11
422 static inline void call_func1( void *ptr, int arg1 )
426 ADD_imm8s_r32( 4, R_ESP );
429 #define CALL_FUNC2_SIZE 12
430 static inline void call_func2( void *ptr, int arg1, int arg2 )
435 ADD_imm8s_r32( 8, R_ESP );
439 * Write a double (64-bit) value into memory, with the first word in arg2a, and
440 * the second in arg2b
443 #define MEM_WRITE_DOUBLE_SIZE 30
444 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
446 ADD_imm8s_r32( 4, addr );
449 ADD_imm8s_r32( -4, addr );
452 call_func0(sh4_write_long);
453 ADD_imm8s_r32( 8, R_ESP );
454 call_func0(sh4_write_long);
455 ADD_imm8s_r32( 8, R_ESP );
459 * Read a double (64-bit) value from memory, writing the first word into arg2a
460 * and the second into arg2b. The addr must not be in EAX
463 #define MEM_READ_DOUBLE_SIZE 27
464 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
467 call_func0(sh4_read_long);
470 ADD_imm8s_r32( 4, addr );
472 call_func0(sh4_read_long);
473 ADD_imm8s_r32( 4, R_ESP );
474 MOV_r32_r32( R_EAX, arg2b );
478 #define EXIT_BLOCK_SIZE 29
480 * Exit the block to an absolute PC
482 void exit_block( sh4addr_t pc, sh4addr_t endpc )
484 load_imm32( R_ECX, pc ); // 5
485 store_spreg( R_ECX, REG_OFFSET(pc) ); // 3
486 MOV_moff32_EAX( xlat_get_lut_entry(pc) ); // 5
487 AND_imm8s_r32( 0xFC, R_EAX ); // 3
488 load_imm32( R_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
489 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
495 * Write the block trailer (exception handling block)
497 void sh4_translate_end_block( sh4addr_t pc ) {
498 if( sh4_x86.branch_taken == FALSE ) {
499 // Didn't exit unconditionally already, so write the termination here
500 exit_block( pc, pc );
502 if( sh4_x86.backpatch_posn != 0 ) {
503 uint8_t *end_ptr = xlat_output;
504 // Exception termination. Jump block for various exception codes:
505 PUSH_imm32( EXC_DATA_ADDR_READ );
506 JMP_rel8( 33, target1 );
507 PUSH_imm32( EXC_DATA_ADDR_WRITE );
508 JMP_rel8( 26, target2 );
509 PUSH_imm32( EXC_ILLEGAL );
510 JMP_rel8( 19, target3 );
511 PUSH_imm32( EXC_SLOT_ILLEGAL );
512 JMP_rel8( 12, target4 );
513 PUSH_imm32( EXC_FPU_DISABLED );
514 JMP_rel8( 5, target5 );
515 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
523 load_spreg( R_ECX, REG_OFFSET(pc) );
524 ADD_r32_r32( R_EDX, R_ECX );
525 ADD_r32_r32( R_EDX, R_ECX );
526 store_spreg( R_ECX, REG_OFFSET(pc) );
527 MOV_moff32_EAX( &sh4_cpu_period );
529 ADD_r32_sh4r( R_EAX, REG_OFFSET(slice_cycle) );
531 call_func0( sh4_raise_exception );
532 ADD_imm8s_r32( 4, R_ESP );
533 load_spreg( R_EAX, REG_OFFSET(pc) );
534 call_func1(xlat_get_code,R_EAX);
538 sh4_x86_do_backpatch( end_ptr );
543 /* Exception checks - Note that all exception checks will clobber EAX */
544 #define precheck() load_imm32(R_EDX, (pc-sh4_x86.block_start_pc-(sh4_x86.in_delay_slot?2:0))>>1)
546 #define check_priv( ) \
547 if( !sh4_x86.priv_checked ) { \
548 sh4_x86.priv_checked = TRUE;\
550 load_spreg( R_EAX, R_SR );\
551 AND_imm32_r32( SR_MD, R_EAX );\
552 if( sh4_x86.in_delay_slot ) {\
553 JE_exit( EXIT_SLOT_ILLEGAL );\
555 JE_exit( EXIT_ILLEGAL );\
560 static void check_priv_no_precheck()
562 if( !sh4_x86.priv_checked ) {
563 sh4_x86.priv_checked = TRUE;
564 load_spreg( R_EAX, R_SR );
565 AND_imm32_r32( SR_MD, R_EAX );
566 if( sh4_x86.in_delay_slot ) {
567 JE_exit( EXIT_SLOT_ILLEGAL );
569 JE_exit( EXIT_ILLEGAL );
574 #define check_fpuen( ) \
575 if( !sh4_x86.fpuen_checked ) {\
576 sh4_x86.fpuen_checked = TRUE;\
578 load_spreg( R_EAX, R_SR );\
579 AND_imm32_r32( SR_FD, R_EAX );\
580 if( sh4_x86.in_delay_slot ) {\
581 JNE_exit(EXIT_SLOT_FPU_DISABLED);\
583 JNE_exit(EXIT_FPU_DISABLED);\
587 static void check_fpuen_no_precheck()
589 if( !sh4_x86.fpuen_checked ) {
590 sh4_x86.fpuen_checked = TRUE;
591 load_spreg( R_EAX, R_SR );
592 AND_imm32_r32( SR_FD, R_EAX );
593 if( sh4_x86.in_delay_slot ) {
594 JNE_exit(EXIT_SLOT_FPU_DISABLED);
596 JNE_exit(EXIT_FPU_DISABLED);
602 static void check_ralign16( int x86reg )
604 TEST_imm32_r32( 0x00000001, x86reg );
605 JNE_exit(EXIT_DATA_ADDR_READ);
608 static void check_walign16( int x86reg )
610 TEST_imm32_r32( 0x00000001, x86reg );
611 JNE_exit(EXIT_DATA_ADDR_WRITE);
614 static void check_ralign32( int x86reg )
616 TEST_imm32_r32( 0x00000003, x86reg );
617 JNE_exit(EXIT_DATA_ADDR_READ);
619 static void check_walign32( int x86reg )
621 TEST_imm32_r32( 0x00000003, x86reg );
622 JNE_exit(EXIT_DATA_ADDR_WRITE);
626 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
627 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
628 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
629 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
630 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
631 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
632 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
634 #define SLOTILLEGAL() precheck(); JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
639 * Emit the 'start of block' assembly. Sets up the stack frame and save
642 void sh4_translate_begin_block( sh4addr_t pc )
646 load_imm32( R_EBP, (uint32_t)&sh4r );
648 sh4_x86.in_delay_slot = FALSE;
649 sh4_x86.priv_checked = FALSE;
650 sh4_x86.fpuen_checked = FALSE;
651 sh4_x86.branch_taken = FALSE;
652 sh4_x86.backpatch_posn = 0;
653 sh4_x86.block_start_pc = pc;
654 sh4_x86.tstate = TSTATE_NONE;
658 * Exit the block with sh4r.pc already written
661 void exit_block_pcset( pc )
663 load_imm32( R_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
664 ADD_r32_sh4r( R_ECX, REG_OFFSET(slice_cycle) ); // 6
665 load_spreg( R_EAX, REG_OFFSET(pc) );
666 call_func1(xlat_get_code,R_EAX);
671 extern uint16_t *sh4_icache;
672 extern uint32_t sh4_icache_addr;
675 * Translate a single instruction. Delayed branches are handled specially
676 * by translating both branch and delayed instruction as a single unit (as
679 * @return true if the instruction marks the end of a basic block
682 uint32_t sh4_translate_instruction( sh4addr_t pc )
685 /* Read instruction */
686 uint32_t pageaddr = pc >> 12;
687 if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
688 ir = sh4_icache[(pc&0xFFF)>>1];
690 sh4_icache = (uint16_t *)mem_get_page(pc);
691 if( ((uintptr_t)sh4_icache) < MAX_IO_REGIONS ) {
692 /* If someone's actually been so daft as to try to execute out of an IO
693 * region, fallback on the full-blown memory read
696 ir = sh4_read_word(pc);
698 sh4_icache_addr = pageaddr;
699 ir = sh4_icache[(pc&0xFFF)>>1];
703 switch( (ir&0xF000) >> 12 ) {
707 switch( (ir&0x80) >> 7 ) {
709 switch( (ir&0x70) >> 4 ) {
712 uint32_t Rn = ((ir>>8)&0xF);
714 call_func0(sh4_read_sr);
715 store_reg( R_EAX, Rn );
716 sh4_x86.tstate = TSTATE_NONE;
721 uint32_t Rn = ((ir>>8)&0xF);
722 load_spreg( R_EAX, R_GBR );
723 store_reg( R_EAX, Rn );
728 uint32_t Rn = ((ir>>8)&0xF);
730 load_spreg( R_EAX, R_VBR );
731 store_reg( R_EAX, Rn );
732 sh4_x86.tstate = TSTATE_NONE;
737 uint32_t Rn = ((ir>>8)&0xF);
739 load_spreg( R_EAX, R_SSR );
740 store_reg( R_EAX, Rn );
741 sh4_x86.tstate = TSTATE_NONE;
746 uint32_t Rn = ((ir>>8)&0xF);
748 load_spreg( R_EAX, R_SPC );
749 store_reg( R_EAX, Rn );
750 sh4_x86.tstate = TSTATE_NONE;
759 { /* STC Rm_BANK, Rn */
760 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
762 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
763 store_reg( R_EAX, Rn );
764 sh4_x86.tstate = TSTATE_NONE;
770 switch( (ir&0xF0) >> 4 ) {
773 uint32_t Rn = ((ir>>8)&0xF);
774 if( sh4_x86.in_delay_slot ) {
777 load_imm32( R_ECX, pc + 4 );
778 store_spreg( R_ECX, R_PR );
779 ADD_sh4r_r32( REG_OFFSET(r[Rn]), R_ECX );
780 store_spreg( R_ECX, REG_OFFSET(pc) );
781 sh4_x86.in_delay_slot = TRUE;
782 sh4_x86.tstate = TSTATE_NONE;
783 sh4_translate_instruction( pc + 2 );
784 exit_block_pcset(pc+2);
785 sh4_x86.branch_taken = TRUE;
792 uint32_t Rn = ((ir>>8)&0xF);
793 if( sh4_x86.in_delay_slot ) {
796 load_reg( R_EAX, Rn );
797 ADD_imm32_r32( pc + 4, R_EAX );
798 store_spreg( R_EAX, REG_OFFSET(pc) );
799 sh4_x86.in_delay_slot = TRUE;
800 sh4_x86.tstate = TSTATE_NONE;
801 sh4_translate_instruction( pc + 2 );
802 exit_block_pcset(pc+2);
803 sh4_x86.branch_taken = TRUE;
810 uint32_t Rn = ((ir>>8)&0xF);
811 load_reg( R_EAX, Rn );
813 AND_imm32_r32( 0xFC000000, R_EAX );
814 CMP_imm32_r32( 0xE0000000, R_EAX );
815 JNE_rel8(CALL_FUNC0_SIZE, end);
816 call_func0( sh4_flush_store_queue );
818 ADD_imm8s_r32( 4, R_ESP );
819 sh4_x86.tstate = TSTATE_NONE;
824 uint32_t Rn = ((ir>>8)&0xF);
829 uint32_t Rn = ((ir>>8)&0xF);
834 uint32_t Rn = ((ir>>8)&0xF);
838 { /* MOVCA.L R0, @Rn */
839 uint32_t Rn = ((ir>>8)&0xF);
840 load_reg( R_EAX, 0 );
841 load_reg( R_ECX, Rn );
843 check_walign32( R_ECX );
844 MEM_WRITE_LONG( R_ECX, R_EAX );
845 sh4_x86.tstate = TSTATE_NONE;
854 { /* MOV.B Rm, @(R0, Rn) */
855 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
856 load_reg( R_EAX, 0 );
857 load_reg( R_ECX, Rn );
858 ADD_r32_r32( R_EAX, R_ECX );
859 load_reg( R_EAX, Rm );
860 MEM_WRITE_BYTE( R_ECX, R_EAX );
861 sh4_x86.tstate = TSTATE_NONE;
865 { /* MOV.W Rm, @(R0, Rn) */
866 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
867 load_reg( R_EAX, 0 );
868 load_reg( R_ECX, Rn );
869 ADD_r32_r32( R_EAX, R_ECX );
871 check_walign16( R_ECX );
872 load_reg( R_EAX, Rm );
873 MEM_WRITE_WORD( R_ECX, R_EAX );
874 sh4_x86.tstate = TSTATE_NONE;
878 { /* MOV.L Rm, @(R0, Rn) */
879 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
880 load_reg( R_EAX, 0 );
881 load_reg( R_ECX, Rn );
882 ADD_r32_r32( R_EAX, R_ECX );
884 check_walign32( R_ECX );
885 load_reg( R_EAX, Rm );
886 MEM_WRITE_LONG( R_ECX, R_EAX );
887 sh4_x86.tstate = TSTATE_NONE;
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 );
896 store_spreg( R_EAX, R_MACL );
897 sh4_x86.tstate = TSTATE_NONE;
901 switch( (ir&0xFF0) >> 4 ) {
906 sh4_x86.tstate = TSTATE_C;
913 sh4_x86.tstate = TSTATE_C;
918 XOR_r32_r32(R_EAX, R_EAX);
919 store_spreg( R_EAX, R_MACL );
920 store_spreg( R_EAX, R_MACH );
921 sh4_x86.tstate = TSTATE_NONE;
932 sh4_x86.tstate = TSTATE_C;
939 sh4_x86.tstate = TSTATE_C;
948 switch( (ir&0xF0) >> 4 ) {
951 /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */
956 XOR_r32_r32( R_EAX, R_EAX );
957 store_spreg( R_EAX, R_Q );
958 store_spreg( R_EAX, R_M );
959 store_spreg( R_EAX, R_T );
960 sh4_x86.tstate = TSTATE_C; // works for DIV1
965 uint32_t Rn = ((ir>>8)&0xF);
966 load_spreg( R_EAX, R_T );
967 store_reg( R_EAX, Rn );
976 switch( (ir&0xF0) >> 4 ) {
979 uint32_t Rn = ((ir>>8)&0xF);
980 load_spreg( R_EAX, R_MACH );
981 store_reg( R_EAX, Rn );
986 uint32_t Rn = ((ir>>8)&0xF);
987 load_spreg( R_EAX, R_MACL );
988 store_reg( R_EAX, Rn );
993 uint32_t Rn = ((ir>>8)&0xF);
994 load_spreg( R_EAX, R_PR );
995 store_reg( R_EAX, Rn );
1000 uint32_t Rn = ((ir>>8)&0xF);
1002 load_spreg( R_EAX, R_SGR );
1003 store_reg( R_EAX, Rn );
1004 sh4_x86.tstate = TSTATE_NONE;
1008 { /* STS FPUL, Rn */
1009 uint32_t Rn = ((ir>>8)&0xF);
1010 load_spreg( R_EAX, R_FPUL );
1011 store_reg( R_EAX, Rn );
1015 { /* STS FPSCR, Rn */
1016 uint32_t Rn = ((ir>>8)&0xF);
1017 load_spreg( R_EAX, R_FPSCR );
1018 store_reg( R_EAX, Rn );
1023 uint32_t Rn = ((ir>>8)&0xF);
1025 load_spreg( R_EAX, R_DBR );
1026 store_reg( R_EAX, Rn );
1027 sh4_x86.tstate = TSTATE_NONE;
1036 switch( (ir&0xFF0) >> 4 ) {
1039 if( sh4_x86.in_delay_slot ) {
1042 load_spreg( R_ECX, R_PR );
1043 store_spreg( R_ECX, REG_OFFSET(pc) );
1044 sh4_x86.in_delay_slot = TRUE;
1045 sh4_translate_instruction(pc+2);
1046 exit_block_pcset(pc+2);
1047 sh4_x86.branch_taken = TRUE;
1055 call_func0( sh4_sleep );
1056 sh4_x86.tstate = TSTATE_NONE;
1057 sh4_x86.in_delay_slot = FALSE;
1063 if( sh4_x86.in_delay_slot ) {
1067 load_spreg( R_ECX, R_SPC );
1068 store_spreg( R_ECX, REG_OFFSET(pc) );
1069 load_spreg( R_EAX, R_SSR );
1070 call_func1( sh4_write_sr, R_EAX );
1071 sh4_x86.in_delay_slot = TRUE;
1072 sh4_x86.priv_checked = FALSE;
1073 sh4_x86.fpuen_checked = FALSE;
1074 sh4_x86.tstate = TSTATE_NONE;
1075 sh4_translate_instruction(pc+2);
1076 exit_block_pcset(pc+2);
1077 sh4_x86.branch_taken = TRUE;
1088 { /* MOV.B @(R0, Rm), Rn */
1089 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1090 load_reg( R_EAX, 0 );
1091 load_reg( R_ECX, Rm );
1092 ADD_r32_r32( R_EAX, R_ECX );
1093 MEM_READ_BYTE( R_ECX, R_EAX );
1094 store_reg( R_EAX, Rn );
1095 sh4_x86.tstate = TSTATE_NONE;
1099 { /* MOV.W @(R0, Rm), Rn */
1100 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1101 load_reg( R_EAX, 0 );
1102 load_reg( R_ECX, Rm );
1103 ADD_r32_r32( R_EAX, R_ECX );
1105 check_ralign16( R_ECX );
1106 MEM_READ_WORD( R_ECX, R_EAX );
1107 store_reg( R_EAX, Rn );
1108 sh4_x86.tstate = TSTATE_NONE;
1112 { /* MOV.L @(R0, Rm), Rn */
1113 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1114 load_reg( R_EAX, 0 );
1115 load_reg( R_ECX, Rm );
1116 ADD_r32_r32( R_EAX, R_ECX );
1118 check_ralign32( R_ECX );
1119 MEM_READ_LONG( R_ECX, R_EAX );
1120 store_reg( R_EAX, Rn );
1121 sh4_x86.tstate = TSTATE_NONE;
1125 { /* MAC.L @Rm+, @Rn+ */
1126 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1127 load_reg( R_ECX, Rm );
1129 check_ralign32( R_ECX );
1130 load_reg( R_ECX, Rn );
1131 check_ralign32( R_ECX );
1132 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
1133 MEM_READ_LONG( R_ECX, R_EAX );
1135 load_reg( R_ECX, Rm );
1136 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
1137 MEM_READ_LONG( R_ECX, R_EAX );
1140 ADD_r32_sh4r( R_EAX, R_MACL );
1141 ADC_r32_sh4r( R_EDX, R_MACH );
1143 load_spreg( R_ECX, R_S );
1144 TEST_r32_r32(R_ECX, R_ECX);
1145 JE_rel8( CALL_FUNC0_SIZE, nosat );
1146 call_func0( signsat48 );
1147 JMP_TARGET( nosat );
1148 sh4_x86.tstate = TSTATE_NONE;
1157 { /* MOV.L Rm, @(disp, Rn) */
1158 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
1159 load_reg( R_ECX, Rn );
1160 load_reg( R_EAX, Rm );
1161 ADD_imm32_r32( disp, R_ECX );
1163 check_walign32( R_ECX );
1164 MEM_WRITE_LONG( R_ECX, R_EAX );
1165 sh4_x86.tstate = TSTATE_NONE;
1171 { /* MOV.B Rm, @Rn */
1172 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1173 load_reg( R_EAX, Rm );
1174 load_reg( R_ECX, Rn );
1175 MEM_WRITE_BYTE( R_ECX, R_EAX );
1176 sh4_x86.tstate = TSTATE_NONE;
1180 { /* MOV.W Rm, @Rn */
1181 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1182 load_reg( R_ECX, Rn );
1184 check_walign16( R_ECX );
1185 load_reg( R_EAX, Rm );
1186 MEM_WRITE_WORD( R_ECX, R_EAX );
1187 sh4_x86.tstate = TSTATE_NONE;
1191 { /* MOV.L Rm, @Rn */
1192 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1193 load_reg( R_EAX, Rm );
1194 load_reg( R_ECX, Rn );
1196 check_walign32(R_ECX);
1197 MEM_WRITE_LONG( R_ECX, R_EAX );
1198 sh4_x86.tstate = TSTATE_NONE;
1202 { /* MOV.B Rm, @-Rn */
1203 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1204 load_reg( R_EAX, Rm );
1205 load_reg( R_ECX, Rn );
1206 ADD_imm8s_r32( -1, R_ECX );
1207 store_reg( R_ECX, Rn );
1208 MEM_WRITE_BYTE( R_ECX, R_EAX );
1209 sh4_x86.tstate = TSTATE_NONE;
1213 { /* MOV.W Rm, @-Rn */
1214 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1215 load_reg( R_ECX, Rn );
1217 check_walign16( R_ECX );
1218 load_reg( R_EAX, Rm );
1219 ADD_imm8s_r32( -2, R_ECX );
1220 store_reg( R_ECX, Rn );
1221 MEM_WRITE_WORD( R_ECX, R_EAX );
1222 sh4_x86.tstate = TSTATE_NONE;
1226 { /* MOV.L Rm, @-Rn */
1227 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1228 load_reg( R_EAX, Rm );
1229 load_reg( R_ECX, Rn );
1231 check_walign32( R_ECX );
1232 ADD_imm8s_r32( -4, R_ECX );
1233 store_reg( R_ECX, Rn );
1234 MEM_WRITE_LONG( R_ECX, R_EAX );
1235 sh4_x86.tstate = TSTATE_NONE;
1239 { /* DIV0S Rm, Rn */
1240 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1241 load_reg( R_EAX, Rm );
1242 load_reg( R_ECX, Rn );
1243 SHR_imm8_r32( 31, R_EAX );
1244 SHR_imm8_r32( 31, R_ECX );
1245 store_spreg( R_EAX, R_M );
1246 store_spreg( R_ECX, R_Q );
1247 CMP_r32_r32( R_EAX, R_ECX );
1249 sh4_x86.tstate = TSTATE_NE;
1254 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1255 load_reg( R_EAX, Rm );
1256 load_reg( R_ECX, Rn );
1257 TEST_r32_r32( R_EAX, R_ECX );
1259 sh4_x86.tstate = TSTATE_E;
1264 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1265 load_reg( R_EAX, Rm );
1266 load_reg( R_ECX, Rn );
1267 AND_r32_r32( R_EAX, R_ECX );
1268 store_reg( R_ECX, Rn );
1269 sh4_x86.tstate = TSTATE_NONE;
1274 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1275 load_reg( R_EAX, Rm );
1276 load_reg( R_ECX, Rn );
1277 XOR_r32_r32( R_EAX, R_ECX );
1278 store_reg( R_ECX, Rn );
1279 sh4_x86.tstate = TSTATE_NONE;
1284 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1285 load_reg( R_EAX, Rm );
1286 load_reg( R_ECX, Rn );
1287 OR_r32_r32( R_EAX, R_ECX );
1288 store_reg( R_ECX, Rn );
1289 sh4_x86.tstate = TSTATE_NONE;
1293 { /* CMP/STR Rm, Rn */
1294 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1295 load_reg( R_EAX, Rm );
1296 load_reg( R_ECX, Rn );
1297 XOR_r32_r32( R_ECX, R_EAX );
1298 TEST_r8_r8( R_AL, R_AL );
1299 JE_rel8(13, target1);
1300 TEST_r8_r8( R_AH, R_AH ); // 2
1301 JE_rel8(9, target2);
1302 SHR_imm8_r32( 16, R_EAX ); // 3
1303 TEST_r8_r8( R_AL, R_AL ); // 2
1304 JE_rel8(2, target3);
1305 TEST_r8_r8( R_AH, R_AH ); // 2
1306 JMP_TARGET(target1);
1307 JMP_TARGET(target2);
1308 JMP_TARGET(target3);
1310 sh4_x86.tstate = TSTATE_E;
1314 { /* XTRCT Rm, Rn */
1315 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1316 load_reg( R_EAX, Rm );
1317 load_reg( R_ECX, Rn );
1318 SHL_imm8_r32( 16, R_EAX );
1319 SHR_imm8_r32( 16, R_ECX );
1320 OR_r32_r32( R_EAX, R_ECX );
1321 store_reg( R_ECX, Rn );
1322 sh4_x86.tstate = TSTATE_NONE;
1326 { /* MULU.W Rm, Rn */
1327 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1328 load_reg16u( R_EAX, Rm );
1329 load_reg16u( R_ECX, Rn );
1331 store_spreg( R_EAX, R_MACL );
1332 sh4_x86.tstate = TSTATE_NONE;
1336 { /* MULS.W Rm, Rn */
1337 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1338 load_reg16s( R_EAX, Rm );
1339 load_reg16s( R_ECX, Rn );
1341 store_spreg( R_EAX, R_MACL );
1342 sh4_x86.tstate = TSTATE_NONE;
1353 { /* CMP/EQ Rm, Rn */
1354 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1355 load_reg( R_EAX, Rm );
1356 load_reg( R_ECX, Rn );
1357 CMP_r32_r32( R_EAX, R_ECX );
1359 sh4_x86.tstate = TSTATE_E;
1363 { /* CMP/HS Rm, Rn */
1364 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1365 load_reg( R_EAX, Rm );
1366 load_reg( R_ECX, Rn );
1367 CMP_r32_r32( R_EAX, R_ECX );
1369 sh4_x86.tstate = TSTATE_AE;
1373 { /* CMP/GE Rm, Rn */
1374 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1375 load_reg( R_EAX, Rm );
1376 load_reg( R_ECX, Rn );
1377 CMP_r32_r32( R_EAX, R_ECX );
1379 sh4_x86.tstate = TSTATE_GE;
1384 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1385 load_spreg( R_ECX, R_M );
1386 load_reg( R_EAX, Rn );
1387 if( sh4_x86.tstate != TSTATE_C ) {
1391 SETC_r8( R_DL ); // Q'
1392 CMP_sh4r_r32( R_Q, R_ECX );
1393 JE_rel8(5, mqequal);
1394 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1396 JMP_TARGET(mqequal);
1397 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
1399 store_reg( R_EAX, Rn ); // Done with Rn now
1400 SETC_r8(R_AL); // tmp1
1401 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
1402 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
1403 store_spreg( R_ECX, R_Q );
1404 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
1405 MOVZX_r8_r32( R_AL, R_EAX );
1406 store_spreg( R_EAX, R_T );
1407 sh4_x86.tstate = TSTATE_NONE;
1411 { /* DMULU.L Rm, Rn */
1412 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1413 load_reg( R_EAX, Rm );
1414 load_reg( R_ECX, Rn );
1416 store_spreg( R_EDX, R_MACH );
1417 store_spreg( R_EAX, R_MACL );
1418 sh4_x86.tstate = TSTATE_NONE;
1422 { /* CMP/HI Rm, Rn */
1423 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1424 load_reg( R_EAX, Rm );
1425 load_reg( R_ECX, Rn );
1426 CMP_r32_r32( R_EAX, R_ECX );
1428 sh4_x86.tstate = TSTATE_A;
1432 { /* CMP/GT Rm, Rn */
1433 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1434 load_reg( R_EAX, Rm );
1435 load_reg( R_ECX, Rn );
1436 CMP_r32_r32( R_EAX, R_ECX );
1438 sh4_x86.tstate = TSTATE_G;
1443 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1444 load_reg( R_EAX, Rm );
1445 load_reg( R_ECX, Rn );
1446 SUB_r32_r32( R_EAX, R_ECX );
1447 store_reg( R_ECX, Rn );
1448 sh4_x86.tstate = TSTATE_NONE;
1453 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1454 load_reg( R_EAX, Rm );
1455 load_reg( R_ECX, Rn );
1456 if( sh4_x86.tstate != TSTATE_C ) {
1459 SBB_r32_r32( R_EAX, R_ECX );
1460 store_reg( R_ECX, Rn );
1462 sh4_x86.tstate = TSTATE_C;
1467 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1468 load_reg( R_EAX, Rm );
1469 load_reg( R_ECX, Rn );
1470 SUB_r32_r32( R_EAX, R_ECX );
1471 store_reg( R_ECX, Rn );
1473 sh4_x86.tstate = TSTATE_O;
1478 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1479 load_reg( R_EAX, Rm );
1480 load_reg( R_ECX, Rn );
1481 ADD_r32_r32( R_EAX, R_ECX );
1482 store_reg( R_ECX, Rn );
1483 sh4_x86.tstate = TSTATE_NONE;
1487 { /* DMULS.L Rm, Rn */
1488 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1489 load_reg( R_EAX, Rm );
1490 load_reg( R_ECX, Rn );
1492 store_spreg( R_EDX, R_MACH );
1493 store_spreg( R_EAX, R_MACL );
1494 sh4_x86.tstate = TSTATE_NONE;
1499 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1500 if( sh4_x86.tstate != TSTATE_C ) {
1503 load_reg( R_EAX, Rm );
1504 load_reg( R_ECX, Rn );
1505 ADC_r32_r32( R_EAX, R_ECX );
1506 store_reg( R_ECX, Rn );
1508 sh4_x86.tstate = TSTATE_C;
1513 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
1514 load_reg( R_EAX, Rm );
1515 load_reg( R_ECX, Rn );
1516 ADD_r32_r32( R_EAX, R_ECX );
1517 store_reg( R_ECX, Rn );
1519 sh4_x86.tstate = TSTATE_O;
1530 switch( (ir&0xF0) >> 4 ) {
1533 uint32_t Rn = ((ir>>8)&0xF);
1534 load_reg( R_EAX, Rn );
1537 store_reg( R_EAX, Rn );
1538 sh4_x86.tstate = TSTATE_C;
1543 uint32_t Rn = ((ir>>8)&0xF);
1544 load_reg( R_EAX, Rn );
1545 ADD_imm8s_r32( -1, R_EAX );
1546 store_reg( R_EAX, Rn );
1548 sh4_x86.tstate = TSTATE_E;
1553 uint32_t Rn = ((ir>>8)&0xF);
1554 load_reg( R_EAX, Rn );
1557 store_reg( R_EAX, Rn );
1558 sh4_x86.tstate = TSTATE_C;
1567 switch( (ir&0xF0) >> 4 ) {
1570 uint32_t Rn = ((ir>>8)&0xF);
1571 load_reg( R_EAX, Rn );
1574 store_reg( R_EAX, Rn );
1575 sh4_x86.tstate = TSTATE_C;
1580 uint32_t Rn = ((ir>>8)&0xF);
1581 load_reg( R_EAX, Rn );
1582 CMP_imm8s_r32( 0, R_EAX );
1584 sh4_x86.tstate = TSTATE_GE;
1589 uint32_t Rn = ((ir>>8)&0xF);
1590 load_reg( R_EAX, Rn );
1593 store_reg( R_EAX, Rn );
1594 sh4_x86.tstate = TSTATE_C;
1603 switch( (ir&0xF0) >> 4 ) {
1605 { /* STS.L MACH, @-Rn */
1606 uint32_t Rn = ((ir>>8)&0xF);
1607 load_reg( R_ECX, Rn );
1609 check_walign32( R_ECX );
1610 ADD_imm8s_r32( -4, R_ECX );
1611 store_reg( R_ECX, Rn );
1612 load_spreg( R_EAX, R_MACH );
1613 MEM_WRITE_LONG( R_ECX, R_EAX );
1614 sh4_x86.tstate = TSTATE_NONE;
1618 { /* STS.L MACL, @-Rn */
1619 uint32_t Rn = ((ir>>8)&0xF);
1620 load_reg( R_ECX, Rn );
1622 check_walign32( R_ECX );
1623 ADD_imm8s_r32( -4, R_ECX );
1624 store_reg( R_ECX, Rn );
1625 load_spreg( R_EAX, R_MACL );
1626 MEM_WRITE_LONG( R_ECX, R_EAX );
1627 sh4_x86.tstate = TSTATE_NONE;
1631 { /* STS.L PR, @-Rn */
1632 uint32_t Rn = ((ir>>8)&0xF);
1633 load_reg( R_ECX, Rn );
1635 check_walign32( R_ECX );
1636 ADD_imm8s_r32( -4, R_ECX );
1637 store_reg( R_ECX, Rn );
1638 load_spreg( R_EAX, R_PR );
1639 MEM_WRITE_LONG( R_ECX, R_EAX );
1640 sh4_x86.tstate = TSTATE_NONE;
1644 { /* STC.L SGR, @-Rn */
1645 uint32_t Rn = ((ir>>8)&0xF);
1647 check_priv_no_precheck();
1648 load_reg( R_ECX, Rn );
1649 check_walign32( R_ECX );
1650 ADD_imm8s_r32( -4, R_ECX );
1651 store_reg( R_ECX, Rn );
1652 load_spreg( R_EAX, R_SGR );
1653 MEM_WRITE_LONG( R_ECX, R_EAX );
1654 sh4_x86.tstate = TSTATE_NONE;
1658 { /* STS.L FPUL, @-Rn */
1659 uint32_t Rn = ((ir>>8)&0xF);
1660 load_reg( R_ECX, Rn );
1662 check_walign32( R_ECX );
1663 ADD_imm8s_r32( -4, R_ECX );
1664 store_reg( R_ECX, Rn );
1665 load_spreg( R_EAX, R_FPUL );
1666 MEM_WRITE_LONG( R_ECX, R_EAX );
1667 sh4_x86.tstate = TSTATE_NONE;
1671 { /* STS.L FPSCR, @-Rn */
1672 uint32_t Rn = ((ir>>8)&0xF);
1673 load_reg( R_ECX, Rn );
1675 check_walign32( R_ECX );
1676 ADD_imm8s_r32( -4, R_ECX );
1677 store_reg( R_ECX, Rn );
1678 load_spreg( R_EAX, R_FPSCR );
1679 MEM_WRITE_LONG( R_ECX, R_EAX );
1680 sh4_x86.tstate = TSTATE_NONE;
1684 { /* STC.L DBR, @-Rn */
1685 uint32_t Rn = ((ir>>8)&0xF);
1687 check_priv_no_precheck();
1688 load_reg( R_ECX, Rn );
1689 check_walign32( R_ECX );
1690 ADD_imm8s_r32( -4, R_ECX );
1691 store_reg( R_ECX, Rn );
1692 load_spreg( R_EAX, R_DBR );
1693 MEM_WRITE_LONG( R_ECX, R_EAX );
1694 sh4_x86.tstate = TSTATE_NONE;
1703 switch( (ir&0x80) >> 7 ) {
1705 switch( (ir&0x70) >> 4 ) {
1707 { /* STC.L SR, @-Rn */
1708 uint32_t Rn = ((ir>>8)&0xF);
1710 check_priv_no_precheck();
1711 call_func0( sh4_read_sr );
1712 load_reg( R_ECX, Rn );
1713 check_walign32( R_ECX );
1714 ADD_imm8s_r32( -4, R_ECX );
1715 store_reg( R_ECX, Rn );
1716 MEM_WRITE_LONG( R_ECX, R_EAX );
1717 sh4_x86.tstate = TSTATE_NONE;
1721 { /* STC.L GBR, @-Rn */
1722 uint32_t Rn = ((ir>>8)&0xF);
1723 load_reg( R_ECX, Rn );
1725 check_walign32( R_ECX );
1726 ADD_imm8s_r32( -4, R_ECX );
1727 store_reg( R_ECX, Rn );
1728 load_spreg( R_EAX, R_GBR );
1729 MEM_WRITE_LONG( R_ECX, R_EAX );
1730 sh4_x86.tstate = TSTATE_NONE;
1734 { /* STC.L VBR, @-Rn */
1735 uint32_t Rn = ((ir>>8)&0xF);
1737 check_priv_no_precheck();
1738 load_reg( R_ECX, Rn );
1739 check_walign32( R_ECX );
1740 ADD_imm8s_r32( -4, R_ECX );
1741 store_reg( R_ECX, Rn );
1742 load_spreg( R_EAX, R_VBR );
1743 MEM_WRITE_LONG( R_ECX, R_EAX );
1744 sh4_x86.tstate = TSTATE_NONE;
1748 { /* STC.L SSR, @-Rn */
1749 uint32_t Rn = ((ir>>8)&0xF);
1751 check_priv_no_precheck();
1752 load_reg( R_ECX, Rn );
1753 check_walign32( R_ECX );
1754 ADD_imm8s_r32( -4, R_ECX );
1755 store_reg( R_ECX, Rn );
1756 load_spreg( R_EAX, R_SSR );
1757 MEM_WRITE_LONG( R_ECX, R_EAX );
1758 sh4_x86.tstate = TSTATE_NONE;
1762 { /* STC.L SPC, @-Rn */
1763 uint32_t Rn = ((ir>>8)&0xF);
1765 check_priv_no_precheck();
1766 load_reg( R_ECX, Rn );
1767 check_walign32( R_ECX );
1768 ADD_imm8s_r32( -4, R_ECX );
1769 store_reg( R_ECX, Rn );
1770 load_spreg( R_EAX, R_SPC );
1771 MEM_WRITE_LONG( R_ECX, R_EAX );
1772 sh4_x86.tstate = TSTATE_NONE;
1781 { /* STC.L Rm_BANK, @-Rn */
1782 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm_BANK = ((ir>>4)&0x7);
1784 check_priv_no_precheck();
1785 load_reg( R_ECX, Rn );
1786 check_walign32( R_ECX );
1787 ADD_imm8s_r32( -4, R_ECX );
1788 store_reg( R_ECX, Rn );
1789 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1790 MEM_WRITE_LONG( R_ECX, R_EAX );
1791 sh4_x86.tstate = TSTATE_NONE;
1797 switch( (ir&0xF0) >> 4 ) {
1800 uint32_t Rn = ((ir>>8)&0xF);
1801 load_reg( R_EAX, Rn );
1803 store_reg( R_EAX, Rn );
1805 sh4_x86.tstate = TSTATE_C;
1810 uint32_t Rn = ((ir>>8)&0xF);
1811 load_reg( R_EAX, Rn );
1812 if( sh4_x86.tstate != TSTATE_C ) {
1816 store_reg( R_EAX, Rn );
1818 sh4_x86.tstate = TSTATE_C;
1827 switch( (ir&0xF0) >> 4 ) {
1830 uint32_t Rn = ((ir>>8)&0xF);
1831 load_reg( R_EAX, Rn );
1833 store_reg( R_EAX, Rn );
1835 sh4_x86.tstate = TSTATE_C;
1840 uint32_t Rn = ((ir>>8)&0xF);
1841 load_reg( R_EAX, Rn );
1842 CMP_imm8s_r32( 0, R_EAX );
1844 sh4_x86.tstate = TSTATE_G;
1849 uint32_t Rn = ((ir>>8)&0xF);
1850 load_reg( R_EAX, Rn );
1851 if( sh4_x86.tstate != TSTATE_C ) {
1855 store_reg( R_EAX, Rn );
1857 sh4_x86.tstate = TSTATE_C;
1866 switch( (ir&0xF0) >> 4 ) {
1868 { /* LDS.L @Rm+, MACH */
1869 uint32_t Rm = ((ir>>8)&0xF);
1870 load_reg( R_EAX, Rm );
1872 check_ralign32( R_EAX );
1873 MOV_r32_r32( R_EAX, R_ECX );
1874 ADD_imm8s_r32( 4, R_EAX );
1875 store_reg( R_EAX, Rm );
1876 MEM_READ_LONG( R_ECX, R_EAX );
1877 store_spreg( R_EAX, R_MACH );
1878 sh4_x86.tstate = TSTATE_NONE;
1882 { /* LDS.L @Rm+, MACL */
1883 uint32_t Rm = ((ir>>8)&0xF);
1884 load_reg( R_EAX, Rm );
1886 check_ralign32( R_EAX );
1887 MOV_r32_r32( R_EAX, R_ECX );
1888 ADD_imm8s_r32( 4, R_EAX );
1889 store_reg( R_EAX, Rm );
1890 MEM_READ_LONG( R_ECX, R_EAX );
1891 store_spreg( R_EAX, R_MACL );
1892 sh4_x86.tstate = TSTATE_NONE;
1896 { /* LDS.L @Rm+, PR */
1897 uint32_t Rm = ((ir>>8)&0xF);
1898 load_reg( R_EAX, Rm );
1900 check_ralign32( R_EAX );
1901 MOV_r32_r32( R_EAX, R_ECX );
1902 ADD_imm8s_r32( 4, R_EAX );
1903 store_reg( R_EAX, Rm );
1904 MEM_READ_LONG( R_ECX, R_EAX );
1905 store_spreg( R_EAX, R_PR );
1906 sh4_x86.tstate = TSTATE_NONE;
1910 { /* LDC.L @Rm+, SGR */
1911 uint32_t Rm = ((ir>>8)&0xF);
1913 check_priv_no_precheck();
1914 load_reg( R_EAX, Rm );
1915 check_ralign32( R_EAX );
1916 MOV_r32_r32( R_EAX, R_ECX );
1917 ADD_imm8s_r32( 4, R_EAX );
1918 store_reg( R_EAX, Rm );
1919 MEM_READ_LONG( R_ECX, R_EAX );
1920 store_spreg( R_EAX, R_SGR );
1921 sh4_x86.tstate = TSTATE_NONE;
1925 { /* LDS.L @Rm+, FPUL */
1926 uint32_t Rm = ((ir>>8)&0xF);
1927 load_reg( R_EAX, Rm );
1929 check_ralign32( R_EAX );
1930 MOV_r32_r32( R_EAX, R_ECX );
1931 ADD_imm8s_r32( 4, R_EAX );
1932 store_reg( R_EAX, Rm );
1933 MEM_READ_LONG( R_ECX, R_EAX );
1934 store_spreg( R_EAX, R_FPUL );
1935 sh4_x86.tstate = TSTATE_NONE;
1939 { /* LDS.L @Rm+, FPSCR */
1940 uint32_t Rm = ((ir>>8)&0xF);
1941 load_reg( R_EAX, Rm );
1943 check_ralign32( R_EAX );
1944 MOV_r32_r32( R_EAX, R_ECX );
1945 ADD_imm8s_r32( 4, R_EAX );
1946 store_reg( R_EAX, Rm );
1947 MEM_READ_LONG( R_ECX, R_EAX );
1948 store_spreg( R_EAX, R_FPSCR );
1949 update_fr_bank( R_EAX );
1950 sh4_x86.tstate = TSTATE_NONE;
1954 { /* LDC.L @Rm+, DBR */
1955 uint32_t Rm = ((ir>>8)&0xF);
1957 check_priv_no_precheck();
1958 load_reg( R_EAX, Rm );
1959 check_ralign32( R_EAX );
1960 MOV_r32_r32( R_EAX, R_ECX );
1961 ADD_imm8s_r32( 4, R_EAX );
1962 store_reg( R_EAX, Rm );
1963 MEM_READ_LONG( R_ECX, R_EAX );
1964 store_spreg( R_EAX, R_DBR );
1965 sh4_x86.tstate = TSTATE_NONE;
1974 switch( (ir&0x80) >> 7 ) {
1976 switch( (ir&0x70) >> 4 ) {
1978 { /* LDC.L @Rm+, SR */
1979 uint32_t Rm = ((ir>>8)&0xF);
1980 if( sh4_x86.in_delay_slot ) {
1984 check_priv_no_precheck();
1985 load_reg( R_EAX, Rm );
1986 check_ralign32( R_EAX );
1987 MOV_r32_r32( R_EAX, R_ECX );
1988 ADD_imm8s_r32( 4, R_EAX );
1989 store_reg( R_EAX, Rm );
1990 MEM_READ_LONG( R_ECX, R_EAX );
1991 call_func1( sh4_write_sr, R_EAX );
1992 sh4_x86.priv_checked = FALSE;
1993 sh4_x86.fpuen_checked = FALSE;
1994 sh4_x86.tstate = TSTATE_NONE;
1999 { /* LDC.L @Rm+, GBR */
2000 uint32_t Rm = ((ir>>8)&0xF);
2001 load_reg( R_EAX, Rm );
2003 check_ralign32( R_EAX );
2004 MOV_r32_r32( R_EAX, R_ECX );
2005 ADD_imm8s_r32( 4, R_EAX );
2006 store_reg( R_EAX, Rm );
2007 MEM_READ_LONG( R_ECX, R_EAX );
2008 store_spreg( R_EAX, R_GBR );
2009 sh4_x86.tstate = TSTATE_NONE;
2013 { /* LDC.L @Rm+, VBR */
2014 uint32_t Rm = ((ir>>8)&0xF);
2016 check_priv_no_precheck();
2017 load_reg( R_EAX, Rm );
2018 check_ralign32( R_EAX );
2019 MOV_r32_r32( R_EAX, R_ECX );
2020 ADD_imm8s_r32( 4, R_EAX );
2021 store_reg( R_EAX, Rm );
2022 MEM_READ_LONG( R_ECX, R_EAX );
2023 store_spreg( R_EAX, R_VBR );
2024 sh4_x86.tstate = TSTATE_NONE;
2028 { /* LDC.L @Rm+, SSR */
2029 uint32_t Rm = ((ir>>8)&0xF);
2031 check_priv_no_precheck();
2032 load_reg( R_EAX, Rm );
2033 check_ralign32( R_EAX );
2034 MOV_r32_r32( R_EAX, R_ECX );
2035 ADD_imm8s_r32( 4, R_EAX );
2036 store_reg( R_EAX, Rm );
2037 MEM_READ_LONG( R_ECX, R_EAX );
2038 store_spreg( R_EAX, R_SSR );
2039 sh4_x86.tstate = TSTATE_NONE;
2043 { /* LDC.L @Rm+, SPC */
2044 uint32_t Rm = ((ir>>8)&0xF);
2046 check_priv_no_precheck();
2047 load_reg( R_EAX, Rm );
2048 check_ralign32( R_EAX );
2049 MOV_r32_r32( R_EAX, R_ECX );
2050 ADD_imm8s_r32( 4, R_EAX );
2051 store_reg( R_EAX, Rm );
2052 MEM_READ_LONG( R_ECX, R_EAX );
2053 store_spreg( R_EAX, R_SPC );
2054 sh4_x86.tstate = TSTATE_NONE;
2063 { /* LDC.L @Rm+, Rn_BANK */
2064 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2066 check_priv_no_precheck();
2067 load_reg( R_EAX, Rm );
2068 check_ralign32( R_EAX );
2069 MOV_r32_r32( R_EAX, R_ECX );
2070 ADD_imm8s_r32( 4, R_EAX );
2071 store_reg( R_EAX, Rm );
2072 MEM_READ_LONG( R_ECX, R_EAX );
2073 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2074 sh4_x86.tstate = TSTATE_NONE;
2080 switch( (ir&0xF0) >> 4 ) {
2083 uint32_t Rn = ((ir>>8)&0xF);
2084 load_reg( R_EAX, Rn );
2085 SHL_imm8_r32( 2, R_EAX );
2086 store_reg( R_EAX, Rn );
2087 sh4_x86.tstate = TSTATE_NONE;
2092 uint32_t Rn = ((ir>>8)&0xF);
2093 load_reg( R_EAX, Rn );
2094 SHL_imm8_r32( 8, R_EAX );
2095 store_reg( R_EAX, Rn );
2096 sh4_x86.tstate = TSTATE_NONE;
2101 uint32_t Rn = ((ir>>8)&0xF);
2102 load_reg( R_EAX, Rn );
2103 SHL_imm8_r32( 16, R_EAX );
2104 store_reg( R_EAX, Rn );
2105 sh4_x86.tstate = TSTATE_NONE;
2114 switch( (ir&0xF0) >> 4 ) {
2117 uint32_t Rn = ((ir>>8)&0xF);
2118 load_reg( R_EAX, Rn );
2119 SHR_imm8_r32( 2, R_EAX );
2120 store_reg( R_EAX, Rn );
2121 sh4_x86.tstate = TSTATE_NONE;
2126 uint32_t Rn = ((ir>>8)&0xF);
2127 load_reg( R_EAX, Rn );
2128 SHR_imm8_r32( 8, R_EAX );
2129 store_reg( R_EAX, Rn );
2130 sh4_x86.tstate = TSTATE_NONE;
2135 uint32_t Rn = ((ir>>8)&0xF);
2136 load_reg( R_EAX, Rn );
2137 SHR_imm8_r32( 16, R_EAX );
2138 store_reg( R_EAX, Rn );
2139 sh4_x86.tstate = TSTATE_NONE;
2148 switch( (ir&0xF0) >> 4 ) {
2150 { /* LDS Rm, MACH */
2151 uint32_t Rm = ((ir>>8)&0xF);
2152 load_reg( R_EAX, Rm );
2153 store_spreg( R_EAX, R_MACH );
2157 { /* LDS Rm, MACL */
2158 uint32_t Rm = ((ir>>8)&0xF);
2159 load_reg( R_EAX, Rm );
2160 store_spreg( R_EAX, R_MACL );
2165 uint32_t Rm = ((ir>>8)&0xF);
2166 load_reg( R_EAX, Rm );
2167 store_spreg( R_EAX, R_PR );
2172 uint32_t Rm = ((ir>>8)&0xF);
2174 load_reg( R_EAX, Rm );
2175 store_spreg( R_EAX, R_SGR );
2176 sh4_x86.tstate = TSTATE_NONE;
2180 { /* LDS Rm, FPUL */
2181 uint32_t Rm = ((ir>>8)&0xF);
2182 load_reg( R_EAX, Rm );
2183 store_spreg( R_EAX, R_FPUL );
2187 { /* LDS Rm, FPSCR */
2188 uint32_t Rm = ((ir>>8)&0xF);
2189 load_reg( R_EAX, Rm );
2190 store_spreg( R_EAX, R_FPSCR );
2191 update_fr_bank( R_EAX );
2192 sh4_x86.tstate = TSTATE_NONE;
2197 uint32_t Rm = ((ir>>8)&0xF);
2199 load_reg( R_EAX, Rm );
2200 store_spreg( R_EAX, R_DBR );
2201 sh4_x86.tstate = TSTATE_NONE;
2210 switch( (ir&0xF0) >> 4 ) {
2213 uint32_t Rn = ((ir>>8)&0xF);
2214 if( sh4_x86.in_delay_slot ) {
2217 load_imm32( R_EAX, pc + 4 );
2218 store_spreg( R_EAX, R_PR );
2219 load_reg( R_ECX, Rn );
2220 store_spreg( R_ECX, REG_OFFSET(pc) );
2221 sh4_x86.in_delay_slot = TRUE;
2222 sh4_translate_instruction(pc+2);
2223 exit_block_pcset(pc+2);
2224 sh4_x86.branch_taken = TRUE;
2231 uint32_t Rn = ((ir>>8)&0xF);
2232 load_reg( R_ECX, Rn );
2233 MEM_READ_BYTE( R_ECX, R_EAX );
2234 TEST_r8_r8( R_AL, R_AL );
2236 OR_imm8_r8( 0x80, R_AL );
2237 load_reg( R_ECX, Rn );
2238 MEM_WRITE_BYTE( R_ECX, R_EAX );
2239 sh4_x86.tstate = TSTATE_NONE;
2244 uint32_t Rn = ((ir>>8)&0xF);
2245 if( sh4_x86.in_delay_slot ) {
2248 load_reg( R_ECX, Rn );
2249 store_spreg( R_ECX, REG_OFFSET(pc) );
2250 sh4_x86.in_delay_slot = TRUE;
2251 sh4_translate_instruction(pc+2);
2252 exit_block_pcset(pc+2);
2253 sh4_x86.branch_taken = TRUE;
2265 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2266 /* Annoyingly enough, not directly convertible */
2267 load_reg( R_EAX, Rn );
2268 load_reg( R_ECX, Rm );
2269 CMP_imm32_r32( 0, R_ECX );
2270 JGE_rel8(16, doshl);
2272 NEG_r32( R_ECX ); // 2
2273 AND_imm8_r8( 0x1F, R_CL ); // 3
2274 JE_rel8( 4, emptysar); // 2
2275 SAR_r32_CL( R_EAX ); // 2
2276 JMP_rel8(10, end); // 2
2278 JMP_TARGET(emptysar);
2279 SAR_imm8_r32(31, R_EAX ); // 3
2283 AND_imm8_r8( 0x1F, R_CL ); // 3
2284 SHL_r32_CL( R_EAX ); // 2
2287 store_reg( R_EAX, Rn );
2288 sh4_x86.tstate = TSTATE_NONE;
2293 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2294 load_reg( R_EAX, Rn );
2295 load_reg( R_ECX, Rm );
2296 CMP_imm32_r32( 0, R_ECX );
2297 JGE_rel8(15, doshl);
2299 NEG_r32( R_ECX ); // 2
2300 AND_imm8_r8( 0x1F, R_CL ); // 3
2301 JE_rel8( 4, emptyshr );
2302 SHR_r32_CL( R_EAX ); // 2
2303 JMP_rel8(9, end); // 2
2305 JMP_TARGET(emptyshr);
2306 XOR_r32_r32( R_EAX, R_EAX );
2310 AND_imm8_r8( 0x1F, R_CL ); // 3
2311 SHL_r32_CL( R_EAX ); // 2
2314 store_reg( R_EAX, Rn );
2315 sh4_x86.tstate = TSTATE_NONE;
2319 switch( (ir&0x80) >> 7 ) {
2321 switch( (ir&0x70) >> 4 ) {
2324 uint32_t Rm = ((ir>>8)&0xF);
2325 if( sh4_x86.in_delay_slot ) {
2329 load_reg( R_EAX, Rm );
2330 call_func1( sh4_write_sr, R_EAX );
2331 sh4_x86.priv_checked = FALSE;
2332 sh4_x86.fpuen_checked = FALSE;
2333 sh4_x86.tstate = TSTATE_NONE;
2339 uint32_t Rm = ((ir>>8)&0xF);
2340 load_reg( R_EAX, Rm );
2341 store_spreg( R_EAX, R_GBR );
2346 uint32_t Rm = ((ir>>8)&0xF);
2348 load_reg( R_EAX, Rm );
2349 store_spreg( R_EAX, R_VBR );
2350 sh4_x86.tstate = TSTATE_NONE;
2355 uint32_t Rm = ((ir>>8)&0xF);
2357 load_reg( R_EAX, Rm );
2358 store_spreg( R_EAX, R_SSR );
2359 sh4_x86.tstate = TSTATE_NONE;
2364 uint32_t Rm = ((ir>>8)&0xF);
2366 load_reg( R_EAX, Rm );
2367 store_spreg( R_EAX, R_SPC );
2368 sh4_x86.tstate = TSTATE_NONE;
2377 { /* LDC Rm, Rn_BANK */
2378 uint32_t Rm = ((ir>>8)&0xF); uint32_t Rn_BANK = ((ir>>4)&0x7);
2380 load_reg( R_EAX, Rm );
2381 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2382 sh4_x86.tstate = TSTATE_NONE;
2388 { /* MAC.W @Rm+, @Rn+ */
2389 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2390 load_reg( R_ECX, Rm );
2392 check_ralign16( R_ECX );
2393 load_reg( R_ECX, Rn );
2394 check_ralign16( R_ECX );
2395 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
2396 MEM_READ_WORD( R_ECX, R_EAX );
2398 load_reg( R_ECX, Rm );
2399 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
2400 MEM_READ_WORD( R_ECX, R_EAX );
2404 load_spreg( R_ECX, R_S );
2405 TEST_r32_r32( R_ECX, R_ECX );
2406 JE_rel8( 47, nosat );
2408 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2409 JNO_rel8( 51, end ); // 2
2410 load_imm32( R_EDX, 1 ); // 5
2411 store_spreg( R_EDX, R_MACH ); // 6
2412 JS_rel8( 13, positive ); // 2
2413 load_imm32( R_EAX, 0x80000000 );// 5
2414 store_spreg( R_EAX, R_MACL ); // 6
2415 JMP_rel8( 25, end2 ); // 2
2417 JMP_TARGET(positive);
2418 load_imm32( R_EAX, 0x7FFFFFFF );// 5
2419 store_spreg( R_EAX, R_MACL ); // 6
2420 JMP_rel8( 12, end3); // 2
2423 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
2424 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
2428 sh4_x86.tstate = TSTATE_NONE;
2434 { /* MOV.L @(disp, Rm), Rn */
2435 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<2;
2436 load_reg( R_ECX, Rm );
2437 ADD_imm8s_r32( disp, R_ECX );
2439 check_ralign32( R_ECX );
2440 MEM_READ_LONG( R_ECX, R_EAX );
2441 store_reg( R_EAX, Rn );
2442 sh4_x86.tstate = TSTATE_NONE;
2448 { /* MOV.B @Rm, Rn */
2449 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2450 load_reg( R_ECX, Rm );
2451 MEM_READ_BYTE( R_ECX, R_EAX );
2452 store_reg( R_EAX, Rn );
2453 sh4_x86.tstate = TSTATE_NONE;
2457 { /* MOV.W @Rm, Rn */
2458 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2459 load_reg( R_ECX, Rm );
2461 check_ralign16( R_ECX );
2462 MEM_READ_WORD( R_ECX, R_EAX );
2463 store_reg( R_EAX, Rn );
2464 sh4_x86.tstate = TSTATE_NONE;
2468 { /* MOV.L @Rm, Rn */
2469 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2470 load_reg( R_ECX, Rm );
2472 check_ralign32( R_ECX );
2473 MEM_READ_LONG( R_ECX, R_EAX );
2474 store_reg( R_EAX, Rn );
2475 sh4_x86.tstate = TSTATE_NONE;
2480 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2481 load_reg( R_EAX, Rm );
2482 store_reg( R_EAX, Rn );
2486 { /* MOV.B @Rm+, Rn */
2487 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2488 load_reg( R_ECX, Rm );
2489 MOV_r32_r32( R_ECX, R_EAX );
2490 ADD_imm8s_r32( 1, R_EAX );
2491 store_reg( R_EAX, Rm );
2492 MEM_READ_BYTE( R_ECX, R_EAX );
2493 store_reg( R_EAX, Rn );
2494 sh4_x86.tstate = TSTATE_NONE;
2498 { /* MOV.W @Rm+, Rn */
2499 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2500 load_reg( R_EAX, Rm );
2502 check_ralign16( R_EAX );
2503 MOV_r32_r32( R_EAX, R_ECX );
2504 ADD_imm8s_r32( 2, R_EAX );
2505 store_reg( R_EAX, Rm );
2506 MEM_READ_WORD( R_ECX, R_EAX );
2507 store_reg( R_EAX, Rn );
2508 sh4_x86.tstate = TSTATE_NONE;
2512 { /* MOV.L @Rm+, Rn */
2513 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2514 load_reg( R_EAX, Rm );
2516 check_ralign32( R_EAX );
2517 MOV_r32_r32( R_EAX, R_ECX );
2518 ADD_imm8s_r32( 4, R_EAX );
2519 store_reg( R_EAX, Rm );
2520 MEM_READ_LONG( R_ECX, R_EAX );
2521 store_reg( R_EAX, Rn );
2522 sh4_x86.tstate = TSTATE_NONE;
2527 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2528 load_reg( R_EAX, Rm );
2530 store_reg( R_EAX, Rn );
2531 sh4_x86.tstate = TSTATE_NONE;
2535 { /* SWAP.B Rm, Rn */
2536 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2537 load_reg( R_EAX, Rm );
2538 XCHG_r8_r8( R_AL, R_AH );
2539 store_reg( R_EAX, Rn );
2543 { /* SWAP.W Rm, Rn */
2544 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2545 load_reg( R_EAX, Rm );
2546 MOV_r32_r32( R_EAX, R_ECX );
2547 SHL_imm8_r32( 16, R_ECX );
2548 SHR_imm8_r32( 16, R_EAX );
2549 OR_r32_r32( R_EAX, R_ECX );
2550 store_reg( R_ECX, Rn );
2551 sh4_x86.tstate = TSTATE_NONE;
2556 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2557 load_reg( R_EAX, Rm );
2558 XOR_r32_r32( R_ECX, R_ECX );
2560 SBB_r32_r32( R_EAX, R_ECX );
2561 store_reg( R_ECX, Rn );
2563 sh4_x86.tstate = TSTATE_C;
2568 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2569 load_reg( R_EAX, Rm );
2571 store_reg( R_EAX, Rn );
2572 sh4_x86.tstate = TSTATE_NONE;
2576 { /* EXTU.B Rm, Rn */
2577 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2578 load_reg( R_EAX, Rm );
2579 MOVZX_r8_r32( R_EAX, R_EAX );
2580 store_reg( R_EAX, Rn );
2584 { /* EXTU.W Rm, Rn */
2585 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2586 load_reg( R_EAX, Rm );
2587 MOVZX_r16_r32( R_EAX, R_EAX );
2588 store_reg( R_EAX, Rn );
2592 { /* EXTS.B Rm, Rn */
2593 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2594 load_reg( R_EAX, Rm );
2595 MOVSX_r8_r32( R_EAX, R_EAX );
2596 store_reg( R_EAX, Rn );
2600 { /* EXTS.W Rm, Rn */
2601 uint32_t Rn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
2602 load_reg( R_EAX, Rm );
2603 MOVSX_r16_r32( R_EAX, R_EAX );
2604 store_reg( R_EAX, Rn );
2610 { /* ADD #imm, Rn */
2611 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
2612 load_reg( R_EAX, Rn );
2613 ADD_imm8s_r32( imm, R_EAX );
2614 store_reg( R_EAX, Rn );
2615 sh4_x86.tstate = TSTATE_NONE;
2619 switch( (ir&0xF00) >> 8 ) {
2621 { /* MOV.B R0, @(disp, Rn) */
2622 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2623 load_reg( R_EAX, 0 );
2624 load_reg( R_ECX, Rn );
2625 ADD_imm32_r32( disp, R_ECX );
2626 MEM_WRITE_BYTE( R_ECX, R_EAX );
2627 sh4_x86.tstate = TSTATE_NONE;
2631 { /* MOV.W R0, @(disp, Rn) */
2632 uint32_t Rn = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2633 load_reg( R_ECX, Rn );
2634 load_reg( R_EAX, 0 );
2635 ADD_imm32_r32( disp, R_ECX );
2637 check_walign16( R_ECX );
2638 MEM_WRITE_WORD( R_ECX, R_EAX );
2639 sh4_x86.tstate = TSTATE_NONE;
2643 { /* MOV.B @(disp, Rm), R0 */
2644 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF);
2645 load_reg( R_ECX, Rm );
2646 ADD_imm32_r32( disp, R_ECX );
2647 MEM_READ_BYTE( R_ECX, R_EAX );
2648 store_reg( R_EAX, 0 );
2649 sh4_x86.tstate = TSTATE_NONE;
2653 { /* MOV.W @(disp, Rm), R0 */
2654 uint32_t Rm = ((ir>>4)&0xF); uint32_t disp = (ir&0xF)<<1;
2655 load_reg( R_ECX, Rm );
2656 ADD_imm32_r32( disp, R_ECX );
2658 check_ralign16( R_ECX );
2659 MEM_READ_WORD( R_ECX, R_EAX );
2660 store_reg( R_EAX, 0 );
2661 sh4_x86.tstate = TSTATE_NONE;
2665 { /* CMP/EQ #imm, R0 */
2666 int32_t imm = SIGNEXT8(ir&0xFF);
2667 load_reg( R_EAX, 0 );
2668 CMP_imm8s_r32(imm, R_EAX);
2670 sh4_x86.tstate = TSTATE_E;
2675 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2676 if( sh4_x86.in_delay_slot ) {
2679 JF_rel8( EXIT_BLOCK_SIZE, nottaken );
2680 exit_block( disp + pc + 4, pc+2 );
2681 JMP_TARGET(nottaken);
2688 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2689 if( sh4_x86.in_delay_slot ) {
2692 JT_rel8( EXIT_BLOCK_SIZE, nottaken );
2693 exit_block( disp + pc + 4, pc+2 );
2694 JMP_TARGET(nottaken);
2701 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2702 if( sh4_x86.in_delay_slot ) {
2705 sh4_x86.in_delay_slot = TRUE;
2706 if( sh4_x86.tstate == TSTATE_NONE ) {
2707 CMP_imm8s_sh4r( 1, R_T );
2708 sh4_x86.tstate = TSTATE_E;
2710 OP(0x0F); OP(0x80+(sh4_x86.tstate^1)); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JE rel32
2711 sh4_translate_instruction(pc+2);
2712 exit_block( disp + pc + 4, pc+4 );
2714 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2715 sh4_translate_instruction(pc+2);
2722 int32_t disp = SIGNEXT8(ir&0xFF)<<1;
2723 if( sh4_x86.in_delay_slot ) {
2726 sh4_x86.in_delay_slot = TRUE;
2727 if( sh4_x86.tstate == TSTATE_NONE ) {
2728 CMP_imm8s_sh4r( 1, R_T );
2729 sh4_x86.tstate = TSTATE_E;
2731 OP(0x0F); OP(0x80+sh4_x86.tstate); uint32_t *patch = (uint32_t *)xlat_output; OP32(0); // JNE rel32
2732 sh4_translate_instruction(pc+2);
2733 exit_block( disp + pc + 4, pc+4 );
2735 *patch = (xlat_output - ((uint8_t *)patch)) - 4;
2736 sh4_translate_instruction(pc+2);
2747 { /* MOV.W @(disp, PC), Rn */
2748 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<1;
2749 if( sh4_x86.in_delay_slot ) {
2752 load_imm32( R_ECX, pc + disp + 4 );
2753 MEM_READ_WORD( R_ECX, R_EAX );
2754 store_reg( R_EAX, Rn );
2755 sh4_x86.tstate = TSTATE_NONE;
2761 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2762 if( sh4_x86.in_delay_slot ) {
2765 sh4_x86.in_delay_slot = TRUE;
2766 sh4_translate_instruction( pc + 2 );
2767 exit_block( disp + pc + 4, pc+4 );
2768 sh4_x86.branch_taken = TRUE;
2775 int32_t disp = SIGNEXT12(ir&0xFFF)<<1;
2776 if( sh4_x86.in_delay_slot ) {
2779 load_imm32( R_EAX, pc + 4 );
2780 store_spreg( R_EAX, R_PR );
2781 sh4_x86.in_delay_slot = TRUE;
2782 sh4_translate_instruction( pc + 2 );
2783 exit_block( disp + pc + 4, pc+4 );
2784 sh4_x86.branch_taken = TRUE;
2790 switch( (ir&0xF00) >> 8 ) {
2792 { /* MOV.B R0, @(disp, GBR) */
2793 uint32_t disp = (ir&0xFF);
2794 load_reg( R_EAX, 0 );
2795 load_spreg( R_ECX, R_GBR );
2796 ADD_imm32_r32( disp, R_ECX );
2797 MEM_WRITE_BYTE( R_ECX, R_EAX );
2798 sh4_x86.tstate = TSTATE_NONE;
2802 { /* MOV.W R0, @(disp, GBR) */
2803 uint32_t disp = (ir&0xFF)<<1;
2804 load_spreg( R_ECX, R_GBR );
2805 load_reg( R_EAX, 0 );
2806 ADD_imm32_r32( disp, R_ECX );
2808 check_walign16( R_ECX );
2809 MEM_WRITE_WORD( R_ECX, R_EAX );
2810 sh4_x86.tstate = TSTATE_NONE;
2814 { /* MOV.L R0, @(disp, GBR) */
2815 uint32_t disp = (ir&0xFF)<<2;
2816 load_spreg( R_ECX, R_GBR );
2817 load_reg( R_EAX, 0 );
2818 ADD_imm32_r32( disp, R_ECX );
2820 check_walign32( R_ECX );
2821 MEM_WRITE_LONG( R_ECX, R_EAX );
2822 sh4_x86.tstate = TSTATE_NONE;
2827 uint32_t imm = (ir&0xFF);
2828 if( sh4_x86.in_delay_slot ) {
2831 load_imm32( R_EAX, imm );
2832 call_func1( sh4_raise_trap, R_EAX );
2833 ADD_imm8s_r32( 4, R_ESP );
2834 sh4_x86.tstate = TSTATE_NONE;
2835 exit_block_pcset(pc);
2836 sh4_x86.branch_taken = TRUE;
2842 { /* MOV.B @(disp, GBR), R0 */
2843 uint32_t disp = (ir&0xFF);
2844 load_spreg( R_ECX, R_GBR );
2845 ADD_imm32_r32( disp, R_ECX );
2846 MEM_READ_BYTE( R_ECX, R_EAX );
2847 store_reg( R_EAX, 0 );
2848 sh4_x86.tstate = TSTATE_NONE;
2852 { /* MOV.W @(disp, GBR), R0 */
2853 uint32_t disp = (ir&0xFF)<<1;
2854 load_spreg( R_ECX, R_GBR );
2855 ADD_imm32_r32( disp, R_ECX );
2857 check_ralign16( R_ECX );
2858 MEM_READ_WORD( R_ECX, R_EAX );
2859 store_reg( R_EAX, 0 );
2860 sh4_x86.tstate = TSTATE_NONE;
2864 { /* MOV.L @(disp, GBR), R0 */
2865 uint32_t disp = (ir&0xFF)<<2;
2866 load_spreg( R_ECX, R_GBR );
2867 ADD_imm32_r32( disp, R_ECX );
2869 check_ralign32( R_ECX );
2870 MEM_READ_LONG( R_ECX, R_EAX );
2871 store_reg( R_EAX, 0 );
2872 sh4_x86.tstate = TSTATE_NONE;
2876 { /* MOVA @(disp, PC), R0 */
2877 uint32_t disp = (ir&0xFF)<<2;
2878 if( sh4_x86.in_delay_slot ) {
2881 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
2882 store_reg( R_ECX, 0 );
2887 { /* TST #imm, R0 */
2888 uint32_t imm = (ir&0xFF);
2889 load_reg( R_EAX, 0 );
2890 TEST_imm32_r32( imm, R_EAX );
2892 sh4_x86.tstate = TSTATE_E;
2896 { /* AND #imm, R0 */
2897 uint32_t imm = (ir&0xFF);
2898 load_reg( R_EAX, 0 );
2899 AND_imm32_r32(imm, R_EAX);
2900 store_reg( R_EAX, 0 );
2901 sh4_x86.tstate = TSTATE_NONE;
2905 { /* XOR #imm, R0 */
2906 uint32_t imm = (ir&0xFF);
2907 load_reg( R_EAX, 0 );
2908 XOR_imm32_r32( imm, R_EAX );
2909 store_reg( R_EAX, 0 );
2910 sh4_x86.tstate = TSTATE_NONE;
2915 uint32_t imm = (ir&0xFF);
2916 load_reg( R_EAX, 0 );
2917 OR_imm32_r32(imm, R_EAX);
2918 store_reg( R_EAX, 0 );
2919 sh4_x86.tstate = TSTATE_NONE;
2923 { /* TST.B #imm, @(R0, GBR) */
2924 uint32_t imm = (ir&0xFF);
2925 load_reg( R_EAX, 0);
2926 load_reg( R_ECX, R_GBR);
2927 ADD_r32_r32( R_EAX, R_ECX );
2928 MEM_READ_BYTE( R_ECX, R_EAX );
2929 TEST_imm8_r8( imm, R_AL );
2931 sh4_x86.tstate = TSTATE_E;
2935 { /* AND.B #imm, @(R0, GBR) */
2936 uint32_t imm = (ir&0xFF);
2937 load_reg( R_EAX, 0 );
2938 load_spreg( R_ECX, R_GBR );
2939 ADD_r32_r32( R_EAX, R_ECX );
2941 MEM_READ_BYTE( R_ECX, R_EAX );
2943 AND_imm32_r32(imm, R_EAX );
2944 MEM_WRITE_BYTE( R_ECX, R_EAX );
2945 sh4_x86.tstate = TSTATE_NONE;
2949 { /* XOR.B #imm, @(R0, GBR) */
2950 uint32_t imm = (ir&0xFF);
2951 load_reg( R_EAX, 0 );
2952 load_spreg( R_ECX, R_GBR );
2953 ADD_r32_r32( R_EAX, R_ECX );
2955 MEM_READ_BYTE(R_ECX, R_EAX);
2957 XOR_imm32_r32( imm, R_EAX );
2958 MEM_WRITE_BYTE( R_ECX, R_EAX );
2959 sh4_x86.tstate = TSTATE_NONE;
2963 { /* OR.B #imm, @(R0, GBR) */
2964 uint32_t imm = (ir&0xFF);
2965 load_reg( R_EAX, 0 );
2966 load_spreg( R_ECX, R_GBR );
2967 ADD_r32_r32( R_EAX, R_ECX );
2969 MEM_READ_BYTE( R_ECX, R_EAX );
2971 OR_imm32_r32(imm, R_EAX );
2972 MEM_WRITE_BYTE( R_ECX, R_EAX );
2973 sh4_x86.tstate = TSTATE_NONE;
2979 { /* MOV.L @(disp, PC), Rn */
2980 uint32_t Rn = ((ir>>8)&0xF); uint32_t disp = (ir&0xFF)<<2;
2981 if( sh4_x86.in_delay_slot ) {
2984 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
2985 sh4ptr_t ptr = mem_get_region(target);
2987 MOV_moff32_EAX( ptr );
2989 load_imm32( R_ECX, target );
2990 MEM_READ_LONG( R_ECX, R_EAX );
2992 store_reg( R_EAX, Rn );
2993 sh4_x86.tstate = TSTATE_NONE;
2998 { /* MOV #imm, Rn */
2999 uint32_t Rn = ((ir>>8)&0xF); int32_t imm = SIGNEXT8(ir&0xFF);
3000 load_imm32( R_EAX, imm );
3001 store_reg( R_EAX, Rn );
3007 { /* FADD FRm, FRn */
3008 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3010 load_spreg( R_ECX, R_FPSCR );
3011 TEST_imm32_r32( FPSCR_PR, R_ECX );
3012 load_fr_bank( R_EDX );
3013 JNE_rel8(13,doubleprec);
3014 push_fr(R_EDX, FRm);
3015 push_fr(R_EDX, FRn);
3019 JMP_TARGET(doubleprec);
3020 push_dr(R_EDX, FRm);
3021 push_dr(R_EDX, FRn);
3025 sh4_x86.tstate = TSTATE_NONE;
3029 { /* FSUB FRm, FRn */
3030 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3032 load_spreg( R_ECX, R_FPSCR );
3033 TEST_imm32_r32( FPSCR_PR, R_ECX );
3034 load_fr_bank( R_EDX );
3035 JNE_rel8(13, doubleprec);
3036 push_fr(R_EDX, FRn);
3037 push_fr(R_EDX, FRm);
3041 JMP_TARGET(doubleprec);
3042 push_dr(R_EDX, FRn);
3043 push_dr(R_EDX, FRm);
3047 sh4_x86.tstate = TSTATE_NONE;
3051 { /* FMUL FRm, FRn */
3052 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3054 load_spreg( R_ECX, R_FPSCR );
3055 TEST_imm32_r32( FPSCR_PR, R_ECX );
3056 load_fr_bank( R_EDX );
3057 JNE_rel8(13, doubleprec);
3058 push_fr(R_EDX, FRm);
3059 push_fr(R_EDX, FRn);
3063 JMP_TARGET(doubleprec);
3064 push_dr(R_EDX, FRm);
3065 push_dr(R_EDX, FRn);
3069 sh4_x86.tstate = TSTATE_NONE;
3073 { /* FDIV FRm, FRn */
3074 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3076 load_spreg( R_ECX, R_FPSCR );
3077 TEST_imm32_r32( FPSCR_PR, R_ECX );
3078 load_fr_bank( R_EDX );
3079 JNE_rel8(13, doubleprec);
3080 push_fr(R_EDX, FRn);
3081 push_fr(R_EDX, FRm);
3085 JMP_TARGET(doubleprec);
3086 push_dr(R_EDX, FRn);
3087 push_dr(R_EDX, FRm);
3091 sh4_x86.tstate = TSTATE_NONE;
3095 { /* FCMP/EQ FRm, FRn */
3096 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3098 load_spreg( R_ECX, R_FPSCR );
3099 TEST_imm32_r32( FPSCR_PR, R_ECX );
3100 load_fr_bank( R_EDX );
3101 JNE_rel8(8, doubleprec);
3102 push_fr(R_EDX, FRm);
3103 push_fr(R_EDX, FRn);
3105 JMP_TARGET(doubleprec);
3106 push_dr(R_EDX, FRm);
3107 push_dr(R_EDX, FRn);
3112 sh4_x86.tstate = TSTATE_NONE;
3116 { /* FCMP/GT FRm, FRn */
3117 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3119 load_spreg( R_ECX, R_FPSCR );
3120 TEST_imm32_r32( FPSCR_PR, R_ECX );
3121 load_fr_bank( R_EDX );
3122 JNE_rel8(8, doubleprec);
3123 push_fr(R_EDX, FRm);
3124 push_fr(R_EDX, FRn);
3126 JMP_TARGET(doubleprec);
3127 push_dr(R_EDX, FRm);
3128 push_dr(R_EDX, FRn);
3133 sh4_x86.tstate = TSTATE_NONE;
3137 { /* FMOV @(R0, Rm), FRn */
3138 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3140 check_fpuen_no_precheck();
3141 load_reg( R_ECX, Rm );
3142 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
3143 check_ralign32( R_ECX );
3144 load_spreg( R_EDX, R_FPSCR );
3145 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3146 JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
3147 MEM_READ_LONG( R_ECX, R_EAX );
3148 load_fr_bank( R_EDX );
3149 store_fr( R_EDX, R_EAX, FRn );
3151 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
3152 JMP_TARGET(doublesize);
3153 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3154 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3155 load_xf_bank( R_EDX );
3156 store_fr( R_EDX, R_EAX, FRn&0x0E );
3157 store_fr( R_EDX, R_ECX, FRn|0x01 );
3160 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
3161 JMP_TARGET(doublesize);
3162 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3163 load_fr_bank( R_EDX );
3164 store_fr( R_EDX, R_EAX, FRn&0x0E );
3165 store_fr( R_EDX, R_ECX, FRn|0x01 );
3168 sh4_x86.tstate = TSTATE_NONE;
3172 { /* FMOV FRm, @(R0, Rn) */
3173 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3175 check_fpuen_no_precheck();
3176 load_reg( R_ECX, Rn );
3177 ADD_sh4r_r32( REG_OFFSET(r[0]), R_ECX );
3178 check_walign32( R_ECX );
3179 load_spreg( R_EDX, R_FPSCR );
3180 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3181 JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
3182 load_fr_bank( R_EDX );
3183 load_fr( R_EDX, R_EAX, FRm );
3184 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3186 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3187 JMP_TARGET(doublesize);
3188 load_xf_bank( R_EDX );
3189 load_fr( R_EDX, R_EAX, FRm&0x0E );
3190 load_fr( R_EDX, R_EDX, FRm|0x01 );
3191 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3194 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3195 JMP_TARGET(doublesize);
3196 load_fr_bank( R_EDX );
3197 load_fr( R_EDX, R_EAX, FRm&0x0E );
3198 load_fr( R_EDX, R_EDX, FRm|0x01 );
3199 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3202 sh4_x86.tstate = TSTATE_NONE;
3206 { /* FMOV @Rm, FRn */
3207 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3209 check_fpuen_no_precheck();
3210 load_reg( R_ECX, Rm );
3211 check_ralign32( R_ECX );
3212 load_spreg( R_EDX, R_FPSCR );
3213 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3214 JNE_rel8(8 + CALL_FUNC1_SIZE, doublesize);
3215 MEM_READ_LONG( R_ECX, R_EAX );
3216 load_fr_bank( R_EDX );
3217 store_fr( R_EDX, R_EAX, FRn );
3219 JMP_rel8(21 + MEM_READ_DOUBLE_SIZE, end);
3220 JMP_TARGET(doublesize);
3221 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3222 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3223 load_xf_bank( R_EDX );
3224 store_fr( R_EDX, R_EAX, FRn&0x0E );
3225 store_fr( R_EDX, R_ECX, FRn|0x01 );
3228 JMP_rel8(9 + MEM_READ_DOUBLE_SIZE, end);
3229 JMP_TARGET(doublesize);
3230 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3231 load_fr_bank( R_EDX );
3232 store_fr( R_EDX, R_EAX, FRn&0x0E );
3233 store_fr( R_EDX, R_ECX, FRn|0x01 );
3236 sh4_x86.tstate = TSTATE_NONE;
3240 { /* FMOV @Rm+, FRn */
3241 uint32_t FRn = ((ir>>8)&0xF); uint32_t Rm = ((ir>>4)&0xF);
3243 check_fpuen_no_precheck();
3244 load_reg( R_ECX, Rm );
3245 check_ralign32( R_ECX );
3246 MOV_r32_r32( R_ECX, R_EAX );
3247 load_spreg( R_EDX, R_FPSCR );
3248 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3249 JNE_rel8(14 + CALL_FUNC1_SIZE, doublesize);
3250 ADD_imm8s_r32( 4, R_EAX );
3251 store_reg( R_EAX, Rm );
3252 MEM_READ_LONG( R_ECX, R_EAX );
3253 load_fr_bank( R_EDX );
3254 store_fr( R_EDX, R_EAX, FRn );
3256 JMP_rel8(27 + MEM_READ_DOUBLE_SIZE, end);
3257 JMP_TARGET(doublesize);
3258 ADD_imm8s_r32( 8, R_EAX );
3259 store_reg(R_EAX, Rm);
3260 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3261 load_spreg( R_EDX, R_FPSCR ); // assume read_long clobbered it
3262 load_xf_bank( R_EDX );
3263 store_fr( R_EDX, R_EAX, FRn&0x0E );
3264 store_fr( R_EDX, R_ECX, FRn|0x01 );
3267 JMP_rel8(15 + MEM_READ_DOUBLE_SIZE, end);
3268 ADD_imm8s_r32( 8, R_EAX );
3269 store_reg(R_EAX, Rm);
3270 MEM_READ_DOUBLE( R_ECX, R_EAX, R_ECX );
3271 load_fr_bank( R_EDX );
3272 store_fr( R_EDX, R_EAX, FRn&0x0E );
3273 store_fr( R_EDX, R_ECX, FRn|0x01 );
3276 sh4_x86.tstate = TSTATE_NONE;
3280 { /* FMOV FRm, @Rn */
3281 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3283 check_fpuen_no_precheck();
3284 load_reg( R_ECX, Rn );
3285 check_walign32( R_ECX );
3286 load_spreg( R_EDX, R_FPSCR );
3287 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3288 JNE_rel8(8 + CALL_FUNC2_SIZE, doublesize);
3289 load_fr_bank( R_EDX );
3290 load_fr( R_EDX, R_EAX, FRm );
3291 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3293 JMP_rel8( 18 + MEM_WRITE_DOUBLE_SIZE, end );
3294 JMP_TARGET(doublesize);
3295 load_xf_bank( R_EDX );
3296 load_fr( R_EDX, R_EAX, FRm&0x0E );
3297 load_fr( R_EDX, R_EDX, FRm|0x01 );
3298 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3301 JMP_rel8( 9 + MEM_WRITE_DOUBLE_SIZE, end );
3302 JMP_TARGET(doublesize);
3303 load_fr_bank( R_EDX );
3304 load_fr( R_EDX, R_EAX, FRm&0x0E );
3305 load_fr( R_EDX, R_EDX, FRm|0x01 );
3306 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3309 sh4_x86.tstate = TSTATE_NONE;
3313 { /* FMOV FRm, @-Rn */
3314 uint32_t Rn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3316 check_fpuen_no_precheck();
3317 load_reg( R_ECX, Rn );
3318 check_walign32( R_ECX );
3319 load_spreg( R_EDX, R_FPSCR );
3320 TEST_imm32_r32( FPSCR_SZ, R_EDX );
3321 JNE_rel8(14 + CALL_FUNC2_SIZE, doublesize);
3322 load_fr_bank( R_EDX );
3323 load_fr( R_EDX, R_EAX, FRm );
3324 ADD_imm8s_r32(-4,R_ECX);
3325 store_reg( R_ECX, Rn );
3326 MEM_WRITE_LONG( R_ECX, R_EAX ); // 12
3328 JMP_rel8( 24 + MEM_WRITE_DOUBLE_SIZE, end );
3329 JMP_TARGET(doublesize);
3330 load_xf_bank( R_EDX );
3331 load_fr( R_EDX, R_EAX, FRm&0x0E );
3332 load_fr( R_EDX, R_EDX, FRm|0x01 );
3333 ADD_imm8s_r32(-8,R_ECX);
3334 store_reg( R_ECX, Rn );
3335 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3338 JMP_rel8( 15 + MEM_WRITE_DOUBLE_SIZE, end );
3339 JMP_TARGET(doublesize);
3340 load_fr_bank( R_EDX );
3341 load_fr( R_EDX, R_EAX, FRm&0x0E );
3342 load_fr( R_EDX, R_EDX, FRm|0x01 );
3343 ADD_imm8s_r32(-8,R_ECX);
3344 store_reg( R_ECX, Rn );
3345 MEM_WRITE_DOUBLE( R_ECX, R_EAX, R_EDX );
3348 sh4_x86.tstate = TSTATE_NONE;
3352 { /* FMOV FRm, FRn */
3353 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3354 /* As horrible as this looks, it's actually covering 5 separate cases:
3355 * 1. 32-bit fr-to-fr (PR=0)
3356 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
3357 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
3358 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
3359 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
3362 load_spreg( R_ECX, R_FPSCR );
3363 load_fr_bank( R_EDX );
3364 TEST_imm32_r32( FPSCR_SZ, R_ECX );
3365 JNE_rel8(8, doublesize);
3366 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
3367 store_fr( R_EDX, R_EAX, FRn );
3370 JMP_TARGET(doublesize);
3371 load_xf_bank( R_ECX );
3372 load_fr( R_ECX, R_EAX, FRm-1 );
3374 load_fr( R_ECX, R_EDX, FRm );
3375 store_fr( R_ECX, R_EAX, FRn-1 );
3376 store_fr( R_ECX, R_EDX, FRn );
3377 } else /* FRn&1 == 0 */ {
3378 load_fr( R_ECX, R_ECX, FRm );
3379 store_fr( R_EDX, R_EAX, FRn );
3380 store_fr( R_EDX, R_ECX, FRn+1 );
3383 } else /* FRm&1 == 0 */ {
3386 load_xf_bank( R_ECX );
3387 load_fr( R_EDX, R_EAX, FRm );
3388 load_fr( R_EDX, R_EDX, FRm+1 );
3389 store_fr( R_ECX, R_EAX, FRn-1 );
3390 store_fr( R_ECX, R_EDX, FRn );
3392 } else /* FRn&1 == 0 */ {
3394 load_fr( R_EDX, R_EAX, FRm );
3395 load_fr( R_EDX, R_ECX, FRm+1 );
3396 store_fr( R_EDX, R_EAX, FRn );
3397 store_fr( R_EDX, R_ECX, FRn+1 );
3401 sh4_x86.tstate = TSTATE_NONE;
3405 switch( (ir&0xF0) >> 4 ) {
3407 { /* FSTS FPUL, FRn */
3408 uint32_t FRn = ((ir>>8)&0xF);
3410 load_fr_bank( R_ECX );
3411 load_spreg( R_EAX, R_FPUL );
3412 store_fr( R_ECX, R_EAX, FRn );
3413 sh4_x86.tstate = TSTATE_NONE;
3417 { /* FLDS FRm, FPUL */
3418 uint32_t FRm = ((ir>>8)&0xF);
3420 load_fr_bank( R_ECX );
3421 load_fr( R_ECX, R_EAX, FRm );
3422 store_spreg( R_EAX, R_FPUL );
3423 sh4_x86.tstate = TSTATE_NONE;
3427 { /* FLOAT FPUL, FRn */
3428 uint32_t FRn = ((ir>>8)&0xF);
3430 load_spreg( R_ECX, R_FPSCR );
3431 load_spreg(R_EDX, REG_OFFSET(fr_bank));
3433 TEST_imm32_r32( FPSCR_PR, R_ECX );
3434 JNE_rel8(5, doubleprec);
3435 pop_fr( R_EDX, FRn );
3437 JMP_TARGET(doubleprec);
3438 pop_dr( R_EDX, FRn );
3440 sh4_x86.tstate = TSTATE_NONE;
3444 { /* FTRC FRm, FPUL */
3445 uint32_t FRm = ((ir>>8)&0xF);
3447 load_spreg( R_ECX, R_FPSCR );
3448 load_fr_bank( R_EDX );
3449 TEST_imm32_r32( FPSCR_PR, R_ECX );
3450 JNE_rel8(5, doubleprec);
3451 push_fr( R_EDX, FRm );
3453 JMP_TARGET(doubleprec);
3454 push_dr( R_EDX, FRm );
3456 load_imm32( R_ECX, (uint32_t)&max_int );
3457 FILD_r32ind( R_ECX );
3459 JNA_rel8( 32, sat );
3460 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
3461 FILD_r32ind( R_ECX ); // 2
3463 JAE_rel8( 21, sat2 ); // 2
3464 load_imm32( R_EAX, (uint32_t)&save_fcw );
3465 FNSTCW_r32ind( R_EAX );
3466 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
3467 FLDCW_r32ind( R_EDX );
3468 FISTP_sh4r(R_FPUL); // 3
3469 FLDCW_r32ind( R_EAX );
3470 JMP_rel8( 9, end ); // 2
3474 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
3475 store_spreg( R_ECX, R_FPUL );
3478 sh4_x86.tstate = TSTATE_NONE;
3483 uint32_t FRn = ((ir>>8)&0xF);
3485 load_spreg( R_ECX, R_FPSCR );
3486 TEST_imm32_r32( FPSCR_PR, R_ECX );
3487 load_fr_bank( R_EDX );
3488 JNE_rel8(10, doubleprec);
3489 push_fr(R_EDX, FRn);
3493 JMP_TARGET(doubleprec);
3494 push_dr(R_EDX, FRn);
3498 sh4_x86.tstate = TSTATE_NONE;
3503 uint32_t FRn = ((ir>>8)&0xF);
3505 load_spreg( R_ECX, R_FPSCR );
3506 load_fr_bank( R_EDX );
3507 TEST_imm32_r32( FPSCR_PR, R_ECX );
3508 JNE_rel8(10, doubleprec);
3509 push_fr(R_EDX, FRn); // 3
3511 pop_fr( R_EDX, FRn); //3
3512 JMP_rel8(8,end); // 2
3513 JMP_TARGET(doubleprec);
3514 push_dr(R_EDX, FRn);
3518 sh4_x86.tstate = TSTATE_NONE;
3523 uint32_t FRn = ((ir>>8)&0xF);
3525 load_spreg( R_ECX, R_FPSCR );
3526 TEST_imm32_r32( FPSCR_PR, R_ECX );
3527 load_fr_bank( R_EDX );
3528 JNE_rel8(10, doubleprec);
3529 push_fr(R_EDX, FRn);
3533 JMP_TARGET(doubleprec);
3534 push_dr(R_EDX, FRn);
3538 sh4_x86.tstate = TSTATE_NONE;
3543 uint32_t FRn = ((ir>>8)&0xF);
3545 load_spreg( R_ECX, R_FPSCR );
3546 TEST_imm32_r32( FPSCR_PR, R_ECX );
3547 load_fr_bank( R_EDX );
3548 JNE_rel8(12, end); // PR=0 only
3550 push_fr(R_EDX, FRn);
3555 sh4_x86.tstate = TSTATE_NONE;
3560 uint32_t FRn = ((ir>>8)&0xF);
3563 load_spreg( R_ECX, R_FPSCR );
3564 TEST_imm32_r32( FPSCR_PR, R_ECX );
3566 XOR_r32_r32( R_EAX, R_EAX );
3567 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3568 store_fr( R_ECX, R_EAX, FRn );
3570 sh4_x86.tstate = TSTATE_NONE;
3575 uint32_t FRn = ((ir>>8)&0xF);
3578 load_spreg( R_ECX, R_FPSCR );
3579 TEST_imm32_r32( FPSCR_PR, R_ECX );
3581 load_imm32(R_EAX, 0x3F800000);
3582 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
3583 store_fr( R_ECX, R_EAX, FRn );
3585 sh4_x86.tstate = TSTATE_NONE;
3589 { /* FCNVSD FPUL, FRn */
3590 uint32_t FRn = ((ir>>8)&0xF);
3592 load_spreg( R_ECX, R_FPSCR );
3593 TEST_imm32_r32( FPSCR_PR, R_ECX );
3594 JE_rel8(9, end); // only when PR=1
3595 load_fr_bank( R_ECX );
3597 pop_dr( R_ECX, FRn );
3599 sh4_x86.tstate = TSTATE_NONE;
3603 { /* FCNVDS FRm, FPUL */
3604 uint32_t FRm = ((ir>>8)&0xF);
3606 load_spreg( R_ECX, R_FPSCR );
3607 TEST_imm32_r32( FPSCR_PR, R_ECX );
3608 JE_rel8(9, end); // only when PR=1
3609 load_fr_bank( R_ECX );
3610 push_dr( R_ECX, FRm );
3613 sh4_x86.tstate = TSTATE_NONE;
3617 { /* FIPR FVm, FVn */
3618 uint32_t FVn = ((ir>>10)&0x3); uint32_t FVm = ((ir>>8)&0x3);
3620 load_spreg( R_ECX, R_FPSCR );
3621 TEST_imm32_r32( FPSCR_PR, R_ECX );
3622 JNE_rel8(44, doubleprec);
3624 load_fr_bank( R_ECX );
3625 push_fr( R_ECX, FVm<<2 );
3626 push_fr( R_ECX, FVn<<2 );
3628 push_fr( R_ECX, (FVm<<2)+1);
3629 push_fr( R_ECX, (FVn<<2)+1);
3632 push_fr( R_ECX, (FVm<<2)+2);
3633 push_fr( R_ECX, (FVn<<2)+2);
3636 push_fr( R_ECX, (FVm<<2)+3);
3637 push_fr( R_ECX, (FVn<<2)+3);
3640 pop_fr( R_ECX, (FVn<<2)+3);
3641 JMP_TARGET(doubleprec);
3642 sh4_x86.tstate = TSTATE_NONE;
3646 switch( (ir&0x100) >> 8 ) {
3648 { /* FSCA FPUL, FRn */
3649 uint32_t FRn = ((ir>>9)&0x7)<<1;
3651 load_spreg( R_ECX, R_FPSCR );
3652 TEST_imm32_r32( FPSCR_PR, R_ECX );
3653 JNE_rel8( CALL_FUNC2_SIZE + 9, doubleprec );
3654 load_fr_bank( R_ECX );
3655 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
3656 load_spreg( R_EDX, R_FPUL );
3657 call_func2( sh4_fsca, R_EDX, R_ECX );
3658 JMP_TARGET(doubleprec);
3659 sh4_x86.tstate = TSTATE_NONE;
3663 switch( (ir&0x200) >> 9 ) {
3665 { /* FTRV XMTRX, FVn */
3666 uint32_t FVn = ((ir>>10)&0x3);
3668 load_spreg( R_ECX, R_FPSCR );
3669 TEST_imm32_r32( FPSCR_PR, R_ECX );
3670 JNE_rel8( 18 + CALL_FUNC2_SIZE, doubleprec );
3671 load_fr_bank( R_EDX ); // 3
3672 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
3673 load_xf_bank( R_ECX ); // 12
3674 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
3675 JMP_TARGET(doubleprec);
3676 sh4_x86.tstate = TSTATE_NONE;
3680 switch( (ir&0xC00) >> 10 ) {
3684 load_spreg( R_ECX, R_FPSCR );
3685 XOR_imm32_r32( FPSCR_SZ, R_ECX );
3686 store_spreg( R_ECX, R_FPSCR );
3687 sh4_x86.tstate = TSTATE_NONE;
3693 load_spreg( R_ECX, R_FPSCR );
3694 XOR_imm32_r32( FPSCR_FR, R_ECX );
3695 store_spreg( R_ECX, R_FPSCR );
3696 update_fr_bank( R_ECX );
3697 sh4_x86.tstate = TSTATE_NONE;
3702 if( sh4_x86.in_delay_slot ) {
3706 JMP_exit(EXIT_ILLEGAL);
3726 { /* FMAC FR0, FRm, FRn */
3727 uint32_t FRn = ((ir>>8)&0xF); uint32_t FRm = ((ir>>4)&0xF);
3729 load_spreg( R_ECX, R_FPSCR );
3730 load_spreg( R_EDX, REG_OFFSET(fr_bank));
3731 TEST_imm32_r32( FPSCR_PR, R_ECX );
3732 JNE_rel8(18, doubleprec);
3733 push_fr( R_EDX, 0 );
3734 push_fr( R_EDX, FRm );
3736 push_fr( R_EDX, FRn );
3738 pop_fr( R_EDX, FRn );
3740 JMP_TARGET(doubleprec);
3741 push_dr( R_EDX, 0 );
3742 push_dr( R_EDX, FRm );
3744 push_dr( R_EDX, FRn );
3746 pop_dr( R_EDX, FRn );
3748 sh4_x86.tstate = TSTATE_NONE;
3758 sh4_x86.in_delay_slot = FALSE;
.