Search
lxdream.org :: lxdream/src/sh4/sh4x86.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 386:6fb10951326a
prev382:fce3f4da92ab
next388:13bae2fb0373
author nkeynes
date Sun Sep 16 07:03:23 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Implement MAC.W, MAC.L and DIV1
Correct SHAD/SHLD
Fix privilege and slot illegal checks on LDC/STC opcodes
Fix various other small bugs
view annotate diff log raw
     1 /**
     2  * $Id: sh4x86.in,v 1.10 2007-09-16 07:03:23 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>
    23 #ifndef NDEBUG
    24 #define DEBUG_JUMPS 1
    25 #endif
    27 #include "sh4/sh4core.h"
    28 #include "sh4/sh4trans.h"
    29 #include "sh4/x86op.h"
    30 #include "clock.h"
    32 #define DEFAULT_BACKPATCH_SIZE 4096
    34 /** 
    35  * Struct to manage internal translation state. This state is not saved -
    36  * it is only valid between calls to sh4_translate_begin_block() and
    37  * sh4_translate_end_block()
    38  */
    39 struct sh4_x86_state {
    40     gboolean in_delay_slot;
    41     gboolean priv_checked; /* true if we've already checked the cpu mode. */
    42     gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
    44     /* Allocated memory for the (block-wide) back-patch list */
    45     uint32_t **backpatch_list;
    46     uint32_t backpatch_posn;
    47     uint32_t backpatch_size;
    48 };
    50 #define EXIT_DATA_ADDR_READ 0
    51 #define EXIT_DATA_ADDR_WRITE 7
    52 #define EXIT_ILLEGAL 14
    53 #define EXIT_SLOT_ILLEGAL 21
    54 #define EXIT_FPU_DISABLED 28
    55 #define EXIT_SLOT_FPU_DISABLED 35
    57 static struct sh4_x86_state sh4_x86;
    59 void signsat48( void )
    60 {
    61     if( ((int64_t)sh4r.mac) < (int64_t)0xFFFF800000000000LL )
    62 	sh4r.mac = 0xFFFF800000000000LL;
    63     else if( ((int64_t)sh4r.mac) > (int64_t)0x00007FFFFFFFFFFFLL )
    64 	sh4r.mac = 0x00007FFFFFFFFFFFLL;
    65 }
    68 void sh4_x86_init()
    69 {
    70     sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
    71     sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
    72 }
    75 static void sh4_x86_add_backpatch( uint8_t *ptr )
    76 {
    77     if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
    78 	sh4_x86.backpatch_size <<= 1;
    79 	sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
    80 	assert( sh4_x86.backpatch_list != NULL );
    81     }
    82     sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
    83 }
    85 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
    86 {
    87     unsigned int i;
    88     for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
    89 	*sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
    90     }
    91 }
    93 /**
    94  * Emit an instruction to load an SH4 reg into a real register
    95  */
    96 static inline void load_reg( int x86reg, int sh4reg ) 
    97 {
    98     /* mov [bp+n], reg */
    99     OP(0x8B);
   100     OP(0x45 + (x86reg<<3));
   101     OP(REG_OFFSET(r[sh4reg]));
   102 }
   104 static inline void load_reg16s( int x86reg, int sh4reg )
   105 {
   106     OP(0x0F);
   107     OP(0xBF);
   108     MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
   109 }
   111 static inline void load_reg16u( int x86reg, int sh4reg )
   112 {
   113     OP(0x0F);
   114     OP(0xB7);
   115     MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
   117 }
   119 #define load_spreg( x86reg, regoff ) MOV_sh4r_r32( regoff, x86reg )
   120 #define store_spreg( x86reg, regoff ) MOV_r32_sh4r( x86reg, regoff )
   121 /**
   122  * Emit an instruction to load an immediate value into a register
   123  */
   124 static inline void load_imm32( int x86reg, uint32_t value ) {
   125     /* mov #value, reg */
   126     OP(0xB8 + x86reg);
   127     OP32(value);
   128 }
   130 /**
   131  * Emit an instruction to store an SH4 reg (RN)
   132  */
   133 void static inline store_reg( int x86reg, int sh4reg ) {
   134     /* mov reg, [bp+n] */
   135     OP(0x89);
   136     OP(0x45 + (x86reg<<3));
   137     OP(REG_OFFSET(r[sh4reg]));
   138 }
   140 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
   142 /**
   143  * Load an FR register (single-precision floating point) into an integer x86
   144  * register (eg for register-to-register moves)
   145  */
   146 void static inline load_fr( int bankreg, int x86reg, int frm )
   147 {
   148     OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
   149 }
   151 /**
   152  * Store an FR register (single-precision floating point) into an integer x86
   153  * register (eg for register-to-register moves)
   154  */
   155 void static inline store_fr( int bankreg, int x86reg, int frn )
   156 {
   157     OP(0x89);  OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
   158 }
   161 /**
   162  * Load a pointer to the back fp back into the specified x86 register. The
   163  * bankreg must have been previously loaded with FPSCR.
   164  * NB: 10 bytes
   165  */
   166 static inline void load_xf_bank( int bankreg )
   167 {
   168     NOT_r32( bankreg );
   169     SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
   170     AND_imm8s_r32( 0x40, bankreg );    // Complete extraction
   171     OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
   172 }
   174 /**
   175  * Update the fr_bank pointer based on the current fpscr value.
   176  */
   177 static inline void update_fr_bank( int fpscrreg )
   178 {
   179     SHR_imm8_r32( (21 - 6), fpscrreg ); // Extract bit 21 then *64 for bank size
   180     AND_imm8s_r32( 0x40, fpscrreg );    // Complete extraction
   181     OP(0x8D); OP(0x44+(fpscrreg<<3)); OP(0x28+fpscrreg); OP(REG_OFFSET(fr)); // LEA [ebp+fpscrreg+disp], fpscrreg
   182     store_spreg( fpscrreg, REG_OFFSET(fr_bank) );
   183 }
   184 /**
   185  * Push FPUL (as a 32-bit float) onto the FPU stack
   186  */
   187 static inline void push_fpul( )
   188 {
   189     OP(0xD9); OP(0x45); OP(R_FPUL);
   190 }
   192 /**
   193  * Pop FPUL (as a 32-bit float) from the FPU stack
   194  */
   195 static inline void pop_fpul( )
   196 {
   197     OP(0xD9); OP(0x5D); OP(R_FPUL);
   198 }
   200 /**
   201  * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
   202  * with the location of the current fp bank.
   203  */
   204 static inline void push_fr( int bankreg, int frm ) 
   205 {
   206     OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2);  // FLD.S [bankreg + frm^1*4]
   207 }
   209 /**
   210  * Pop a 32-bit float from the FPU stack and store it back into the fp bank, 
   211  * with bankreg previously loaded with the location of the current fp bank.
   212  */
   213 static inline void pop_fr( int bankreg, int frm )
   214 {
   215     OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
   216 }
   218 /**
   219  * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
   220  * with the location of the current fp bank.
   221  */
   222 static inline void push_dr( int bankreg, int frm )
   223 {
   224     OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
   225 }
   227 static inline void pop_dr( int bankreg, int frm )
   228 {
   229     OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
   230 }
   232 /**
   233  * Note: clobbers EAX to make the indirect call - this isn't usually
   234  * a problem since the callee will usually clobber it anyway.
   235  */
   236 static inline void call_func0( void *ptr )
   237 {
   238     load_imm32(R_EAX, (uint32_t)ptr);
   239     CALL_r32(R_EAX);
   240 }
   242 static inline void call_func1( void *ptr, int arg1 )
   243 {
   244     PUSH_r32(arg1);
   245     call_func0(ptr);
   246     ADD_imm8s_r32( 4, R_ESP );
   247 }
   249 static inline void call_func2( void *ptr, int arg1, int arg2 )
   250 {
   251     PUSH_r32(arg2);
   252     PUSH_r32(arg1);
   253     call_func0(ptr);
   254     ADD_imm8s_r32( 8, R_ESP );
   255 }
   257 /**
   258  * Write a double (64-bit) value into memory, with the first word in arg2a, and
   259  * the second in arg2b
   260  * NB: 30 bytes
   261  */
   262 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
   263 {
   264     ADD_imm8s_r32( 4, addr );
   265     PUSH_r32(arg2b);
   266     PUSH_r32(addr);
   267     ADD_imm8s_r32( -4, addr );
   268     PUSH_r32(arg2a);
   269     PUSH_r32(addr);
   270     call_func0(sh4_write_long);
   271     ADD_imm8s_r32( 8, R_ESP );
   272     call_func0(sh4_write_long);
   273     ADD_imm8s_r32( 8, R_ESP );
   274 }
   276 /**
   277  * Read a double (64-bit) value from memory, writing the first word into arg2a
   278  * and the second into arg2b. The addr must not be in EAX
   279  * NB: 27 bytes
   280  */
   281 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
   282 {
   283     PUSH_r32(addr);
   284     call_func0(sh4_read_long);
   285     POP_r32(addr);
   286     PUSH_r32(R_EAX);
   287     ADD_imm8s_r32( 4, addr );
   288     PUSH_r32(addr);
   289     call_func0(sh4_read_long);
   290     ADD_imm8s_r32( 4, R_ESP );
   291     MOV_r32_r32( R_EAX, arg2b );
   292     POP_r32(arg2a);
   293 }
   295 /* Exception checks - Note that all exception checks will clobber EAX */
   296 static void check_priv( )
   297 {
   298     if( !sh4_x86.priv_checked ) {
   299 	sh4_x86.priv_checked = TRUE;
   300 	load_spreg( R_EAX, R_SR );
   301 	AND_imm32_r32( SR_MD, R_EAX );
   302 	if( sh4_x86.in_delay_slot ) {
   303 	    JE_exit( EXIT_SLOT_ILLEGAL );
   304 	} else {
   305 	    JE_exit( EXIT_ILLEGAL );
   306 	}
   307     }
   308 }
   310 static void check_fpuen( )
   311 {
   312     if( !sh4_x86.fpuen_checked ) {
   313 	sh4_x86.fpuen_checked = TRUE;
   314 	load_spreg( R_EAX, R_SR );
   315 	AND_imm32_r32( SR_FD, R_EAX );
   316 	if( sh4_x86.in_delay_slot ) {
   317 	    JNE_exit(EXIT_SLOT_FPU_DISABLED);
   318 	} else {
   319 	    JNE_exit(EXIT_FPU_DISABLED);
   320 	}
   321     }
   322 }
   324 static void check_ralign16( int x86reg )
   325 {
   326     TEST_imm32_r32( 0x00000001, x86reg );
   327     JNE_exit(EXIT_DATA_ADDR_READ);
   328 }
   330 static void check_walign16( int x86reg )
   331 {
   332     TEST_imm32_r32( 0x00000001, x86reg );
   333     JNE_exit(EXIT_DATA_ADDR_WRITE);
   334 }
   336 static void check_ralign32( int x86reg )
   337 {
   338     TEST_imm32_r32( 0x00000003, x86reg );
   339     JNE_exit(EXIT_DATA_ADDR_READ);
   340 }
   341 static void check_walign32( int x86reg )
   342 {
   343     TEST_imm32_r32( 0x00000003, x86reg );
   344     JNE_exit(EXIT_DATA_ADDR_WRITE);
   345 }
   347 static inline void raise_exception( int exc )
   348 {
   349     PUSH_imm32(exc);
   350     call_func0(sh4_raise_exception);
   351     ADD_imm8s_r32( 4, R_ESP );
   352     sh4_x86.in_delay_slot = FALSE;
   353 }
   355 #define UNDEF()
   356 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
   357 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
   358 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
   359 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
   360 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
   361 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
   362 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
   364 #define RAISE_EXCEPTION( exc ) raise_exception(exc); return 1;
   365 #define SLOTILLEGAL() JMP_exit(EXIT_SLOT_ILLEGAL); sh4_x86.in_delay_slot = FALSE; return 1;
   369 /**
   370  * Emit the 'start of block' assembly. Sets up the stack frame and save
   371  * SI/DI as required
   372  */
   373 void sh4_translate_begin_block() 
   374 {
   375     PUSH_r32(R_EBP);
   376     /* mov &sh4r, ebp */
   377     load_imm32( R_EBP, (uint32_t)&sh4r );
   378     PUSH_r32(R_EDI);
   379     PUSH_r32(R_ESI);
   380     XOR_r32_r32(R_ESI, R_ESI);
   382     sh4_x86.in_delay_slot = FALSE;
   383     sh4_x86.priv_checked = FALSE;
   384     sh4_x86.fpuen_checked = FALSE;
   385     sh4_x86.backpatch_posn = 0;
   386 }
   388 /**
   389  * Exit the block early (ie branch out), conditionally or otherwise
   390  */
   391 void exit_block( )
   392 {
   393     store_spreg( R_EDI, REG_OFFSET(pc) );
   394     MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
   395     load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   396     MUL_r32( R_ESI );
   397     ADD_r32_r32( R_EAX, R_ECX );
   398     store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   399     load_imm32( R_EAX, 1 );
   400     POP_r32(R_ESI);
   401     POP_r32(R_EDI);
   402     POP_r32(R_EBP);
   403     RET();
   404 }
   406 /**
   407  * Flush any open regs back to memory, restore SI/DI/, update PC, etc
   408  */
   409 void sh4_translate_end_block( sh4addr_t pc ) {
   410     assert( !sh4_x86.in_delay_slot ); // should never stop here
   411     // Normal termination - save PC, cycle count
   412     exit_block( );
   414     uint8_t *end_ptr = xlat_output;
   415     // Exception termination. Jump block for various exception codes:
   416     PUSH_imm32( EXC_DATA_ADDR_READ );
   417     JMP_rel8( 33, target1 );
   418     PUSH_imm32( EXC_DATA_ADDR_WRITE );
   419     JMP_rel8( 26, target2 );
   420     PUSH_imm32( EXC_ILLEGAL );
   421     JMP_rel8( 19, target3 );
   422     PUSH_imm32( EXC_SLOT_ILLEGAL ); 
   423     JMP_rel8( 12, target4 );
   424     PUSH_imm32( EXC_FPU_DISABLED ); 
   425     JMP_rel8( 5, target5 );
   426     PUSH_imm32( EXC_SLOT_FPU_DISABLED );
   427     // target
   428     JMP_TARGET(target1);
   429     JMP_TARGET(target2);
   430     JMP_TARGET(target3);
   431     JMP_TARGET(target4);
   432     JMP_TARGET(target5);
   433     load_spreg( R_ECX, REG_OFFSET(pc) );
   434     ADD_r32_r32( R_ESI, R_ECX );
   435     ADD_r32_r32( R_ESI, R_ECX );
   436     store_spreg( R_ECX, REG_OFFSET(pc) );
   437     MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
   438     load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   439     MUL_r32( R_ESI );
   440     ADD_r32_r32( R_EAX, R_ECX );
   441     store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   443     load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
   444     CALL_r32( R_EAX ); // 2
   445     ADD_imm8s_r32( 4, R_ESP );
   446     POP_r32(R_ESI);
   447     POP_r32(R_EDI);
   448     POP_r32(R_EBP);
   449     RET();
   451     sh4_x86_do_backpatch( end_ptr );
   452 }
   454 /**
   455  * Translate a single instruction. Delayed branches are handled specially
   456  * by translating both branch and delayed instruction as a single unit (as
   457  * 
   458  *
   459  * @return true if the instruction marks the end of a basic block
   460  * (eg a branch or 
   461  */
   462 uint32_t sh4_x86_translate_instruction( uint32_t pc )
   463 {
   464     uint16_t ir = sh4_read_word( pc );
   466 %%
   467 /* ALU operations */
   468 ADD Rm, Rn {:
   469     load_reg( R_EAX, Rm );
   470     load_reg( R_ECX, Rn );
   471     ADD_r32_r32( R_EAX, R_ECX );
   472     store_reg( R_ECX, Rn );
   473 :}
   474 ADD #imm, Rn {:  
   475     load_reg( R_EAX, Rn );
   476     ADD_imm8s_r32( imm, R_EAX );
   477     store_reg( R_EAX, Rn );
   478 :}
   479 ADDC Rm, Rn {:
   480     load_reg( R_EAX, Rm );
   481     load_reg( R_ECX, Rn );
   482     LDC_t();
   483     ADC_r32_r32( R_EAX, R_ECX );
   484     store_reg( R_ECX, Rn );
   485     SETC_t();
   486 :}
   487 ADDV Rm, Rn {:
   488     load_reg( R_EAX, Rm );
   489     load_reg( R_ECX, Rn );
   490     ADD_r32_r32( R_EAX, R_ECX );
   491     store_reg( R_ECX, Rn );
   492     SETO_t();
   493 :}
   494 AND Rm, Rn {:
   495     load_reg( R_EAX, Rm );
   496     load_reg( R_ECX, Rn );
   497     AND_r32_r32( R_EAX, R_ECX );
   498     store_reg( R_ECX, Rn );
   499 :}
   500 AND #imm, R0 {:  
   501     load_reg( R_EAX, 0 );
   502     AND_imm32_r32(imm, R_EAX); 
   503     store_reg( R_EAX, 0 );
   504 :}
   505 AND.B #imm, @(R0, GBR) {: 
   506     load_reg( R_EAX, 0 );
   507     load_spreg( R_ECX, R_GBR );
   508     ADD_r32_r32( R_EAX, R_ECX );
   509     PUSH_r32(R_ECX);
   510     call_func0(sh4_read_byte);
   511     POP_r32(R_ECX);
   512     AND_imm32_r32(imm, R_EAX );
   513     MEM_WRITE_BYTE( R_ECX, R_EAX );
   514 :}
   515 CMP/EQ Rm, Rn {:  
   516     load_reg( R_EAX, Rm );
   517     load_reg( R_ECX, Rn );
   518     CMP_r32_r32( R_EAX, R_ECX );
   519     SETE_t();
   520 :}
   521 CMP/EQ #imm, R0 {:  
   522     load_reg( R_EAX, 0 );
   523     CMP_imm8s_r32(imm, R_EAX);
   524     SETE_t();
   525 :}
   526 CMP/GE Rm, Rn {:  
   527     load_reg( R_EAX, Rm );
   528     load_reg( R_ECX, Rn );
   529     CMP_r32_r32( R_EAX, R_ECX );
   530     SETGE_t();
   531 :}
   532 CMP/GT Rm, Rn {: 
   533     load_reg( R_EAX, Rm );
   534     load_reg( R_ECX, Rn );
   535     CMP_r32_r32( R_EAX, R_ECX );
   536     SETG_t();
   537 :}
   538 CMP/HI Rm, Rn {:  
   539     load_reg( R_EAX, Rm );
   540     load_reg( R_ECX, Rn );
   541     CMP_r32_r32( R_EAX, R_ECX );
   542     SETA_t();
   543 :}
   544 CMP/HS Rm, Rn {: 
   545     load_reg( R_EAX, Rm );
   546     load_reg( R_ECX, Rn );
   547     CMP_r32_r32( R_EAX, R_ECX );
   548     SETAE_t();
   549  :}
   550 CMP/PL Rn {: 
   551     load_reg( R_EAX, Rn );
   552     CMP_imm8s_r32( 0, R_EAX );
   553     SETG_t();
   554 :}
   555 CMP/PZ Rn {:  
   556     load_reg( R_EAX, Rn );
   557     CMP_imm8s_r32( 0, R_EAX );
   558     SETGE_t();
   559 :}
   560 CMP/STR Rm, Rn {:  
   561     load_reg( R_EAX, Rm );
   562     load_reg( R_ECX, Rn );
   563     XOR_r32_r32( R_ECX, R_EAX );
   564     TEST_r8_r8( R_AL, R_AL );
   565     JE_rel8(13, target1);
   566     TEST_r8_r8( R_AH, R_AH ); // 2
   567     JE_rel8(9, target2);
   568     SHR_imm8_r32( 16, R_EAX ); // 3
   569     TEST_r8_r8( R_AL, R_AL ); // 2
   570     JE_rel8(2, target3);
   571     TEST_r8_r8( R_AH, R_AH ); // 2
   572     JMP_TARGET(target1);
   573     JMP_TARGET(target2);
   574     JMP_TARGET(target3);
   575     SETE_t();
   576 :}
   577 DIV0S Rm, Rn {:
   578     load_reg( R_EAX, Rm );
   579     load_reg( R_ECX, Rn );
   580     SHR_imm8_r32( 31, R_EAX );
   581     SHR_imm8_r32( 31, R_ECX );
   582     store_spreg( R_EAX, R_M );
   583     store_spreg( R_ECX, R_Q );
   584     CMP_r32_r32( R_EAX, R_ECX );
   585     SETNE_t();
   586 :}
   587 DIV0U {:  
   588     XOR_r32_r32( R_EAX, R_EAX );
   589     store_spreg( R_EAX, R_Q );
   590     store_spreg( R_EAX, R_M );
   591     store_spreg( R_EAX, R_T );
   592 :}
   593 DIV1 Rm, Rn {:
   594     load_spreg( R_ECX, R_M );
   595     load_reg( R_EAX, Rn );
   596     LDC_t();
   597     RCL1_r32( R_EAX );
   598     SETC_r8( R_DL ); // Q'
   599     CMP_sh4r_r32( R_Q, R_ECX );
   600     JE_rel8(5, mqequal);
   601     ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
   602     JMP_rel8(3, end);
   603     JMP_TARGET(mqequal);
   604     SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_EAX );
   605     JMP_TARGET(end);
   606     store_reg( R_EAX, Rn ); // Done with Rn now
   607     SETC_r8(R_AL); // tmp1
   608     XOR_r8_r8( R_DL, R_AL ); // Q' = Q ^ tmp1
   609     XOR_r8_r8( R_AL, R_CL ); // Q'' = Q' ^ M
   610     store_spreg( R_ECX, R_Q );
   611     XOR_imm8s_r32( 1, R_AL );   // T = !Q'
   612     MOVZX_r8_r32( R_AL, R_EAX );
   613     store_spreg( R_EAX, R_T );
   614 :}
   615 DMULS.L Rm, Rn {:  
   616     load_reg( R_EAX, Rm );
   617     load_reg( R_ECX, Rn );
   618     IMUL_r32(R_ECX);
   619     store_spreg( R_EDX, R_MACH );
   620     store_spreg( R_EAX, R_MACL );
   621 :}
   622 DMULU.L Rm, Rn {:  
   623     load_reg( R_EAX, Rm );
   624     load_reg( R_ECX, Rn );
   625     MUL_r32(R_ECX);
   626     store_spreg( R_EDX, R_MACH );
   627     store_spreg( R_EAX, R_MACL );    
   628 :}
   629 DT Rn {:  
   630     load_reg( R_EAX, Rn );
   631     ADD_imm8s_r32( -1, R_EAX );
   632     store_reg( R_EAX, Rn );
   633     SETE_t();
   634 :}
   635 EXTS.B Rm, Rn {:  
   636     load_reg( R_EAX, Rm );
   637     MOVSX_r8_r32( R_EAX, R_EAX );
   638     store_reg( R_EAX, Rn );
   639 :}
   640 EXTS.W Rm, Rn {:  
   641     load_reg( R_EAX, Rm );
   642     MOVSX_r16_r32( R_EAX, R_EAX );
   643     store_reg( R_EAX, Rn );
   644 :}
   645 EXTU.B Rm, Rn {:  
   646     load_reg( R_EAX, Rm );
   647     MOVZX_r8_r32( R_EAX, R_EAX );
   648     store_reg( R_EAX, Rn );
   649 :}
   650 EXTU.W Rm, Rn {:  
   651     load_reg( R_EAX, Rm );
   652     MOVZX_r16_r32( R_EAX, R_EAX );
   653     store_reg( R_EAX, Rn );
   654 :}
   655 MAC.L @Rm+, @Rn+ {:  
   656     load_reg( R_ECX, Rm );
   657     check_ralign32( R_ECX );
   658     load_reg( R_ECX, Rn );
   659     check_ralign32( R_ECX );
   660     ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rn]) );
   661     MEM_READ_LONG( R_ECX, R_EAX );
   662     PUSH_r32( R_EAX );
   663     load_reg( R_ECX, Rm );
   664     ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );
   665     MEM_READ_LONG( R_ECX, R_EAX );
   666     POP_r32( R_ECX );
   667     IMUL_r32( R_ECX );
   668     ADD_r32_sh4r( R_EAX, R_MACL );
   669     ADC_r32_sh4r( R_EDX, R_MACH );
   671     load_spreg( R_ECX, R_S );
   672     TEST_r32_r32(R_ECX, R_ECX);
   673     JE_rel8( 7, nosat );
   674     call_func0( signsat48 );
   675     JMP_TARGET( nosat );
   676 :}
   677 MAC.W @Rm+, @Rn+ {:  
   678     load_reg( R_ECX, Rm );
   679     check_ralign16( R_ECX );
   680     load_reg( R_ECX, Rn );
   681     check_ralign16( R_ECX );
   682     ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rn]) );
   683     MEM_READ_WORD( R_ECX, R_EAX );
   684     PUSH_r32( R_EAX );
   685     load_reg( R_ECX, Rm );
   686     ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );
   687     MEM_READ_WORD( R_ECX, R_EAX );
   688     POP_r32( R_ECX );
   689     IMUL_r32( R_ECX );
   691     load_spreg( R_ECX, R_S );
   692     TEST_r32_r32( R_ECX, R_ECX );
   693     JE_rel8( 47, nosat );
   695     ADD_r32_sh4r( R_EAX, R_MACL );  // 6
   696     JNO_rel8( 51, end );            // 2
   697     load_imm32( R_EDX, 1 );         // 5
   698     store_spreg( R_EDX, R_MACH );   // 6
   699     JS_rel8( 13, positive );        // 2
   700     load_imm32( R_EAX, 0x80000000 );// 5
   701     store_spreg( R_EAX, R_MACL );   // 6
   702     JMP_rel8( 25, end2 );           // 2
   704     JMP_TARGET(positive);
   705     load_imm32( R_EAX, 0x7FFFFFFF );// 5
   706     store_spreg( R_EAX, R_MACL );   // 6
   707     JMP_rel8( 12, end3);            // 2
   709     JMP_TARGET(nosat);
   710     ADD_r32_sh4r( R_EAX, R_MACL );  // 6
   711     ADC_r32_sh4r( R_EDX, R_MACH );  // 6
   712     JMP_TARGET(end);
   713     JMP_TARGET(end2);
   714     JMP_TARGET(end3);
   715 :}
   716 MOVT Rn {:  
   717     load_spreg( R_EAX, R_T );
   718     store_reg( R_EAX, Rn );
   719 :}
   720 MUL.L Rm, Rn {:  
   721     load_reg( R_EAX, Rm );
   722     load_reg( R_ECX, Rn );
   723     MUL_r32( R_ECX );
   724     store_spreg( R_EAX, R_MACL );
   725 :}
   726 MULS.W Rm, Rn {:
   727     load_reg16s( R_EAX, Rm );
   728     load_reg16s( R_ECX, Rn );
   729     MUL_r32( R_ECX );
   730     store_spreg( R_EAX, R_MACL );
   731 :}
   732 MULU.W Rm, Rn {:  
   733     load_reg16u( R_EAX, Rm );
   734     load_reg16u( R_ECX, Rn );
   735     MUL_r32( R_ECX );
   736     store_spreg( R_EAX, R_MACL );
   737 :}
   738 NEG Rm, Rn {:
   739     load_reg( R_EAX, Rm );
   740     NEG_r32( R_EAX );
   741     store_reg( R_EAX, Rn );
   742 :}
   743 NEGC Rm, Rn {:  
   744     load_reg( R_EAX, Rm );
   745     XOR_r32_r32( R_ECX, R_ECX );
   746     LDC_t();
   747     SBB_r32_r32( R_EAX, R_ECX );
   748     store_reg( R_ECX, Rn );
   749     SETC_t();
   750 :}
   751 NOT Rm, Rn {:  
   752     load_reg( R_EAX, Rm );
   753     NOT_r32( R_EAX );
   754     store_reg( R_EAX, Rn );
   755 :}
   756 OR Rm, Rn {:  
   757     load_reg( R_EAX, Rm );
   758     load_reg( R_ECX, Rn );
   759     OR_r32_r32( R_EAX, R_ECX );
   760     store_reg( R_ECX, Rn );
   761 :}
   762 OR #imm, R0 {:
   763     load_reg( R_EAX, 0 );
   764     OR_imm32_r32(imm, R_EAX);
   765     store_reg( R_EAX, 0 );
   766 :}
   767 OR.B #imm, @(R0, GBR) {:  
   768     load_reg( R_EAX, 0 );
   769     load_spreg( R_ECX, R_GBR );
   770     ADD_r32_r32( R_EAX, R_ECX );
   771     PUSH_r32(R_ECX);
   772     call_func0(sh4_read_byte);
   773     POP_r32(R_ECX);
   774     OR_imm32_r32(imm, R_EAX );
   775     MEM_WRITE_BYTE( R_ECX, R_EAX );
   776 :}
   777 ROTCL Rn {:
   778     load_reg( R_EAX, Rn );
   779     LDC_t();
   780     RCL1_r32( R_EAX );
   781     store_reg( R_EAX, Rn );
   782     SETC_t();
   783 :}
   784 ROTCR Rn {:  
   785     load_reg( R_EAX, Rn );
   786     LDC_t();
   787     RCR1_r32( R_EAX );
   788     store_reg( R_EAX, Rn );
   789     SETC_t();
   790 :}
   791 ROTL Rn {:  
   792     load_reg( R_EAX, Rn );
   793     ROL1_r32( R_EAX );
   794     store_reg( R_EAX, Rn );
   795     SETC_t();
   796 :}
   797 ROTR Rn {:  
   798     load_reg( R_EAX, Rn );
   799     ROR1_r32( R_EAX );
   800     store_reg( R_EAX, Rn );
   801     SETC_t();
   802 :}
   803 SHAD Rm, Rn {:
   804     /* Annoyingly enough, not directly convertible */
   805     load_reg( R_EAX, Rn );
   806     load_reg( R_ECX, Rm );
   807     CMP_imm32_r32( 0, R_ECX );
   808     JGE_rel8(16, doshl);
   810     NEG_r32( R_ECX );      // 2
   811     AND_imm8_r8( 0x1F, R_CL ); // 3
   812     JE_rel8( 4, emptysar);     // 2
   813     SAR_r32_CL( R_EAX );       // 2
   814     JMP_rel8(10, end);          // 2
   816     JMP_TARGET(emptysar);
   817     SAR_imm8_r32(31, R_EAX );  // 3
   818     JMP_rel8(5, end2);
   820     JMP_TARGET(doshl);
   821     AND_imm8_r8( 0x1F, R_CL ); // 3
   822     SHL_r32_CL( R_EAX );       // 2
   823     JMP_TARGET(end);
   824     JMP_TARGET(end2);
   825     store_reg( R_EAX, Rn );
   826 :}
   827 SHLD Rm, Rn {:  
   828     load_reg( R_EAX, Rn );
   829     load_reg( R_ECX, Rm );
   830     CMP_imm32_r32( 0, R_ECX );
   831     JGE_rel8(15, doshl);
   833     NEG_r32( R_ECX );      // 2
   834     AND_imm8_r8( 0x1F, R_CL ); // 3
   835     JE_rel8( 4, emptyshr );
   836     SHR_r32_CL( R_EAX );       // 2
   837     JMP_rel8(9, end);          // 2
   839     JMP_TARGET(emptyshr);
   840     XOR_r32_r32( R_EAX, R_EAX );
   841     JMP_rel8(5, end2);
   843     JMP_TARGET(doshl);
   844     AND_imm8_r8( 0x1F, R_CL ); // 3
   845     SHL_r32_CL( R_EAX );       // 2
   846     JMP_TARGET(end);
   847     JMP_TARGET(end2);
   848     store_reg( R_EAX, Rn );
   849 :}
   850 SHAL Rn {: 
   851     load_reg( R_EAX, Rn );
   852     SHL1_r32( R_EAX );
   853     store_reg( R_EAX, Rn );
   854 :}
   855 SHAR Rn {:  
   856     load_reg( R_EAX, Rn );
   857     SAR1_r32( R_EAX );
   858     store_reg( R_EAX, Rn );
   859 :}
   860 SHLL Rn {:  
   861     load_reg( R_EAX, Rn );
   862     SHL1_r32( R_EAX );
   863     store_reg( R_EAX, Rn );
   864 :}
   865 SHLL2 Rn {:
   866     load_reg( R_EAX, Rn );
   867     SHL_imm8_r32( 2, R_EAX );
   868     store_reg( R_EAX, Rn );
   869 :}
   870 SHLL8 Rn {:  
   871     load_reg( R_EAX, Rn );
   872     SHL_imm8_r32( 8, R_EAX );
   873     store_reg( R_EAX, Rn );
   874 :}
   875 SHLL16 Rn {:  
   876     load_reg( R_EAX, Rn );
   877     SHL_imm8_r32( 16, R_EAX );
   878     store_reg( R_EAX, Rn );
   879 :}
   880 SHLR Rn {:  
   881     load_reg( R_EAX, Rn );
   882     SHR1_r32( R_EAX );
   883     store_reg( R_EAX, Rn );
   884 :}
   885 SHLR2 Rn {:  
   886     load_reg( R_EAX, Rn );
   887     SHR_imm8_r32( 2, R_EAX );
   888     store_reg( R_EAX, Rn );
   889 :}
   890 SHLR8 Rn {:  
   891     load_reg( R_EAX, Rn );
   892     SHR_imm8_r32( 8, R_EAX );
   893     store_reg( R_EAX, Rn );
   894 :}
   895 SHLR16 Rn {:  
   896     load_reg( R_EAX, Rn );
   897     SHR_imm8_r32( 16, R_EAX );
   898     store_reg( R_EAX, Rn );
   899 :}
   900 SUB Rm, Rn {:  
   901     load_reg( R_EAX, Rm );
   902     load_reg( R_ECX, Rn );
   903     SUB_r32_r32( R_EAX, R_ECX );
   904     store_reg( R_ECX, Rn );
   905 :}
   906 SUBC Rm, Rn {:  
   907     load_reg( R_EAX, Rm );
   908     load_reg( R_ECX, Rn );
   909     LDC_t();
   910     SBB_r32_r32( R_EAX, R_ECX );
   911     store_reg( R_ECX, Rn );
   912 :}
   913 SUBV Rm, Rn {:  
   914     load_reg( R_EAX, Rm );
   915     load_reg( R_ECX, Rn );
   916     SUB_r32_r32( R_EAX, R_ECX );
   917     store_reg( R_ECX, Rn );
   918     SETO_t();
   919 :}
   920 SWAP.B Rm, Rn {:  
   921     load_reg( R_EAX, Rm );
   922     XCHG_r8_r8( R_AL, R_AH );
   923     store_reg( R_EAX, Rn );
   924 :}
   925 SWAP.W Rm, Rn {:  
   926     load_reg( R_EAX, Rm );
   927     MOV_r32_r32( R_EAX, R_ECX );
   928     SHL_imm8_r32( 16, R_ECX );
   929     SHR_imm8_r32( 16, R_EAX );
   930     OR_r32_r32( R_EAX, R_ECX );
   931     store_reg( R_ECX, Rn );
   932 :}
   933 TAS.B @Rn {:  
   934     load_reg( R_ECX, Rn );
   935     MEM_READ_BYTE( R_ECX, R_EAX );
   936     TEST_r8_r8( R_AL, R_AL );
   937     SETE_t();
   938     OR_imm8_r8( 0x80, R_AL );
   939     load_reg( R_ECX, Rn );
   940     MEM_WRITE_BYTE( R_ECX, R_EAX );
   941 :}
   942 TST Rm, Rn {:  
   943     load_reg( R_EAX, Rm );
   944     load_reg( R_ECX, Rn );
   945     TEST_r32_r32( R_EAX, R_ECX );
   946     SETE_t();
   947 :}
   948 TST #imm, R0 {:  
   949     load_reg( R_EAX, 0 );
   950     TEST_imm32_r32( imm, R_EAX );
   951     SETE_t();
   952 :}
   953 TST.B #imm, @(R0, GBR) {:  
   954     load_reg( R_EAX, 0);
   955     load_reg( R_ECX, R_GBR);
   956     ADD_r32_r32( R_EAX, R_ECX );
   957     MEM_READ_BYTE( R_ECX, R_EAX );
   958     TEST_imm8_r8( imm, R_EAX );
   959     SETE_t();
   960 :}
   961 XOR Rm, Rn {:  
   962     load_reg( R_EAX, Rm );
   963     load_reg( R_ECX, Rn );
   964     XOR_r32_r32( R_EAX, R_ECX );
   965     store_reg( R_ECX, Rn );
   966 :}
   967 XOR #imm, R0 {:  
   968     load_reg( R_EAX, 0 );
   969     XOR_imm32_r32( imm, R_EAX );
   970     store_reg( R_EAX, 0 );
   971 :}
   972 XOR.B #imm, @(R0, GBR) {:  
   973     load_reg( R_EAX, 0 );
   974     load_spreg( R_ECX, R_GBR );
   975     ADD_r32_r32( R_EAX, R_ECX );
   976     PUSH_r32(R_ECX);
   977     call_func0(sh4_read_byte);
   978     POP_r32(R_ECX);
   979     XOR_imm32_r32( imm, R_EAX );
   980     MEM_WRITE_BYTE( R_ECX, R_EAX );
   981 :}
   982 XTRCT Rm, Rn {:
   983     load_reg( R_EAX, Rm );
   984     MOV_r32_r32( R_EAX, R_ECX );
   985     SHR_imm8_r32( 16, R_EAX );
   986     SHL_imm8_r32( 16, R_ECX );
   987     OR_r32_r32( R_EAX, R_ECX );
   988     store_reg( R_ECX, Rn );
   989 :}
   991 /* Data move instructions */
   992 MOV Rm, Rn {:  
   993     load_reg( R_EAX, Rm );
   994     store_reg( R_EAX, Rn );
   995 :}
   996 MOV #imm, Rn {:  
   997     load_imm32( R_EAX, imm );
   998     store_reg( R_EAX, Rn );
   999 :}
  1000 MOV.B Rm, @Rn {:  
  1001     load_reg( R_EAX, Rm );
  1002     load_reg( R_ECX, Rn );
  1003     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1004 :}
  1005 MOV.B Rm, @-Rn {:  
  1006     load_reg( R_EAX, Rm );
  1007     load_reg( R_ECX, Rn );
  1008     ADD_imm8s_r32( -1, R_ECX );
  1009     store_reg( R_ECX, Rn );
  1010     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1011 :}
  1012 MOV.B Rm, @(R0, Rn) {:  
  1013     load_reg( R_EAX, 0 );
  1014     load_reg( R_ECX, Rn );
  1015     ADD_r32_r32( R_EAX, R_ECX );
  1016     load_reg( R_EAX, Rm );
  1017     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1018 :}
  1019 MOV.B R0, @(disp, GBR) {:  
  1020     load_reg( R_EAX, 0 );
  1021     load_spreg( R_ECX, R_GBR );
  1022     ADD_imm32_r32( disp, R_ECX );
  1023     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1024 :}
  1025 MOV.B R0, @(disp, Rn) {:  
  1026     load_reg( R_EAX, 0 );
  1027     load_reg( R_ECX, Rn );
  1028     ADD_imm32_r32( disp, R_ECX );
  1029     MEM_WRITE_BYTE( R_ECX, R_EAX );
  1030 :}
  1031 MOV.B @Rm, Rn {:  
  1032     load_reg( R_ECX, Rm );
  1033     MEM_READ_BYTE( R_ECX, R_EAX );
  1034     store_reg( R_EAX, Rn );
  1035 :}
  1036 MOV.B @Rm+, Rn {:  
  1037     load_reg( R_ECX, Rm );
  1038     MOV_r32_r32( R_ECX, R_EAX );
  1039     ADD_imm8s_r32( 1, R_EAX );
  1040     store_reg( R_EAX, Rm );
  1041     MEM_READ_BYTE( R_ECX, R_EAX );
  1042     store_reg( R_EAX, Rn );
  1043 :}
  1044 MOV.B @(R0, Rm), Rn {:  
  1045     load_reg( R_EAX, 0 );
  1046     load_reg( R_ECX, Rm );
  1047     ADD_r32_r32( R_EAX, R_ECX );
  1048     MEM_READ_BYTE( R_ECX, R_EAX );
  1049     store_reg( R_EAX, Rn );
  1050 :}
  1051 MOV.B @(disp, GBR), R0 {:  
  1052     load_spreg( R_ECX, R_GBR );
  1053     ADD_imm32_r32( disp, R_ECX );
  1054     MEM_READ_BYTE( R_ECX, R_EAX );
  1055     store_reg( R_EAX, 0 );
  1056 :}
  1057 MOV.B @(disp, Rm), R0 {:  
  1058     load_reg( R_ECX, Rm );
  1059     ADD_imm32_r32( disp, R_ECX );
  1060     MEM_READ_BYTE( R_ECX, R_EAX );
  1061     store_reg( R_EAX, 0 );
  1062 :}
  1063 MOV.L Rm, @Rn {:
  1064     load_reg( R_EAX, Rm );
  1065     load_reg( R_ECX, Rn );
  1066     check_walign32(R_ECX);
  1067     MEM_WRITE_LONG( R_ECX, R_EAX );
  1068 :}
  1069 MOV.L Rm, @-Rn {:  
  1070     load_reg( R_EAX, Rm );
  1071     load_reg( R_ECX, Rn );
  1072     check_walign32( R_ECX );
  1073     ADD_imm8s_r32( -4, R_ECX );
  1074     store_reg( R_ECX, Rn );
  1075     MEM_WRITE_LONG( R_ECX, R_EAX );
  1076 :}
  1077 MOV.L Rm, @(R0, Rn) {:  
  1078     load_reg( R_EAX, 0 );
  1079     load_reg( R_ECX, Rn );
  1080     ADD_r32_r32( R_EAX, R_ECX );
  1081     check_walign32( R_ECX );
  1082     load_reg( R_EAX, Rm );
  1083     MEM_WRITE_LONG( R_ECX, R_EAX );
  1084 :}
  1085 MOV.L R0, @(disp, GBR) {:  
  1086     load_spreg( R_ECX, R_GBR );
  1087     load_reg( R_EAX, 0 );
  1088     ADD_imm32_r32( disp, R_ECX );
  1089     check_walign32( R_ECX );
  1090     MEM_WRITE_LONG( R_ECX, R_EAX );
  1091 :}
  1092 MOV.L Rm, @(disp, Rn) {:  
  1093     load_reg( R_ECX, Rn );
  1094     load_reg( R_EAX, Rm );
  1095     ADD_imm32_r32( disp, R_ECX );
  1096     check_walign32( R_ECX );
  1097     MEM_WRITE_LONG( R_ECX, R_EAX );
  1098 :}
  1099 MOV.L @Rm, Rn {:  
  1100     load_reg( R_ECX, Rm );
  1101     check_ralign32( R_ECX );
  1102     MEM_READ_LONG( R_ECX, R_EAX );
  1103     store_reg( R_EAX, Rn );
  1104 :}
  1105 MOV.L @Rm+, Rn {:  
  1106     load_reg( R_EAX, Rm );
  1107     check_ralign32( R_EAX );
  1108     MOV_r32_r32( R_EAX, R_ECX );
  1109     ADD_imm8s_r32( 4, R_EAX );
  1110     store_reg( R_EAX, Rm );
  1111     MEM_READ_LONG( R_ECX, R_EAX );
  1112     store_reg( R_EAX, Rn );
  1113 :}
  1114 MOV.L @(R0, Rm), Rn {:  
  1115     load_reg( R_EAX, 0 );
  1116     load_reg( R_ECX, Rm );
  1117     ADD_r32_r32( R_EAX, R_ECX );
  1118     check_ralign32( R_ECX );
  1119     MEM_READ_LONG( R_ECX, R_EAX );
  1120     store_reg( R_EAX, Rn );
  1121 :}
  1122 MOV.L @(disp, GBR), R0 {:
  1123     load_spreg( R_ECX, R_GBR );
  1124     ADD_imm32_r32( disp, R_ECX );
  1125     check_ralign32( R_ECX );
  1126     MEM_READ_LONG( R_ECX, R_EAX );
  1127     store_reg( R_EAX, 0 );
  1128 :}
  1129 MOV.L @(disp, PC), Rn {:  
  1130     if( sh4_x86.in_delay_slot ) {
  1131 	SLOTILLEGAL();
  1132     } else {
  1133 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1134 	MEM_READ_LONG( R_ECX, R_EAX );
  1135 	store_reg( R_EAX, Rn );
  1137 :}
  1138 MOV.L @(disp, Rm), Rn {:  
  1139     load_reg( R_ECX, Rm );
  1140     ADD_imm8s_r32( disp, R_ECX );
  1141     check_ralign32( R_ECX );
  1142     MEM_READ_LONG( R_ECX, R_EAX );
  1143     store_reg( R_EAX, Rn );
  1144 :}
  1145 MOV.W Rm, @Rn {:  
  1146     load_reg( R_ECX, Rn );
  1147     check_walign16( R_ECX );
  1148     load_reg( R_EAX, Rm );
  1149     MEM_WRITE_WORD( R_ECX, R_EAX );
  1150 :}
  1151 MOV.W Rm, @-Rn {:  
  1152     load_reg( R_ECX, Rn );
  1153     check_walign16( R_ECX );
  1154     load_reg( R_EAX, Rm );
  1155     ADD_imm8s_r32( -2, R_ECX );
  1156     store_reg( R_ECX, Rn );
  1157     MEM_WRITE_WORD( R_ECX, R_EAX );
  1158 :}
  1159 MOV.W Rm, @(R0, Rn) {:  
  1160     load_reg( R_EAX, 0 );
  1161     load_reg( R_ECX, Rn );
  1162     ADD_r32_r32( R_EAX, R_ECX );
  1163     check_walign16( R_ECX );
  1164     load_reg( R_EAX, Rm );
  1165     MEM_WRITE_WORD( R_ECX, R_EAX );
  1166 :}
  1167 MOV.W R0, @(disp, GBR) {:  
  1168     load_spreg( R_ECX, R_GBR );
  1169     load_reg( R_EAX, 0 );
  1170     ADD_imm32_r32( disp, R_ECX );
  1171     check_walign16( R_ECX );
  1172     MEM_WRITE_WORD( R_ECX, R_EAX );
  1173 :}
  1174 MOV.W R0, @(disp, Rn) {:  
  1175     load_reg( R_ECX, Rn );
  1176     load_reg( R_EAX, 0 );
  1177     ADD_imm32_r32( disp, R_ECX );
  1178     check_walign16( R_ECX );
  1179     MEM_WRITE_WORD( R_ECX, R_EAX );
  1180 :}
  1181 MOV.W @Rm, Rn {:  
  1182     load_reg( R_ECX, Rm );
  1183     check_ralign16( R_ECX );
  1184     MEM_READ_WORD( R_ECX, R_EAX );
  1185     store_reg( R_EAX, Rn );
  1186 :}
  1187 MOV.W @Rm+, Rn {:  
  1188     load_reg( R_EAX, Rm );
  1189     check_ralign16( R_EAX );
  1190     MOV_r32_r32( R_EAX, R_ECX );
  1191     ADD_imm8s_r32( 2, R_EAX );
  1192     store_reg( R_EAX, Rm );
  1193     MEM_READ_WORD( R_ECX, R_EAX );
  1194     store_reg( R_EAX, Rn );
  1195 :}
  1196 MOV.W @(R0, Rm), Rn {:  
  1197     load_reg( R_EAX, 0 );
  1198     load_reg( R_ECX, Rm );
  1199     ADD_r32_r32( R_EAX, R_ECX );
  1200     check_ralign16( R_ECX );
  1201     MEM_READ_WORD( R_ECX, R_EAX );
  1202     store_reg( R_EAX, Rn );
  1203 :}
  1204 MOV.W @(disp, GBR), R0 {:  
  1205     load_spreg( R_ECX, R_GBR );
  1206     ADD_imm32_r32( disp, R_ECX );
  1207     check_ralign16( R_ECX );
  1208     MEM_READ_WORD( R_ECX, R_EAX );
  1209     store_reg( R_EAX, 0 );
  1210 :}
  1211 MOV.W @(disp, PC), Rn {:  
  1212     if( sh4_x86.in_delay_slot ) {
  1213 	SLOTILLEGAL();
  1214     } else {
  1215 	load_imm32( R_ECX, pc + disp + 4 );
  1216 	MEM_READ_WORD( R_ECX, R_EAX );
  1217 	store_reg( R_EAX, Rn );
  1219 :}
  1220 MOV.W @(disp, Rm), R0 {:  
  1221     load_reg( R_ECX, Rm );
  1222     ADD_imm32_r32( disp, R_ECX );
  1223     check_ralign16( R_ECX );
  1224     MEM_READ_WORD( R_ECX, R_EAX );
  1225     store_reg( R_EAX, 0 );
  1226 :}
  1227 MOVA @(disp, PC), R0 {:  
  1228     if( sh4_x86.in_delay_slot ) {
  1229 	SLOTILLEGAL();
  1230     } else {
  1231 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1232 	store_reg( R_ECX, 0 );
  1234 :}
  1235 MOVCA.L R0, @Rn {:  
  1236     load_reg( R_EAX, 0 );
  1237     load_reg( R_ECX, Rn );
  1238     check_walign32( R_ECX );
  1239     MEM_WRITE_LONG( R_ECX, R_EAX );
  1240 :}
  1242 /* Control transfer instructions */
  1243 BF disp {:
  1244     if( sh4_x86.in_delay_slot ) {
  1245 	SLOTILLEGAL();
  1246     } else {
  1247 	load_imm32( R_EDI, pc + 2 );
  1248 	CMP_imm8s_sh4r( 0, R_T );
  1249 	JNE_rel8( 5, nottaken );
  1250 	load_imm32( R_EDI, disp + pc + 4 );
  1251 	JMP_TARGET(nottaken);
  1252 	INC_r32(R_ESI);
  1253 	return 1;
  1255 :}
  1256 BF/S disp {:
  1257     if( sh4_x86.in_delay_slot ) {
  1258 	SLOTILLEGAL();
  1259     } else {
  1260 	load_imm32( R_EDI, pc + 4 );
  1261 	CMP_imm8s_sh4r( 0, R_T );
  1262 	JNE_rel8( 5, nottaken );
  1263 	load_imm32( R_EDI, disp + pc + 4 );
  1264 	JMP_TARGET(nottaken);
  1265 	sh4_x86.in_delay_slot = TRUE;
  1266 	return 0;
  1268 :}
  1269 BRA disp {:  
  1270     if( sh4_x86.in_delay_slot ) {
  1271 	SLOTILLEGAL();
  1272     } else {
  1273 	load_imm32( R_EDI, disp + pc + 4 );
  1274 	sh4_x86.in_delay_slot = TRUE;
  1275 	return 0;
  1277 :}
  1278 BRAF Rn {:  
  1279     if( sh4_x86.in_delay_slot ) {
  1280 	SLOTILLEGAL();
  1281     } else {
  1282 	load_reg( R_EDI, Rn );
  1283 	ADD_imm32_r32( pc + 4, R_EDI );
  1284 	sh4_x86.in_delay_slot = TRUE;
  1285 	return 0;
  1287 :}
  1288 BSR disp {:  
  1289     if( sh4_x86.in_delay_slot ) {
  1290 	SLOTILLEGAL();
  1291     } else {
  1292 	load_imm32( R_EAX, pc + 4 );
  1293 	store_spreg( R_EAX, R_PR );
  1294 	load_imm32( R_EDI, disp + pc + 4 );
  1295 	sh4_x86.in_delay_slot = TRUE;
  1296 	return 0;
  1298 :}
  1299 BSRF Rn {:  
  1300     if( sh4_x86.in_delay_slot ) {
  1301 	SLOTILLEGAL();
  1302     } else {
  1303 	load_imm32( R_EAX, pc + 4 );
  1304 	store_spreg( R_EAX, R_PR );
  1305 	load_reg( R_EDI, Rn );
  1306 	ADD_r32_r32( R_EAX, R_EDI );
  1307 	sh4_x86.in_delay_slot = TRUE;
  1308 	return 0;
  1310 :}
  1311 BT disp {:
  1312     if( sh4_x86.in_delay_slot ) {
  1313 	SLOTILLEGAL();
  1314     } else {
  1315 	load_imm32( R_EDI, pc + 2 );
  1316 	CMP_imm8s_sh4r( 0, R_T );
  1317 	JE_rel8( 5, nottaken );
  1318 	load_imm32( R_EDI, disp + pc + 4 );
  1319 	JMP_TARGET(nottaken);
  1320 	INC_r32(R_ESI);
  1321 	return 1;
  1323 :}
  1324 BT/S disp {:
  1325     if( sh4_x86.in_delay_slot ) {
  1326 	SLOTILLEGAL();
  1327     } else {
  1328 	load_imm32( R_EDI, pc + 4 );
  1329 	CMP_imm8s_sh4r( 0, R_T );
  1330 	JE_rel8( 5, nottaken );
  1331 	load_imm32( R_EDI, disp + pc + 4 );
  1332 	JMP_TARGET(nottaken);
  1333 	sh4_x86.in_delay_slot = TRUE;
  1334 	return 0;
  1336 :}
  1337 JMP @Rn {:  
  1338     if( sh4_x86.in_delay_slot ) {
  1339 	SLOTILLEGAL();
  1340     } else {
  1341 	load_reg( R_EDI, Rn );
  1342 	sh4_x86.in_delay_slot = TRUE;
  1343 	return 0;
  1345 :}
  1346 JSR @Rn {:  
  1347     if( sh4_x86.in_delay_slot ) {
  1348 	SLOTILLEGAL();
  1349     } else {
  1350 	load_imm32( R_EAX, pc + 4 );
  1351 	store_spreg( R_EAX, R_PR );
  1352 	load_reg( R_EDI, Rn );
  1353 	sh4_x86.in_delay_slot = TRUE;
  1354 	return 0;
  1356 :}
  1357 RTE {:  
  1358     check_priv();
  1359     if( sh4_x86.in_delay_slot ) {
  1360 	SLOTILLEGAL();
  1361     } else {
  1362 	load_spreg( R_EDI, R_SPC );
  1363 	load_spreg( R_EAX, R_SSR );
  1364 	call_func1( sh4_write_sr, R_EAX );
  1365 	sh4_x86.in_delay_slot = TRUE;
  1366 	sh4_x86.priv_checked = FALSE;
  1367 	sh4_x86.fpuen_checked = FALSE;
  1368 	return 0;
  1370 :}
  1371 RTS {:  
  1372     if( sh4_x86.in_delay_slot ) {
  1373 	SLOTILLEGAL();
  1374     } else {
  1375 	load_spreg( R_EDI, R_PR );
  1376 	sh4_x86.in_delay_slot = TRUE;
  1377 	return 0;
  1379 :}
  1380 TRAPA #imm {:  
  1381     if( sh4_x86.in_delay_slot ) {
  1382 	SLOTILLEGAL();
  1383     } else {
  1384 	// TODO: Write TRA 
  1385 	RAISE_EXCEPTION(EXC_TRAP);
  1387 :}
  1388 UNDEF {:  
  1389     if( sh4_x86.in_delay_slot ) {
  1390 	SLOTILLEGAL();
  1391     } else {
  1392 	JMP_exit(EXIT_ILLEGAL);
  1393 	return 1;
  1395 :}
  1397 CLRMAC {:  
  1398     XOR_r32_r32(R_EAX, R_EAX);
  1399     store_spreg( R_EAX, R_MACL );
  1400     store_spreg( R_EAX, R_MACH );
  1401 :}
  1402 CLRS {:
  1403     CLC();
  1404     SETC_sh4r(R_S);
  1405 :}
  1406 CLRT {:  
  1407     CLC();
  1408     SETC_t();
  1409 :}
  1410 SETS {:  
  1411     STC();
  1412     SETC_sh4r(R_S);
  1413 :}
  1414 SETT {:  
  1415     STC();
  1416     SETC_t();
  1417 :}
  1419 /* Floating point moves */
  1420 FMOV FRm, FRn {:  
  1421     /* As horrible as this looks, it's actually covering 5 separate cases:
  1422      * 1. 32-bit fr-to-fr (PR=0)
  1423      * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
  1424      * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
  1425      * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
  1426      * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
  1427      */
  1428     check_fpuen();
  1429     load_spreg( R_ECX, R_FPSCR );
  1430     load_fr_bank( R_EDX );
  1431     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1432     JNE_rel8(8, doublesize);
  1433     load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
  1434     store_fr( R_EDX, R_EAX, FRn );
  1435     if( FRm&1 ) {
  1436 	JMP_rel8(24, end);
  1437 	JMP_TARGET(doublesize);
  1438 	load_xf_bank( R_ECX ); 
  1439 	load_fr( R_ECX, R_EAX, FRm-1 );
  1440 	if( FRn&1 ) {
  1441 	    load_fr( R_ECX, R_EDX, FRm );
  1442 	    store_fr( R_ECX, R_EAX, FRn-1 );
  1443 	    store_fr( R_ECX, R_EDX, FRn );
  1444 	} else /* FRn&1 == 0 */ {
  1445 	    load_fr( R_ECX, R_ECX, FRm );
  1446 	    store_fr( R_EDX, R_EAX, FRn-1 );
  1447 	    store_fr( R_EDX, R_ECX, FRn );
  1449 	JMP_TARGET(end);
  1450     } else /* FRm&1 == 0 */ {
  1451 	if( FRn&1 ) {
  1452 	    JMP_rel8(24, end);
  1453 	    load_xf_bank( R_ECX );
  1454 	    load_fr( R_EDX, R_EAX, FRm );
  1455 	    load_fr( R_EDX, R_EDX, FRm+1 );
  1456 	    store_fr( R_ECX, R_EAX, FRn-1 );
  1457 	    store_fr( R_ECX, R_EDX, FRn );
  1458 	    JMP_TARGET(end);
  1459 	} else /* FRn&1 == 0 */ {
  1460 	    JMP_rel8(12, end);
  1461 	    load_fr( R_EDX, R_EAX, FRm );
  1462 	    load_fr( R_EDX, R_ECX, FRm+1 );
  1463 	    store_fr( R_EDX, R_EAX, FRn );
  1464 	    store_fr( R_EDX, R_ECX, FRn+1 );
  1465 	    JMP_TARGET(end);
  1468 :}
  1469 FMOV FRm, @Rn {:  
  1470     check_fpuen();
  1471     load_reg( R_EDX, Rn );
  1472     check_walign32( R_EDX );
  1473     load_spreg( R_ECX, R_FPSCR );
  1474     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1475     JNE_rel8(20, doublesize);
  1476     load_fr_bank( R_ECX );
  1477     load_fr( R_ECX, R_EAX, FRm );
  1478     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1479     if( FRm&1 ) {
  1480 	JMP_rel8( 48, end );
  1481 	JMP_TARGET(doublesize);
  1482 	load_xf_bank( R_ECX );
  1483 	load_fr( R_ECX, R_EAX, FRm&0x0E );
  1484 	load_fr( R_ECX, R_ECX, FRm|0x01 );
  1485 	MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1486 	JMP_TARGET(end);
  1487     } else {
  1488 	JMP_rel8( 39, end );
  1489 	JMP_TARGET(doublesize);
  1490 	load_fr_bank( R_ECX );
  1491 	load_fr( R_ECX, R_EAX, FRm&0x0E );
  1492 	load_fr( R_ECX, R_ECX, FRm|0x01 );
  1493 	MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1494 	JMP_TARGET(end);
  1496 :}
  1497 FMOV @Rm, FRn {:  
  1498     check_fpuen();
  1499     load_reg( R_EDX, Rm );
  1500     check_ralign32( R_EDX );
  1501     load_spreg( R_ECX, R_FPSCR );
  1502     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1503     JNE_rel8(19, doublesize);
  1504     MEM_READ_LONG( R_EDX, R_EAX );
  1505     load_fr_bank( R_ECX );
  1506     store_fr( R_ECX, R_EAX, FRn );
  1507     if( FRn&1 ) {
  1508 	JMP_rel8(48, end);
  1509 	JMP_TARGET(doublesize);
  1510 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1511 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1512 	load_xf_bank( R_ECX );
  1513 	store_fr( R_ECX, R_EAX, FRn&0x0E );
  1514 	store_fr( R_ECX, R_EDX, FRn|0x01 );
  1515 	JMP_TARGET(end);
  1516     } else {
  1517 	JMP_rel8(36, end);
  1518 	JMP_TARGET(doublesize);
  1519 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1520 	load_fr_bank( R_ECX );
  1521 	store_fr( R_ECX, R_EAX, FRn&0x0E );
  1522 	store_fr( R_ECX, R_EDX, FRn|0x01 );
  1523 	JMP_TARGET(end);
  1525 :}
  1526 FMOV FRm, @-Rn {:  
  1527     check_fpuen();
  1528     load_reg( R_EDX, Rn );
  1529     check_walign32( R_EDX );
  1530     load_spreg( R_ECX, R_FPSCR );
  1531     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1532     JNE_rel8(26, doublesize);
  1533     load_fr_bank( R_ECX );
  1534     load_fr( R_ECX, R_EAX, FRm );
  1535     ADD_imm8s_r32(-4,R_EDX);
  1536     store_reg( R_EDX, Rn );
  1537     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1538     if( FRm&1 ) {
  1539 	JMP_rel8( 54, end );
  1540 	JMP_TARGET(doublesize);
  1541 	load_xf_bank( R_ECX );
  1542 	load_fr( R_ECX, R_EAX, FRm&0x0E );
  1543 	load_fr( R_ECX, R_ECX, FRm|0x01 );
  1544 	ADD_imm8s_r32(-8,R_EDX);
  1545 	store_reg( R_EDX, Rn );
  1546 	MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1547 	JMP_TARGET(end);
  1548     } else {
  1549 	JMP_rel8( 45, end );
  1550 	JMP_TARGET(doublesize);
  1551 	load_fr_bank( R_ECX );
  1552 	load_fr( R_ECX, R_EAX, FRm&0x0E );
  1553 	load_fr( R_ECX, R_ECX, FRm|0x01 );
  1554 	ADD_imm8s_r32(-8,R_EDX);
  1555 	store_reg( R_EDX, Rn );
  1556 	MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1557 	JMP_TARGET(end);
  1559 :}
  1560 FMOV @Rm+, FRn {:  
  1561     check_fpuen();
  1562     load_reg( R_EDX, Rm );
  1563     check_ralign32( R_EDX );
  1564     MOV_r32_r32( R_EDX, R_EAX );
  1565     load_spreg( R_ECX, R_FPSCR );
  1566     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1567     JNE_rel8(25, doublesize);
  1568     ADD_imm8s_r32( 4, R_EAX );
  1569     store_reg( R_EAX, Rm );
  1570     MEM_READ_LONG( R_EDX, R_EAX );
  1571     load_fr_bank( R_ECX );
  1572     store_fr( R_ECX, R_EAX, FRn );
  1573     if( FRn&1 ) {
  1574 	JMP_rel8(54, end);
  1575 	JMP_TARGET(doublesize);
  1576 	ADD_imm8s_r32( 8, R_EAX );
  1577 	store_reg(R_EAX, Rm);
  1578 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1579 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1580 	load_xf_bank( R_ECX );
  1581 	store_fr( R_ECX, R_EAX, FRn&0x0E );
  1582 	store_fr( R_ECX, R_EDX, FRn|0x01 );
  1583 	JMP_TARGET(end);
  1584     } else {
  1585 	JMP_rel8(42, end);
  1586 	ADD_imm8s_r32( 8, R_EAX );
  1587 	store_reg(R_EAX, Rm);
  1588 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1589 	load_fr_bank( R_ECX );
  1590 	store_fr( R_ECX, R_EAX, FRn&0x0E );
  1591 	store_fr( R_ECX, R_EDX, FRn|0x01 );
  1592 	JMP_TARGET(end);
  1594 :}
  1595 FMOV FRm, @(R0, Rn) {:  
  1596     check_fpuen();
  1597     load_reg( R_EDX, Rn );
  1598     ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
  1599     check_walign32( R_EDX );
  1600     load_spreg( R_ECX, R_FPSCR );
  1601     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1602     JNE_rel8(20, doublesize);
  1603     load_fr_bank( R_ECX );
  1604     load_fr( R_ECX, R_EAX, FRm );
  1605     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1606     if( FRm&1 ) {
  1607 	JMP_rel8( 48, end );
  1608 	JMP_TARGET(doublesize);
  1609 	load_xf_bank( R_ECX );
  1610 	load_fr( R_ECX, R_EAX, FRm&0x0E );
  1611 	load_fr( R_ECX, R_ECX, FRm|0x01 );
  1612 	MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1613 	JMP_TARGET(end);
  1614     } else {
  1615 	JMP_rel8( 39, end );
  1616 	JMP_TARGET(doublesize);
  1617 	load_fr_bank( R_ECX );
  1618 	load_fr( R_ECX, R_EAX, FRm&0x0E );
  1619 	load_fr( R_ECX, R_ECX, FRm|0x01 );
  1620 	MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1621 	JMP_TARGET(end);
  1623 :}
  1624 FMOV @(R0, Rm), FRn {:  
  1625     check_fpuen();
  1626     load_reg( R_EDX, Rm );
  1627     ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
  1628     check_ralign32( R_EDX );
  1629     load_spreg( R_ECX, R_FPSCR );
  1630     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1631     JNE_rel8(19, doublesize);
  1632     MEM_READ_LONG( R_EDX, R_EAX );
  1633     load_fr_bank( R_ECX );
  1634     store_fr( R_ECX, R_EAX, FRn );
  1635     if( FRn&1 ) {
  1636 	JMP_rel8(48, end);
  1637 	JMP_TARGET(doublesize);
  1638 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1639 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1640 	load_xf_bank( R_ECX );
  1641 	store_fr( R_ECX, R_EAX, FRn&0x0E );
  1642 	store_fr( R_ECX, R_EDX, FRn|0x01 );
  1643 	JMP_TARGET(end);
  1644     } else {
  1645 	JMP_rel8(36, end);
  1646 	JMP_TARGET(doublesize);
  1647 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1648 	load_fr_bank( R_ECX );
  1649 	store_fr( R_ECX, R_EAX, FRn&0x0E );
  1650 	store_fr( R_ECX, R_EDX, FRn|0x01 );
  1651 	JMP_TARGET(end);
  1653 :}
  1654 FLDI0 FRn {:  /* IFF PR=0 */
  1655     check_fpuen();
  1656     load_spreg( R_ECX, R_FPSCR );
  1657     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1658     JNE_rel8(8, end);
  1659     XOR_r32_r32( R_EAX, R_EAX );
  1660     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1661     store_fr( R_ECX, R_EAX, FRn );
  1662     JMP_TARGET(end);
  1663 :}
  1664 FLDI1 FRn {:  /* IFF PR=0 */
  1665     check_fpuen();
  1666     load_spreg( R_ECX, R_FPSCR );
  1667     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1668     JNE_rel8(11, end);
  1669     load_imm32(R_EAX, 0x3F800000);
  1670     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1671     store_fr( R_ECX, R_EAX, FRn );
  1672     JMP_TARGET(end);
  1673 :}
  1675 FLOAT FPUL, FRn {:  
  1676     check_fpuen();
  1677     load_spreg( R_ECX, R_FPSCR );
  1678     load_spreg(R_EDX, REG_OFFSET(fr_bank));
  1679     FILD_sh4r(R_FPUL);
  1680     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1681     JNE_rel8(5, doubleprec);
  1682     pop_fr( R_EDX, FRn );
  1683     JMP_rel8(3, end);
  1684     JMP_TARGET(doubleprec);
  1685     pop_dr( R_EDX, FRn );
  1686     JMP_TARGET(end);
  1687 :}
  1688 FTRC FRm, FPUL {:  
  1689     check_fpuen();
  1690     // TODO
  1691 :}
  1692 FLDS FRm, FPUL {:  
  1693     check_fpuen();
  1694     load_fr_bank( R_ECX );
  1695     load_fr( R_ECX, R_EAX, FRm );
  1696     store_spreg( R_EAX, R_FPUL );
  1697 :}
  1698 FSTS FPUL, FRn {:  
  1699     check_fpuen();
  1700     load_fr_bank( R_ECX );
  1701     load_spreg( R_EAX, R_FPUL );
  1702     store_fr( R_ECX, R_EAX, FRn );
  1703 :}
  1704 FCNVDS FRm, FPUL {:  
  1705     check_fpuen();
  1706     load_spreg( R_ECX, R_FPSCR );
  1707     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1708     JE_rel8(9, end); // only when PR=1
  1709     load_fr_bank( R_ECX );
  1710     push_dr( R_ECX, FRm );
  1711     pop_fpul();
  1712     JMP_TARGET(end);
  1713 :}
  1714 FCNVSD FPUL, FRn {:  
  1715     check_fpuen();
  1716     check_fpuen();
  1717     load_spreg( R_ECX, R_FPSCR );
  1718     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1719     JE_rel8(9, end); // only when PR=1
  1720     load_fr_bank( R_ECX );
  1721     push_fpul();
  1722     pop_dr( R_ECX, FRn );
  1723     JMP_TARGET(end);
  1724 :}
  1726 /* Floating point instructions */
  1727 FABS FRn {:  
  1728     check_fpuen();
  1729     load_spreg( R_ECX, R_FPSCR );
  1730     load_fr_bank( R_EDX );
  1731     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1732     JNE_rel8(10, doubleprec);
  1733     push_fr(R_EDX, FRn); // 3
  1734     FABS_st0(); // 2
  1735     pop_fr( R_EDX, FRn); //3
  1736     JMP_rel8(8,end); // 2
  1737     JMP_TARGET(doubleprec);
  1738     push_dr(R_EDX, FRn);
  1739     FABS_st0();
  1740     pop_dr(R_EDX, FRn);
  1741     JMP_TARGET(end);
  1742 :}
  1743 FADD FRm, FRn {:  
  1744     check_fpuen();
  1745     load_spreg( R_ECX, R_FPSCR );
  1746     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1747     load_fr_bank( R_EDX );
  1748     JNE_rel8(13,doubleprec);
  1749     push_fr(R_EDX, FRm);
  1750     push_fr(R_EDX, FRn);
  1751     FADDP_st(1);
  1752     pop_fr(R_EDX, FRn);
  1753     JMP_rel8(11,end);
  1754     JMP_TARGET(doubleprec);
  1755     push_dr(R_EDX, FRm);
  1756     push_dr(R_EDX, FRn);
  1757     FADDP_st(1);
  1758     pop_dr(R_EDX, FRn);
  1759     JMP_TARGET(end);
  1760 :}
  1761 FDIV FRm, FRn {:  
  1762     check_fpuen();
  1763     load_spreg( R_ECX, R_FPSCR );
  1764     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1765     load_fr_bank( R_EDX );
  1766     JNE_rel8(13, doubleprec);
  1767     push_fr(R_EDX, FRn);
  1768     push_fr(R_EDX, FRm);
  1769     FDIVP_st(1);
  1770     pop_fr(R_EDX, FRn);
  1771     JMP_rel8(11, end);
  1772     JMP_TARGET(doubleprec);
  1773     push_dr(R_EDX, FRn);
  1774     push_dr(R_EDX, FRm);
  1775     FDIVP_st(1);
  1776     pop_dr(R_EDX, FRn);
  1777     JMP_TARGET(end);
  1778 :}
  1779 FMAC FR0, FRm, FRn {:  
  1780     check_fpuen();
  1781     load_spreg( R_ECX, R_FPSCR );
  1782     load_spreg( R_EDX, REG_OFFSET(fr_bank));
  1783     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1784     JNE_rel8(18, doubleprec);
  1785     push_fr( R_EDX, 0 );
  1786     push_fr( R_EDX, FRm );
  1787     FMULP_st(1);
  1788     push_fr( R_EDX, FRn );
  1789     FADDP_st(1);
  1790     pop_fr( R_EDX, FRn );
  1791     JMP_rel8(16, end);
  1792     JMP_TARGET(doubleprec);
  1793     push_dr( R_EDX, 0 );
  1794     push_dr( R_EDX, FRm );
  1795     FMULP_st(1);
  1796     push_dr( R_EDX, FRn );
  1797     FADDP_st(1);
  1798     pop_dr( R_EDX, FRn );
  1799     JMP_TARGET(end);
  1800 :}
  1802 FMUL FRm, FRn {:  
  1803     check_fpuen();
  1804     load_spreg( R_ECX, R_FPSCR );
  1805     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1806     load_fr_bank( R_EDX );
  1807     JNE_rel8(13, doubleprec);
  1808     push_fr(R_EDX, FRm);
  1809     push_fr(R_EDX, FRn);
  1810     FMULP_st(1);
  1811     pop_fr(R_EDX, FRn);
  1812     JMP_rel8(11, end);
  1813     JMP_TARGET(doubleprec);
  1814     push_dr(R_EDX, FRm);
  1815     push_dr(R_EDX, FRn);
  1816     FMULP_st(1);
  1817     pop_dr(R_EDX, FRn);
  1818     JMP_TARGET(end);
  1819 :}
  1820 FNEG FRn {:  
  1821     check_fpuen();
  1822     load_spreg( R_ECX, R_FPSCR );
  1823     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1824     load_fr_bank( R_EDX );
  1825     JNE_rel8(10, doubleprec);
  1826     push_fr(R_EDX, FRn);
  1827     FCHS_st0();
  1828     pop_fr(R_EDX, FRn);
  1829     JMP_rel8(8, end);
  1830     JMP_TARGET(doubleprec);
  1831     push_dr(R_EDX, FRn);
  1832     FCHS_st0();
  1833     pop_dr(R_EDX, FRn);
  1834     JMP_TARGET(end);
  1835 :}
  1836 FSRRA FRn {:  
  1837     check_fpuen();
  1838     load_spreg( R_ECX, R_FPSCR );
  1839     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1840     load_fr_bank( R_EDX );
  1841     JNE_rel8(12, end); // PR=0 only
  1842     FLD1_st0();
  1843     push_fr(R_EDX, FRn);
  1844     FSQRT_st0();
  1845     FDIVP_st(1);
  1846     pop_fr(R_EDX, FRn);
  1847     JMP_TARGET(end);
  1848 :}
  1849 FSQRT FRn {:  
  1850     check_fpuen();
  1851     load_spreg( R_ECX, R_FPSCR );
  1852     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1853     load_fr_bank( R_EDX );
  1854     JNE_rel8(10, doubleprec);
  1855     push_fr(R_EDX, FRn);
  1856     FSQRT_st0();
  1857     pop_fr(R_EDX, FRn);
  1858     JMP_rel8(8, end);
  1859     JMP_TARGET(doubleprec);
  1860     push_dr(R_EDX, FRn);
  1861     FSQRT_st0();
  1862     pop_dr(R_EDX, FRn);
  1863     JMP_TARGET(end);
  1864 :}
  1865 FSUB FRm, FRn {:  
  1866     check_fpuen();
  1867     load_spreg( R_ECX, R_FPSCR );
  1868     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1869     load_fr_bank( R_EDX );
  1870     JNE_rel8(13, doubleprec);
  1871     push_fr(R_EDX, FRn);
  1872     push_fr(R_EDX, FRm);
  1873     FMULP_st(1);
  1874     pop_fr(R_EDX, FRn);
  1875     JMP_rel8(11, end);
  1876     JMP_TARGET(doubleprec);
  1877     push_dr(R_EDX, FRn);
  1878     push_dr(R_EDX, FRm);
  1879     FMULP_st(1);
  1880     pop_dr(R_EDX, FRn);
  1881     JMP_TARGET(end);
  1882 :}
  1884 FCMP/EQ FRm, FRn {:  
  1885     check_fpuen();
  1886     load_spreg( R_ECX, R_FPSCR );
  1887     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1888     load_fr_bank( R_EDX );
  1889     JNE_rel8(8, doubleprec);
  1890     push_fr(R_EDX, FRm);
  1891     push_fr(R_EDX, FRn);
  1892     JMP_rel8(6, end);
  1893     JMP_TARGET(doubleprec);
  1894     push_dr(R_EDX, FRm);
  1895     push_dr(R_EDX, FRn);
  1896     JMP_TARGET(end);
  1897     FCOMIP_st(1);
  1898     SETE_t();
  1899     FPOP_st();
  1900 :}
  1901 FCMP/GT FRm, FRn {:  
  1902     check_fpuen();
  1903     load_spreg( R_ECX, R_FPSCR );
  1904     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1905     load_fr_bank( R_EDX );
  1906     JNE_rel8(8, doubleprec);
  1907     push_fr(R_EDX, FRm);
  1908     push_fr(R_EDX, FRn);
  1909     JMP_rel8(6, end);
  1910     JMP_TARGET(doubleprec);
  1911     push_dr(R_EDX, FRm);
  1912     push_dr(R_EDX, FRn);
  1913     JMP_TARGET(end);
  1914     FCOMIP_st(1);
  1915     SETA_t();
  1916     FPOP_st();
  1917 :}
  1919 FSCA FPUL, FRn {:  
  1920     check_fpuen();
  1921 :}
  1922 FIPR FVm, FVn {:  
  1923     check_fpuen();
  1924 :}
  1925 FTRV XMTRX, FVn {:  
  1926     check_fpuen();
  1927 :}
  1929 FRCHG {:  
  1930     check_fpuen();
  1931     load_spreg( R_ECX, R_FPSCR );
  1932     XOR_imm32_r32( FPSCR_FR, R_ECX );
  1933     store_spreg( R_ECX, R_FPSCR );
  1934     update_fr_bank( R_ECX );
  1935 :}
  1936 FSCHG {:  
  1937     check_fpuen();
  1938     load_spreg( R_ECX, R_FPSCR );
  1939     XOR_imm32_r32( FPSCR_SZ, R_ECX );
  1940     store_spreg( R_ECX, R_FPSCR );
  1941 :}
  1943 /* Processor control instructions */
  1944 LDC Rm, SR {:
  1945     if( sh4_x86.in_delay_slot ) {
  1946 	SLOTILLEGAL();
  1947     } else {
  1948 	check_priv();
  1949 	load_reg( R_EAX, Rm );
  1950 	call_func1( sh4_write_sr, R_EAX );
  1951 	sh4_x86.priv_checked = FALSE;
  1952 	sh4_x86.fpuen_checked = FALSE;
  1954 :}
  1955 LDC Rm, GBR {: 
  1956     load_reg( R_EAX, Rm );
  1957     store_spreg( R_EAX, R_GBR );
  1958 :}
  1959 LDC Rm, VBR {:  
  1960     check_priv();
  1961     load_reg( R_EAX, Rm );
  1962     store_spreg( R_EAX, R_VBR );
  1963 :}
  1964 LDC Rm, SSR {:  
  1965     check_priv();
  1966     load_reg( R_EAX, Rm );
  1967     store_spreg( R_EAX, R_SSR );
  1968 :}
  1969 LDC Rm, SGR {:  
  1970     check_priv();
  1971     load_reg( R_EAX, Rm );
  1972     store_spreg( R_EAX, R_SGR );
  1973 :}
  1974 LDC Rm, SPC {:  
  1975     check_priv();
  1976     load_reg( R_EAX, Rm );
  1977     store_spreg( R_EAX, R_SPC );
  1978 :}
  1979 LDC Rm, DBR {:  
  1980     check_priv();
  1981     load_reg( R_EAX, Rm );
  1982     store_spreg( R_EAX, R_DBR );
  1983 :}
  1984 LDC Rm, Rn_BANK {:  
  1985     check_priv();
  1986     load_reg( R_EAX, Rm );
  1987     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  1988 :}
  1989 LDC.L @Rm+, GBR {:  
  1990     load_reg( R_EAX, Rm );
  1991     MOV_r32_r32( R_EAX, R_ECX );
  1992     ADD_imm8s_r32( 4, R_EAX );
  1993     store_reg( R_EAX, Rm );
  1994     MEM_READ_LONG( R_ECX, R_EAX );
  1995     store_spreg( R_EAX, R_GBR );
  1996 :}
  1997 LDC.L @Rm+, SR {:
  1998     if( sh4_x86.in_delay_slot ) {
  1999 	SLOTILLEGAL();
  2000     } else {
  2001 	check_priv();
  2002 	load_reg( R_EAX, Rm );
  2003 	MOV_r32_r32( R_EAX, R_ECX );
  2004 	ADD_imm8s_r32( 4, R_EAX );
  2005 	store_reg( R_EAX, Rm );
  2006 	MEM_READ_LONG( R_ECX, R_EAX );
  2007 	call_func1( sh4_write_sr, R_EAX );
  2008 	sh4_x86.priv_checked = FALSE;
  2009 	sh4_x86.fpuen_checked = FALSE;
  2011 :}
  2012 LDC.L @Rm+, VBR {:  
  2013     check_priv();
  2014     load_reg( R_EAX, Rm );
  2015     MOV_r32_r32( R_EAX, R_ECX );
  2016     ADD_imm8s_r32( 4, R_EAX );
  2017     store_reg( R_EAX, Rm );
  2018     MEM_READ_LONG( R_ECX, R_EAX );
  2019     store_spreg( R_EAX, R_VBR );
  2020 :}
  2021 LDC.L @Rm+, SSR {:
  2022     check_priv();
  2023     load_reg( R_EAX, Rm );
  2024     MOV_r32_r32( R_EAX, R_ECX );
  2025     ADD_imm8s_r32( 4, R_EAX );
  2026     store_reg( R_EAX, Rm );
  2027     MEM_READ_LONG( R_ECX, R_EAX );
  2028     store_spreg( R_EAX, R_SSR );
  2029 :}
  2030 LDC.L @Rm+, SGR {:  
  2031     check_priv();
  2032     load_reg( R_EAX, Rm );
  2033     MOV_r32_r32( R_EAX, R_ECX );
  2034     ADD_imm8s_r32( 4, R_EAX );
  2035     store_reg( R_EAX, Rm );
  2036     MEM_READ_LONG( R_ECX, R_EAX );
  2037     store_spreg( R_EAX, R_SGR );
  2038 :}
  2039 LDC.L @Rm+, SPC {:  
  2040     check_priv();
  2041     load_reg( R_EAX, Rm );
  2042     MOV_r32_r32( R_EAX, R_ECX );
  2043     ADD_imm8s_r32( 4, R_EAX );
  2044     store_reg( R_EAX, Rm );
  2045     MEM_READ_LONG( R_ECX, R_EAX );
  2046     store_spreg( R_EAX, R_SPC );
  2047 :}
  2048 LDC.L @Rm+, DBR {:  
  2049     check_priv();
  2050     load_reg( R_EAX, Rm );
  2051     MOV_r32_r32( R_EAX, R_ECX );
  2052     ADD_imm8s_r32( 4, R_EAX );
  2053     store_reg( R_EAX, Rm );
  2054     MEM_READ_LONG( R_ECX, R_EAX );
  2055     store_spreg( R_EAX, R_DBR );
  2056 :}
  2057 LDC.L @Rm+, Rn_BANK {:  
  2058     check_priv();
  2059     load_reg( R_EAX, Rm );
  2060     MOV_r32_r32( R_EAX, R_ECX );
  2061     ADD_imm8s_r32( 4, R_EAX );
  2062     store_reg( R_EAX, Rm );
  2063     MEM_READ_LONG( R_ECX, R_EAX );
  2064     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  2065 :}
  2066 LDS Rm, FPSCR {:  
  2067     load_reg( R_EAX, Rm );
  2068     store_spreg( R_EAX, R_FPSCR );
  2069     update_fr_bank( R_EAX );
  2070 :}
  2071 LDS.L @Rm+, FPSCR {:  
  2072     load_reg( R_EAX, Rm );
  2073     MOV_r32_r32( R_EAX, R_ECX );
  2074     ADD_imm8s_r32( 4, R_EAX );
  2075     store_reg( R_EAX, Rm );
  2076     MEM_READ_LONG( R_ECX, R_EAX );
  2077     store_spreg( R_EAX, R_FPSCR );
  2078     update_fr_bank( R_EAX );
  2079 :}
  2080 LDS Rm, FPUL {:  
  2081     load_reg( R_EAX, Rm );
  2082     store_spreg( R_EAX, R_FPUL );
  2083 :}
  2084 LDS.L @Rm+, FPUL {:  
  2085     load_reg( R_EAX, Rm );
  2086     MOV_r32_r32( R_EAX, R_ECX );
  2087     ADD_imm8s_r32( 4, R_EAX );
  2088     store_reg( R_EAX, Rm );
  2089     MEM_READ_LONG( R_ECX, R_EAX );
  2090     store_spreg( R_EAX, R_FPUL );
  2091 :}
  2092 LDS Rm, MACH {: 
  2093     load_reg( R_EAX, Rm );
  2094     store_spreg( R_EAX, R_MACH );
  2095 :}
  2096 LDS.L @Rm+, MACH {:  
  2097     load_reg( R_EAX, Rm );
  2098     MOV_r32_r32( R_EAX, R_ECX );
  2099     ADD_imm8s_r32( 4, R_EAX );
  2100     store_reg( R_EAX, Rm );
  2101     MEM_READ_LONG( R_ECX, R_EAX );
  2102     store_spreg( R_EAX, R_MACH );
  2103 :}
  2104 LDS Rm, MACL {:  
  2105     load_reg( R_EAX, Rm );
  2106     store_spreg( R_EAX, R_MACL );
  2107 :}
  2108 LDS.L @Rm+, MACL {:  
  2109     load_reg( R_EAX, Rm );
  2110     MOV_r32_r32( R_EAX, R_ECX );
  2111     ADD_imm8s_r32( 4, R_EAX );
  2112     store_reg( R_EAX, Rm );
  2113     MEM_READ_LONG( R_ECX, R_EAX );
  2114     store_spreg( R_EAX, R_MACL );
  2115 :}
  2116 LDS Rm, PR {:  
  2117     load_reg( R_EAX, Rm );
  2118     store_spreg( R_EAX, R_PR );
  2119 :}
  2120 LDS.L @Rm+, PR {:  
  2121     load_reg( R_EAX, Rm );
  2122     MOV_r32_r32( R_EAX, R_ECX );
  2123     ADD_imm8s_r32( 4, R_EAX );
  2124     store_reg( R_EAX, Rm );
  2125     MEM_READ_LONG( R_ECX, R_EAX );
  2126     store_spreg( R_EAX, R_PR );
  2127 :}
  2128 LDTLB {:  :}
  2129 OCBI @Rn {:  :}
  2130 OCBP @Rn {:  :}
  2131 OCBWB @Rn {:  :}
  2132 PREF @Rn {:
  2133     load_reg( R_EAX, Rn );
  2134     PUSH_r32( R_EAX );
  2135     AND_imm32_r32( 0xFC000000, R_EAX );
  2136     CMP_imm32_r32( 0xE0000000, R_EAX );
  2137     JNE_rel8(7, end);
  2138     call_func0( sh4_flush_store_queue );
  2139     JMP_TARGET(end);
  2140     ADD_imm8s_r32( 4, R_ESP );
  2141 :}
  2142 SLEEP {: /* TODO */ :}
  2143 STC SR, Rn {:
  2144     check_priv();
  2145     call_func0(sh4_read_sr);
  2146     store_reg( R_EAX, Rn );
  2147 :}
  2148 STC GBR, Rn {:  
  2149     load_spreg( R_EAX, R_GBR );
  2150     store_reg( R_EAX, Rn );
  2151 :}
  2152 STC VBR, Rn {:  
  2153     check_priv();
  2154     load_spreg( R_EAX, R_VBR );
  2155     store_reg( R_EAX, Rn );
  2156 :}
  2157 STC SSR, Rn {:  
  2158     check_priv();
  2159     load_spreg( R_EAX, R_SSR );
  2160     store_reg( R_EAX, Rn );
  2161 :}
  2162 STC SPC, Rn {:  
  2163     check_priv();
  2164     load_spreg( R_EAX, R_SPC );
  2165     store_reg( R_EAX, Rn );
  2166 :}
  2167 STC SGR, Rn {:  
  2168     check_priv();
  2169     load_spreg( R_EAX, R_SGR );
  2170     store_reg( R_EAX, Rn );
  2171 :}
  2172 STC DBR, Rn {:  
  2173     check_priv();
  2174     load_spreg( R_EAX, R_DBR );
  2175     store_reg( R_EAX, Rn );
  2176 :}
  2177 STC Rm_BANK, Rn {:
  2178     check_priv();
  2179     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  2180     store_reg( R_EAX, Rn );
  2181 :}
  2182 STC.L SR, @-Rn {:
  2183     check_priv();
  2184     load_reg( R_ECX, Rn );
  2185     ADD_imm8s_r32( -4, R_ECX );
  2186     store_reg( R_ECX, Rn );
  2187     call_func0( sh4_read_sr );
  2188     MEM_WRITE_LONG( R_ECX, R_EAX );
  2189 :}
  2190 STC.L VBR, @-Rn {:  
  2191     check_priv();
  2192     load_reg( R_ECX, Rn );
  2193     ADD_imm8s_r32( -4, R_ECX );
  2194     store_reg( R_ECX, Rn );
  2195     load_spreg( R_EAX, R_VBR );
  2196     MEM_WRITE_LONG( R_ECX, R_EAX );
  2197 :}
  2198 STC.L SSR, @-Rn {:  
  2199     check_priv();
  2200     load_reg( R_ECX, Rn );
  2201     ADD_imm8s_r32( -4, R_ECX );
  2202     store_reg( R_ECX, Rn );
  2203     load_spreg( R_EAX, R_SSR );
  2204     MEM_WRITE_LONG( R_ECX, R_EAX );
  2205 :}
  2206 STC.L SPC, @-Rn {:  
  2207     check_priv();
  2208     load_reg( R_ECX, Rn );
  2209     ADD_imm8s_r32( -4, R_ECX );
  2210     store_reg( R_ECX, Rn );
  2211     load_spreg( R_EAX, R_SPC );
  2212     MEM_WRITE_LONG( R_ECX, R_EAX );
  2213 :}
  2214 STC.L SGR, @-Rn {:  
  2215     check_priv();
  2216     load_reg( R_ECX, Rn );
  2217     ADD_imm8s_r32( -4, R_ECX );
  2218     store_reg( R_ECX, Rn );
  2219     load_spreg( R_EAX, R_SGR );
  2220     MEM_WRITE_LONG( R_ECX, R_EAX );
  2221 :}
  2222 STC.L DBR, @-Rn {:  
  2223     check_priv();
  2224     load_reg( R_ECX, Rn );
  2225     ADD_imm8s_r32( -4, R_ECX );
  2226     store_reg( R_ECX, Rn );
  2227     load_spreg( R_EAX, R_DBR );
  2228     MEM_WRITE_LONG( R_ECX, R_EAX );
  2229 :}
  2230 STC.L Rm_BANK, @-Rn {:  
  2231     check_priv();
  2232     load_reg( R_ECX, Rn );
  2233     ADD_imm8s_r32( -4, R_ECX );
  2234     store_reg( R_ECX, Rn );
  2235     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  2236     MEM_WRITE_LONG( R_ECX, R_EAX );
  2237 :}
  2238 STC.L GBR, @-Rn {:  
  2239     load_reg( R_ECX, Rn );
  2240     ADD_imm8s_r32( -4, R_ECX );
  2241     store_reg( R_ECX, Rn );
  2242     load_spreg( R_EAX, R_GBR );
  2243     MEM_WRITE_LONG( R_ECX, R_EAX );
  2244 :}
  2245 STS FPSCR, Rn {:  
  2246     load_spreg( R_EAX, R_FPSCR );
  2247     store_reg( R_EAX, Rn );
  2248 :}
  2249 STS.L FPSCR, @-Rn {:  
  2250     load_reg( R_ECX, Rn );
  2251     ADD_imm8s_r32( -4, R_ECX );
  2252     store_reg( R_ECX, Rn );
  2253     load_spreg( R_EAX, R_FPSCR );
  2254     MEM_WRITE_LONG( R_ECX, R_EAX );
  2255 :}
  2256 STS FPUL, Rn {:  
  2257     load_spreg( R_EAX, R_FPUL );
  2258     store_reg( R_EAX, Rn );
  2259 :}
  2260 STS.L FPUL, @-Rn {:  
  2261     load_reg( R_ECX, Rn );
  2262     ADD_imm8s_r32( -4, R_ECX );
  2263     store_reg( R_ECX, Rn );
  2264     load_spreg( R_EAX, R_FPUL );
  2265     MEM_WRITE_LONG( R_ECX, R_EAX );
  2266 :}
  2267 STS MACH, Rn {:  
  2268     load_spreg( R_EAX, R_MACH );
  2269     store_reg( R_EAX, Rn );
  2270 :}
  2271 STS.L MACH, @-Rn {:  
  2272     load_reg( R_ECX, Rn );
  2273     ADD_imm8s_r32( -4, R_ECX );
  2274     store_reg( R_ECX, Rn );
  2275     load_spreg( R_EAX, R_MACH );
  2276     MEM_WRITE_LONG( R_ECX, R_EAX );
  2277 :}
  2278 STS MACL, Rn {:  
  2279     load_spreg( R_EAX, R_MACL );
  2280     store_reg( R_EAX, Rn );
  2281 :}
  2282 STS.L MACL, @-Rn {:  
  2283     load_reg( R_ECX, Rn );
  2284     ADD_imm8s_r32( -4, R_ECX );
  2285     store_reg( R_ECX, Rn );
  2286     load_spreg( R_EAX, R_MACL );
  2287     MEM_WRITE_LONG( R_ECX, R_EAX );
  2288 :}
  2289 STS PR, Rn {:  
  2290     load_spreg( R_EAX, R_PR );
  2291     store_reg( R_EAX, Rn );
  2292 :}
  2293 STS.L PR, @-Rn {:  
  2294     load_reg( R_ECX, Rn );
  2295     ADD_imm8s_r32( -4, R_ECX );
  2296     store_reg( R_ECX, Rn );
  2297     load_spreg( R_EAX, R_PR );
  2298     MEM_WRITE_LONG( R_ECX, R_EAX );
  2299 :}
  2301 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
  2302 %%
  2303     if( sh4_x86.in_delay_slot ) {
  2304 	ADD_imm8s_r32(2,R_ESI);
  2305 	sh4_x86.in_delay_slot = FALSE;
  2306 	return 1;
  2307     } else {
  2308 	INC_r32(R_ESI);
  2310     return 0;
.