2 * $Id: sh4x86.in,v 1.13 2007-09-19 10:04: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/sh4core.h"
29 #include "sh4/sh4trans.h"
30 #include "sh4/sh4mmio.h"
31 #include "sh4/x86op.h"
34 #define DEFAULT_BACKPATCH_SIZE 4096
37 * Struct to manage internal translation state. This state is not saved -
38 * it is only valid between calls to sh4_translate_begin_block() and
39 * sh4_translate_end_block()
41 struct sh4_x86_state {
42 gboolean in_delay_slot;
43 gboolean priv_checked; /* true if we've already checked the cpu mode. */
44 gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
47 /* Allocated memory for the (block-wide) back-patch list */
48 uint32_t **backpatch_list;
49 uint32_t backpatch_posn;
50 uint32_t backpatch_size;
53 #define EXIT_DATA_ADDR_READ 0
54 #define EXIT_DATA_ADDR_WRITE 7
55 #define EXIT_ILLEGAL 14
56 #define EXIT_SLOT_ILLEGAL 21
57 #define EXIT_FPU_DISABLED 28
58 #define EXIT_SLOT_FPU_DISABLED 35
60 static struct sh4_x86_state sh4_x86;
62 static uint32_t max_int = 0x7FFFFFFF;
63 static uint32_t min_int = 0x80000000;
64 static uint32_t save_fcw; /* save value for fpu control word */
65 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
66 void signsat48( void )
68 if( ((int64_t)sh4r.mac) < (int64_t)0xFFFF800000000000LL )
69 sh4r.mac = 0xFFFF800000000000LL;
70 else if( ((int64_t)sh4r.mac) > (int64_t)0x00007FFFFFFFFFFFLL )
71 sh4r.mac = 0x00007FFFFFFFFFFFLL;
74 void sh4_fsca( uint32_t anglei, float *fr )
76 float angle = (((float)(anglei&0xFFFF))/65536.0) * 2 * M_PI;
83 if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
84 sh4r.sh4_state = SH4_STATE_STANDBY;
86 sh4r.sh4_state = SH4_STATE_SLEEP;
91 * Compute the matrix tranform of fv given the matrix xf.
92 * Both fv and xf are word-swapped as per the sh4r.fr banks
94 void sh4_ftrv( float *target, float *xf )
96 float fv[4] = { target[1], target[0], target[3], target[2] };
97 target[1] = xf[1] * fv[0] + xf[5]*fv[1] +
98 xf[9]*fv[2] + xf[13]*fv[3];
99 target[0] = xf[0] * fv[0] + xf[4]*fv[1] +
100 xf[8]*fv[2] + xf[12]*fv[3];
101 target[3] = xf[3] * fv[0] + xf[7]*fv[1] +
102 xf[11]*fv[2] + xf[15]*fv[3];
103 target[2] = xf[2] * fv[0] + xf[6]*fv[1] +
104 xf[10]*fv[2] + xf[14]*fv[3];
111 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
112 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
116 static void sh4_x86_add_backpatch( uint8_t *ptr )
118 if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
119 sh4_x86.backpatch_size <<= 1;
120 sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
121 assert( sh4_x86.backpatch_list != NULL );
123 sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
126 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
129 for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
130 *sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
135 * Emit an instruction to load an SH4 reg into a real register
137 static inline void load_reg( int x86reg, int sh4reg )
139 /* mov [bp+n], reg */
141 OP(0x45 + (x86reg<<3));
142 OP(REG_OFFSET(r[sh4reg]));
145 static inline void load_reg16s( int x86reg, int sh4reg )
149 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
152 static inline void load_reg16u( int x86reg, int sh4reg )
156 MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
160 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
161 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
163 * Emit an instruction to load an immediate value into a register
165 static inline void load_imm32( int x86reg, uint32_t value ) {
166 /* mov #value, reg */
172 * Emit an instruction to store an SH4 reg (RN)
174 void static inline store_reg( int x86reg, int sh4reg ) {
175 /* mov reg, [bp+n] */
177 OP(0x45 + (x86reg<<3));
178 OP(REG_OFFSET(r[sh4reg]));
181 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
184 * Load an FR register (single-precision floating point) into an integer x86
185 * register (eg for register-to-register moves)
187 void static inline load_fr( int bankreg, int x86reg, int frm )
189 OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
193 * Store an FR register (single-precision floating point) into an integer x86
194 * register (eg for register-to-register moves)
196 void static inline store_fr( int bankreg, int x86reg, int frn )
198 OP(0x89); OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
203 * Load a pointer to the back fp back into the specified x86 register. The
204 * bankreg must have been previously loaded with FPSCR.
207 static inline void load_xf_bank( int bankreg )
210 SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
211 AND_imm8s_r32( 0x40, bankreg ); // Complete extraction
212 OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
216 * Update the fr_bank pointer based on the current fpscr value.
218 static inline void update_fr_bank( int fpscrreg )
220 SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
221 AND_imm8s_r32( 0x40, fpscrreg ); // Complete extraction
222 OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
223 store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
226 * Push FPUL (as a 32-bit float) onto the FPU stack
228 static inline void push_fpul( )
230 OP(0xD9); OP(0x45); OP(R_FPUL);
234 * Pop FPUL (as a 32-bit float) from the FPU stack
236 static inline void pop_fpul( )
238 OP(0xD9); OP(0x5D); OP(R_FPUL);
242 * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
243 * with the location of the current fp bank.
245 static inline void push_fr( int bankreg, int frm )
247 OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2); // FLD.S [bankreg + frm^1*4]
251 * Pop a 32-bit float from the FPU stack and store it back into the fp bank,
252 * with bankreg previously loaded with the location of the current fp bank.
254 static inline void pop_fr( int bankreg, int frm )
256 OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
260 * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
261 * with the location of the current fp bank.
263 static inline void push_dr( int bankreg, int frm )
265 OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
268 static inline void pop_dr( int bankreg, int frm )
270 OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
274 * Note: clobbers EAX to make the indirect call - this isn't usually
275 * a problem since the callee will usually clobber it anyway.
277 static inline void call_func0( void *ptr )
279 load_imm32(R_EAX, (uint32_t)ptr);
283 static inline void call_func1( void *ptr, int arg1 )
287 ADD_imm8s_r32( 4, R_ESP );
290 static inline void call_func2( void *ptr, int arg1, int arg2 )
295 ADD_imm8s_r32( 8, R_ESP );
299 * Write a double (64-bit) value into memory, with the first word in arg2a, and
300 * the second in arg2b
303 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
305 ADD_imm8s_r32( 4, addr );
308 ADD_imm8s_r32( -4, addr );
311 call_func0(sh4_write_long);
312 ADD_imm8s_r32( 8, R_ESP );
313 call_func0(sh4_write_long);
314 ADD_imm8s_r32( 8, R_ESP );
318 * Read a double (64-bit) value from memory, writing the first word into arg2a
319 * and the second into arg2b. The addr must not be in EAX
322 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
325 call_func0(sh4_read_long);
328 ADD_imm8s_r32( 4, addr );
330 call_func0(sh4_read_long);
331 ADD_imm8s_r32( 4, R_ESP );
332 MOV_r32_r32( R_EAX, arg2b );
336 /* Exception checks - Note that all exception checks will clobber EAX */
337 static void check_priv( )
339 if( !sh4_x86.priv_checked ) {
340 sh4_x86.priv_checked = TRUE;
341 load_spreg( R_EAX, R_SR );
342 AND_imm32_r32( SR_MD, R_EAX );
343 if( sh4_x86.in_delay_slot ) {
344 JE_exit( EXIT_SLOT_ILLEGAL );
346 JE_exit( EXIT_ILLEGAL );
351 static void check_fpuen( )
353 if( !sh4_x86.fpuen_checked ) {
354 sh4_x86.fpuen_checked = TRUE;
355 load_spreg( R_EAX, R_SR );
356 AND_imm32_r32( SR_FD, R_EAX );
357 if( sh4_x86.in_delay_slot ) {
358 JNE_exit(EXIT_SLOT_FPU_DISABLED);
360 JNE_exit(EXIT_FPU_DISABLED);
365 static void check_ralign16( int x86reg )
367 TEST_imm32_r32( 0x00000001, x86reg );
368 JNE_exit(EXIT_DATA_ADDR_READ);
371 static void check_walign16( int x86reg )
373 TEST_imm32_r32( 0x00000001, x86reg );
374 JNE_exit(EXIT_DATA_ADDR_WRITE);
377 static void check_ralign32( int x86reg )
379 TEST_imm32_r32( 0x00000003, x86reg );
380 JNE_exit(EXIT_DATA_ADDR_READ);
382 static void check_walign32( int x86reg )
384 TEST_imm32_r32( 0x00000003, x86reg );
385 JNE_exit(EXIT_DATA_ADDR_WRITE);
389 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
390 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
391 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
392 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
393 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
394 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
395 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
397 #define SLOTILLEGAL() JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
402 * Emit the 'start of block' assembly. Sets up the stack frame and save
405 void sh4_translate_begin_block()
409 load_imm32( R_EBP, (uint32_t)&sh4r );
412 XOR_r32_r32(R_ESI, R_ESI);
414 sh4_x86.in_delay_slot = FALSE;
415 sh4_x86.priv_checked = FALSE;
416 sh4_x86.fpuen_checked = FALSE;
417 sh4_x86.backpatch_posn = 0;
418 sh4_x86.exit_code = 1;
422 * Exit the block early (ie branch out), conditionally or otherwise
426 store_spreg( R_EDI, REG_OFFSET(pc) );
427 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
428 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
430 ADD_r32_r32( R_EAX, R_ECX );
431 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
432 load_imm32( R_EAX, sh4_x86.exit_code );
440 * Flush any open regs back to memory, restore SI/DI/, update PC, etc
442 void sh4_translate_end_block( sh4addr_t pc ) {
443 assert( !sh4_x86.in_delay_slot ); // should never stop here
444 // Normal termination - save PC, cycle count
447 if( sh4_x86.backpatch_posn != 0 ) {
448 uint8_t *end_ptr = xlat_output;
449 // Exception termination. Jump block for various exception codes:
450 PUSH_imm32( EXC_DATA_ADDR_READ );
451 JMP_rel8( 33, target1 );
452 PUSH_imm32( EXC_DATA_ADDR_WRITE );
453 JMP_rel8( 26, target2 );
454 PUSH_imm32( EXC_ILLEGAL );
455 JMP_rel8( 19, target3 );
456 PUSH_imm32( EXC_SLOT_ILLEGAL );
457 JMP_rel8( 12, target4 );
458 PUSH_imm32( EXC_FPU_DISABLED );
459 JMP_rel8( 5, target5 );
460 PUSH_imm32( EXC_SLOT_FPU_DISABLED );
467 load_spreg( R_ECX, REG_OFFSET(pc) );
468 ADD_r32_r32( R_ESI, R_ECX );
469 ADD_r32_r32( R_ESI, R_ECX );
470 store_spreg( R_ECX, REG_OFFSET(pc) );
471 MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
472 load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
474 ADD_r32_r32( R_EAX, R_ECX );
475 store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
477 load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
478 CALL_r32( R_EAX ); // 2
479 ADD_imm8s_r32( 4, R_ESP );
485 sh4_x86_do_backpatch( end_ptr );
491 extern uint16_t *sh4_icache;
492 extern uint32_t sh4_icache_addr;
495 * Translate a single instruction. Delayed branches are handled specially
496 * by translating both branch and delayed instruction as a single unit (as
499 * @return true if the instruction marks the end of a basic block
502 uint32_t sh4_x86_translate_instruction( uint32_t pc )
505 /* Read instruction */
506 uint32_t pageaddr = pc >> 12;
507 if( sh4_icache != NULL && pageaddr == sh4_icache_addr ) {
508 ir = sh4_icache[(pc&0xFFF)>>1];
510 sh4_icache = (uint16_t *)mem_get_page(pc);
511 if( ((uint32_t)sh4_icache) < MAX_IO_REGIONS ) {
512 /* If someone's actually been so daft as to try to execute out of an IO
513 * region, fallback on the full-blown memory read
516 ir = sh4_read_word(pc);
518 sh4_icache_addr = pageaddr;
519 ir = sh4_icache[(pc&0xFFF)>>1];
526 load_reg( R_EAX, Rm );
527 load_reg( R_ECX, Rn );
528 ADD_r32_r32( R_EAX, R_ECX );
529 store_reg( R_ECX, Rn );
532 load_reg( R_EAX, Rn );
533 ADD_imm8s_r32( imm, R_EAX );
534 store_reg( R_EAX, Rn );
537 load_reg( R_EAX, Rm );
538 load_reg( R_ECX, Rn );
540 ADC_r32_r32( R_EAX, R_ECX );
541 store_reg( R_ECX, Rn );
545 load_reg( R_EAX, Rm );
546 load_reg( R_ECX, Rn );
547 ADD_r32_r32( R_EAX, R_ECX );
548 store_reg( R_ECX, Rn );
552 load_reg( R_EAX, Rm );
553 load_reg( R_ECX, Rn );
554 AND_r32_r32( R_EAX, R_ECX );
555 store_reg( R_ECX, Rn );
558 load_reg( R_EAX, 0 );
559 AND_imm32_r32(imm, R_EAX);
560 store_reg( R_EAX, 0 );
562 AND.B #imm, @(R0, GBR) {:
563 load_reg( R_EAX, 0 );
564 load_spreg( R_ECX, R_GBR );
565 ADD_r32_r32( R_EAX, R_ECX );
567 call_func0(sh4_read_byte);
569 AND_imm32_r32(imm, R_EAX );
570 MEM_WRITE_BYTE( R_ECX, R_EAX );
573 load_reg( R_EAX, Rm );
574 load_reg( R_ECX, Rn );
575 CMP_r32_r32( R_EAX, R_ECX );
579 load_reg( R_EAX, 0 );
580 CMP_imm8s_r32(imm, R_EAX);
584 load_reg( R_EAX, Rm );
585 load_reg( R_ECX, Rn );
586 CMP_r32_r32( R_EAX, R_ECX );
590 load_reg( R_EAX, Rm );
591 load_reg( R_ECX, Rn );
592 CMP_r32_r32( R_EAX, R_ECX );
596 load_reg( R_EAX, Rm );
597 load_reg( R_ECX, Rn );
598 CMP_r32_r32( R_EAX, R_ECX );
602 load_reg( R_EAX, Rm );
603 load_reg( R_ECX, Rn );
604 CMP_r32_r32( R_EAX, R_ECX );
608 load_reg( R_EAX, Rn );
609 CMP_imm8s_r32( 0, R_EAX );
613 load_reg( R_EAX, Rn );
614 CMP_imm8s_r32( 0, R_EAX );
618 load_reg( R_EAX, Rm );
619 load_reg( R_ECX, Rn );
620 XOR_r32_r32( R_ECX, R_EAX );
621 TEST_r8_r8( R_AL, R_AL );
622 JE_rel8(13, target1);
623 TEST_r8_r8( R_AH, R_AH ); // 2
625 SHR_imm8_r32( 16, R_EAX ); // 3
626 TEST_r8_r8( R_AL, R_AL ); // 2
628 TEST_r8_r8( R_AH, R_AH ); // 2
635 load_reg( R_EAX, Rm );
636 load_reg( R_ECX, Rn );
637 SHR_imm8_r32( 31, R_EAX );
638 SHR_imm8_r32( 31, R_ECX );
639 store_spreg( R_EAX, R_M );
640 store_spreg( R_ECX, R_Q );
641 CMP_r32_r32( R_EAX, R_ECX );
645 XOR_r32_r32( R_EAX, R_EAX );
646 store_spreg( R_EAX, R_Q );
647 store_spreg( R_EAX, R_M );
648 store_spreg( R_EAX, R_T );
651 load_spreg( R_ECX, R_M );
652 load_reg( R_EAX, Rn );
655 SETC_r8( R_DL ); // Q'
656 CMP_sh4r_r32( R_Q, R_ECX );
658 ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
661 SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
663 store_reg( R_EAX, Rn ); // Done with Rn now
664 SETC_r8(R_AL); // tmp1
665 XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
666 XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
667 store_spreg( R_ECX, R_Q );
668 XOR_imm8s_r32( 1, R_AL ); // T = !Q'
669 MOVZX_r8_r32( R_AL, R_EAX );
670 store_spreg( R_EAX, R_T );
673 load_reg( R_EAX, Rm );
674 load_reg( R_ECX, Rn );
676 store_spreg( R_EDX, R_MACH );
677 store_spreg( R_EAX, R_MACL );
680 load_reg( R_EAX, Rm );
681 load_reg( R_ECX, Rn );
683 store_spreg( R_EDX, R_MACH );
684 store_spreg( R_EAX, R_MACL );
687 load_reg( R_EAX, Rn );
688 ADD_imm8s_r32( -1, R_EAX );
689 store_reg( R_EAX, Rn );
693 load_reg( R_EAX, Rm );
694 MOVSX_r8_r32( R_EAX, R_EAX );
695 store_reg( R_EAX, Rn );
698 load_reg( R_EAX, Rm );
699 MOVSX_r16_r32( R_EAX, R_EAX );
700 store_reg( R_EAX, Rn );
703 load_reg( R_EAX, Rm );
704 MOVZX_r8_r32( R_EAX, R_EAX );
705 store_reg( R_EAX, Rn );
708 load_reg( R_EAX, Rm );
709 MOVZX_r16_r32( R_EAX, R_EAX );
710 store_reg( R_EAX, Rn );
713 load_reg( R_ECX, Rm );
714 check_ralign32( R_ECX );
715 load_reg( R_ECX, Rn );
716 check_ralign32( R_ECX );
717 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
718 MEM_READ_LONG( R_ECX, R_EAX );
720 load_reg( R_ECX, Rm );
721 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
722 MEM_READ_LONG( R_ECX, R_EAX );
725 ADD_r32_sh4r( R_EAX, R_MACL );
726 ADC_r32_sh4r( R_EDX, R_MACH );
728 load_spreg( R_ECX, R_S );
729 TEST_r32_r32(R_ECX, R_ECX);
731 call_func0( signsat48 );
735 load_reg( R_ECX, Rm );
736 check_ralign16( R_ECX );
737 load_reg( R_ECX, Rn );
738 check_ralign16( R_ECX );
739 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
740 MEM_READ_WORD( R_ECX, R_EAX );
742 load_reg( R_ECX, Rm );
743 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
744 MEM_READ_WORD( R_ECX, R_EAX );
748 load_spreg( R_ECX, R_S );
749 TEST_r32_r32( R_ECX, R_ECX );
750 JE_rel8( 47, nosat );
752 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
753 JNO_rel8( 51, end ); // 2
754 load_imm32( R_EDX, 1 ); // 5
755 store_spreg( R_EDX, R_MACH ); // 6
756 JS_rel8( 13, positive ); // 2
757 load_imm32( R_EAX, 0x80000000 );// 5
758 store_spreg( R_EAX, R_MACL ); // 6
759 JMP_rel8( 25, end2 ); // 2
761 JMP_TARGET(positive);
762 load_imm32( R_EAX, 0x7FFFFFFF );// 5
763 store_spreg( R_EAX, R_MACL ); // 6
764 JMP_rel8( 12, end3); // 2
767 ADD_r32_sh4r( R_EAX, R_MACL ); // 6
768 ADC_r32_sh4r( R_EDX, R_MACH ); // 6
774 load_spreg( R_EAX, R_T );
775 store_reg( R_EAX, Rn );
778 load_reg( R_EAX, Rm );
779 load_reg( R_ECX, Rn );
781 store_spreg( R_EAX, R_MACL );
784 load_reg16s( R_EAX, Rm );
785 load_reg16s( R_ECX, Rn );
787 store_spreg( R_EAX, R_MACL );
790 load_reg16u( R_EAX, Rm );
791 load_reg16u( R_ECX, Rn );
793 store_spreg( R_EAX, R_MACL );
796 load_reg( R_EAX, Rm );
798 store_reg( R_EAX, Rn );
801 load_reg( R_EAX, Rm );
802 XOR_r32_r32( R_ECX, R_ECX );
804 SBB_r32_r32( R_EAX, R_ECX );
805 store_reg( R_ECX, Rn );
809 load_reg( R_EAX, Rm );
811 store_reg( R_EAX, Rn );
814 load_reg( R_EAX, Rm );
815 load_reg( R_ECX, Rn );
816 OR_r32_r32( R_EAX, R_ECX );
817 store_reg( R_ECX, Rn );
820 load_reg( R_EAX, 0 );
821 OR_imm32_r32(imm, R_EAX);
822 store_reg( R_EAX, 0 );
824 OR.B #imm, @(R0, GBR) {:
825 load_reg( R_EAX, 0 );
826 load_spreg( R_ECX, R_GBR );
827 ADD_r32_r32( R_EAX, R_ECX );
829 call_func0(sh4_read_byte);
831 OR_imm32_r32(imm, R_EAX );
832 MEM_WRITE_BYTE( R_ECX, R_EAX );
835 load_reg( R_EAX, Rn );
838 store_reg( R_EAX, Rn );
842 load_reg( R_EAX, Rn );
845 store_reg( R_EAX, Rn );
849 load_reg( R_EAX, Rn );
851 store_reg( R_EAX, Rn );
855 load_reg( R_EAX, Rn );
857 store_reg( R_EAX, Rn );
861 /* Annoyingly enough, not directly convertible */
862 load_reg( R_EAX, Rn );
863 load_reg( R_ECX, Rm );
864 CMP_imm32_r32( 0, R_ECX );
867 NEG_r32( R_ECX ); // 2
868 AND_imm8_r8( 0x1F, R_CL ); // 3
869 JE_rel8( 4, emptysar); // 2
870 SAR_r32_CL( R_EAX ); // 2
871 JMP_rel8(10, end); // 2
873 JMP_TARGET(emptysar);
874 SAR_imm8_r32(31, R_EAX ); // 3
878 AND_imm8_r8( 0x1F, R_CL ); // 3
879 SHL_r32_CL( R_EAX ); // 2
882 store_reg( R_EAX, Rn );
885 load_reg( R_EAX, Rn );
886 load_reg( R_ECX, Rm );
887 CMP_imm32_r32( 0, R_ECX );
890 NEG_r32( R_ECX ); // 2
891 AND_imm8_r8( 0x1F, R_CL ); // 3
892 JE_rel8( 4, emptyshr );
893 SHR_r32_CL( R_EAX ); // 2
894 JMP_rel8(9, end); // 2
896 JMP_TARGET(emptyshr);
897 XOR_r32_r32( R_EAX, R_EAX );
901 AND_imm8_r8( 0x1F, R_CL ); // 3
902 SHL_r32_CL( R_EAX ); // 2
905 store_reg( R_EAX, Rn );
908 load_reg( R_EAX, Rn );
910 store_reg( R_EAX, Rn );
913 load_reg( R_EAX, Rn );
915 store_reg( R_EAX, Rn );
918 load_reg( R_EAX, Rn );
920 store_reg( R_EAX, Rn );
923 load_reg( R_EAX, Rn );
924 SHL_imm8_r32( 2, R_EAX );
925 store_reg( R_EAX, Rn );
928 load_reg( R_EAX, Rn );
929 SHL_imm8_r32( 8, R_EAX );
930 store_reg( R_EAX, Rn );
933 load_reg( R_EAX, Rn );
934 SHL_imm8_r32( 16, R_EAX );
935 store_reg( R_EAX, Rn );
938 load_reg( R_EAX, Rn );
940 store_reg( R_EAX, Rn );
943 load_reg( R_EAX, Rn );
944 SHR_imm8_r32( 2, R_EAX );
945 store_reg( R_EAX, Rn );
948 load_reg( R_EAX, Rn );
949 SHR_imm8_r32( 8, R_EAX );
950 store_reg( R_EAX, Rn );
953 load_reg( R_EAX, Rn );
954 SHR_imm8_r32( 16, R_EAX );
955 store_reg( R_EAX, Rn );
958 load_reg( R_EAX, Rm );
959 load_reg( R_ECX, Rn );
960 SUB_r32_r32( R_EAX, R_ECX );
961 store_reg( R_ECX, Rn );
964 load_reg( R_EAX, Rm );
965 load_reg( R_ECX, Rn );
967 SBB_r32_r32( R_EAX, R_ECX );
968 store_reg( R_ECX, Rn );
972 load_reg( R_EAX, Rm );
973 load_reg( R_ECX, Rn );
974 SUB_r32_r32( R_EAX, R_ECX );
975 store_reg( R_ECX, Rn );
979 load_reg( R_EAX, Rm );
980 XCHG_r8_r8( R_AL, R_AH );
981 store_reg( R_EAX, Rn );
984 load_reg( R_EAX, Rm );
985 MOV_r32_r32( R_EAX, R_ECX );
986 SHL_imm8_r32( 16, R_ECX );
987 SHR_imm8_r32( 16, R_EAX );
988 OR_r32_r32( R_EAX, R_ECX );
989 store_reg( R_ECX, Rn );
992 load_reg( R_ECX, Rn );
993 MEM_READ_BYTE( R_ECX, R_EAX );
994 TEST_r8_r8( R_AL, R_AL );
996 OR_imm8_r8( 0x80, R_AL );
997 load_reg( R_ECX, Rn );
998 MEM_WRITE_BYTE( R_ECX, R_EAX );
1001 load_reg( R_EAX, Rm );
1002 load_reg( R_ECX, Rn );
1003 TEST_r32_r32( R_EAX, R_ECX );
1007 load_reg( R_EAX, 0 );
1008 TEST_imm32_r32( imm, R_EAX );
1011 TST.B #imm, @(R0, GBR) {:
1012 load_reg( R_EAX, 0);
1013 load_reg( R_ECX, R_GBR);
1014 ADD_r32_r32( R_EAX, R_ECX );
1015 MEM_READ_BYTE( R_ECX, R_EAX );
1016 TEST_imm8_r8( imm, R_AL );
1020 load_reg( R_EAX, Rm );
1021 load_reg( R_ECX, Rn );
1022 XOR_r32_r32( R_EAX, R_ECX );
1023 store_reg( R_ECX, Rn );
1026 load_reg( R_EAX, 0 );
1027 XOR_imm32_r32( imm, R_EAX );
1028 store_reg( R_EAX, 0 );
1030 XOR.B #imm, @(R0, GBR) {:
1031 load_reg( R_EAX, 0 );
1032 load_spreg( R_ECX, R_GBR );
1033 ADD_r32_r32( R_EAX, R_ECX );
1035 call_func0(sh4_read_byte);
1037 XOR_imm32_r32( imm, R_EAX );
1038 MEM_WRITE_BYTE( R_ECX, R_EAX );
1041 load_reg( R_EAX, Rm );
1042 load_reg( R_ECX, Rn );
1043 SHL_imm8_r32( 16, R_EAX );
1044 SHR_imm8_r32( 16, R_ECX );
1045 OR_r32_r32( R_EAX, R_ECX );
1046 store_reg( R_ECX, Rn );
1049 /* Data move instructions */
1051 load_reg( R_EAX, Rm );
1052 store_reg( R_EAX, Rn );
1055 load_imm32( R_EAX, imm );
1056 store_reg( R_EAX, Rn );
1059 load_reg( R_EAX, Rm );
1060 load_reg( R_ECX, Rn );
1061 MEM_WRITE_BYTE( R_ECX, R_EAX );
1064 load_reg( R_EAX, Rm );
1065 load_reg( R_ECX, Rn );
1066 ADD_imm8s_r32( -1, R_ECX );
1067 store_reg( R_ECX, Rn );
1068 MEM_WRITE_BYTE( R_ECX, R_EAX );
1070 MOV.B Rm, @(R0, Rn) {:
1071 load_reg( R_EAX, 0 );
1072 load_reg( R_ECX, Rn );
1073 ADD_r32_r32( R_EAX, R_ECX );
1074 load_reg( R_EAX, Rm );
1075 MEM_WRITE_BYTE( R_ECX, R_EAX );
1077 MOV.B R0, @(disp, GBR) {:
1078 load_reg( R_EAX, 0 );
1079 load_spreg( R_ECX, R_GBR );
1080 ADD_imm32_r32( disp, R_ECX );
1081 MEM_WRITE_BYTE( R_ECX, R_EAX );
1083 MOV.B R0, @(disp, Rn) {:
1084 load_reg( R_EAX, 0 );
1085 load_reg( R_ECX, Rn );
1086 ADD_imm32_r32( disp, R_ECX );
1087 MEM_WRITE_BYTE( R_ECX, R_EAX );
1090 load_reg( R_ECX, Rm );
1091 MEM_READ_BYTE( R_ECX, R_EAX );
1092 store_reg( R_EAX, Rn );
1095 load_reg( R_ECX, Rm );
1096 MOV_r32_r32( R_ECX, R_EAX );
1097 ADD_imm8s_r32( 1, R_EAX );
1098 store_reg( R_EAX, Rm );
1099 MEM_READ_BYTE( R_ECX, R_EAX );
1100 store_reg( R_EAX, Rn );
1102 MOV.B @(R0, Rm), Rn {:
1103 load_reg( R_EAX, 0 );
1104 load_reg( R_ECX, Rm );
1105 ADD_r32_r32( R_EAX, R_ECX );
1106 MEM_READ_BYTE( R_ECX, R_EAX );
1107 store_reg( R_EAX, Rn );
1109 MOV.B @(disp, GBR), R0 {:
1110 load_spreg( R_ECX, R_GBR );
1111 ADD_imm32_r32( disp, R_ECX );
1112 MEM_READ_BYTE( R_ECX, R_EAX );
1113 store_reg( R_EAX, 0 );
1115 MOV.B @(disp, Rm), R0 {:
1116 load_reg( R_ECX, Rm );
1117 ADD_imm32_r32( disp, R_ECX );
1118 MEM_READ_BYTE( R_ECX, R_EAX );
1119 store_reg( R_EAX, 0 );
1122 load_reg( R_EAX, Rm );
1123 load_reg( R_ECX, Rn );
1124 check_walign32(R_ECX);
1125 MEM_WRITE_LONG( R_ECX, R_EAX );
1128 load_reg( R_EAX, Rm );
1129 load_reg( R_ECX, Rn );
1130 check_walign32( R_ECX );
1131 ADD_imm8s_r32( -4, R_ECX );
1132 store_reg( R_ECX, Rn );
1133 MEM_WRITE_LONG( R_ECX, R_EAX );
1135 MOV.L Rm, @(R0, Rn) {:
1136 load_reg( R_EAX, 0 );
1137 load_reg( R_ECX, Rn );
1138 ADD_r32_r32( R_EAX, R_ECX );
1139 check_walign32( R_ECX );
1140 load_reg( R_EAX, Rm );
1141 MEM_WRITE_LONG( R_ECX, R_EAX );
1143 MOV.L R0, @(disp, GBR) {:
1144 load_spreg( R_ECX, R_GBR );
1145 load_reg( R_EAX, 0 );
1146 ADD_imm32_r32( disp, R_ECX );
1147 check_walign32( R_ECX );
1148 MEM_WRITE_LONG( R_ECX, R_EAX );
1150 MOV.L Rm, @(disp, Rn) {:
1151 load_reg( R_ECX, Rn );
1152 load_reg( R_EAX, Rm );
1153 ADD_imm32_r32( disp, R_ECX );
1154 check_walign32( R_ECX );
1155 MEM_WRITE_LONG( R_ECX, R_EAX );
1158 load_reg( R_ECX, Rm );
1159 check_ralign32( R_ECX );
1160 MEM_READ_LONG( R_ECX, R_EAX );
1161 store_reg( R_EAX, Rn );
1164 load_reg( R_EAX, Rm );
1165 check_ralign32( R_EAX );
1166 MOV_r32_r32( R_EAX, R_ECX );
1167 ADD_imm8s_r32( 4, R_EAX );
1168 store_reg( R_EAX, Rm );
1169 MEM_READ_LONG( R_ECX, R_EAX );
1170 store_reg( R_EAX, Rn );
1172 MOV.L @(R0, Rm), Rn {:
1173 load_reg( R_EAX, 0 );
1174 load_reg( R_ECX, Rm );
1175 ADD_r32_r32( R_EAX, R_ECX );
1176 check_ralign32( R_ECX );
1177 MEM_READ_LONG( R_ECX, R_EAX );
1178 store_reg( R_EAX, Rn );
1180 MOV.L @(disp, GBR), R0 {:
1181 load_spreg( R_ECX, R_GBR );
1182 ADD_imm32_r32( disp, R_ECX );
1183 check_ralign32( R_ECX );
1184 MEM_READ_LONG( R_ECX, R_EAX );
1185 store_reg( R_EAX, 0 );
1187 MOV.L @(disp, PC), Rn {:
1188 if( sh4_x86.in_delay_slot ) {
1191 uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
1192 char *ptr = mem_get_region(target);
1194 MOV_moff32_EAX( (uint32_t)ptr );
1196 load_imm32( R_ECX, target );
1197 MEM_READ_LONG( R_ECX, R_EAX );
1199 store_reg( R_EAX, Rn );
1202 MOV.L @(disp, Rm), Rn {:
1203 load_reg( R_ECX, Rm );
1204 ADD_imm8s_r32( disp, R_ECX );
1205 check_ralign32( R_ECX );
1206 MEM_READ_LONG( R_ECX, R_EAX );
1207 store_reg( R_EAX, Rn );
1210 load_reg( R_ECX, Rn );
1211 check_walign16( R_ECX );
1212 load_reg( R_EAX, Rm );
1213 MEM_WRITE_WORD( R_ECX, R_EAX );
1216 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 );
1223 MOV.W Rm, @(R0, Rn) {:
1224 load_reg( R_EAX, 0 );
1225 load_reg( R_ECX, Rn );
1226 ADD_r32_r32( R_EAX, R_ECX );
1227 check_walign16( R_ECX );
1228 load_reg( R_EAX, Rm );
1229 MEM_WRITE_WORD( R_ECX, R_EAX );
1231 MOV.W R0, @(disp, GBR) {:
1232 load_spreg( R_ECX, R_GBR );
1233 load_reg( R_EAX, 0 );
1234 ADD_imm32_r32( disp, R_ECX );
1235 check_walign16( R_ECX );
1236 MEM_WRITE_WORD( R_ECX, R_EAX );
1238 MOV.W R0, @(disp, Rn) {:
1239 load_reg( R_ECX, Rn );
1240 load_reg( R_EAX, 0 );
1241 ADD_imm32_r32( disp, R_ECX );
1242 check_walign16( R_ECX );
1243 MEM_WRITE_WORD( R_ECX, R_EAX );
1246 load_reg( R_ECX, Rm );
1247 check_ralign16( R_ECX );
1248 MEM_READ_WORD( R_ECX, R_EAX );
1249 store_reg( R_EAX, Rn );
1252 load_reg( R_EAX, Rm );
1253 check_ralign16( R_EAX );
1254 MOV_r32_r32( R_EAX, R_ECX );
1255 ADD_imm8s_r32( 2, R_EAX );
1256 store_reg( R_EAX, Rm );
1257 MEM_READ_WORD( R_ECX, R_EAX );
1258 store_reg( R_EAX, Rn );
1260 MOV.W @(R0, Rm), Rn {:
1261 load_reg( R_EAX, 0 );
1262 load_reg( R_ECX, Rm );
1263 ADD_r32_r32( R_EAX, R_ECX );
1264 check_ralign16( R_ECX );
1265 MEM_READ_WORD( R_ECX, R_EAX );
1266 store_reg( R_EAX, Rn );
1268 MOV.W @(disp, GBR), R0 {:
1269 load_spreg( R_ECX, R_GBR );
1270 ADD_imm32_r32( disp, R_ECX );
1271 check_ralign16( R_ECX );
1272 MEM_READ_WORD( R_ECX, R_EAX );
1273 store_reg( R_EAX, 0 );
1275 MOV.W @(disp, PC), Rn {:
1276 if( sh4_x86.in_delay_slot ) {
1279 load_imm32( R_ECX, pc + disp + 4 );
1280 MEM_READ_WORD( R_ECX, R_EAX );
1281 store_reg( R_EAX, Rn );
1284 MOV.W @(disp, Rm), R0 {:
1285 load_reg( R_ECX, Rm );
1286 ADD_imm32_r32( disp, R_ECX );
1287 check_ralign16( R_ECX );
1288 MEM_READ_WORD( R_ECX, R_EAX );
1289 store_reg( R_EAX, 0 );
1291 MOVA @(disp, PC), R0 {:
1292 if( sh4_x86.in_delay_slot ) {
1295 load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
1296 store_reg( R_ECX, 0 );
1300 load_reg( R_EAX, 0 );
1301 load_reg( R_ECX, Rn );
1302 check_walign32( R_ECX );
1303 MEM_WRITE_LONG( R_ECX, R_EAX );
1306 /* Control transfer instructions */
1308 if( sh4_x86.in_delay_slot ) {
1311 load_imm32( R_EDI, pc + 2 );
1312 CMP_imm8s_sh4r( 0, R_T );
1313 JNE_rel8( 5, nottaken );
1314 load_imm32( R_EDI, disp + pc + 4 );
1315 JMP_TARGET(nottaken);
1321 if( sh4_x86.in_delay_slot ) {
1324 load_imm32( R_EDI, pc + 4 );
1325 CMP_imm8s_sh4r( 0, R_T );
1326 JNE_rel8( 5, nottaken );
1327 load_imm32( R_EDI, disp + pc + 4 );
1328 JMP_TARGET(nottaken);
1329 sh4_x86.in_delay_slot = TRUE;
1334 if( sh4_x86.in_delay_slot ) {
1337 load_imm32( R_EDI, disp + pc + 4 );
1338 sh4_x86.in_delay_slot = TRUE;
1343 if( sh4_x86.in_delay_slot ) {
1346 load_reg( R_EDI, Rn );
1347 ADD_imm32_r32( pc + 4, R_EDI );
1348 sh4_x86.in_delay_slot = TRUE;
1353 if( sh4_x86.in_delay_slot ) {
1356 load_imm32( R_EAX, pc + 4 );
1357 store_spreg( R_EAX, R_PR );
1358 load_imm32( R_EDI, disp + pc + 4 );
1359 sh4_x86.in_delay_slot = TRUE;
1364 if( sh4_x86.in_delay_slot ) {
1367 load_imm32( R_EAX, pc + 4 );
1368 store_spreg( R_EAX, R_PR );
1369 load_reg( R_EDI, Rn );
1370 ADD_r32_r32( R_EAX, R_EDI );
1371 sh4_x86.in_delay_slot = TRUE;
1376 if( sh4_x86.in_delay_slot ) {
1379 load_imm32( R_EDI, pc + 2 );
1380 CMP_imm8s_sh4r( 0, R_T );
1381 JE_rel8( 5, nottaken );
1382 load_imm32( R_EDI, disp + pc + 4 );
1383 JMP_TARGET(nottaken);
1389 if( sh4_x86.in_delay_slot ) {
1392 load_imm32( R_EDI, pc + 4 );
1393 CMP_imm8s_sh4r( 0, R_T );
1394 JE_rel8( 5, nottaken );
1395 load_imm32( R_EDI, disp + pc + 4 );
1396 JMP_TARGET(nottaken);
1397 sh4_x86.in_delay_slot = TRUE;
1402 if( sh4_x86.in_delay_slot ) {
1405 load_reg( R_EDI, Rn );
1406 sh4_x86.in_delay_slot = TRUE;
1411 if( sh4_x86.in_delay_slot ) {
1414 load_imm32( R_EAX, pc + 4 );
1415 store_spreg( R_EAX, R_PR );
1416 load_reg( R_EDI, Rn );
1417 sh4_x86.in_delay_slot = TRUE;
1423 if( sh4_x86.in_delay_slot ) {
1426 load_spreg( R_EDI, R_SPC );
1427 load_spreg( R_EAX, R_SSR );
1428 call_func1( sh4_write_sr, R_EAX );
1429 sh4_x86.in_delay_slot = TRUE;
1430 sh4_x86.priv_checked = FALSE;
1431 sh4_x86.fpuen_checked = FALSE;
1436 if( sh4_x86.in_delay_slot ) {
1439 load_spreg( R_EDI, R_PR );
1440 sh4_x86.in_delay_slot = TRUE;
1445 if( sh4_x86.in_delay_slot ) {
1449 call_func0( sh4_raise_trap );
1450 ADD_imm8s_r32( 4, R_ESP );
1454 if( sh4_x86.in_delay_slot ) {
1457 JMP_exit(EXIT_ILLEGAL);
1463 XOR_r32_r32(R_EAX, R_EAX);
1464 store_spreg( R_EAX, R_MACL );
1465 store_spreg( R_EAX, R_MACH );
1484 /* Floating point moves */
1486 /* As horrible as this looks, it's actually covering 5 separate cases:
1487 * 1. 32-bit fr-to-fr (PR=0)
1488 * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
1489 * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
1490 * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
1491 * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
1494 load_spreg( R_ECX, R_FPSCR );
1495 load_fr_bank( R_EDX );
1496 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1497 JNE_rel8(8, doublesize);
1498 load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
1499 store_fr( R_EDX, R_EAX, FRn );
1502 JMP_TARGET(doublesize);
1503 load_xf_bank( R_ECX );
1504 load_fr( R_ECX, R_EAX, FRm-1 );
1506 load_fr( R_ECX, R_EDX, FRm );
1507 store_fr( R_ECX, R_EAX, FRn-1 );
1508 store_fr( R_ECX, R_EDX, FRn );
1509 } else /* FRn&1 == 0 */ {
1510 load_fr( R_ECX, R_ECX, FRm );
1511 store_fr( R_EDX, R_EAX, FRn );
1512 store_fr( R_EDX, R_ECX, FRn+1 );
1515 } else /* FRm&1 == 0 */ {
1518 load_xf_bank( R_ECX );
1519 load_fr( R_EDX, R_EAX, FRm );
1520 load_fr( R_EDX, R_EDX, FRm+1 );
1521 store_fr( R_ECX, R_EAX, FRn-1 );
1522 store_fr( R_ECX, R_EDX, FRn );
1524 } else /* FRn&1 == 0 */ {
1526 load_fr( R_EDX, R_EAX, FRm );
1527 load_fr( R_EDX, R_ECX, FRm+1 );
1528 store_fr( R_EDX, R_EAX, FRn );
1529 store_fr( R_EDX, R_ECX, FRn+1 );
1536 load_reg( R_EDX, Rn );
1537 check_walign32( R_EDX );
1538 load_spreg( R_ECX, R_FPSCR );
1539 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1540 JNE_rel8(20, doublesize);
1541 load_fr_bank( R_ECX );
1542 load_fr( R_ECX, R_EAX, FRm );
1543 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1545 JMP_rel8( 48, end );
1546 JMP_TARGET(doublesize);
1547 load_xf_bank( R_ECX );
1548 load_fr( R_ECX, R_EAX, FRm&0x0E );
1549 load_fr( R_ECX, R_ECX, FRm|0x01 );
1550 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1553 JMP_rel8( 39, end );
1554 JMP_TARGET(doublesize);
1555 load_fr_bank( R_ECX );
1556 load_fr( R_ECX, R_EAX, FRm&0x0E );
1557 load_fr( R_ECX, R_ECX, FRm|0x01 );
1558 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1564 load_reg( R_EDX, Rm );
1565 check_ralign32( R_EDX );
1566 load_spreg( R_ECX, R_FPSCR );
1567 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1568 JNE_rel8(19, doublesize);
1569 MEM_READ_LONG( R_EDX, R_EAX );
1570 load_fr_bank( R_ECX );
1571 store_fr( R_ECX, R_EAX, FRn );
1574 JMP_TARGET(doublesize);
1575 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1576 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1577 load_xf_bank( R_ECX );
1578 store_fr( R_ECX, R_EAX, FRn&0x0E );
1579 store_fr( R_ECX, R_EDX, FRn|0x01 );
1583 JMP_TARGET(doublesize);
1584 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1585 load_fr_bank( R_ECX );
1586 store_fr( R_ECX, R_EAX, FRn&0x0E );
1587 store_fr( R_ECX, R_EDX, FRn|0x01 );
1593 load_reg( R_EDX, Rn );
1594 check_walign32( R_EDX );
1595 load_spreg( R_ECX, R_FPSCR );
1596 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1597 JNE_rel8(26, doublesize);
1598 load_fr_bank( R_ECX );
1599 load_fr( R_ECX, R_EAX, FRm );
1600 ADD_imm8s_r32(-4,R_EDX);
1601 store_reg( R_EDX, Rn );
1602 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1604 JMP_rel8( 54, end );
1605 JMP_TARGET(doublesize);
1606 load_xf_bank( R_ECX );
1607 load_fr( R_ECX, R_EAX, FRm&0x0E );
1608 load_fr( R_ECX, R_ECX, FRm|0x01 );
1609 ADD_imm8s_r32(-8,R_EDX);
1610 store_reg( R_EDX, Rn );
1611 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1614 JMP_rel8( 45, end );
1615 JMP_TARGET(doublesize);
1616 load_fr_bank( R_ECX );
1617 load_fr( R_ECX, R_EAX, FRm&0x0E );
1618 load_fr( R_ECX, R_ECX, FRm|0x01 );
1619 ADD_imm8s_r32(-8,R_EDX);
1620 store_reg( R_EDX, Rn );
1621 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1627 load_reg( R_EDX, Rm );
1628 check_ralign32( R_EDX );
1629 MOV_r32_r32( R_EDX, R_EAX );
1630 load_spreg( R_ECX, R_FPSCR );
1631 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1632 JNE_rel8(25, doublesize);
1633 ADD_imm8s_r32( 4, R_EAX );
1634 store_reg( R_EAX, Rm );
1635 MEM_READ_LONG( R_EDX, R_EAX );
1636 load_fr_bank( R_ECX );
1637 store_fr( R_ECX, R_EAX, FRn );
1640 JMP_TARGET(doublesize);
1641 ADD_imm8s_r32( 8, R_EAX );
1642 store_reg(R_EAX, Rm);
1643 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1644 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1645 load_xf_bank( R_ECX );
1646 store_fr( R_ECX, R_EAX, FRn&0x0E );
1647 store_fr( R_ECX, R_EDX, FRn|0x01 );
1651 ADD_imm8s_r32( 8, R_EAX );
1652 store_reg(R_EAX, Rm);
1653 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1654 load_fr_bank( R_ECX );
1655 store_fr( R_ECX, R_EAX, FRn&0x0E );
1656 store_fr( R_ECX, R_EDX, FRn|0x01 );
1660 FMOV FRm, @(R0, Rn) {:
1662 load_reg( R_EDX, Rn );
1663 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
1664 check_walign32( R_EDX );
1665 load_spreg( R_ECX, R_FPSCR );
1666 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1667 JNE_rel8(20, doublesize);
1668 load_fr_bank( R_ECX );
1669 load_fr( R_ECX, R_EAX, FRm );
1670 MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
1672 JMP_rel8( 48, end );
1673 JMP_TARGET(doublesize);
1674 load_xf_bank( R_ECX );
1675 load_fr( R_ECX, R_EAX, FRm&0x0E );
1676 load_fr( R_ECX, R_ECX, FRm|0x01 );
1677 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1680 JMP_rel8( 39, end );
1681 JMP_TARGET(doublesize);
1682 load_fr_bank( R_ECX );
1683 load_fr( R_ECX, R_EAX, FRm&0x0E );
1684 load_fr( R_ECX, R_ECX, FRm|0x01 );
1685 MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
1689 FMOV @(R0, Rm), FRn {:
1691 load_reg( R_EDX, Rm );
1692 ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
1693 check_ralign32( R_EDX );
1694 load_spreg( R_ECX, R_FPSCR );
1695 TEST_imm32_r32( FPSCR_SZ, R_ECX );
1696 JNE_rel8(19, doublesize);
1697 MEM_READ_LONG( R_EDX, R_EAX );
1698 load_fr_bank( R_ECX );
1699 store_fr( R_ECX, R_EAX, FRn );
1702 JMP_TARGET(doublesize);
1703 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1704 load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
1705 load_xf_bank( R_ECX );
1706 store_fr( R_ECX, R_EAX, FRn&0x0E );
1707 store_fr( R_ECX, R_EDX, FRn|0x01 );
1711 JMP_TARGET(doublesize);
1712 MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
1713 load_fr_bank( R_ECX );
1714 store_fr( R_ECX, R_EAX, FRn&0x0E );
1715 store_fr( R_ECX, R_EDX, FRn|0x01 );
1719 FLDI0 FRn {: /* IFF PR=0 */
1721 load_spreg( R_ECX, R_FPSCR );
1722 TEST_imm32_r32( FPSCR_PR, R_ECX );
1724 XOR_r32_r32( R_EAX, R_EAX );
1725 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1726 store_fr( R_ECX, R_EAX, FRn );
1729 FLDI1 FRn {: /* IFF PR=0 */
1731 load_spreg( R_ECX, R_FPSCR );
1732 TEST_imm32_r32( FPSCR_PR, R_ECX );
1734 load_imm32(R_EAX, 0x3F800000);
1735 load_spreg( R_ECX, REG_OFFSET(fr_bank) );
1736 store_fr( R_ECX, R_EAX, FRn );
1742 load_spreg( R_ECX, R_FPSCR );
1743 load_spreg(R_EDX, REG_OFFSET(fr_bank));
1745 TEST_imm32_r32( FPSCR_PR, R_ECX );
1746 JNE_rel8(5, doubleprec);
1747 pop_fr( R_EDX, FRn );
1749 JMP_TARGET(doubleprec);
1750 pop_dr( R_EDX, FRn );
1755 load_spreg( R_ECX, R_FPSCR );
1756 load_fr_bank( R_EDX );
1757 TEST_imm32_r32( FPSCR_PR, R_ECX );
1758 JNE_rel8(5, doubleprec);
1759 push_fr( R_EDX, FRm );
1761 JMP_TARGET(doubleprec);
1762 push_dr( R_EDX, FRm );
1764 load_imm32( R_ECX, (uint32_t)&max_int );
1765 FILD_r32ind( R_ECX );
1767 JNA_rel8( 32, sat );
1768 load_imm32( R_ECX, (uint32_t)&min_int ); // 5
1769 FILD_r32ind( R_ECX ); // 2
1771 JAE_rel8( 21, sat2 ); // 2
1772 load_imm32( R_EAX, (uint32_t)&save_fcw );
1773 FNSTCW_r32ind( R_EAX );
1774 load_imm32( R_EDX, (uint32_t)&trunc_fcw );
1775 FLDCW_r32ind( R_EDX );
1776 FISTP_sh4r(R_FPUL); // 3
1777 FLDCW_r32ind( R_EAX );
1778 JMP_rel8( 9, end ); // 2
1782 MOV_r32ind_r32( R_ECX, R_ECX ); // 2
1783 store_spreg( R_ECX, R_FPUL );
1789 load_fr_bank( R_ECX );
1790 load_fr( R_ECX, R_EAX, FRm );
1791 store_spreg( R_EAX, R_FPUL );
1795 load_fr_bank( R_ECX );
1796 load_spreg( R_EAX, R_FPUL );
1797 store_fr( R_ECX, R_EAX, FRn );
1801 load_spreg( R_ECX, R_FPSCR );
1802 TEST_imm32_r32( FPSCR_PR, R_ECX );
1803 JE_rel8(9, end); // only when PR=1
1804 load_fr_bank( R_ECX );
1805 push_dr( R_ECX, FRm );
1811 load_spreg( R_ECX, R_FPSCR );
1812 TEST_imm32_r32( FPSCR_PR, R_ECX );
1813 JE_rel8(9, end); // only when PR=1
1814 load_fr_bank( R_ECX );
1816 pop_dr( R_ECX, FRn );
1820 /* Floating point instructions */
1823 load_spreg( R_ECX, R_FPSCR );
1824 load_fr_bank( R_EDX );
1825 TEST_imm32_r32( FPSCR_PR, R_ECX );
1826 JNE_rel8(10, doubleprec);
1827 push_fr(R_EDX, FRn); // 3
1829 pop_fr( R_EDX, FRn); //3
1830 JMP_rel8(8,end); // 2
1831 JMP_TARGET(doubleprec);
1832 push_dr(R_EDX, FRn);
1839 load_spreg( R_ECX, R_FPSCR );
1840 TEST_imm32_r32( FPSCR_PR, R_ECX );
1841 load_fr_bank( R_EDX );
1842 JNE_rel8(13,doubleprec);
1843 push_fr(R_EDX, FRm);
1844 push_fr(R_EDX, FRn);
1848 JMP_TARGET(doubleprec);
1849 push_dr(R_EDX, FRm);
1850 push_dr(R_EDX, FRn);
1857 load_spreg( R_ECX, R_FPSCR );
1858 TEST_imm32_r32( FPSCR_PR, R_ECX );
1859 load_fr_bank( R_EDX );
1860 JNE_rel8(13, doubleprec);
1861 push_fr(R_EDX, FRn);
1862 push_fr(R_EDX, FRm);
1866 JMP_TARGET(doubleprec);
1867 push_dr(R_EDX, FRn);
1868 push_dr(R_EDX, FRm);
1873 FMAC FR0, FRm, FRn {:
1875 load_spreg( R_ECX, R_FPSCR );
1876 load_spreg( R_EDX, REG_OFFSET(fr_bank));
1877 TEST_imm32_r32( FPSCR_PR, R_ECX );
1878 JNE_rel8(18, doubleprec);
1879 push_fr( R_EDX, 0 );
1880 push_fr( R_EDX, FRm );
1882 push_fr( R_EDX, FRn );
1884 pop_fr( R_EDX, FRn );
1886 JMP_TARGET(doubleprec);
1887 push_dr( R_EDX, 0 );
1888 push_dr( R_EDX, FRm );
1890 push_dr( R_EDX, FRn );
1892 pop_dr( R_EDX, FRn );
1898 load_spreg( R_ECX, R_FPSCR );
1899 TEST_imm32_r32( FPSCR_PR, R_ECX );
1900 load_fr_bank( R_EDX );
1901 JNE_rel8(13, doubleprec);
1902 push_fr(R_EDX, FRm);
1903 push_fr(R_EDX, FRn);
1907 JMP_TARGET(doubleprec);
1908 push_dr(R_EDX, FRm);
1909 push_dr(R_EDX, FRn);
1916 load_spreg( R_ECX, R_FPSCR );
1917 TEST_imm32_r32( FPSCR_PR, R_ECX );
1918 load_fr_bank( R_EDX );
1919 JNE_rel8(10, doubleprec);
1920 push_fr(R_EDX, FRn);
1924 JMP_TARGET(doubleprec);
1925 push_dr(R_EDX, FRn);
1932 load_spreg( R_ECX, R_FPSCR );
1933 TEST_imm32_r32( FPSCR_PR, R_ECX );
1934 load_fr_bank( R_EDX );
1935 JNE_rel8(12, end); // PR=0 only
1937 push_fr(R_EDX, FRn);
1945 load_spreg( R_ECX, R_FPSCR );
1946 TEST_imm32_r32( FPSCR_PR, R_ECX );
1947 load_fr_bank( R_EDX );
1948 JNE_rel8(10, doubleprec);
1949 push_fr(R_EDX, FRn);
1953 JMP_TARGET(doubleprec);
1954 push_dr(R_EDX, FRn);
1961 load_spreg( R_ECX, R_FPSCR );
1962 TEST_imm32_r32( FPSCR_PR, R_ECX );
1963 load_fr_bank( R_EDX );
1964 JNE_rel8(13, doubleprec);
1965 push_fr(R_EDX, FRn);
1966 push_fr(R_EDX, FRm);
1970 JMP_TARGET(doubleprec);
1971 push_dr(R_EDX, FRn);
1972 push_dr(R_EDX, FRm);
1980 load_spreg( R_ECX, R_FPSCR );
1981 TEST_imm32_r32( FPSCR_PR, R_ECX );
1982 load_fr_bank( R_EDX );
1983 JNE_rel8(8, doubleprec);
1984 push_fr(R_EDX, FRm);
1985 push_fr(R_EDX, FRn);
1987 JMP_TARGET(doubleprec);
1988 push_dr(R_EDX, FRm);
1989 push_dr(R_EDX, FRn);
1997 load_spreg( R_ECX, R_FPSCR );
1998 TEST_imm32_r32( FPSCR_PR, R_ECX );
1999 load_fr_bank( R_EDX );
2000 JNE_rel8(8, doubleprec);
2001 push_fr(R_EDX, FRm);
2002 push_fr(R_EDX, FRn);
2004 JMP_TARGET(doubleprec);
2005 push_dr(R_EDX, FRm);
2006 push_dr(R_EDX, FRn);
2015 load_spreg( R_ECX, R_FPSCR );
2016 TEST_imm32_r32( FPSCR_PR, R_ECX );
2017 JNE_rel8( 21, doubleprec );
2018 load_fr_bank( R_ECX );
2019 ADD_imm8s_r32( (FRn&0x0E)<<2, R_ECX );
2020 load_spreg( R_EDX, R_FPUL );
2021 call_func2( sh4_fsca, R_EDX, R_ECX );
2022 JMP_TARGET(doubleprec);
2026 load_spreg( R_ECX, R_FPSCR );
2027 TEST_imm32_r32( FPSCR_PR, R_ECX );
2028 JNE_rel8(44, doubleprec);
2030 load_fr_bank( R_ECX );
2031 push_fr( R_ECX, FVm<<2 );
2032 push_fr( R_ECX, FVn<<2 );
2034 push_fr( R_ECX, (FVm<<2)+1);
2035 push_fr( R_ECX, (FVn<<2)+1);
2038 push_fr( R_ECX, (FVm<<2)+2);
2039 push_fr( R_ECX, (FVn<<2)+2);
2042 push_fr( R_ECX, (FVm<<2)+3);
2043 push_fr( R_ECX, (FVn<<2)+3);
2046 pop_fr( R_ECX, (FVn<<2)+3);
2047 JMP_TARGET(doubleprec);
2051 load_spreg( R_ECX, R_FPSCR );
2052 TEST_imm32_r32( FPSCR_PR, R_ECX );
2053 JNE_rel8( 30, doubleprec );
2054 load_fr_bank( R_EDX ); // 3
2055 ADD_imm8s_r32( FVn<<4, R_EDX ); // 3
2056 load_xf_bank( R_ECX ); // 12
2057 call_func2( sh4_ftrv, R_EDX, R_ECX ); // 12
2058 JMP_TARGET(doubleprec);
2063 load_spreg( R_ECX, R_FPSCR );
2064 XOR_imm32_r32( FPSCR_FR, R_ECX );
2065 store_spreg( R_ECX, R_FPSCR );
2066 update_fr_bank( R_ECX );
2070 load_spreg( R_ECX, R_FPSCR );
2071 XOR_imm32_r32( FPSCR_SZ, R_ECX );
2072 store_spreg( R_ECX, R_FPSCR );
2075 /* Processor control instructions */
2077 if( sh4_x86.in_delay_slot ) {
2081 load_reg( R_EAX, Rm );
2082 call_func1( sh4_write_sr, R_EAX );
2083 sh4_x86.priv_checked = FALSE;
2084 sh4_x86.fpuen_checked = FALSE;
2088 load_reg( R_EAX, Rm );
2089 store_spreg( R_EAX, R_GBR );
2093 load_reg( R_EAX, Rm );
2094 store_spreg( R_EAX, R_VBR );
2098 load_reg( R_EAX, Rm );
2099 store_spreg( R_EAX, R_SSR );
2103 load_reg( R_EAX, Rm );
2104 store_spreg( R_EAX, R_SGR );
2108 load_reg( R_EAX, Rm );
2109 store_spreg( R_EAX, R_SPC );
2113 load_reg( R_EAX, Rm );
2114 store_spreg( R_EAX, R_DBR );
2118 load_reg( R_EAX, Rm );
2119 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2122 load_reg( R_EAX, Rm );
2123 check_ralign32( R_EAX );
2124 MOV_r32_r32( R_EAX, R_ECX );
2125 ADD_imm8s_r32( 4, R_EAX );
2126 store_reg( R_EAX, Rm );
2127 MEM_READ_LONG( R_ECX, R_EAX );
2128 store_spreg( R_EAX, R_GBR );
2131 if( sh4_x86.in_delay_slot ) {
2135 load_reg( R_EAX, Rm );
2136 check_ralign32( R_EAX );
2137 MOV_r32_r32( R_EAX, R_ECX );
2138 ADD_imm8s_r32( 4, R_EAX );
2139 store_reg( R_EAX, Rm );
2140 MEM_READ_LONG( R_ECX, R_EAX );
2141 call_func1( sh4_write_sr, R_EAX );
2142 sh4_x86.priv_checked = FALSE;
2143 sh4_x86.fpuen_checked = FALSE;
2148 load_reg( R_EAX, Rm );
2149 check_ralign32( R_EAX );
2150 MOV_r32_r32( R_EAX, R_ECX );
2151 ADD_imm8s_r32( 4, R_EAX );
2152 store_reg( R_EAX, Rm );
2153 MEM_READ_LONG( R_ECX, R_EAX );
2154 store_spreg( R_EAX, R_VBR );
2158 load_reg( R_EAX, Rm );
2159 MOV_r32_r32( R_EAX, R_ECX );
2160 ADD_imm8s_r32( 4, R_EAX );
2161 store_reg( R_EAX, Rm );
2162 MEM_READ_LONG( R_ECX, R_EAX );
2163 store_spreg( R_EAX, R_SSR );
2167 load_reg( R_EAX, Rm );
2168 check_ralign32( R_EAX );
2169 MOV_r32_r32( R_EAX, R_ECX );
2170 ADD_imm8s_r32( 4, R_EAX );
2171 store_reg( R_EAX, Rm );
2172 MEM_READ_LONG( R_ECX, R_EAX );
2173 store_spreg( R_EAX, R_SGR );
2177 load_reg( R_EAX, Rm );
2178 check_ralign32( R_EAX );
2179 MOV_r32_r32( R_EAX, R_ECX );
2180 ADD_imm8s_r32( 4, R_EAX );
2181 store_reg( R_EAX, Rm );
2182 MEM_READ_LONG( R_ECX, R_EAX );
2183 store_spreg( R_EAX, R_SPC );
2187 load_reg( R_EAX, Rm );
2188 check_ralign32( R_EAX );
2189 MOV_r32_r32( R_EAX, R_ECX );
2190 ADD_imm8s_r32( 4, R_EAX );
2191 store_reg( R_EAX, Rm );
2192 MEM_READ_LONG( R_ECX, R_EAX );
2193 store_spreg( R_EAX, R_DBR );
2195 LDC.L @Rm+, Rn_BANK {:
2197 load_reg( R_EAX, Rm );
2198 check_ralign32( R_EAX );
2199 MOV_r32_r32( R_EAX, R_ECX );
2200 ADD_imm8s_r32( 4, R_EAX );
2201 store_reg( R_EAX, Rm );
2202 MEM_READ_LONG( R_ECX, R_EAX );
2203 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
2206 load_reg( R_EAX, Rm );
2207 store_spreg( R_EAX, R_FPSCR );
2208 update_fr_bank( R_EAX );
2210 LDS.L @Rm+, FPSCR {:
2211 load_reg( R_EAX, Rm );
2212 check_ralign32( R_EAX );
2213 MOV_r32_r32( R_EAX, R_ECX );
2214 ADD_imm8s_r32( 4, R_EAX );
2215 store_reg( R_EAX, Rm );
2216 MEM_READ_LONG( R_ECX, R_EAX );
2217 store_spreg( R_EAX, R_FPSCR );
2218 update_fr_bank( R_EAX );
2221 load_reg( R_EAX, Rm );
2222 store_spreg( R_EAX, R_FPUL );
2225 load_reg( R_EAX, Rm );
2226 check_ralign32( R_EAX );
2227 MOV_r32_r32( R_EAX, R_ECX );
2228 ADD_imm8s_r32( 4, R_EAX );
2229 store_reg( R_EAX, Rm );
2230 MEM_READ_LONG( R_ECX, R_EAX );
2231 store_spreg( R_EAX, R_FPUL );
2234 load_reg( R_EAX, Rm );
2235 store_spreg( R_EAX, R_MACH );
2238 load_reg( R_EAX, Rm );
2239 check_ralign32( R_EAX );
2240 MOV_r32_r32( R_EAX, R_ECX );
2241 ADD_imm8s_r32( 4, R_EAX );
2242 store_reg( R_EAX, Rm );
2243 MEM_READ_LONG( R_ECX, R_EAX );
2244 store_spreg( R_EAX, R_MACH );
2247 load_reg( R_EAX, Rm );
2248 store_spreg( R_EAX, R_MACL );
2251 load_reg( R_EAX, Rm );
2252 check_ralign32( R_EAX );
2253 MOV_r32_r32( R_EAX, R_ECX );
2254 ADD_imm8s_r32( 4, R_EAX );
2255 store_reg( R_EAX, Rm );
2256 MEM_READ_LONG( R_ECX, R_EAX );
2257 store_spreg( R_EAX, R_MACL );
2260 load_reg( R_EAX, Rm );
2261 store_spreg( R_EAX, R_PR );
2264 load_reg( R_EAX, Rm );
2265 check_ralign32( R_EAX );
2266 MOV_r32_r32( R_EAX, R_ECX );
2267 ADD_imm8s_r32( 4, R_EAX );
2268 store_reg( R_EAX, Rm );
2269 MEM_READ_LONG( R_ECX, R_EAX );
2270 store_spreg( R_EAX, R_PR );
2277 load_reg( R_EAX, Rn );
2279 AND_imm32_r32( 0xFC000000, R_EAX );
2280 CMP_imm32_r32( 0xE0000000, R_EAX );
2282 call_func0( sh4_flush_store_queue );
2284 ADD_imm8s_r32( 4, R_ESP );
2288 call_func0( sh4_sleep );
2289 sh4_x86.exit_code = 0;
2290 sh4_x86.in_delay_slot = FALSE;
2296 call_func0(sh4_read_sr);
2297 store_reg( R_EAX, Rn );
2300 load_spreg( R_EAX, R_GBR );
2301 store_reg( R_EAX, Rn );
2305 load_spreg( R_EAX, R_VBR );
2306 store_reg( R_EAX, Rn );
2310 load_spreg( R_EAX, R_SSR );
2311 store_reg( R_EAX, Rn );
2315 load_spreg( R_EAX, R_SPC );
2316 store_reg( R_EAX, Rn );
2320 load_spreg( R_EAX, R_SGR );
2321 store_reg( R_EAX, Rn );
2325 load_spreg( R_EAX, R_DBR );
2326 store_reg( R_EAX, Rn );
2330 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
2331 store_reg( R_EAX, Rn );
2335 call_func0( sh4_read_sr );
2336 load_reg( R_ECX, Rn );
2337 check_walign32( R_ECX );
2338 ADD_imm8s_r32( -4, R_ECX );
2339 store_reg( R_ECX, Rn );
2340 MEM_WRITE_LONG( R_ECX, R_EAX );
2344 load_reg( R_ECX, Rn );
2345 check_walign32( R_ECX );
2346 ADD_imm8s_r32( -4, R_ECX );
2347 store_reg( R_ECX, Rn );
2348 load_spreg( R_EAX, R_VBR );
2349 MEM_WRITE_LONG( R_ECX, R_EAX );
2353 load_reg( R_ECX, Rn );
2354 check_walign32( R_ECX );
2355 ADD_imm8s_r32( -4, R_ECX );
2356 store_reg( R_ECX, Rn );
2357 load_spreg( R_EAX, R_SSR );
2358 MEM_WRITE_LONG( R_ECX, R_EAX );
2362 load_reg( R_ECX, Rn );
2363 check_walign32( R_ECX );
2364 ADD_imm8s_r32( -4, R_ECX );
2365 store_reg( R_ECX, Rn );
2366 load_spreg( R_EAX, R_SPC );
2367 MEM_WRITE_LONG( R_ECX, R_EAX );
2371 load_reg( R_ECX, Rn );
2372 check_walign32( R_ECX );
2373 ADD_imm8s_r32( -4, R_ECX );
2374 store_reg( R_ECX, Rn );
2375 load_spreg( R_EAX, R_SGR );
2376 MEM_WRITE_LONG( R_ECX, R_EAX );
2380 load_reg( R_ECX, Rn );
2381 check_walign32( R_ECX );
2382 ADD_imm8s_r32( -4, R_ECX );
2383 store_reg( R_ECX, Rn );
2384 load_spreg( R_EAX, R_DBR );
2385 MEM_WRITE_LONG( R_ECX, R_EAX );
2387 STC.L Rm_BANK, @-Rn {:
2389 load_reg( R_ECX, Rn );
2390 check_walign32( R_ECX );
2391 ADD_imm8s_r32( -4, R_ECX );
2392 store_reg( R_ECX, Rn );
2393 load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
2394 MEM_WRITE_LONG( R_ECX, R_EAX );
2397 load_reg( R_ECX, Rn );
2398 check_walign32( R_ECX );
2399 ADD_imm8s_r32( -4, R_ECX );
2400 store_reg( R_ECX, Rn );
2401 load_spreg( R_EAX, R_GBR );
2402 MEM_WRITE_LONG( R_ECX, R_EAX );
2405 load_spreg( R_EAX, R_FPSCR );
2406 store_reg( R_EAX, Rn );
2408 STS.L FPSCR, @-Rn {:
2409 load_reg( R_ECX, Rn );
2410 check_walign32( R_ECX );
2411 ADD_imm8s_r32( -4, R_ECX );
2412 store_reg( R_ECX, Rn );
2413 load_spreg( R_EAX, R_FPSCR );
2414 MEM_WRITE_LONG( R_ECX, R_EAX );
2417 load_spreg( R_EAX, R_FPUL );
2418 store_reg( R_EAX, Rn );
2421 load_reg( R_ECX, Rn );
2422 check_walign32( R_ECX );
2423 ADD_imm8s_r32( -4, R_ECX );
2424 store_reg( R_ECX, Rn );
2425 load_spreg( R_EAX, R_FPUL );
2426 MEM_WRITE_LONG( R_ECX, R_EAX );
2429 load_spreg( R_EAX, R_MACH );
2430 store_reg( R_EAX, Rn );
2433 load_reg( R_ECX, Rn );
2434 check_walign32( R_ECX );
2435 ADD_imm8s_r32( -4, R_ECX );
2436 store_reg( R_ECX, Rn );
2437 load_spreg( R_EAX, R_MACH );
2438 MEM_WRITE_LONG( R_ECX, R_EAX );
2441 load_spreg( R_EAX, R_MACL );
2442 store_reg( R_EAX, Rn );
2445 load_reg( R_ECX, Rn );
2446 check_walign32( R_ECX );
2447 ADD_imm8s_r32( -4, R_ECX );
2448 store_reg( R_ECX, Rn );
2449 load_spreg( R_EAX, R_MACL );
2450 MEM_WRITE_LONG( R_ECX, R_EAX );
2453 load_spreg( R_EAX, R_PR );
2454 store_reg( R_EAX, Rn );
2457 load_reg( R_ECX, Rn );
2458 check_walign32( R_ECX );
2459 ADD_imm8s_r32( -4, R_ECX );
2460 store_reg( R_ECX, Rn );
2461 load_spreg( R_EAX, R_PR );
2462 MEM_WRITE_LONG( R_ECX, R_EAX );
2465 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
2467 if( sh4_x86.in_delay_slot ) {
2468 ADD_imm8s_r32(2,R_ESI);
2469 sh4_x86.in_delay_slot = FALSE;
.