Search
lxdream.org :: lxdream/src/sh4/sh4x86.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 394:7eb172bfeefe
prev388:13bae2fb0373
next395:c473acbde186
author nkeynes
date Wed Sep 19 09:15:18 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Fix SUBC (not updating T), FTRC (not truncating), and XTRCT (just b0rked)
view annotate diff log raw
     1 /**
     2  * $Id: sh4x86.in,v 1.12 2007-09-19 09:15:18 nkeynes Exp $
     3  * 
     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.
     7  *
     8  * Copyright (c) 2007 Nathan Keynes.
     9  *
    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.
    14  *
    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.
    19  */
    21 #include <assert.h>
    22 #include <math.h>
    24 #ifndef NDEBUG
    25 #define DEBUG_JUMPS 1
    26 #endif
    28 #include "sh4/sh4core.h"
    29 #include "sh4/sh4trans.h"
    30 #include "sh4/sh4mmio.h"
    31 #include "sh4/x86op.h"
    32 #include "clock.h"
    34 #define DEFAULT_BACKPATCH_SIZE 4096
    36 /** 
    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()
    40  */
    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. */
    45     int exit_code;
    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;
    51 };
    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 )
    67 {
    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;
    72 }
    74 void sh4_fsca( uint32_t anglei, float *fr )
    75 {
    76     float angle = (((float)(anglei&0xFFFF))/65536.0) * 2 * M_PI;
    77     *fr++ = cosf(angle);
    78     *fr = sinf(angle);
    79 }
    81 void sh4_sleep()
    82 {
    83     if( MMIO_READ( CPG, STBCR ) & 0x80 ) {
    84 	sh4r.sh4_state = SH4_STATE_STANDBY;
    85     } else {
    86 	sh4r.sh4_state = SH4_STATE_SLEEP;
    87     }
    88 }
    90 /**
    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
    93  */
    94 void sh4_ftrv( float *target, float *xf )
    95 {
    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];
   105 }
   109 void sh4_x86_init()
   110 {
   111     sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
   112     sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
   113 }
   116 static void sh4_x86_add_backpatch( uint8_t *ptr )
   117 {
   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 );
   122     }
   123     sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
   124 }
   126 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
   127 {
   128     unsigned int i;
   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);
   131     }
   132 }
   134 /**
   135  * Emit an instruction to load an SH4 reg into a real register
   136  */
   137 static inline void load_reg( int x86reg, int sh4reg ) 
   138 {
   139     /* mov [bp+n], reg */
   140     OP(0x8B);
   141     OP(0x45 + (x86reg<<3));
   142     OP(REG_OFFSET(r[sh4reg]));
   143 }
   145 static inline void load_reg16s( int x86reg, int sh4reg )
   146 {
   147     OP(0x0F);
   148     OP(0xBF);
   149     MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
   150 }
   152 static inline void load_reg16u( int x86reg, int sh4reg )
   153 {
   154     OP(0x0F);
   155     OP(0xB7);
   156     MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
   158 }
   160 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
   161 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
   162 /**
   163  * Emit an instruction to load an immediate value into a register
   164  */
   165 static inline void load_imm32( int x86reg, uint32_t value ) {
   166     /* mov #value, reg */
   167     OP(0xB8 + x86reg);
   168     OP32(value);
   169 }
   171 /**
   172  * Emit an instruction to store an SH4 reg (RN)
   173  */
   174 void static inline store_reg( int x86reg, int sh4reg ) {
   175     /* mov reg, [bp+n] */
   176     OP(0x89);
   177     OP(0x45 + (x86reg<<3));
   178     OP(REG_OFFSET(r[sh4reg]));
   179 }
   181 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
   183 /**
   184  * Load an FR register (single-precision floating point) into an integer x86
   185  * register (eg for register-to-register moves)
   186  */
   187 void static inline load_fr( int bankreg, int x86reg, int frm )
   188 {
   189     OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
   190 }
   192 /**
   193  * Store an FR register (single-precision floating point) into an integer x86
   194  * register (eg for register-to-register moves)
   195  */
   196 void static inline store_fr( int bankreg, int x86reg, int frn )
   197 {
   198     OP(0x89);  OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
   199 }
   202 /**
   203  * Load a pointer to the back fp back into the specified x86 register. The
   204  * bankreg must have been previously loaded with FPSCR.
   205  * NB: 12 bytes
   206  */
   207 static inline void load_xf_bank( int bankreg )
   208 {
   209     NOT_r32( 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
   213 }
   215 /**
   216  * Update the fr_bank pointer based on the current fpscr value.
   217  */
   218 static inline void update_fr_bank( int fpscrreg )
   219 {
   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) );
   224 }
   225 /**
   226  * Push FPUL (as a 32-bit float) onto the FPU stack
   227  */
   228 static inline void push_fpul( )
   229 {
   230     OP(0xD9); OP(0x45); OP(R_FPUL);
   231 }
   233 /**
   234  * Pop FPUL (as a 32-bit float) from the FPU stack
   235  */
   236 static inline void pop_fpul( )
   237 {
   238     OP(0xD9); OP(0x5D); OP(R_FPUL);
   239 }
   241 /**
   242  * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
   243  * with the location of the current fp bank.
   244  */
   245 static inline void push_fr( int bankreg, int frm ) 
   246 {
   247     OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2);  // FLD.S [bankreg + frm^1*4]
   248 }
   250 /**
   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.
   253  */
   254 static inline void pop_fr( int bankreg, int frm )
   255 {
   256     OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
   257 }
   259 /**
   260  * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
   261  * with the location of the current fp bank.
   262  */
   263 static inline void push_dr( int bankreg, int frm )
   264 {
   265     OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
   266 }
   268 static inline void pop_dr( int bankreg, int frm )
   269 {
   270     OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
   271 }
   273 /**
   274  * Note: clobbers EAX to make the indirect call - this isn't usually
   275  * a problem since the callee will usually clobber it anyway.
   276  */
   277 static inline void call_func0( void *ptr )
   278 {
   279     load_imm32(R_EAX, (uint32_t)ptr);
   280     CALL_r32(R_EAX);
   281 }
   283 static inline void call_func1( void *ptr, int arg1 )
   284 {
   285     PUSH_r32(arg1);
   286     call_func0(ptr);
   287     ADD_imm8s_r32( 4, R_ESP );
   288 }
   290 static inline void call_func2( void *ptr, int arg1, int arg2 )
   291 {
   292     PUSH_r32(arg2);
   293     PUSH_r32(arg1);
   294     call_func0(ptr);
   295     ADD_imm8s_r32( 8, R_ESP );
   296 }
   298 /**
   299  * Write a double (64-bit) value into memory, with the first word in arg2a, and
   300  * the second in arg2b
   301  * NB: 30 bytes
   302  */
   303 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
   304 {
   305     ADD_imm8s_r32( 4, addr );
   306     PUSH_r32(arg2b);
   307     PUSH_r32(addr);
   308     ADD_imm8s_r32( -4, addr );
   309     PUSH_r32(arg2a);
   310     PUSH_r32(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 );
   315 }
   317 /**
   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
   320  * NB: 27 bytes
   321  */
   322 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
   323 {
   324     PUSH_r32(addr);
   325     call_func0(sh4_read_long);
   326     POP_r32(addr);
   327     PUSH_r32(R_EAX);
   328     ADD_imm8s_r32( 4, addr );
   329     PUSH_r32(addr);
   330     call_func0(sh4_read_long);
   331     ADD_imm8s_r32( 4, R_ESP );
   332     MOV_r32_r32( R_EAX, arg2b );
   333     POP_r32(arg2a);
   334 }
   336 /* Exception checks - Note that all exception checks will clobber EAX */
   337 static void check_priv( )
   338 {
   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 );
   345 	} else {
   346 	    JE_exit( EXIT_ILLEGAL );
   347 	}
   348     }
   349 }
   351 static void check_fpuen( )
   352 {
   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);
   359 	} else {
   360 	    JNE_exit(EXIT_FPU_DISABLED);
   361 	}
   362     }
   363 }
   365 static void check_ralign16( int x86reg )
   366 {
   367     TEST_imm32_r32( 0x00000001, x86reg );
   368     JNE_exit(EXIT_DATA_ADDR_READ);
   369 }
   371 static void check_walign16( int x86reg )
   372 {
   373     TEST_imm32_r32( 0x00000001, x86reg );
   374     JNE_exit(EXIT_DATA_ADDR_WRITE);
   375 }
   377 static void check_ralign32( int x86reg )
   378 {
   379     TEST_imm32_r32( 0x00000003, x86reg );
   380     JNE_exit(EXIT_DATA_ADDR_READ);
   381 }
   382 static void check_walign32( int x86reg )
   383 {
   384     TEST_imm32_r32( 0x00000003, x86reg );
   385     JNE_exit(EXIT_DATA_ADDR_WRITE);
   386 }
   388 #define UNDEF()
   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;
   401 /**
   402  * Emit the 'start of block' assembly. Sets up the stack frame and save
   403  * SI/DI as required
   404  */
   405 void sh4_translate_begin_block() 
   406 {
   407     PUSH_r32(R_EBP);
   408     /* mov &sh4r, ebp */
   409     load_imm32( R_EBP, (uint32_t)&sh4r );
   410     PUSH_r32(R_EDI);
   411     PUSH_r32(R_ESI);
   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;
   419 }
   421 /**
   422  * Exit the block early (ie branch out), conditionally or otherwise
   423  */
   424 void exit_block( )
   425 {
   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) );
   429     MUL_r32( R_ESI );
   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 );
   433     POP_r32(R_ESI);
   434     POP_r32(R_EDI);
   435     POP_r32(R_EBP);
   436     RET();
   437 }
   439 /**
   440  * Flush any open regs back to memory, restore SI/DI/, update PC, etc
   441  */
   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
   445     exit_block( );
   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 );
   461 	// target
   462 	JMP_TARGET(target1);
   463 	JMP_TARGET(target2);
   464 	JMP_TARGET(target3);
   465 	JMP_TARGET(target4);
   466 	JMP_TARGET(target5);
   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) );
   473 	MUL_r32( R_ESI );
   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 );
   480 	POP_r32(R_ESI);
   481 	POP_r32(R_EDI);
   482 	POP_r32(R_EBP);
   483 	RET();
   485 	sh4_x86_do_backpatch( end_ptr );
   486     }
   488 }
   491 extern uint16_t *sh4_icache;
   492 extern uint32_t sh4_icache_addr;
   494 /**
   495  * Translate a single instruction. Delayed branches are handled specially
   496  * by translating both branch and delayed instruction as a single unit (as
   497  * 
   498  *
   499  * @return true if the instruction marks the end of a basic block
   500  * (eg a branch or 
   501  */
   502 uint32_t sh4_x86_translate_instruction( uint32_t pc )
   503 {
   504     uint32_t ir;
   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];
   509     } else {
   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
   514 	     */
   515 	    sh4_icache = NULL;
   516 	    ir = sh4_read_word(pc);
   517 	} else {
   518 	    sh4_icache_addr = pageaddr;
   519 	    ir = sh4_icache[(pc&0xFFF)>>1];
   520 	}
   521     }
   523 %%
   524 /* ALU operations */
   525 ADD Rm, Rn {:
   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 );
   530 :}
   531 ADD #imm, Rn {:  
   532     load_reg( R_EAX, Rn );
   533     ADD_imm8s_r32( imm, R_EAX );
   534     store_reg( R_EAX, Rn );
   535 :}
   536 ADDC Rm, Rn {:
   537     load_reg( R_EAX, Rm );
   538     load_reg( R_ECX, Rn );
   539     LDC_t();
   540     ADC_r32_r32( R_EAX, R_ECX );
   541     store_reg( R_ECX, Rn );
   542     SETC_t();
   543 :}
   544 ADDV Rm, 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 );
   549     SETO_t();
   550 :}
   551 AND Rm, 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 );
   556 :}
   557 AND #imm, R0 {:  
   558     load_reg( R_EAX, 0 );
   559     AND_imm32_r32(imm, R_EAX); 
   560     store_reg( R_EAX, 0 );
   561 :}
   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 );
   566     PUSH_r32(R_ECX);
   567     call_func0(sh4_read_byte);
   568     POP_r32(R_ECX);
   569     AND_imm32_r32(imm, R_EAX );
   570     MEM_WRITE_BYTE( R_ECX, R_EAX );
   571 :}
   572 CMP/EQ Rm, Rn {:  
   573     load_reg( R_EAX, Rm );
   574     load_reg( R_ECX, Rn );
   575     CMP_r32_r32( R_EAX, R_ECX );
   576     SETE_t();
   577 :}
   578 CMP/EQ #imm, R0 {:  
   579     load_reg( R_EAX, 0 );
   580     CMP_imm8s_r32(imm, R_EAX);
   581     SETE_t();
   582 :}
   583 CMP/GE Rm, Rn {:  
   584     load_reg( R_EAX, Rm );
   585     load_reg( R_ECX, Rn );
   586     CMP_r32_r32( R_EAX, R_ECX );
   587     SETGE_t();
   588 :}
   589 CMP/GT Rm, Rn {: 
   590     load_reg( R_EAX, Rm );
   591     load_reg( R_ECX, Rn );
   592     CMP_r32_r32( R_EAX, R_ECX );
   593     SETG_t();
   594 :}
   595 CMP/HI Rm, Rn {:  
   596     load_reg( R_EAX, Rm );
   597     load_reg( R_ECX, Rn );
   598     CMP_r32_r32( R_EAX, R_ECX );
   599     SETA_t();
   600 :}
   601 CMP/HS Rm, Rn {: 
   602     load_reg( R_EAX, Rm );
   603     load_reg( R_ECX, Rn );
   604     CMP_r32_r32( R_EAX, R_ECX );
   605     SETAE_t();
   606  :}
   607 CMP/PL Rn {: 
   608     load_reg( R_EAX, Rn );
   609     CMP_imm8s_r32( 0, R_EAX );
   610     SETG_t();
   611 :}
   612 CMP/PZ Rn {:  
   613     load_reg( R_EAX, Rn );
   614     CMP_imm8s_r32( 0, R_EAX );
   615     SETGE_t();
   616 :}
   617 CMP/STR Rm, Rn {:  
   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
   624     JE_rel8(9, target2);
   625     SHR_imm8_r32( 16, R_EAX ); // 3
   626     TEST_r8_r8( R_AL, R_AL ); // 2
   627     JE_rel8(2, target3);
   628     TEST_r8_r8( R_AH, R_AH ); // 2
   629     JMP_TARGET(target1);
   630     JMP_TARGET(target2);
   631     JMP_TARGET(target3);
   632     SETE_t();
   633 :}
   634 DIV0S Rm, Rn {:
   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 );
   642     SETNE_t();
   643 :}
   644 DIV0U {:  
   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 );
   649 :}
   650 DIV1 Rm, Rn {:
   651     load_spreg( R_ECX, R_M );
   652     load_reg( R_EAX, Rn );
   653     LDC_t();
   654     RCL1_r32( R_EAX );
   655     SETC_r8( R_DL ); // Q'
   656     CMP_sh4r_r32( R_Q, R_ECX );
   657     JE_rel8(5, mqequal);
   658     ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
   659     JMP_rel8(3, end);
   660     JMP_TARGET(mqequal);
   661     SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
   662     JMP_TARGET(end);
   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 );
   671 :}
   672 DMULS.L Rm, Rn {:  
   673     load_reg( R_EAX, Rm );
   674     load_reg( R_ECX, Rn );
   675     IMUL_r32(R_ECX);
   676     store_spreg( R_EDX, R_MACH );
   677     store_spreg( R_EAX, R_MACL );
   678 :}
   679 DMULU.L Rm, Rn {:  
   680     load_reg( R_EAX, Rm );
   681     load_reg( R_ECX, Rn );
   682     MUL_r32(R_ECX);
   683     store_spreg( R_EDX, R_MACH );
   684     store_spreg( R_EAX, R_MACL );    
   685 :}
   686 DT Rn {:  
   687     load_reg( R_EAX, Rn );
   688     ADD_imm8s_r32( -1, R_EAX );
   689     store_reg( R_EAX, Rn );
   690     SETE_t();
   691 :}
   692 EXTS.B Rm, Rn {:  
   693     load_reg( R_EAX, Rm );
   694     MOVSX_r8_r32( R_EAX, R_EAX );
   695     store_reg( R_EAX, Rn );
   696 :}
   697 EXTS.W Rm, Rn {:  
   698     load_reg( R_EAX, Rm );
   699     MOVSX_r16_r32( R_EAX, R_EAX );
   700     store_reg( R_EAX, Rn );
   701 :}
   702 EXTU.B Rm, Rn {:  
   703     load_reg( R_EAX, Rm );
   704     MOVZX_r8_r32( R_EAX, R_EAX );
   705     store_reg( R_EAX, Rn );
   706 :}
   707 EXTU.W Rm, Rn {:  
   708     load_reg( R_EAX, Rm );
   709     MOVZX_r16_r32( R_EAX, R_EAX );
   710     store_reg( R_EAX, Rn );
   711 :}
   712 MAC.L @Rm+, @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 );
   719     PUSH_r32( 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 );
   723     POP_r32( R_ECX );
   724     IMUL_r32( R_ECX );
   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);
   730     JE_rel8( 7, nosat );
   731     call_func0( signsat48 );
   732     JMP_TARGET( nosat );
   733 :}
   734 MAC.W @Rm+, @Rn+ {:  
   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 );
   741     PUSH_r32( 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 );
   745     POP_r32( R_ECX );
   746     IMUL_r32( R_ECX );
   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
   766     JMP_TARGET(nosat);
   767     ADD_r32_sh4r( R_EAX, R_MACL );  // 6
   768     ADC_r32_sh4r( R_EDX, R_MACH );  // 6
   769     JMP_TARGET(end);
   770     JMP_TARGET(end2);
   771     JMP_TARGET(end3);
   772 :}
   773 MOVT Rn {:  
   774     load_spreg( R_EAX, R_T );
   775     store_reg( R_EAX, Rn );
   776 :}
   777 MUL.L Rm, Rn {:  
   778     load_reg( R_EAX, Rm );
   779     load_reg( R_ECX, Rn );
   780     MUL_r32( R_ECX );
   781     store_spreg( R_EAX, R_MACL );
   782 :}
   783 MULS.W Rm, Rn {:
   784     load_reg16s( R_EAX, Rm );
   785     load_reg16s( R_ECX, Rn );
   786     MUL_r32( R_ECX );
   787     store_spreg( R_EAX, R_MACL );
   788 :}
   789 MULU.W Rm, Rn {:  
   790     load_reg16u( R_EAX, Rm );
   791     load_reg16u( R_ECX, Rn );
   792     MUL_r32( R_ECX );
   793     store_spreg( R_EAX, R_MACL );
   794 :}
   795 NEG Rm, Rn {:
   796     load_reg( R_EAX, Rm );
   797     NEG_r32( R_EAX );
   798     store_reg( R_EAX, Rn );
   799 :}
   800 NEGC Rm, Rn {:  
   801     load_reg( R_EAX, Rm );
   802     XOR_r32_r32( R_ECX, R_ECX );
   803     LDC_t();
   804     SBB_r32_r32( R_EAX, R_ECX );
   805     store_reg( R_ECX, Rn );
   806     SETC_t();
   807 :}
   808 NOT Rm, Rn {:  
   809     load_reg( R_EAX, Rm );
   810     NOT_r32( R_EAX );
   811     store_reg( R_EAX, Rn );
   812 :}
   813 OR Rm, 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 );
   818 :}
   819 OR #imm, R0 {:
   820     load_reg( R_EAX, 0 );
   821     OR_imm32_r32(imm, R_EAX);
   822     store_reg( R_EAX, 0 );
   823 :}
   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 );
   828     PUSH_r32(R_ECX);
   829     call_func0(sh4_read_byte);
   830     POP_r32(R_ECX);
   831     OR_imm32_r32(imm, R_EAX );
   832     MEM_WRITE_BYTE( R_ECX, R_EAX );
   833 :}
   834 ROTCL Rn {:
   835     load_reg( R_EAX, Rn );
   836     LDC_t();
   837     RCL1_r32( R_EAX );
   838     store_reg( R_EAX, Rn );
   839     SETC_t();
   840 :}
   841 ROTCR Rn {:  
   842     load_reg( R_EAX, Rn );
   843     LDC_t();
   844     RCR1_r32( R_EAX );
   845     store_reg( R_EAX, Rn );
   846     SETC_t();
   847 :}
   848 ROTL Rn {:  
   849     load_reg( R_EAX, Rn );
   850     ROL1_r32( R_EAX );
   851     store_reg( R_EAX, Rn );
   852     SETC_t();
   853 :}
   854 ROTR Rn {:  
   855     load_reg( R_EAX, Rn );
   856     ROR1_r32( R_EAX );
   857     store_reg( R_EAX, Rn );
   858     SETC_t();
   859 :}
   860 SHAD Rm, 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 );
   865     JGE_rel8(16, doshl);
   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
   875     JMP_rel8(5, end2);
   877     JMP_TARGET(doshl);
   878     AND_imm8_r8( 0x1F, R_CL ); // 3
   879     SHL_r32_CL( R_EAX );       // 2
   880     JMP_TARGET(end);
   881     JMP_TARGET(end2);
   882     store_reg( R_EAX, Rn );
   883 :}
   884 SHLD Rm, Rn {:  
   885     load_reg( R_EAX, Rn );
   886     load_reg( R_ECX, Rm );
   887     CMP_imm32_r32( 0, R_ECX );
   888     JGE_rel8(15, doshl);
   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 );
   898     JMP_rel8(5, end2);
   900     JMP_TARGET(doshl);
   901     AND_imm8_r8( 0x1F, R_CL ); // 3
   902     SHL_r32_CL( R_EAX );       // 2
   903     JMP_TARGET(end);
   904     JMP_TARGET(end2);
   905     store_reg( R_EAX, Rn );
   906 :}
   907 SHAL Rn {: 
   908     load_reg( R_EAX, Rn );
   909     SHL1_r32( R_EAX );
   910     store_reg( R_EAX, Rn );
   911 :}
   912 SHAR Rn {:  
   913     load_reg( R_EAX, Rn );
   914     SAR1_r32( R_EAX );
   915     store_reg( R_EAX, Rn );
   916 :}
   917 SHLL Rn {:  
   918     load_reg( R_EAX, Rn );
   919     SHL1_r32( R_EAX );
   920     store_reg( R_EAX, Rn );
   921 :}
   922 SHLL2 Rn {:
   923     load_reg( R_EAX, Rn );
   924     SHL_imm8_r32( 2, R_EAX );
   925     store_reg( R_EAX, Rn );
   926 :}
   927 SHLL8 Rn {:  
   928     load_reg( R_EAX, Rn );
   929     SHL_imm8_r32( 8, R_EAX );
   930     store_reg( R_EAX, Rn );
   931 :}
   932 SHLL16 Rn {:  
   933     load_reg( R_EAX, Rn );
   934     SHL_imm8_r32( 16, R_EAX );
   935     store_reg( R_EAX, Rn );
   936 :}
   937 SHLR Rn {:  
   938     load_reg( R_EAX, Rn );
   939     SHR1_r32( R_EAX );
   940     store_reg( R_EAX, Rn );
   941 :}
   942 SHLR2 Rn {:  
   943     load_reg( R_EAX, Rn );
   944     SHR_imm8_r32( 2, R_EAX );
   945     store_reg( R_EAX, Rn );
   946 :}
   947 SHLR8 Rn {:  
   948     load_reg( R_EAX, Rn );
   949     SHR_imm8_r32( 8, R_EAX );
   950     store_reg( R_EAX, Rn );
   951 :}
   952 SHLR16 Rn {:  
   953     load_reg( R_EAX, Rn );
   954     SHR_imm8_r32( 16, R_EAX );
   955     store_reg( R_EAX, Rn );
   956 :}
   957 SUB Rm, 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 );
   962 :}
   963 SUBC Rm, Rn {:  
   964     load_reg( R_EAX, Rm );
   965     load_reg( R_ECX, Rn );
   966     LDC_t();
   967     SBB_r32_r32( R_EAX, R_ECX );
   968     store_reg( R_ECX, Rn );
   969     SETC_t();
   970 :}
   971 SUBV Rm, 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 );
   976     SETO_t();
   977 :}
   978 SWAP.B Rm, Rn {:  
   979     load_reg( R_EAX, Rm );
   980     XCHG_r8_r8( R_AL, R_AH );
   981     store_reg( R_EAX, Rn );
   982 :}
   983 SWAP.W Rm, 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 );
   990 :}
   991 TAS.B @Rn {:  
   992     load_reg( R_ECX, Rn );
   993     MEM_READ_BYTE( R_ECX, R_EAX );
   994     TEST_r8_r8( R_AL, R_AL );
   995     SETE_t();
   996     OR_imm8_r8( 0x80, R_AL );
   997     load_reg( R_ECX, Rn );
   998     MEM_WRITE_BYTE( R_ECX, R_EAX );
   999 :}
  1000 TST Rm, Rn {:  
  1001     load_reg( R_EAX, Rm );
  1002     load_reg( R_ECX, Rn );
  1003     TEST_r32_r32( R_EAX, R_ECX );
  1004     SETE_t();
  1005 :}
  1006 TST #imm, R0 {:  
  1007     load_reg( R_EAX, 0 );
  1008     TEST_imm32_r32( imm, R_EAX );
  1009     SETE_t();
  1010 :}
  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 );
  1017     SETE_t();
  1018 :}
  1019 XOR Rm, Rn {:  
  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 );
  1024 :}
  1025 XOR #imm, R0 {:  
  1026     load_reg( R_EAX, 0 );
  1027     XOR_imm32_r32( imm, R_EAX );
  1028     store_reg( R_EAX, 0 );
  1029 :}
  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 );
  1034     PUSH_r32(R_ECX);
  1035     call_func0(sh4_read_byte);
  1036     POP_r32(R_ECX);
  1037     XOR_imm32_r32( imm, R_EAX );
  1038     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1039 :}
  1040 XTRCT Rm, Rn {:
  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 );
  1047 :}
  1049 /* Data move instructions */
  1050 MOV Rm, Rn {:  
  1051     load_reg( R_EAX, Rm );
  1052     store_reg( R_EAX, Rn );
  1053 :}
  1054 MOV #imm, Rn {:  
  1055     load_imm32( R_EAX, imm );
  1056     store_reg( R_EAX, Rn );
  1057 :}
  1058 MOV.B Rm, @Rn {:  
  1059     load_reg( R_EAX, Rm );
  1060     load_reg( R_ECX, Rn );
  1061     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1062 :}
  1063 MOV.B Rm, @-Rn {:  
  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 );
  1069 :}
  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 );
  1076 :}
  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 );
  1082 :}
  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 );
  1088 :}
  1089 MOV.B @Rm, Rn {:  
  1090     load_reg( R_ECX, Rm );
  1091     MEM_READ_BYTE( R_ECX, R_EAX );
  1092     store_reg( R_EAX, Rn );
  1093 :}
  1094 MOV.B @Rm+, 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 );
  1101 :}
  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 );
  1108 :}
  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 );
  1114 :}
  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 );
  1120 :}
  1121 MOV.L Rm, @Rn {:
  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 );
  1126 :}
  1127 MOV.L Rm, @-Rn {:  
  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 );
  1134 :}
  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 );
  1142 :}
  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 );
  1149 :}
  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 );
  1156 :}
  1157 MOV.L @Rm, Rn {:  
  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 );
  1162 :}
  1163 MOV.L @Rm+, 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 );
  1171 :}
  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 );
  1179 :}
  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 );
  1186 :}
  1187 MOV.L @(disp, PC), Rn {:  
  1188     if( sh4_x86.in_delay_slot ) {
  1189 	SLOTILLEGAL();
  1190     } else {
  1191 	uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
  1192 	char *ptr = mem_get_region(target);
  1193 	if( ptr != NULL ) {
  1194 	    MOV_moff32_EAX( (uint32_t)ptr );
  1195 	} else {
  1196 	    load_imm32( R_ECX, target );
  1197 	    MEM_READ_LONG( R_ECX, R_EAX );
  1199 	store_reg( R_EAX, Rn );
  1201 :}
  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 );
  1208 :}
  1209 MOV.W Rm, @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 );
  1214 :}
  1215 MOV.W Rm, @-Rn {:  
  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 );
  1222 :}
  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 );
  1230 :}
  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 );
  1237 :}
  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 );
  1244 :}
  1245 MOV.W @Rm, Rn {:  
  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 );
  1250 :}
  1251 MOV.W @Rm+, 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 );
  1259 :}
  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 );
  1267 :}
  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 );
  1274 :}
  1275 MOV.W @(disp, PC), Rn {:  
  1276     if( sh4_x86.in_delay_slot ) {
  1277 	SLOTILLEGAL();
  1278     } else {
  1279 	load_imm32( R_ECX, pc + disp + 4 );
  1280 	MEM_READ_WORD( R_ECX, R_EAX );
  1281 	store_reg( R_EAX, Rn );
  1283 :}
  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 );
  1290 :}
  1291 MOVA @(disp, PC), R0 {:  
  1292     if( sh4_x86.in_delay_slot ) {
  1293 	SLOTILLEGAL();
  1294     } else {
  1295 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1296 	store_reg( R_ECX, 0 );
  1298 :}
  1299 MOVCA.L R0, @Rn {:  
  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 );
  1304 :}
  1306 /* Control transfer instructions */
  1307 BF disp {:
  1308     if( sh4_x86.in_delay_slot ) {
  1309 	SLOTILLEGAL();
  1310     } else {
  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);
  1316 	INC_r32(R_ESI);
  1317 	return 1;
  1319 :}
  1320 BF/S disp {:
  1321     if( sh4_x86.in_delay_slot ) {
  1322 	SLOTILLEGAL();
  1323     } else {
  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;
  1330 	return 0;
  1332 :}
  1333 BRA disp {:  
  1334     if( sh4_x86.in_delay_slot ) {
  1335 	SLOTILLEGAL();
  1336     } else {
  1337 	load_imm32( R_EDI, disp + pc + 4 );
  1338 	sh4_x86.in_delay_slot = TRUE;
  1339 	return 0;
  1341 :}
  1342 BRAF Rn {:  
  1343     if( sh4_x86.in_delay_slot ) {
  1344 	SLOTILLEGAL();
  1345     } else {
  1346 	load_reg( R_EDI, Rn );
  1347 	ADD_imm32_r32( pc + 4, R_EDI );
  1348 	sh4_x86.in_delay_slot = TRUE;
  1349 	return 0;
  1351 :}
  1352 BSR disp {:  
  1353     if( sh4_x86.in_delay_slot ) {
  1354 	SLOTILLEGAL();
  1355     } else {
  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;
  1360 	return 0;
  1362 :}
  1363 BSRF Rn {:  
  1364     if( sh4_x86.in_delay_slot ) {
  1365 	SLOTILLEGAL();
  1366     } else {
  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;
  1372 	return 0;
  1374 :}
  1375 BT disp {:
  1376     if( sh4_x86.in_delay_slot ) {
  1377 	SLOTILLEGAL();
  1378     } else {
  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);
  1384 	INC_r32(R_ESI);
  1385 	return 1;
  1387 :}
  1388 BT/S disp {:
  1389     if( sh4_x86.in_delay_slot ) {
  1390 	SLOTILLEGAL();
  1391     } else {
  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;
  1398 	return 0;
  1400 :}
  1401 JMP @Rn {:  
  1402     if( sh4_x86.in_delay_slot ) {
  1403 	SLOTILLEGAL();
  1404     } else {
  1405 	load_reg( R_EDI, Rn );
  1406 	sh4_x86.in_delay_slot = TRUE;
  1407 	return 0;
  1409 :}
  1410 JSR @Rn {:  
  1411     if( sh4_x86.in_delay_slot ) {
  1412 	SLOTILLEGAL();
  1413     } else {
  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;
  1418 	return 0;
  1420 :}
  1421 RTE {:  
  1422     check_priv();
  1423     if( sh4_x86.in_delay_slot ) {
  1424 	SLOTILLEGAL();
  1425     } else {
  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;
  1432 	return 0;
  1434 :}
  1435 RTS {:  
  1436     if( sh4_x86.in_delay_slot ) {
  1437 	SLOTILLEGAL();
  1438     } else {
  1439 	load_spreg( R_EDI, R_PR );
  1440 	sh4_x86.in_delay_slot = TRUE;
  1441 	return 0;
  1443 :}
  1444 TRAPA #imm {:  
  1445     if( sh4_x86.in_delay_slot ) {
  1446 	SLOTILLEGAL();
  1447     } else {
  1448 	PUSH_imm32( imm );
  1449 	call_func0( sh4_raise_trap );
  1450 	ADD_imm8s_r32( 4, R_ESP );
  1452 :}
  1453 UNDEF {:  
  1454     if( sh4_x86.in_delay_slot ) {
  1455 	SLOTILLEGAL();
  1456     } else {
  1457 	JMP_exit(EXIT_ILLEGAL);
  1458 	return 1;
  1460 :}
  1462 CLRMAC {:  
  1463     XOR_r32_r32(R_EAX, R_EAX);
  1464     store_spreg( R_EAX, R_MACL );
  1465     store_spreg( R_EAX, R_MACH );
  1466 :}
  1467 CLRS {:
  1468     CLC();
  1469     SETC_sh4r(R_S);
  1470 :}
  1471 CLRT {:  
  1472     CLC();
  1473     SETC_t();
  1474 :}
  1475 SETS {:  
  1476     STC();
  1477     SETC_sh4r(R_S);
  1478 :}
  1479 SETT {:  
  1480     STC();
  1481     SETC_t();
  1482 :}
  1484 /* Floating point moves */
  1485 FMOV FRm, FRn {:  
  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 )
  1492      */
  1493     check_fpuen();
  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 );
  1500     if( FRm&1 ) {
  1501 	JMP_rel8(24, end);
  1502 	JMP_TARGET(doublesize);
  1503 	load_xf_bank( R_ECX ); 
  1504 	load_fr( R_ECX, R_EAX, FRm-1 );
  1505 	if( FRn&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 );
  1514 	JMP_TARGET(end);
  1515     } else /* FRm&1 == 0 */ {
  1516 	if( FRn&1 ) {
  1517 	    JMP_rel8(24, end);
  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 );
  1523 	    JMP_TARGET(end);
  1524 	} else /* FRn&1 == 0 */ {
  1525 	    JMP_rel8(12, end);
  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 );
  1530 	    JMP_TARGET(end);
  1533 :}
  1534 FMOV FRm, @Rn {:  
  1535     check_fpuen();
  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
  1544     if( FRm&1 ) {
  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 );
  1551 	JMP_TARGET(end);
  1552     } else {
  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 );
  1559 	JMP_TARGET(end);
  1561 :}
  1562 FMOV @Rm, FRn {:  
  1563     check_fpuen();
  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 );
  1572     if( FRn&1 ) {
  1573 	JMP_rel8(48, end);
  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 );
  1580 	JMP_TARGET(end);
  1581     } else {
  1582 	JMP_rel8(36, end);
  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 );
  1588 	JMP_TARGET(end);
  1590 :}
  1591 FMOV FRm, @-Rn {:  
  1592     check_fpuen();
  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
  1603     if( FRm&1 ) {
  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 );
  1612 	JMP_TARGET(end);
  1613     } else {
  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 );
  1622 	JMP_TARGET(end);
  1624 :}
  1625 FMOV @Rm+, FRn {:  
  1626     check_fpuen();
  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 );
  1638     if( FRn&1 ) {
  1639 	JMP_rel8(54, end);
  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 );
  1648 	JMP_TARGET(end);
  1649     } else {
  1650 	JMP_rel8(42, end);
  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 );
  1657 	JMP_TARGET(end);
  1659 :}
  1660 FMOV FRm, @(R0, Rn) {:  
  1661     check_fpuen();
  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
  1671     if( FRm&1 ) {
  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 );
  1678 	JMP_TARGET(end);
  1679     } else {
  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 );
  1686 	JMP_TARGET(end);
  1688 :}
  1689 FMOV @(R0, Rm), FRn {:  
  1690     check_fpuen();
  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 );
  1700     if( FRn&1 ) {
  1701 	JMP_rel8(48, end);
  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 );
  1708 	JMP_TARGET(end);
  1709     } else {
  1710 	JMP_rel8(36, end);
  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 );
  1716 	JMP_TARGET(end);
  1718 :}
  1719 FLDI0 FRn {:  /* IFF PR=0 */
  1720     check_fpuen();
  1721     load_spreg( R_ECX, R_FPSCR );
  1722     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1723     JNE_rel8(8, end);
  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 );
  1727     JMP_TARGET(end);
  1728 :}
  1729 FLDI1 FRn {:  /* IFF PR=0 */
  1730     check_fpuen();
  1731     load_spreg( R_ECX, R_FPSCR );
  1732     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1733     JNE_rel8(11, end);
  1734     load_imm32(R_EAX, 0x3F800000);
  1735     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1736     store_fr( R_ECX, R_EAX, FRn );
  1737     JMP_TARGET(end);
  1738 :}
  1740 FLOAT FPUL, FRn {:  
  1741     check_fpuen();
  1742     load_spreg( R_ECX, R_FPSCR );
  1743     load_spreg(R_EDX, REG_OFFSET(fr_bank));
  1744     FILD_sh4r(R_FPUL);
  1745     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1746     JNE_rel8(5, doubleprec);
  1747     pop_fr( R_EDX, FRn );
  1748     JMP_rel8(3, end);
  1749     JMP_TARGET(doubleprec);
  1750     pop_dr( R_EDX, FRn );
  1751     JMP_TARGET(end);
  1752 :}
  1753 FTRC FRm, FPUL {:  
  1754     check_fpuen();
  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 );
  1760     JMP_rel8(3, doop);
  1761     JMP_TARGET(doubleprec);
  1762     push_dr( R_EDX, FRm );
  1763     JMP_TARGET( doop );
  1764     load_imm32( R_ECX, (uint32_t)&max_int );
  1765     FILD_r32ind( R_ECX );
  1766     FCOMIP_st(1);
  1767     JNA_rel8( 32, sat );
  1768     load_imm32( R_ECX, (uint32_t)&min_int );  // 5
  1769     FILD_r32ind( R_ECX );           // 2
  1770     FCOMIP_st(1);                   // 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
  1780     JMP_TARGET(sat);
  1781     JMP_TARGET(sat2);
  1782     MOV_r32ind_r32( R_ECX, R_ECX ); // 2
  1783     store_spreg( R_ECX, R_FPUL );
  1784     FPOP_st();
  1785     JMP_TARGET(end);
  1786 :}
  1787 FLDS FRm, FPUL {:  
  1788     check_fpuen();
  1789     load_fr_bank( R_ECX );
  1790     load_fr( R_ECX, R_EAX, FRm );
  1791     store_spreg( R_EAX, R_FPUL );
  1792 :}
  1793 FSTS FPUL, FRn {:  
  1794     check_fpuen();
  1795     load_fr_bank( R_ECX );
  1796     load_spreg( R_EAX, R_FPUL );
  1797     store_fr( R_ECX, R_EAX, FRn );
  1798 :}
  1799 FCNVDS FRm, FPUL {:  
  1800     check_fpuen();
  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 );
  1806     pop_fpul();
  1807     JMP_TARGET(end);
  1808 :}
  1809 FCNVSD FPUL, FRn {:  
  1810     check_fpuen();
  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 );
  1815     push_fpul();
  1816     pop_dr( R_ECX, FRn );
  1817     JMP_TARGET(end);
  1818 :}
  1820 /* Floating point instructions */
  1821 FABS FRn {:  
  1822     check_fpuen();
  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
  1828     FABS_st0(); // 2
  1829     pop_fr( R_EDX, FRn); //3
  1830     JMP_rel8(8,end); // 2
  1831     JMP_TARGET(doubleprec);
  1832     push_dr(R_EDX, FRn);
  1833     FABS_st0();
  1834     pop_dr(R_EDX, FRn);
  1835     JMP_TARGET(end);
  1836 :}
  1837 FADD FRm, FRn {:  
  1838     check_fpuen();
  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);
  1845     FADDP_st(1);
  1846     pop_fr(R_EDX, FRn);
  1847     JMP_rel8(11,end);
  1848     JMP_TARGET(doubleprec);
  1849     push_dr(R_EDX, FRm);
  1850     push_dr(R_EDX, FRn);
  1851     FADDP_st(1);
  1852     pop_dr(R_EDX, FRn);
  1853     JMP_TARGET(end);
  1854 :}
  1855 FDIV FRm, FRn {:  
  1856     check_fpuen();
  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);
  1863     FDIVP_st(1);
  1864     pop_fr(R_EDX, FRn);
  1865     JMP_rel8(11, end);
  1866     JMP_TARGET(doubleprec);
  1867     push_dr(R_EDX, FRn);
  1868     push_dr(R_EDX, FRm);
  1869     FDIVP_st(1);
  1870     pop_dr(R_EDX, FRn);
  1871     JMP_TARGET(end);
  1872 :}
  1873 FMAC FR0, FRm, FRn {:  
  1874     check_fpuen();
  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 );
  1881     FMULP_st(1);
  1882     push_fr( R_EDX, FRn );
  1883     FADDP_st(1);
  1884     pop_fr( R_EDX, FRn );
  1885     JMP_rel8(16, end);
  1886     JMP_TARGET(doubleprec);
  1887     push_dr( R_EDX, 0 );
  1888     push_dr( R_EDX, FRm );
  1889     FMULP_st(1);
  1890     push_dr( R_EDX, FRn );
  1891     FADDP_st(1);
  1892     pop_dr( R_EDX, FRn );
  1893     JMP_TARGET(end);
  1894 :}
  1896 FMUL FRm, FRn {:  
  1897     check_fpuen();
  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);
  1904     FMULP_st(1);
  1905     pop_fr(R_EDX, FRn);
  1906     JMP_rel8(11, end);
  1907     JMP_TARGET(doubleprec);
  1908     push_dr(R_EDX, FRm);
  1909     push_dr(R_EDX, FRn);
  1910     FMULP_st(1);
  1911     pop_dr(R_EDX, FRn);
  1912     JMP_TARGET(end);
  1913 :}
  1914 FNEG FRn {:  
  1915     check_fpuen();
  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);
  1921     FCHS_st0();
  1922     pop_fr(R_EDX, FRn);
  1923     JMP_rel8(8, end);
  1924     JMP_TARGET(doubleprec);
  1925     push_dr(R_EDX, FRn);
  1926     FCHS_st0();
  1927     pop_dr(R_EDX, FRn);
  1928     JMP_TARGET(end);
  1929 :}
  1930 FSRRA FRn {:  
  1931     check_fpuen();
  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
  1936     FLD1_st0();
  1937     push_fr(R_EDX, FRn);
  1938     FSQRT_st0();
  1939     FDIVP_st(1);
  1940     pop_fr(R_EDX, FRn);
  1941     JMP_TARGET(end);
  1942 :}
  1943 FSQRT FRn {:  
  1944     check_fpuen();
  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);
  1950     FSQRT_st0();
  1951     pop_fr(R_EDX, FRn);
  1952     JMP_rel8(8, end);
  1953     JMP_TARGET(doubleprec);
  1954     push_dr(R_EDX, FRn);
  1955     FSQRT_st0();
  1956     pop_dr(R_EDX, FRn);
  1957     JMP_TARGET(end);
  1958 :}
  1959 FSUB FRm, FRn {:  
  1960     check_fpuen();
  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);
  1967     FSUBP_st(1);
  1968     pop_fr(R_EDX, FRn);
  1969     JMP_rel8(11, end);
  1970     JMP_TARGET(doubleprec);
  1971     push_dr(R_EDX, FRn);
  1972     push_dr(R_EDX, FRm);
  1973     FSUBP_st(1);
  1974     pop_dr(R_EDX, FRn);
  1975     JMP_TARGET(end);
  1976 :}
  1978 FCMP/EQ FRm, FRn {:  
  1979     check_fpuen();
  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);
  1986     JMP_rel8(6, end);
  1987     JMP_TARGET(doubleprec);
  1988     push_dr(R_EDX, FRm);
  1989     push_dr(R_EDX, FRn);
  1990     JMP_TARGET(end);
  1991     FCOMIP_st(1);
  1992     SETE_t();
  1993     FPOP_st();
  1994 :}
  1995 FCMP/GT FRm, FRn {:  
  1996     check_fpuen();
  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);
  2003     JMP_rel8(6, end);
  2004     JMP_TARGET(doubleprec);
  2005     push_dr(R_EDX, FRm);
  2006     push_dr(R_EDX, FRn);
  2007     JMP_TARGET(end);
  2008     FCOMIP_st(1);
  2009     SETA_t();
  2010     FPOP_st();
  2011 :}
  2013 FSCA FPUL, FRn {:  
  2014     check_fpuen();
  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);
  2023 :}
  2024 FIPR FVm, FVn {:  
  2025     check_fpuen();
  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 );
  2033     FMULP_st(1);
  2034     push_fr( R_ECX, (FVm<<2)+1);
  2035     push_fr( R_ECX, (FVn<<2)+1);
  2036     FMULP_st(1);
  2037     FADDP_st(1);
  2038     push_fr( R_ECX, (FVm<<2)+2);
  2039     push_fr( R_ECX, (FVn<<2)+2);
  2040     FMULP_st(1);
  2041     FADDP_st(1);
  2042     push_fr( R_ECX, (FVm<<2)+3);
  2043     push_fr( R_ECX, (FVn<<2)+3);
  2044     FMULP_st(1);
  2045     FADDP_st(1);
  2046     pop_fr( R_ECX, (FVn<<2)+3);
  2047     JMP_TARGET(doubleprec);
  2048 :}
  2049 FTRV XMTRX, FVn {:  
  2050     check_fpuen();
  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);
  2059 :}
  2061 FRCHG {:  
  2062     check_fpuen();
  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 );
  2067 :}
  2068 FSCHG {:  
  2069     check_fpuen();
  2070     load_spreg( R_ECX, R_FPSCR );
  2071     XOR_imm32_r32( FPSCR_SZ, R_ECX );
  2072     store_spreg( R_ECX, R_FPSCR );
  2073 :}
  2075 /* Processor control instructions */
  2076 LDC Rm, SR {:
  2077     if( sh4_x86.in_delay_slot ) {
  2078 	SLOTILLEGAL();
  2079     } else {
  2080 	check_priv();
  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;
  2086 :}
  2087 LDC Rm, GBR {: 
  2088     load_reg( R_EAX, Rm );
  2089     store_spreg( R_EAX, R_GBR );
  2090 :}
  2091 LDC Rm, VBR {:  
  2092     check_priv();
  2093     load_reg( R_EAX, Rm );
  2094     store_spreg( R_EAX, R_VBR );
  2095 :}
  2096 LDC Rm, SSR {:  
  2097     check_priv();
  2098     load_reg( R_EAX, Rm );
  2099     store_spreg( R_EAX, R_SSR );
  2100 :}
  2101 LDC Rm, SGR {:  
  2102     check_priv();
  2103     load_reg( R_EAX, Rm );
  2104     store_spreg( R_EAX, R_SGR );
  2105 :}
  2106 LDC Rm, SPC {:  
  2107     check_priv();
  2108     load_reg( R_EAX, Rm );
  2109     store_spreg( R_EAX, R_SPC );
  2110 :}
  2111 LDC Rm, DBR {:  
  2112     check_priv();
  2113     load_reg( R_EAX, Rm );
  2114     store_spreg( R_EAX, R_DBR );
  2115 :}
  2116 LDC Rm, Rn_BANK {:  
  2117     check_priv();
  2118     load_reg( R_EAX, Rm );
  2119     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  2120 :}
  2121 LDC.L @Rm+, GBR {:  
  2122     load_reg( R_EAX, Rm );
  2123     MOV_r32_r32( R_EAX, R_ECX );
  2124     ADD_imm8s_r32( 4, R_EAX );
  2125     store_reg( R_EAX, Rm );
  2126     MEM_READ_LONG( R_ECX, R_EAX );
  2127     store_spreg( R_EAX, R_GBR );
  2128 :}
  2129 LDC.L @Rm+, SR {:
  2130     if( sh4_x86.in_delay_slot ) {
  2131 	SLOTILLEGAL();
  2132     } else {
  2133 	check_priv();
  2134 	load_reg( R_EAX, Rm );
  2135 	MOV_r32_r32( R_EAX, R_ECX );
  2136 	ADD_imm8s_r32( 4, R_EAX );
  2137 	store_reg( R_EAX, Rm );
  2138 	MEM_READ_LONG( R_ECX, R_EAX );
  2139 	call_func1( sh4_write_sr, R_EAX );
  2140 	sh4_x86.priv_checked = FALSE;
  2141 	sh4_x86.fpuen_checked = FALSE;
  2143 :}
  2144 LDC.L @Rm+, VBR {:  
  2145     check_priv();
  2146     load_reg( R_EAX, Rm );
  2147     MOV_r32_r32( R_EAX, R_ECX );
  2148     ADD_imm8s_r32( 4, R_EAX );
  2149     store_reg( R_EAX, Rm );
  2150     MEM_READ_LONG( R_ECX, R_EAX );
  2151     store_spreg( R_EAX, R_VBR );
  2152 :}
  2153 LDC.L @Rm+, SSR {:
  2154     check_priv();
  2155     load_reg( R_EAX, Rm );
  2156     MOV_r32_r32( R_EAX, R_ECX );
  2157     ADD_imm8s_r32( 4, R_EAX );
  2158     store_reg( R_EAX, Rm );
  2159     MEM_READ_LONG( R_ECX, R_EAX );
  2160     store_spreg( R_EAX, R_SSR );
  2161 :}
  2162 LDC.L @Rm+, SGR {:  
  2163     check_priv();
  2164     load_reg( R_EAX, Rm );
  2165     MOV_r32_r32( R_EAX, R_ECX );
  2166     ADD_imm8s_r32( 4, R_EAX );
  2167     store_reg( R_EAX, Rm );
  2168     MEM_READ_LONG( R_ECX, R_EAX );
  2169     store_spreg( R_EAX, R_SGR );
  2170 :}
  2171 LDC.L @Rm+, SPC {:  
  2172     check_priv();
  2173     load_reg( R_EAX, Rm );
  2174     MOV_r32_r32( R_EAX, R_ECX );
  2175     ADD_imm8s_r32( 4, R_EAX );
  2176     store_reg( R_EAX, Rm );
  2177     MEM_READ_LONG( R_ECX, R_EAX );
  2178     store_spreg( R_EAX, R_SPC );
  2179 :}
  2180 LDC.L @Rm+, DBR {:  
  2181     check_priv();
  2182     load_reg( R_EAX, Rm );
  2183     MOV_r32_r32( R_EAX, R_ECX );
  2184     ADD_imm8s_r32( 4, R_EAX );
  2185     store_reg( R_EAX, Rm );
  2186     MEM_READ_LONG( R_ECX, R_EAX );
  2187     store_spreg( R_EAX, R_DBR );
  2188 :}
  2189 LDC.L @Rm+, Rn_BANK {:  
  2190     check_priv();
  2191     load_reg( R_EAX, Rm );
  2192     MOV_r32_r32( R_EAX, R_ECX );
  2193     ADD_imm8s_r32( 4, R_EAX );
  2194     store_reg( R_EAX, Rm );
  2195     MEM_READ_LONG( R_ECX, R_EAX );
  2196     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  2197 :}
  2198 LDS Rm, FPSCR {:  
  2199     load_reg( R_EAX, Rm );
  2200     store_spreg( R_EAX, R_FPSCR );
  2201     update_fr_bank( R_EAX );
  2202 :}
  2203 LDS.L @Rm+, FPSCR {:  
  2204     load_reg( R_EAX, Rm );
  2205     MOV_r32_r32( R_EAX, R_ECX );
  2206     ADD_imm8s_r32( 4, R_EAX );
  2207     store_reg( R_EAX, Rm );
  2208     MEM_READ_LONG( R_ECX, R_EAX );
  2209     store_spreg( R_EAX, R_FPSCR );
  2210     update_fr_bank( R_EAX );
  2211 :}
  2212 LDS Rm, FPUL {:  
  2213     load_reg( R_EAX, Rm );
  2214     store_spreg( R_EAX, R_FPUL );
  2215 :}
  2216 LDS.L @Rm+, FPUL {:  
  2217     load_reg( R_EAX, Rm );
  2218     MOV_r32_r32( R_EAX, R_ECX );
  2219     ADD_imm8s_r32( 4, R_EAX );
  2220     store_reg( R_EAX, Rm );
  2221     MEM_READ_LONG( R_ECX, R_EAX );
  2222     store_spreg( R_EAX, R_FPUL );
  2223 :}
  2224 LDS Rm, MACH {: 
  2225     load_reg( R_EAX, Rm );
  2226     store_spreg( R_EAX, R_MACH );
  2227 :}
  2228 LDS.L @Rm+, MACH {:  
  2229     load_reg( R_EAX, Rm );
  2230     MOV_r32_r32( R_EAX, R_ECX );
  2231     ADD_imm8s_r32( 4, R_EAX );
  2232     store_reg( R_EAX, Rm );
  2233     MEM_READ_LONG( R_ECX, R_EAX );
  2234     store_spreg( R_EAX, R_MACH );
  2235 :}
  2236 LDS Rm, MACL {:  
  2237     load_reg( R_EAX, Rm );
  2238     store_spreg( R_EAX, R_MACL );
  2239 :}
  2240 LDS.L @Rm+, MACL {:  
  2241     load_reg( R_EAX, Rm );
  2242     MOV_r32_r32( R_EAX, R_ECX );
  2243     ADD_imm8s_r32( 4, R_EAX );
  2244     store_reg( R_EAX, Rm );
  2245     MEM_READ_LONG( R_ECX, R_EAX );
  2246     store_spreg( R_EAX, R_MACL );
  2247 :}
  2248 LDS Rm, PR {:  
  2249     load_reg( R_EAX, Rm );
  2250     store_spreg( R_EAX, R_PR );
  2251 :}
  2252 LDS.L @Rm+, PR {:  
  2253     load_reg( R_EAX, Rm );
  2254     MOV_r32_r32( R_EAX, R_ECX );
  2255     ADD_imm8s_r32( 4, R_EAX );
  2256     store_reg( R_EAX, Rm );
  2257     MEM_READ_LONG( R_ECX, R_EAX );
  2258     store_spreg( R_EAX, R_PR );
  2259 :}
  2260 LDTLB {:  :}
  2261 OCBI @Rn {:  :}
  2262 OCBP @Rn {:  :}
  2263 OCBWB @Rn {:  :}
  2264 PREF @Rn {:
  2265     load_reg( R_EAX, Rn );
  2266     PUSH_r32( R_EAX );
  2267     AND_imm32_r32( 0xFC000000, R_EAX );
  2268     CMP_imm32_r32( 0xE0000000, R_EAX );
  2269     JNE_rel8(7, end);
  2270     call_func0( sh4_flush_store_queue );
  2271     JMP_TARGET(end);
  2272     ADD_imm8s_r32( 4, R_ESP );
  2273 :}
  2274 SLEEP {: 
  2275     check_priv();
  2276     call_func0( sh4_sleep );
  2277     sh4_x86.exit_code = 0;
  2278     sh4_x86.in_delay_slot = FALSE;
  2279     INC_r32(R_ESI);
  2280     return 1;
  2281 :}
  2282 STC SR, Rn {:
  2283     check_priv();
  2284     call_func0(sh4_read_sr);
  2285     store_reg( R_EAX, Rn );
  2286 :}
  2287 STC GBR, Rn {:  
  2288     load_spreg( R_EAX, R_GBR );
  2289     store_reg( R_EAX, Rn );
  2290 :}
  2291 STC VBR, Rn {:  
  2292     check_priv();
  2293     load_spreg( R_EAX, R_VBR );
  2294     store_reg( R_EAX, Rn );
  2295 :}
  2296 STC SSR, Rn {:  
  2297     check_priv();
  2298     load_spreg( R_EAX, R_SSR );
  2299     store_reg( R_EAX, Rn );
  2300 :}
  2301 STC SPC, Rn {:  
  2302     check_priv();
  2303     load_spreg( R_EAX, R_SPC );
  2304     store_reg( R_EAX, Rn );
  2305 :}
  2306 STC SGR, Rn {:  
  2307     check_priv();
  2308     load_spreg( R_EAX, R_SGR );
  2309     store_reg( R_EAX, Rn );
  2310 :}
  2311 STC DBR, Rn {:  
  2312     check_priv();
  2313     load_spreg( R_EAX, R_DBR );
  2314     store_reg( R_EAX, Rn );
  2315 :}
  2316 STC Rm_BANK, Rn {:
  2317     check_priv();
  2318     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  2319     store_reg( R_EAX, Rn );
  2320 :}
  2321 STC.L SR, @-Rn {:
  2322     check_priv();
  2323     load_reg( R_ECX, Rn );
  2324     ADD_imm8s_r32( -4, R_ECX );
  2325     store_reg( R_ECX, Rn );
  2326     call_func0( sh4_read_sr );
  2327     MEM_WRITE_LONG( R_ECX, R_EAX );
  2328 :}
  2329 STC.L VBR, @-Rn {:  
  2330     check_priv();
  2331     load_reg( R_ECX, Rn );
  2332     ADD_imm8s_r32( -4, R_ECX );
  2333     store_reg( R_ECX, Rn );
  2334     load_spreg( R_EAX, R_VBR );
  2335     MEM_WRITE_LONG( R_ECX, R_EAX );
  2336 :}
  2337 STC.L SSR, @-Rn {:  
  2338     check_priv();
  2339     load_reg( R_ECX, Rn );
  2340     ADD_imm8s_r32( -4, R_ECX );
  2341     store_reg( R_ECX, Rn );
  2342     load_spreg( R_EAX, R_SSR );
  2343     MEM_WRITE_LONG( R_ECX, R_EAX );
  2344 :}
  2345 STC.L SPC, @-Rn {:  
  2346     check_priv();
  2347     load_reg( R_ECX, Rn );
  2348     ADD_imm8s_r32( -4, R_ECX );
  2349     store_reg( R_ECX, Rn );
  2350     load_spreg( R_EAX, R_SPC );
  2351     MEM_WRITE_LONG( R_ECX, R_EAX );
  2352 :}
  2353 STC.L SGR, @-Rn {:  
  2354     check_priv();
  2355     load_reg( R_ECX, Rn );
  2356     ADD_imm8s_r32( -4, R_ECX );
  2357     store_reg( R_ECX, Rn );
  2358     load_spreg( R_EAX, R_SGR );
  2359     MEM_WRITE_LONG( R_ECX, R_EAX );
  2360 :}
  2361 STC.L DBR, @-Rn {:  
  2362     check_priv();
  2363     load_reg( R_ECX, Rn );
  2364     ADD_imm8s_r32( -4, R_ECX );
  2365     store_reg( R_ECX, Rn );
  2366     load_spreg( R_EAX, R_DBR );
  2367     MEM_WRITE_LONG( R_ECX, R_EAX );
  2368 :}
  2369 STC.L Rm_BANK, @-Rn {:  
  2370     check_priv();
  2371     load_reg( R_ECX, Rn );
  2372     ADD_imm8s_r32( -4, R_ECX );
  2373     store_reg( R_ECX, Rn );
  2374     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  2375     MEM_WRITE_LONG( R_ECX, R_EAX );
  2376 :}
  2377 STC.L GBR, @-Rn {:  
  2378     load_reg( R_ECX, Rn );
  2379     ADD_imm8s_r32( -4, R_ECX );
  2380     store_reg( R_ECX, Rn );
  2381     load_spreg( R_EAX, R_GBR );
  2382     MEM_WRITE_LONG( R_ECX, R_EAX );
  2383 :}
  2384 STS FPSCR, Rn {:  
  2385     load_spreg( R_EAX, R_FPSCR );
  2386     store_reg( R_EAX, Rn );
  2387 :}
  2388 STS.L FPSCR, @-Rn {:  
  2389     load_reg( R_ECX, Rn );
  2390     ADD_imm8s_r32( -4, R_ECX );
  2391     store_reg( R_ECX, Rn );
  2392     load_spreg( R_EAX, R_FPSCR );
  2393     MEM_WRITE_LONG( R_ECX, R_EAX );
  2394 :}
  2395 STS FPUL, Rn {:  
  2396     load_spreg( R_EAX, R_FPUL );
  2397     store_reg( R_EAX, Rn );
  2398 :}
  2399 STS.L FPUL, @-Rn {:  
  2400     load_reg( R_ECX, Rn );
  2401     ADD_imm8s_r32( -4, R_ECX );
  2402     store_reg( R_ECX, Rn );
  2403     load_spreg( R_EAX, R_FPUL );
  2404     MEM_WRITE_LONG( R_ECX, R_EAX );
  2405 :}
  2406 STS MACH, Rn {:  
  2407     load_spreg( R_EAX, R_MACH );
  2408     store_reg( R_EAX, Rn );
  2409 :}
  2410 STS.L MACH, @-Rn {:  
  2411     load_reg( R_ECX, Rn );
  2412     ADD_imm8s_r32( -4, R_ECX );
  2413     store_reg( R_ECX, Rn );
  2414     load_spreg( R_EAX, R_MACH );
  2415     MEM_WRITE_LONG( R_ECX, R_EAX );
  2416 :}
  2417 STS MACL, Rn {:  
  2418     load_spreg( R_EAX, R_MACL );
  2419     store_reg( R_EAX, Rn );
  2420 :}
  2421 STS.L MACL, @-Rn {:  
  2422     load_reg( R_ECX, Rn );
  2423     ADD_imm8s_r32( -4, R_ECX );
  2424     store_reg( R_ECX, Rn );
  2425     load_spreg( R_EAX, R_MACL );
  2426     MEM_WRITE_LONG( R_ECX, R_EAX );
  2427 :}
  2428 STS PR, Rn {:  
  2429     load_spreg( R_EAX, R_PR );
  2430     store_reg( R_EAX, Rn );
  2431 :}
  2432 STS.L PR, @-Rn {:  
  2433     load_reg( R_ECX, Rn );
  2434     ADD_imm8s_r32( -4, R_ECX );
  2435     store_reg( R_ECX, Rn );
  2436     load_spreg( R_EAX, R_PR );
  2437     MEM_WRITE_LONG( R_ECX, R_EAX );
  2438 :}
  2440 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
  2441 %%
  2442     if( sh4_x86.in_delay_slot ) {
  2443 	ADD_imm8s_r32(2,R_ESI);
  2444 	sh4_x86.in_delay_slot = FALSE;
  2445 	return 1;
  2446     } else {
  2447 	INC_r32(R_ESI);
  2449     return 0;
.