Search
lxdream.org :: lxdream/src/sh4/sh4x86.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 375:4627600f7f8e
prev374:8f80a795513e
next377:fa18743f6905
author nkeynes
date Tue Sep 11 21:23:48 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Start in on the FP instructions (simplest possible impl)
view annotate diff log raw
     1 /**
     2  * $Id: sh4x86.in,v 1.5 2007-09-11 21:23:48 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 #include "sh4/sh4core.h"
    24 #include "sh4/sh4trans.h"
    25 #include "sh4/x86op.h"
    26 #include "clock.h"
    28 #define DEFAULT_BACKPATCH_SIZE 4096
    30 /** 
    31  * Struct to manage internal translation state. This state is not saved -
    32  * it is only valid between calls to sh4_translate_begin_block() and
    33  * sh4_translate_end_block()
    34  */
    35 struct sh4_x86_state {
    36     gboolean in_delay_slot;
    37     gboolean priv_checked; /* true if we've already checked the cpu mode. */
    38     gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
    40     /* Allocated memory for the (block-wide) back-patch list */
    41     uint32_t **backpatch_list;
    42     uint32_t backpatch_posn;
    43     uint32_t backpatch_size;
    44 };
    46 #define EXIT_DATA_ADDR_READ 0
    47 #define EXIT_DATA_ADDR_WRITE 7
    48 #define EXIT_ILLEGAL 14
    49 #define EXIT_SLOT_ILLEGAL 21
    50 #define EXIT_FPU_DISABLED 28
    51 #define EXIT_SLOT_FPU_DISABLED 35
    53 static struct sh4_x86_state sh4_x86;
    55 void sh4_x86_init()
    56 {
    57     sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
    58     sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(uint32_t *);
    59 }
    62 static void sh4_x86_add_backpatch( uint8_t *ptr )
    63 {
    64     if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
    65 	sh4_x86.backpatch_size <<= 1;
    66 	sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, sh4_x86.backpatch_size * sizeof(uint32_t *) );
    67 	assert( sh4_x86.backpatch_list != NULL );
    68     }
    69     sh4_x86.backpatch_list[sh4_x86.backpatch_posn++] = (uint32_t *)ptr;
    70 }
    72 static void sh4_x86_do_backpatch( uint8_t *reloc_base )
    73 {
    74     unsigned int i;
    75     for( i=0; i<sh4_x86.backpatch_posn; i++ ) {
    76 	*sh4_x86.backpatch_list[i] += (reloc_base - ((uint8_t *)sh4_x86.backpatch_list[i]) - 4);
    77     }
    78 }
    80 #ifndef NDEBUG
    81 #define MARK_JMP(x,n) uint8_t *_mark_jmp_##x = xlat_output + n
    82 #define CHECK_JMP(x) assert( _mark_jmp_##x == xlat_output )
    83 #else
    84 #define MARK_JMP(x,n)
    85 #define CHECK_JMP(x)
    86 #endif
    89 /**
    90  * Emit an instruction to load an SH4 reg into a real register
    91  */
    92 static inline void load_reg( int x86reg, int sh4reg ) 
    93 {
    94     /* mov [bp+n], reg */
    95     OP(0x8B);
    96     OP(0x45 + (x86reg<<3));
    97     OP(REG_OFFSET(r[sh4reg]));
    98 }
   100 static inline void load_reg16s( int x86reg, int sh4reg )
   101 {
   102     OP(0x0F);
   103     OP(0xBF);
   104     MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
   105 }
   107 static inline void load_reg16u( int x86reg, int sh4reg )
   108 {
   109     OP(0x0F);
   110     OP(0xB7);
   111     MODRM_r32_sh4r(x86reg, REG_OFFSET(r[sh4reg]));
   113 }
   115 static inline void load_spreg( int x86reg, int regoffset )
   116 {
   117     /* mov [bp+n], reg */
   118     OP(0x8B);
   119     OP(0x45 + (x86reg<<3));
   120     OP(regoffset);
   121 }
   123 /**
   124  * Emit an instruction to load an immediate value into a register
   125  */
   126 static inline void load_imm32( int x86reg, uint32_t value ) {
   127     /* mov #value, reg */
   128     OP(0xB8 + x86reg);
   129     OP32(value);
   130 }
   132 /**
   133  * Emit an instruction to store an SH4 reg (RN)
   134  */
   135 void static inline store_reg( int x86reg, int sh4reg ) {
   136     /* mov reg, [bp+n] */
   137     OP(0x89);
   138     OP(0x45 + (x86reg<<3));
   139     OP(REG_OFFSET(r[sh4reg]));
   140 }
   141 void static inline store_spreg( int x86reg, int regoffset ) {
   142     /* mov reg, [bp+n] */
   143     OP(0x89);
   144     OP(0x45 + (x86reg<<3));
   145     OP(regoffset);
   146 }
   149 #define load_fr_bank(bankreg) load_spreg( bankreg, REG_OFFSET(fr_bank))
   151 /**
   152  * Load an FR register (single-precision floating point) into an integer x86
   153  * register (eg for register-to-register moves)
   154  */
   155 void static inline load_fr( int bankreg, int x86reg, int frm )
   156 {
   157     OP(0x8B); OP(0x40+bankreg+(x86reg<<3)); OP((frm^1)<<2);
   158 }
   160 /**
   161  * Store an FR register (single-precision floating point) into an integer x86
   162  * register (eg for register-to-register moves)
   163  */
   164 void static inline store_fr( int bankreg, int x86reg, int frn )
   165 {
   166     OP(0x89);  OP(0x40+bankreg+(x86reg<<3)); OP((frn^1)<<2);
   167 }
   170 /**
   171  * Load a pointer to the back fp back into the specified x86 register. The
   172  * bankreg must have been previously loaded with FPSCR.
   173  * NB: 10 bytes
   174  */
   175 static inline void load_xf_bank( int bankreg )
   176 {
   177     SHR_imm8_r32( (21 - 6), bankreg ); // Extract bit 21 then *64 for bank size
   178     AND_imm8s_r32( 0x40, bankreg );    // Complete extraction
   179     OP(0x8D); OP(0x44+(bankreg<<3)); OP(0x28+bankreg); OP(REG_OFFSET(fr)); // LEA [ebp+bankreg+disp], bankreg
   180 }
   182 /**
   183  * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
   184  * with the location of the current fp bank.
   185  */
   186 static inline void push_fr( int bankreg, int frm ) 
   187 {
   188     OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2);  // FLD.S [bankreg + frm^1*4]
   189 }
   191 /**
   192  * Pop a 32-bit float from the FPU stack and store it back into the fp bank, 
   193  * with bankreg previously loaded with the location of the current fp bank.
   194  */
   195 static inline void pop_fr( int bankreg, int frm )
   196 {
   197     OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
   198 }
   200 /**
   201  * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
   202  * with the location of the current fp bank.
   203  */
   204 static inline void push_dr( int bankreg, int frm )
   205 {
   206     OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
   207 }
   209 static inline void pop_dr( int bankreg, int frm )
   210 {
   211     OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
   212 }
   214 /**
   215  * Note: clobbers EAX to make the indirect call - this isn't usually
   216  * a problem since the callee will usually clobber it anyway.
   217  */
   218 static inline void call_func0( void *ptr )
   219 {
   220     load_imm32(R_EAX, (uint32_t)ptr);
   221     CALL_r32(R_EAX);
   222 }
   224 static inline void call_func1( void *ptr, int arg1 )
   225 {
   226     PUSH_r32(arg1);
   227     call_func0(ptr);
   228     ADD_imm8s_r32( -4, R_ESP );
   229 }
   231 static inline void call_func2( void *ptr, int arg1, int arg2 )
   232 {
   233     PUSH_r32(arg2);
   234     PUSH_r32(arg1);
   235     call_func0(ptr);
   236     ADD_imm8s_r32( -8, R_ESP );
   237 }
   239 /**
   240  * Write a double (64-bit) value into memory, with the first word in arg2a, and
   241  * the second in arg2b
   242  * NB: 30 bytes
   243  */
   244 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
   245 {
   246     ADD_imm8s_r32( 4, addr );
   247     PUSH_r32(addr);
   248     PUSH_r32(arg2b);
   249     ADD_imm8s_r32( -4, addr );
   250     PUSH_r32(addr);
   251     PUSH_r32(arg2a);
   252     call_func0(sh4_write_long);
   253     ADD_imm8s_r32( -8, R_ESP );
   254     call_func0(sh4_write_long);
   255     ADD_imm8s_r32( -8, R_ESP );
   256 }
   258 /**
   259  * Read a double (64-bit) value from memory, writing the first word into arg2a
   260  * and the second into arg2b. The addr must not be in EAX
   261  * NB: 27 bytes
   262  */
   263 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
   264 {
   265     PUSH_r32(addr);
   266     call_func0(sh4_read_long);
   267     POP_r32(addr);
   268     PUSH_r32(R_EAX);
   269     ADD_imm8s_r32( 4, addr );
   270     PUSH_r32(addr);
   271     call_func0(sh4_read_long);
   272     ADD_imm8s_r32( -4, R_ESP );
   273     MOV_r32_r32( R_EAX, arg2b );
   274     POP_r32(arg2a);
   275 }
   277 /* Exception checks - Note that all exception checks will clobber EAX */
   278 static void check_priv( )
   279 {
   280     if( !sh4_x86.priv_checked ) {
   281 	sh4_x86.priv_checked = TRUE;
   282 	load_spreg( R_EAX, R_SR );
   283 	AND_imm32_r32( SR_MD, R_EAX );
   284 	if( sh4_x86.in_delay_slot ) {
   285 	    JE_exit( EXIT_SLOT_ILLEGAL );
   286 	} else {
   287 	    JE_exit( EXIT_ILLEGAL );
   288 	}
   289     }
   290 }
   292 static void check_fpuen( )
   293 {
   294     if( !sh4_x86.fpuen_checked ) {
   295 	sh4_x86.fpuen_checked = TRUE;
   296 	load_spreg( R_EAX, R_SR );
   297 	AND_imm32_r32( SR_FD, R_EAX );
   298 	if( sh4_x86.in_delay_slot ) {
   299 	    JNE_exit(EXIT_SLOT_FPU_DISABLED);
   300 	} else {
   301 	    JNE_exit(EXIT_FPU_DISABLED);
   302 	}
   303     }
   304 }
   306 static void check_ralign16( int x86reg )
   307 {
   308     TEST_imm32_r32( 0x00000001, x86reg );
   309     JNE_exit(EXIT_DATA_ADDR_READ);
   310 }
   312 static void check_walign16( int x86reg )
   313 {
   314     TEST_imm32_r32( 0x00000001, x86reg );
   315     JNE_exit(EXIT_DATA_ADDR_WRITE);
   316 }
   318 static void check_ralign32( int x86reg )
   319 {
   320     TEST_imm32_r32( 0x00000003, x86reg );
   321     JNE_exit(EXIT_DATA_ADDR_READ);
   322 }
   323 static void check_walign32( int x86reg )
   324 {
   325     TEST_imm32_r32( 0x00000003, x86reg );
   326     JNE_exit(EXIT_DATA_ADDR_WRITE);
   327 }
   330 #define UNDEF()
   331 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
   332 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
   333 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
   334 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
   335 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
   336 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
   337 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
   339 #define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);
   340 #define SLOTILLEGAL() RAISE_EXCEPTION(EXC_SLOT_ILLEGAL); return 1
   344 /**
   345  * Emit the 'start of block' assembly. Sets up the stack frame and save
   346  * SI/DI as required
   347  */
   348 void sh4_translate_begin_block() 
   349 {
   350     PUSH_r32(R_EBP);
   351     /* mov &sh4r, ebp */
   352     load_imm32( R_EBP, (uint32_t)&sh4r );
   353     PUSH_r32(R_EDI);
   354     PUSH_r32(R_ESI);
   356     sh4_x86.in_delay_slot = FALSE;
   357     sh4_x86.priv_checked = FALSE;
   358     sh4_x86.fpuen_checked = FALSE;
   359     sh4_x86.backpatch_posn = 0;
   360 }
   362 /**
   363  * Exit the block early (ie branch out), conditionally or otherwise
   364  */
   365 void exit_block( )
   366 {
   367     store_spreg( R_EDI, REG_OFFSET(pc) );
   368     MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
   369     load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   370     MUL_r32( R_ESI );
   371     ADD_r32_r32( R_EAX, R_ECX );
   372     store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   373     XOR_r32_r32( R_EAX, R_EAX );
   374     POP_r32(R_ESI);
   375     POP_r32(R_EDI);
   376     POP_r32(R_EBP);
   377     RET();
   378 }
   380 /**
   381  * Flush any open regs back to memory, restore SI/DI/, update PC, etc
   382  */
   383 void sh4_translate_end_block( sh4addr_t pc ) {
   384     assert( !sh4_x86.in_delay_slot ); // should never stop here
   385     // Normal termination - save PC, cycle count
   386     exit_block( );
   388     uint8_t *end_ptr = xlat_output;
   389     // Exception termination. Jump block for various exception codes:
   390     PUSH_imm32( EXC_DATA_ADDR_READ );
   391     JMP_rel8( 33 );
   392     PUSH_imm32( EXC_DATA_ADDR_WRITE );
   393     JMP_rel8( 26 );
   394     PUSH_imm32( EXC_ILLEGAL );
   395     JMP_rel8( 19 );
   396     PUSH_imm32( EXC_SLOT_ILLEGAL ); 
   397     JMP_rel8( 12 );
   398     PUSH_imm32( EXC_FPU_DISABLED ); 
   399     JMP_rel8( 5 );                 
   400     PUSH_imm32( EXC_SLOT_FPU_DISABLED );
   401     // target
   402     load_spreg( R_ECX, REG_OFFSET(pc) );
   403     ADD_r32_r32( R_ESI, R_ECX );
   404     ADD_r32_r32( R_ESI, R_ECX );
   405     store_spreg( R_ECX, REG_OFFSET(pc) );
   406     MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
   407     load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   408     MUL_r32( R_ESI );
   409     ADD_r32_r32( R_EAX, R_ECX );
   410     store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   412     load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
   413     CALL_r32( R_EAX ); // 2
   414     POP_r32(R_EBP);
   415     RET();
   417     sh4_x86_do_backpatch( end_ptr );
   418 }
   420 /**
   421  * Translate a single instruction. Delayed branches are handled specially
   422  * by translating both branch and delayed instruction as a single unit (as
   423  * 
   424  *
   425  * @return true if the instruction marks the end of a basic block
   426  * (eg a branch or 
   427  */
   428 uint32_t sh4_x86_translate_instruction( uint32_t pc )
   429 {
   430     uint16_t ir = sh4_read_word( pc );
   432 %%
   433 /* ALU operations */
   434 ADD Rm, Rn {:
   435     load_reg( R_EAX, Rm );
   436     load_reg( R_ECX, Rn );
   437     ADD_r32_r32( R_EAX, R_ECX );
   438     store_reg( R_ECX, Rn );
   439 :}
   440 ADD #imm, Rn {:  
   441     load_reg( R_EAX, Rn );
   442     ADD_imm8s_r32( imm, R_EAX );
   443     store_reg( R_EAX, Rn );
   444 :}
   445 ADDC Rm, Rn {:
   446     load_reg( R_EAX, Rm );
   447     load_reg( R_ECX, Rn );
   448     LDC_t();
   449     ADC_r32_r32( R_EAX, R_ECX );
   450     store_reg( R_ECX, Rn );
   451     SETC_t();
   452 :}
   453 ADDV Rm, Rn {:
   454     load_reg( R_EAX, Rm );
   455     load_reg( R_ECX, Rn );
   456     ADD_r32_r32( R_EAX, R_ECX );
   457     store_reg( R_ECX, Rn );
   458     SETO_t();
   459 :}
   460 AND Rm, Rn {:
   461     load_reg( R_EAX, Rm );
   462     load_reg( R_ECX, Rn );
   463     AND_r32_r32( R_EAX, R_ECX );
   464     store_reg( R_ECX, Rn );
   465 :}
   466 AND #imm, R0 {:  
   467     load_reg( R_EAX, 0 );
   468     AND_imm32_r32(imm, R_EAX); 
   469     store_reg( R_EAX, 0 );
   470 :}
   471 AND.B #imm, @(R0, GBR) {: 
   472     load_reg( R_EAX, 0 );
   473     load_spreg( R_ECX, R_GBR );
   474     ADD_r32_r32( R_EAX, R_ECX );
   475     MEM_READ_BYTE( R_ECX, R_EAX );
   476     AND_imm32_r32(imm, R_ECX );
   477     MEM_WRITE_BYTE( R_ECX, R_EAX );
   478 :}
   479 CMP/EQ Rm, Rn {:  
   480     load_reg( R_EAX, Rm );
   481     load_reg( R_ECX, Rn );
   482     CMP_r32_r32( R_EAX, R_ECX );
   483     SETE_t();
   484 :}
   485 CMP/EQ #imm, R0 {:  
   486     load_reg( R_EAX, 0 );
   487     CMP_imm8s_r32(imm, R_EAX);
   488     SETE_t();
   489 :}
   490 CMP/GE Rm, Rn {:  
   491     load_reg( R_EAX, Rm );
   492     load_reg( R_ECX, Rn );
   493     CMP_r32_r32( R_EAX, R_ECX );
   494     SETGE_t();
   495 :}
   496 CMP/GT Rm, Rn {: 
   497     load_reg( R_EAX, Rm );
   498     load_reg( R_ECX, Rn );
   499     CMP_r32_r32( R_EAX, R_ECX );
   500     SETG_t();
   501 :}
   502 CMP/HI Rm, Rn {:  
   503     load_reg( R_EAX, Rm );
   504     load_reg( R_ECX, Rn );
   505     CMP_r32_r32( R_EAX, R_ECX );
   506     SETA_t();
   507 :}
   508 CMP/HS Rm, Rn {: 
   509     load_reg( R_EAX, Rm );
   510     load_reg( R_ECX, Rn );
   511     CMP_r32_r32( R_EAX, R_ECX );
   512     SETAE_t();
   513  :}
   514 CMP/PL Rn {: 
   515     load_reg( R_EAX, Rn );
   516     CMP_imm8s_r32( 0, R_EAX );
   517     SETG_t();
   518 :}
   519 CMP/PZ Rn {:  
   520     load_reg( R_EAX, Rn );
   521     CMP_imm8s_r32( 0, R_EAX );
   522     SETGE_t();
   523 :}
   524 CMP/STR Rm, Rn {:  
   525     load_reg( R_EAX, Rm );
   526     load_reg( R_ECX, Rn );
   527     XOR_r32_r32( R_ECX, R_EAX );
   528     TEST_r8_r8( R_AL, R_AL );
   529     JE_rel8(13);
   530     TEST_r8_r8( R_AH, R_AH ); // 2
   531     JE_rel8(9);
   532     SHR_imm8_r32( 16, R_EAX ); // 3
   533     TEST_r8_r8( R_AL, R_AL ); // 2
   534     JE_rel8(2);
   535     TEST_r8_r8( R_AH, R_AH ); // 2
   536     SETE_t();
   537 :}
   538 DIV0S Rm, Rn {:
   539     load_reg( R_EAX, Rm );
   540     load_reg( R_ECX, Rm );
   541     SHR_imm8_r32( 31, R_EAX );
   542     SHR_imm8_r32( 31, R_ECX );
   543     store_spreg( R_EAX, R_M );
   544     store_spreg( R_ECX, R_Q );
   545     CMP_r32_r32( R_EAX, R_ECX );
   546     SETE_t();
   547 :}
   548 DIV0U {:  
   549     XOR_r32_r32( R_EAX, R_EAX );
   550     store_spreg( R_EAX, R_Q );
   551     store_spreg( R_EAX, R_M );
   552     store_spreg( R_EAX, R_T );
   553 :}
   554 DIV1 Rm, Rn {:  
   555     load_reg( R_ECX, Rn );
   556     LDC_t();
   557     RCL1_r32( R_ECX ); // OP2
   558     SETC_r32( R_EDX ); // Q
   559     load_spreg( R_EAX, R_Q );
   560     CMP_sh4r_r32( R_M, R_EAX );
   561     JE_rel8(8);
   562     ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
   563     JMP_rel8(3);
   564     SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
   565     // TODO
   566 :}
   567 DMULS.L Rm, Rn {:  
   568     load_reg( R_EAX, Rm );
   569     load_reg( R_ECX, Rn );
   570     IMUL_r32(R_ECX);
   571     store_spreg( R_EDX, R_MACH );
   572     store_spreg( R_EAX, R_MACL );
   573 :}
   574 DMULU.L Rm, Rn {:  
   575     load_reg( R_EAX, Rm );
   576     load_reg( R_ECX, Rn );
   577     MUL_r32(R_ECX);
   578     store_spreg( R_EDX, R_MACH );
   579     store_spreg( R_EAX, R_MACL );    
   580 :}
   581 DT Rn {:  
   582     load_reg( R_EAX, Rn );
   583     ADD_imm8s_r32( -1, Rn );
   584     store_reg( R_EAX, Rn );
   585     SETE_t();
   586 :}
   587 EXTS.B Rm, Rn {:  
   588     load_reg( R_EAX, Rm );
   589     MOVSX_r8_r32( R_EAX, R_EAX );
   590     store_reg( R_EAX, Rn );
   591 :}
   592 EXTS.W Rm, Rn {:  
   593     load_reg( R_EAX, Rm );
   594     MOVSX_r16_r32( R_EAX, R_EAX );
   595     store_reg( R_EAX, Rn );
   596 :}
   597 EXTU.B Rm, Rn {:  
   598     load_reg( R_EAX, Rm );
   599     MOVZX_r8_r32( R_EAX, R_EAX );
   600     store_reg( R_EAX, Rn );
   601 :}
   602 EXTU.W Rm, Rn {:  
   603     load_reg( R_EAX, Rm );
   604     MOVZX_r16_r32( R_EAX, R_EAX );
   605     store_reg( R_EAX, Rn );
   606 :}
   607 MAC.L @Rm+, @Rn+ {:  :}
   608 MAC.W @Rm+, @Rn+ {:  :}
   609 MOVT Rn {:  
   610     load_spreg( R_EAX, R_T );
   611     store_reg( R_EAX, Rn );
   612 :}
   613 MUL.L Rm, Rn {:  
   614     load_reg( R_EAX, Rm );
   615     load_reg( R_ECX, Rn );
   616     MUL_r32( R_ECX );
   617     store_spreg( R_EAX, R_MACL );
   618 :}
   619 MULS.W Rm, Rn {:
   620     load_reg16s( R_EAX, Rm );
   621     load_reg16s( R_ECX, Rn );
   622     MUL_r32( R_ECX );
   623     store_spreg( R_EAX, R_MACL );
   624 :}
   625 MULU.W Rm, Rn {:  
   626     load_reg16u( R_EAX, Rm );
   627     load_reg16u( R_ECX, Rn );
   628     MUL_r32( R_ECX );
   629     store_spreg( R_EAX, R_MACL );
   630 :}
   631 NEG Rm, Rn {:
   632     load_reg( R_EAX, Rm );
   633     NEG_r32( R_EAX );
   634     store_reg( R_EAX, Rn );
   635 :}
   636 NEGC Rm, Rn {:  
   637     load_reg( R_EAX, Rm );
   638     XOR_r32_r32( R_ECX, R_ECX );
   639     LDC_t();
   640     SBB_r32_r32( R_EAX, R_ECX );
   641     store_reg( R_ECX, Rn );
   642     SETC_t();
   643 :}
   644 NOT Rm, Rn {:  
   645     load_reg( R_EAX, Rm );
   646     NOT_r32( R_EAX );
   647     store_reg( R_EAX, Rn );
   648 :}
   649 OR Rm, Rn {:  
   650     load_reg( R_EAX, Rm );
   651     load_reg( R_ECX, Rn );
   652     OR_r32_r32( R_EAX, R_ECX );
   653     store_reg( R_ECX, Rn );
   654 :}
   655 OR #imm, R0 {:
   656     load_reg( R_EAX, 0 );
   657     OR_imm32_r32(imm, R_EAX);
   658     store_reg( R_EAX, 0 );
   659 :}
   660 OR.B #imm, @(R0, GBR) {:  
   661     load_reg( R_EAX, 0 );
   662     load_spreg( R_ECX, R_GBR );
   663     ADD_r32_r32( R_EAX, R_ECX );
   664     MEM_READ_BYTE( R_ECX, R_EAX );
   665     OR_imm32_r32(imm, R_ECX );
   666     MEM_WRITE_BYTE( R_ECX, R_EAX );
   667 :}
   668 ROTCL Rn {:
   669     load_reg( R_EAX, Rn );
   670     LDC_t();
   671     RCL1_r32( R_EAX );
   672     store_reg( R_EAX, Rn );
   673     SETC_t();
   674 :}
   675 ROTCR Rn {:  
   676     load_reg( R_EAX, Rn );
   677     LDC_t();
   678     RCR1_r32( R_EAX );
   679     store_reg( R_EAX, Rn );
   680     SETC_t();
   681 :}
   682 ROTL Rn {:  
   683     load_reg( R_EAX, Rn );
   684     ROL1_r32( R_EAX );
   685     store_reg( R_EAX, Rn );
   686     SETC_t();
   687 :}
   688 ROTR Rn {:  
   689     load_reg( R_EAX, Rn );
   690     ROR1_r32( R_EAX );
   691     store_reg( R_EAX, Rn );
   692     SETC_t();
   693 :}
   694 SHAD Rm, Rn {:
   695     /* Annoyingly enough, not directly convertible */
   696     load_reg( R_EAX, Rn );
   697     load_reg( R_ECX, Rm );
   698     CMP_imm32_r32( 0, R_ECX );
   699     JAE_rel8(9);
   701     NEG_r32( R_ECX );      // 2
   702     AND_imm8_r8( 0x1F, R_CL ); // 3
   703     SAR_r32_CL( R_EAX );       // 2
   704     JMP_rel8(5);               // 2
   706     AND_imm8_r8( 0x1F, R_CL ); // 3
   707     SHL_r32_CL( R_EAX );       // 2
   709     store_reg( R_EAX, Rn );
   710 :}
   711 SHLD Rm, Rn {:  
   712     load_reg( R_EAX, Rn );
   713     load_reg( R_ECX, Rm );
   715     MOV_r32_r32( R_EAX, R_EDX );
   716     SHL_r32_CL( R_EAX );
   717     NEG_r32( R_ECX );
   718     SHR_r32_CL( R_EDX );
   719     CMP_imm8s_r32( 0, R_ECX );
   720     CMOVAE_r32_r32( R_EDX,  R_EAX );
   721     store_reg( R_EAX, Rn );
   722 :}
   723 SHAL Rn {: 
   724     load_reg( R_EAX, Rn );
   725     SHL1_r32( R_EAX );
   726     store_reg( R_EAX, Rn );
   727 :}
   728 SHAR Rn {:  
   729     load_reg( R_EAX, Rn );
   730     SAR1_r32( R_EAX );
   731     store_reg( R_EAX, Rn );
   732 :}
   733 SHLL Rn {:  
   734     load_reg( R_EAX, Rn );
   735     SHL1_r32( R_EAX );
   736     store_reg( R_EAX, Rn );
   737 :}
   738 SHLL2 Rn {:
   739     load_reg( R_EAX, Rn );
   740     SHL_imm8_r32( 2, R_EAX );
   741     store_reg( R_EAX, Rn );
   742 :}
   743 SHLL8 Rn {:  
   744     load_reg( R_EAX, Rn );
   745     SHL_imm8_r32( 8, R_EAX );
   746     store_reg( R_EAX, Rn );
   747 :}
   748 SHLL16 Rn {:  
   749     load_reg( R_EAX, Rn );
   750     SHL_imm8_r32( 16, R_EAX );
   751     store_reg( R_EAX, Rn );
   752 :}
   753 SHLR Rn {:  
   754     load_reg( R_EAX, Rn );
   755     SHR1_r32( R_EAX );
   756     store_reg( R_EAX, Rn );
   757 :}
   758 SHLR2 Rn {:  
   759     load_reg( R_EAX, Rn );
   760     SHR_imm8_r32( 2, R_EAX );
   761     store_reg( R_EAX, Rn );
   762 :}
   763 SHLR8 Rn {:  
   764     load_reg( R_EAX, Rn );
   765     SHR_imm8_r32( 8, R_EAX );
   766     store_reg( R_EAX, Rn );
   767 :}
   768 SHLR16 Rn {:  
   769     load_reg( R_EAX, Rn );
   770     SHR_imm8_r32( 16, R_EAX );
   771     store_reg( R_EAX, Rn );
   772 :}
   773 SUB Rm, Rn {:  
   774     load_reg( R_EAX, Rm );
   775     load_reg( R_ECX, Rn );
   776     SUB_r32_r32( R_EAX, R_ECX );
   777     store_reg( R_ECX, Rn );
   778 :}
   779 SUBC Rm, Rn {:  
   780     load_reg( R_EAX, Rm );
   781     load_reg( R_ECX, Rn );
   782     LDC_t();
   783     SBB_r32_r32( R_EAX, R_ECX );
   784     store_reg( R_ECX, Rn );
   785 :}
   786 SUBV Rm, Rn {:  
   787     load_reg( R_EAX, Rm );
   788     load_reg( R_ECX, Rn );
   789     SUB_r32_r32( R_EAX, R_ECX );
   790     store_reg( R_ECX, Rn );
   791     SETO_t();
   792 :}
   793 SWAP.B Rm, Rn {:  
   794     load_reg( R_EAX, Rm );
   795     XCHG_r8_r8( R_AL, R_AH );
   796     store_reg( R_EAX, Rn );
   797 :}
   798 SWAP.W Rm, Rn {:  
   799     load_reg( R_EAX, Rm );
   800     MOV_r32_r32( R_EAX, R_ECX );
   801     SHL_imm8_r32( 16, R_ECX );
   802     SHR_imm8_r32( 16, R_EAX );
   803     OR_r32_r32( R_EAX, R_ECX );
   804     store_reg( R_ECX, Rn );
   805 :}
   806 TAS.B @Rn {:  
   807     load_reg( R_ECX, Rn );
   808     MEM_READ_BYTE( R_ECX, R_EAX );
   809     TEST_r8_r8( R_AL, R_AL );
   810     SETE_t();
   811     OR_imm8_r8( 0x80, R_AL );
   812     MEM_WRITE_BYTE( R_ECX, R_EAX );
   813 :}
   814 TST Rm, Rn {:  
   815     load_reg( R_EAX, Rm );
   816     load_reg( R_ECX, Rn );
   817     TEST_r32_r32( R_EAX, R_ECX );
   818     SETE_t();
   819 :}
   820 TST #imm, R0 {:  
   821     load_reg( R_EAX, 0 );
   822     TEST_imm32_r32( imm, R_EAX );
   823     SETE_t();
   824 :}
   825 TST.B #imm, @(R0, GBR) {:  
   826     load_reg( R_EAX, 0);
   827     load_reg( R_ECX, R_GBR);
   828     ADD_r32_r32( R_EAX, R_ECX );
   829     MEM_READ_BYTE( R_ECX, R_EAX );
   830     TEST_imm8_r8( imm, R_EAX );
   831     SETE_t();
   832 :}
   833 XOR Rm, Rn {:  
   834     load_reg( R_EAX, Rm );
   835     load_reg( R_ECX, Rn );
   836     XOR_r32_r32( R_EAX, R_ECX );
   837     store_reg( R_ECX, Rn );
   838 :}
   839 XOR #imm, R0 {:  
   840     load_reg( R_EAX, 0 );
   841     XOR_imm32_r32( imm, R_EAX );
   842     store_reg( R_EAX, 0 );
   843 :}
   844 XOR.B #imm, @(R0, GBR) {:  
   845     load_reg( R_EAX, 0 );
   846     load_spreg( R_ECX, R_GBR );
   847     ADD_r32_r32( R_EAX, R_ECX );
   848     MEM_READ_BYTE( R_ECX, R_EAX );
   849     XOR_imm32_r32( imm, R_EAX );
   850     MEM_WRITE_BYTE( R_ECX, R_EAX );
   851 :}
   852 XTRCT Rm, Rn {:
   853     load_reg( R_EAX, Rm );
   854     MOV_r32_r32( R_EAX, R_ECX );
   855     SHR_imm8_r32( 16, R_EAX );
   856     SHL_imm8_r32( 16, R_ECX );
   857     OR_r32_r32( R_EAX, R_ECX );
   858     store_reg( R_ECX, Rn );
   859 :}
   861 /* Data move instructions */
   862 MOV Rm, Rn {:  
   863     load_reg( R_EAX, Rm );
   864     store_reg( R_EAX, Rn );
   865 :}
   866 MOV #imm, Rn {:  
   867     load_imm32( R_EAX, imm );
   868     store_reg( R_EAX, Rn );
   869 :}
   870 MOV.B Rm, @Rn {:  
   871     load_reg( R_EAX, Rm );
   872     load_reg( R_ECX, Rn );
   873     MEM_WRITE_BYTE( R_ECX, R_EAX );
   874 :}
   875 MOV.B Rm, @-Rn {:  
   876     load_reg( R_EAX, Rm );
   877     load_reg( R_ECX, Rn );
   878     ADD_imm8s_r32( -1, Rn );
   879     store_reg( R_ECX, Rn );
   880     MEM_WRITE_BYTE( R_ECX, R_EAX );
   881 :}
   882 MOV.B Rm, @(R0, Rn) {:  
   883     load_reg( R_EAX, 0 );
   884     load_reg( R_ECX, Rn );
   885     ADD_r32_r32( R_EAX, R_ECX );
   886     load_reg( R_EAX, Rm );
   887     MEM_WRITE_BYTE( R_ECX, R_EAX );
   888 :}
   889 MOV.B R0, @(disp, GBR) {:  
   890     load_reg( R_EAX, 0 );
   891     load_spreg( R_ECX, R_GBR );
   892     ADD_imm32_r32( disp, R_ECX );
   893     MEM_WRITE_BYTE( R_ECX, R_EAX );
   894 :}
   895 MOV.B R0, @(disp, Rn) {:  
   896     load_reg( R_EAX, 0 );
   897     load_reg( R_ECX, Rn );
   898     ADD_imm32_r32( disp, R_ECX );
   899     MEM_WRITE_BYTE( R_ECX, R_EAX );
   900 :}
   901 MOV.B @Rm, Rn {:  
   902     load_reg( R_ECX, Rm );
   903     MEM_READ_BYTE( R_ECX, R_EAX );
   904     store_reg( R_ECX, Rn );
   905 :}
   906 MOV.B @Rm+, Rn {:  
   907     load_reg( R_ECX, Rm );
   908     MOV_r32_r32( R_ECX, R_EAX );
   909     ADD_imm8s_r32( 1, R_EAX );
   910     store_reg( R_EAX, Rm );
   911     MEM_READ_BYTE( R_ECX, R_EAX );
   912     store_reg( R_EAX, Rn );
   913 :}
   914 MOV.B @(R0, Rm), Rn {:  
   915     load_reg( R_EAX, 0 );
   916     load_reg( R_ECX, Rm );
   917     ADD_r32_r32( R_EAX, R_ECX );
   918     MEM_READ_BYTE( R_ECX, R_EAX );
   919     store_reg( R_EAX, Rn );
   920 :}
   921 MOV.B @(disp, GBR), R0 {:  
   922     load_spreg( R_ECX, R_GBR );
   923     ADD_imm32_r32( disp, R_ECX );
   924     MEM_READ_BYTE( R_ECX, R_EAX );
   925     store_reg( R_EAX, 0 );
   926 :}
   927 MOV.B @(disp, Rm), R0 {:  
   928     load_reg( R_ECX, Rm );
   929     ADD_imm32_r32( disp, R_ECX );
   930     MEM_READ_BYTE( R_ECX, R_EAX );
   931     store_reg( R_EAX, 0 );
   932 :}
   933 MOV.L Rm, @Rn {:
   934     load_reg( R_EAX, Rm );
   935     load_reg( R_ECX, Rn );
   936     check_walign32(R_ECX);
   937     MEM_WRITE_LONG( R_ECX, R_EAX );
   938 :}
   939 MOV.L Rm, @-Rn {:  
   940     load_reg( R_EAX, Rm );
   941     load_reg( R_ECX, Rn );
   942     check_walign32( R_ECX );
   943     ADD_imm8s_r32( -4, R_ECX );
   944     store_reg( R_ECX, Rn );
   945     MEM_WRITE_LONG( R_ECX, R_EAX );
   946 :}
   947 MOV.L Rm, @(R0, Rn) {:  
   948     load_reg( R_EAX, 0 );
   949     load_reg( R_ECX, Rn );
   950     ADD_r32_r32( R_EAX, R_ECX );
   951     check_walign32( R_ECX );
   952     load_reg( R_EAX, Rm );
   953     MEM_WRITE_LONG( R_ECX, R_EAX );
   954 :}
   955 MOV.L R0, @(disp, GBR) {:  
   956     load_spreg( R_ECX, R_GBR );
   957     load_reg( R_EAX, 0 );
   958     ADD_imm32_r32( disp, R_ECX );
   959     check_walign32( R_ECX );
   960     MEM_WRITE_LONG( R_ECX, R_EAX );
   961 :}
   962 MOV.L Rm, @(disp, Rn) {:  
   963     load_reg( R_ECX, Rn );
   964     load_reg( R_EAX, Rm );
   965     ADD_imm32_r32( disp, R_ECX );
   966     check_walign32( R_ECX );
   967     MEM_WRITE_LONG( R_ECX, R_EAX );
   968 :}
   969 MOV.L @Rm, Rn {:  
   970     load_reg( R_ECX, Rm );
   971     check_ralign32( R_ECX );
   972     MEM_READ_LONG( R_ECX, R_EAX );
   973     store_reg( R_EAX, Rn );
   974 :}
   975 MOV.L @Rm+, Rn {:  
   976     load_reg( R_EAX, Rm );
   977     check_ralign32( R_ECX );
   978     MOV_r32_r32( R_EAX, R_ECX );
   979     ADD_imm8s_r32( 4, R_EAX );
   980     store_reg( R_EAX, Rm );
   981     MEM_READ_LONG( R_ECX, R_EAX );
   982     store_reg( R_EAX, Rn );
   983 :}
   984 MOV.L @(R0, Rm), Rn {:  
   985     load_reg( R_EAX, 0 );
   986     load_reg( R_ECX, Rm );
   987     ADD_r32_r32( R_EAX, R_ECX );
   988     check_ralign32( R_ECX );
   989     MEM_READ_LONG( R_ECX, R_EAX );
   990     store_reg( R_EAX, Rn );
   991 :}
   992 MOV.L @(disp, GBR), R0 {:
   993     load_spreg( R_ECX, R_GBR );
   994     ADD_imm32_r32( disp, R_ECX );
   995     check_ralign32( R_ECX );
   996     MEM_READ_LONG( R_ECX, R_EAX );
   997     store_reg( R_EAX, 0 );
   998 :}
   999 MOV.L @(disp, PC), Rn {:  
  1000     if( sh4_x86.in_delay_slot ) {
  1001 	SLOTILLEGAL();
  1002     } else {
  1003 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1004 	MEM_READ_LONG( R_ECX, R_EAX );
  1005 	store_reg( R_EAX, 0 );
  1007 :}
  1008 MOV.L @(disp, Rm), Rn {:  
  1009     load_reg( R_ECX, Rm );
  1010     ADD_imm8s_r32( disp, R_ECX );
  1011     check_ralign32( R_ECX );
  1012     MEM_READ_LONG( R_ECX, R_EAX );
  1013     store_reg( R_EAX, Rn );
  1014 :}
  1015 MOV.W Rm, @Rn {:  
  1016     load_reg( R_ECX, Rn );
  1017     check_walign16( R_ECX );
  1018     MEM_READ_WORD( R_ECX, R_EAX );
  1019     store_reg( R_EAX, Rn );
  1020 :}
  1021 MOV.W Rm, @-Rn {:  
  1022     load_reg( R_ECX, Rn );
  1023     check_walign16( R_ECX );
  1024     load_reg( R_EAX, Rm );
  1025     ADD_imm8s_r32( -2, R_ECX );
  1026     MEM_WRITE_WORD( R_ECX, R_EAX );
  1027 :}
  1028 MOV.W Rm, @(R0, Rn) {:  
  1029     load_reg( R_EAX, 0 );
  1030     load_reg( R_ECX, Rn );
  1031     ADD_r32_r32( R_EAX, R_ECX );
  1032     check_walign16( R_ECX );
  1033     load_reg( R_EAX, Rm );
  1034     MEM_WRITE_WORD( R_ECX, R_EAX );
  1035 :}
  1036 MOV.W R0, @(disp, GBR) {:  
  1037     load_spreg( R_ECX, R_GBR );
  1038     load_reg( R_EAX, 0 );
  1039     ADD_imm32_r32( disp, R_ECX );
  1040     check_walign16( R_ECX );
  1041     MEM_WRITE_WORD( R_ECX, R_EAX );
  1042 :}
  1043 MOV.W R0, @(disp, Rn) {:  
  1044     load_reg( R_ECX, Rn );
  1045     load_reg( R_EAX, 0 );
  1046     ADD_imm32_r32( disp, R_ECX );
  1047     check_walign16( R_ECX );
  1048     MEM_WRITE_WORD( R_ECX, R_EAX );
  1049 :}
  1050 MOV.W @Rm, Rn {:  
  1051     load_reg( R_ECX, Rm );
  1052     check_ralign16( R_ECX );
  1053     MEM_READ_WORD( R_ECX, R_EAX );
  1054     store_reg( R_EAX, Rn );
  1055 :}
  1056 MOV.W @Rm+, Rn {:  
  1057     load_reg( R_EAX, Rm );
  1058     check_ralign16( R_EAX );
  1059     MOV_r32_r32( R_EAX, R_ECX );
  1060     ADD_imm8s_r32( 2, R_EAX );
  1061     store_reg( R_EAX, Rm );
  1062     MEM_READ_WORD( R_ECX, R_EAX );
  1063     store_reg( R_EAX, Rn );
  1064 :}
  1065 MOV.W @(R0, Rm), Rn {:  
  1066     load_reg( R_EAX, 0 );
  1067     load_reg( R_ECX, Rm );
  1068     ADD_r32_r32( R_EAX, R_ECX );
  1069     check_ralign16( R_ECX );
  1070     MEM_READ_WORD( R_ECX, R_EAX );
  1071     store_reg( R_EAX, Rn );
  1072 :}
  1073 MOV.W @(disp, GBR), R0 {:  
  1074     load_spreg( R_ECX, R_GBR );
  1075     ADD_imm32_r32( disp, R_ECX );
  1076     check_ralign16( R_ECX );
  1077     MEM_READ_WORD( R_ECX, R_EAX );
  1078     store_reg( R_EAX, 0 );
  1079 :}
  1080 MOV.W @(disp, PC), Rn {:  
  1081     if( sh4_x86.in_delay_slot ) {
  1082 	SLOTILLEGAL();
  1083     } else {
  1084 	load_imm32( R_ECX, pc + disp + 4 );
  1085 	MEM_READ_WORD( R_ECX, R_EAX );
  1086 	store_reg( R_EAX, Rn );
  1088 :}
  1089 MOV.W @(disp, Rm), R0 {:  
  1090     load_reg( R_ECX, Rm );
  1091     ADD_imm32_r32( disp, R_ECX );
  1092     check_ralign16( R_ECX );
  1093     MEM_READ_WORD( R_ECX, R_EAX );
  1094     store_reg( R_EAX, 0 );
  1095 :}
  1096 MOVA @(disp, PC), R0 {:  
  1097     if( sh4_x86.in_delay_slot ) {
  1098 	SLOTILLEGAL();
  1099     } else {
  1100 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1101 	store_reg( R_ECX, 0 );
  1103 :}
  1104 MOVCA.L R0, @Rn {:  
  1105     load_reg( R_EAX, 0 );
  1106     load_reg( R_ECX, Rn );
  1107     check_walign32( R_ECX );
  1108     MEM_WRITE_LONG( R_ECX, R_EAX );
  1109 :}
  1111 /* Control transfer instructions */
  1112 BF disp {:
  1113     if( sh4_x86.in_delay_slot ) {
  1114 	SLOTILLEGAL();
  1115     } else {
  1116 	load_imm32( R_EDI, pc + 2 );
  1117 	CMP_imm8s_sh4r( 0, R_T );
  1118 	JNE_rel8( 5 );
  1119 	load_imm32( R_EDI, disp + pc + 4 );
  1120 	INC_r32(R_ESI);
  1121 	return 1;
  1123 :}
  1124 BF/S disp {:
  1125     if( sh4_x86.in_delay_slot ) {
  1126 	SLOTILLEGAL();
  1127     } else {
  1128 	load_imm32( R_EDI, pc + 2 );
  1129 	CMP_imm8s_sh4r( 0, R_T );
  1130 	JNE_rel8( 5 );
  1131 	load_imm32( R_EDI, disp + pc + 4 );
  1132 	sh4_x86.in_delay_slot = TRUE;
  1133 	INC_r32(R_ESI);
  1134 	return 0;
  1136 :}
  1137 BRA disp {:  
  1138     if( sh4_x86.in_delay_slot ) {
  1139 	SLOTILLEGAL();
  1140     } else {
  1141 	load_imm32( R_EDI, disp + pc + 4 );
  1142 	sh4_x86.in_delay_slot = TRUE;
  1143 	INC_r32(R_ESI);
  1144 	return 0;
  1146 :}
  1147 BRAF Rn {:  
  1148     if( sh4_x86.in_delay_slot ) {
  1149 	SLOTILLEGAL();
  1150     } else {
  1151 	load_reg( R_EDI, Rn );
  1152 	sh4_x86.in_delay_slot = TRUE;
  1153 	INC_r32(R_ESI);
  1154 	return 0;
  1156 :}
  1157 BSR disp {:  
  1158     if( sh4_x86.in_delay_slot ) {
  1159 	SLOTILLEGAL();
  1160     } else {
  1161 	load_imm32( R_EAX, pc + 4 );
  1162 	store_spreg( R_EAX, R_PR );
  1163 	load_imm32( R_EDI, disp + pc + 4 );
  1164 	sh4_x86.in_delay_slot = TRUE;
  1165 	INC_r32(R_ESI);
  1166 	return 0;
  1168 :}
  1169 BSRF Rn {:  
  1170     if( sh4_x86.in_delay_slot ) {
  1171 	SLOTILLEGAL();
  1172     } else {
  1173 	load_imm32( R_EAX, pc + 4 );
  1174 	store_spreg( R_EAX, R_PR );
  1175 	load_reg( R_EDI, Rn );
  1176 	ADD_r32_r32( R_EAX, R_EDI );
  1177 	sh4_x86.in_delay_slot = TRUE;
  1178 	INC_r32(R_ESI);
  1179 	return 0;
  1181 :}
  1182 BT disp {:
  1183     if( sh4_x86.in_delay_slot ) {
  1184 	SLOTILLEGAL();
  1185     } else {
  1186 	load_imm32( R_EDI, pc + 2 );
  1187 	CMP_imm8s_sh4r( 0, R_T );
  1188 	JE_rel8( 5 );
  1189 	load_imm32( R_EDI, disp + pc + 4 );
  1190 	INC_r32(R_ESI);
  1191 	return 1;
  1193 :}
  1194 BT/S disp {:
  1195     if( sh4_x86.in_delay_slot ) {
  1196 	SLOTILLEGAL();
  1197     } else {
  1198 	load_imm32( R_EDI, pc + 2 );
  1199 	CMP_imm8s_sh4r( 0, R_T );
  1200 	JE_rel8( 5 );
  1201 	load_imm32( R_EDI, disp + pc + 4 );
  1202 	sh4_x86.in_delay_slot = TRUE;
  1203 	INC_r32(R_ESI);
  1204 	return 0;
  1206 :}
  1207 JMP @Rn {:  
  1208     if( sh4_x86.in_delay_slot ) {
  1209 	SLOTILLEGAL();
  1210     } else {
  1211 	load_reg( R_EDI, Rn );
  1212 	sh4_x86.in_delay_slot = TRUE;
  1213 	INC_r32(R_ESI);
  1214 	return 0;
  1216 :}
  1217 JSR @Rn {:  
  1218     if( sh4_x86.in_delay_slot ) {
  1219 	SLOTILLEGAL();
  1220     } else {
  1221 	load_imm32( R_EAX, pc + 4 );
  1222 	store_spreg( R_EAX, R_PR );
  1223 	load_reg( R_EDI, Rn );
  1224 	sh4_x86.in_delay_slot = TRUE;
  1225 	INC_r32(R_ESI);
  1226 	return 0;
  1228 :}
  1229 RTE {:  
  1230     check_priv();
  1231     if( sh4_x86.in_delay_slot ) {
  1232 	SLOTILLEGAL();
  1233     } else {
  1234 	load_spreg( R_EDI, R_PR );
  1235 	load_spreg( R_EAX, R_SSR );
  1236 	call_func1( sh4_write_sr, R_EAX );
  1237 	sh4_x86.in_delay_slot = TRUE;
  1238 	INC_r32(R_ESI);
  1239 	return 0;
  1241 :}
  1242 RTS {:  
  1243     if( sh4_x86.in_delay_slot ) {
  1244 	SLOTILLEGAL();
  1245     } else {
  1246 	load_spreg( R_EDI, R_PR );
  1247 	sh4_x86.in_delay_slot = TRUE;
  1248 	INC_r32(R_ESI);
  1249 	return 0;
  1251 :}
  1252 TRAPA #imm {:  
  1253     if( sh4_x86.in_delay_slot ) {
  1254 	SLOTILLEGAL();
  1255     } else {
  1256 	// TODO: Write TRA 
  1257 	RAISE_EXCEPTION(EXC_TRAP);
  1259 :}
  1260 UNDEF {:  
  1261     if( sh4_x86.in_delay_slot ) {
  1262 	RAISE_EXCEPTION(EXC_SLOT_ILLEGAL);
  1263     } else {
  1264 	RAISE_EXCEPTION(EXC_ILLEGAL);
  1266     return 1;
  1267 :}
  1269 CLRMAC {:  
  1270     XOR_r32_r32(R_EAX, R_EAX);
  1271     store_spreg( R_EAX, R_MACL );
  1272     store_spreg( R_EAX, R_MACH );
  1273 :}
  1274 CLRS {:
  1275     CLC();
  1276     SETC_sh4r(R_S);
  1277 :}
  1278 CLRT {:  
  1279     CLC();
  1280     SETC_t();
  1281 :}
  1282 SETS {:  
  1283     STC();
  1284     SETC_sh4r(R_S);
  1285 :}
  1286 SETT {:  
  1287     STC();
  1288     SETC_t();
  1289 :}
  1291 /* Floating point moves */
  1292 FMOV FRm, FRn {:  
  1293     /* As horrible as this looks, it's actually covering 5 separate cases:
  1294      * 1. 32-bit fr-to-fr (PR=0)
  1295      * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
  1296      * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
  1297      * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
  1298      * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
  1299      */
  1300     load_spreg( R_ECX, R_FPSCR );
  1301     load_spreg( R_EDX, REG_OFFSET(fr_bank) );
  1302     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1303     JNE_rel8(8);
  1304     load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
  1305     store_fr( R_EDX, R_EAX, FRn );
  1306     if( FRm&1 ) {
  1307 	JMP_rel8(22);
  1308 	load_xf_bank( R_ECX ); 
  1309 	load_fr( R_ECX, R_EAX, FRm-1 );
  1310 	if( FRn&1 ) {
  1311 	    load_fr( R_ECX, R_EDX, FRm );
  1312 	    store_fr( R_ECX, R_EAX, FRn-1 );
  1313 	    store_fr( R_ECX, R_EDX, FRn );
  1314 	} else /* FRn&1 == 0 */ {
  1315 	    load_fr( R_ECX, R_ECX, FRm );
  1316 	    store_fr( R_EDX, R_EAX, FRn-1 );
  1317 	    store_fr( R_EDX, R_ECX, FRn );
  1319     } else /* FRm&1 == 0 */ {
  1320 	if( FRn&1 ) {
  1321 	    JMP_rel8(22);
  1322 	    load_xf_bank( R_ECX );
  1323 	    load_fr( R_EDX, R_EAX, FRm );
  1324 	    load_fr( R_EDX, R_EDX, FRm+1 );
  1325 	    store_fr( R_ECX, R_EAX, FRn-1 );
  1326 	    store_fr( R_ECX, R_EDX, FRn );
  1327 	} else /* FRn&1 == 0 */ {
  1328 	    JMP_rel8(12);
  1329 	    load_fr( R_EDX, R_EAX, FRm );
  1330 	    load_fr( R_EDX, R_ECX, FRm+1 );
  1331 	    store_fr( R_EDX, R_EAX, FRn );
  1332 	    store_fr( R_EDX, R_ECX, FRn+1 );
  1335 :}
  1336 FMOV FRm, @Rn {:  
  1337     load_reg( R_EDX, Rn );
  1338     check_walign32( R_EDX );
  1339     load_spreg( R_ECX, R_FPSCR );
  1340     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1341     JNE_rel8(20);
  1342     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1343     load_fr( R_ECX, R_EAX, FRm );
  1344     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1345     if( FRm&1 ) {
  1346 	JMP_rel8( 46 );
  1347 	load_xf_bank( R_ECX );
  1348     } else {
  1349 	JMP_rel8( 39 );
  1350 	load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1352     load_fr( R_ECX, R_EAX, FRm&0x0E );
  1353     load_fr( R_ECX, R_ECX, FRm|0x01 );
  1354     MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1355 :}
  1356 FMOV @Rm, FRn {:  
  1357     load_reg( R_EDX, Rm );
  1358     check_ralign32( R_EDX );
  1359     load_spreg( R_ECX, R_FPSCR );
  1360     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1361     JNE_rel8(19);
  1362     MEM_READ_LONG( R_EDX, R_EAX );
  1363     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1364     store_fr( R_ECX, R_EAX, FRn );
  1365     if( FRn&1 ) {
  1366 	JMP_rel8(46);
  1367 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1368 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1369 	load_xf_bank( R_ECX );
  1370     } else {
  1371 	JMP_rel8(36);
  1372 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1373 	load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1375     store_fr( R_ECX, R_EAX, FRn&0x0E );
  1376     store_fr( R_ECX, R_EDX, FRn|0x01 );
  1377 :}
  1378 FMOV FRm, @-Rn {:  :}
  1379 FMOV FRm, @(R0, Rn) {:  :}
  1380 FMOV @Rm+, FRn {:  :}
  1381 FMOV @(R0, Rm), FRn {:  :}
  1383 /* Floating point instructions */
  1384 FABS FRn {:  
  1385     load_spreg( R_ECX, R_FPSCR );
  1386     load_spreg( R_EDX, REG_OFFSET(fr_bank) );
  1387     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1388     JNE_rel8(10);
  1389     push_fr(R_EDX, FRn); // 3
  1390     FABS_st0(); // 2
  1391     pop_fr( R_EDX, FRn); //3
  1392     JMP_rel8(8); // 2
  1393     push_dr(R_EDX, FRn);
  1394     FABS_st0();
  1395     pop_dr(R_EDX, FRn);
  1396 :}
  1397 FADD FRm, FRn {:  :}
  1398 FCMP/EQ FRm, FRn {:  :}
  1399 FCMP/GT FRm, FRn {:  :}
  1400 FCNVDS FRm, FPUL {:  :}
  1401 FCNVSD FPUL, FRn {:  :}
  1402 FDIV FRm, FRn {:  :}
  1403 FIPR FVm, FVn {:  :}
  1404 FLDS FRm, FPUL {:  :}
  1405 FLDI0 FRn {:  /* IFF PR=0 */
  1406     load_spreg( R_ECX, R_FPSCR );
  1407     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1408     JNE_rel8(8);
  1409     xor_r32_r32( R_EAX, R_EAX );
  1410     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1411     store_fr( R_ECX, R_EAX, FRn );
  1412 :}
  1413 FLDI1 FRn {:  /* IFF PR=0 */
  1414     load_spreg( R_ECX, R_FPSCR );
  1415     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1416     JNE_rel8(11);
  1417     load_imm32(R_EAX, 0x3F800000);
  1418     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1419     store_fr( R_ECX, R_EAX, FRn );
  1420 :}
  1421 FLOAT FPUL, FRn {:  
  1422     load_spreg( R_ECX, R_FPSCR );
  1423     load_spreg(R_EDX, REG_OFFSET(fr_bank));
  1424     FILD_sh4r(R_FPUL);
  1425     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1426     JNE_rel8(5);
  1427     pop_fr( R_EDX, FRn );
  1428     JMP_rel8(3);
  1429     pop_dr( R_EDX, FRn );
  1430 :}
  1431 FMAC FR0, FRm, FRn {:  
  1432     load_spreg( R_ECX, R_FPSCR );
  1433     load_spreg( R_EDX, REG_OFFSET(fr_bank));
  1434     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1435     JNE_rel8(18);
  1436     push_fr( R_EDX, 0 );
  1437     push_fr( R_EDX, FRm );
  1438     FMULP_st(1);
  1439     push_fr( R_EDX, FRn );
  1440     FADDP_st(1);
  1441     pop_fr( R_EDX, FRn );
  1442     JMP_rel8(16);
  1443     push_dr( R_EDX, 0 );
  1444     push_dr( R_EDX, FRm );
  1445     FMULP_st(1);
  1446     push_dr( R_EDX, FRn );
  1447     FADDP_st(1);
  1448     pop_dr( R_EDX, FRn );
  1449 :}
  1451 FMUL FRm, FRn {:  :}
  1452 FNEG FRn {:  :}
  1453 FRCHG {:  :}
  1454 FSCA FPUL, FRn {:  :}
  1455 FSCHG {:  :}
  1456 FSQRT FRn {:  :}
  1457 FSRRA FRn {:  :}
  1458 FSTS FPUL, FRn {:  :}
  1459 FSUB FRm, FRn {:  :}
  1460 FTRC FRm, FPUL {:  :}
  1461 FTRV XMTRX, FVn {:  :}
  1463 /* Processor control instructions */
  1464 LDC Rm, SR {:
  1465     load_reg( R_EAX, Rm );
  1466     call_func1( sh4_write_sr, R_EAX );
  1467 :}
  1468 LDC Rm, GBR {: 
  1469     load_reg( R_EAX, Rm );
  1470     store_spreg( R_EAX, R_GBR );
  1471 :}
  1472 LDC Rm, VBR {:  
  1473     load_reg( R_EAX, Rm );
  1474     store_spreg( R_EAX, R_VBR );
  1475 :}
  1476 LDC Rm, SSR {:  
  1477     load_reg( R_EAX, Rm );
  1478     store_spreg( R_EAX, R_SSR );
  1479 :}
  1480 LDC Rm, SGR {:  
  1481     load_reg( R_EAX, Rm );
  1482     store_spreg( R_EAX, R_SGR );
  1483 :}
  1484 LDC Rm, SPC {:  
  1485     load_reg( R_EAX, Rm );
  1486     store_spreg( R_EAX, R_SPC );
  1487 :}
  1488 LDC Rm, DBR {:  
  1489     load_reg( R_EAX, Rm );
  1490     store_spreg( R_EAX, R_DBR );
  1491 :}
  1492 LDC Rm, Rn_BANK {:  
  1493     load_reg( R_EAX, Rm );
  1494     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  1495 :}
  1496 LDC.L @Rm+, GBR {:  
  1497     load_reg( R_EAX, Rm );
  1498     MOV_r32_r32( R_EAX, R_ECX );
  1499     ADD_imm8s_r32( 4, R_EAX );
  1500     store_reg( R_EAX, Rm );
  1501     MEM_READ_LONG( R_ECX, R_EAX );
  1502     store_spreg( R_EAX, R_GBR );
  1503 :}
  1504 LDC.L @Rm+, SR {:
  1505     load_reg( R_EAX, Rm );
  1506     MOV_r32_r32( R_EAX, R_ECX );
  1507     ADD_imm8s_r32( 4, R_EAX );
  1508     store_reg( R_EAX, Rm );
  1509     MEM_READ_LONG( R_ECX, R_EAX );
  1510     call_func1( sh4_write_sr, R_EAX );
  1511 :}
  1512 LDC.L @Rm+, VBR {:  
  1513     load_reg( R_EAX, Rm );
  1514     MOV_r32_r32( R_EAX, R_ECX );
  1515     ADD_imm8s_r32( 4, R_EAX );
  1516     store_reg( R_EAX, Rm );
  1517     MEM_READ_LONG( R_ECX, R_EAX );
  1518     store_spreg( R_EAX, R_VBR );
  1519 :}
  1520 LDC.L @Rm+, SSR {:
  1521     load_reg( R_EAX, Rm );
  1522     MOV_r32_r32( R_EAX, R_ECX );
  1523     ADD_imm8s_r32( 4, R_EAX );
  1524     store_reg( R_EAX, Rm );
  1525     MEM_READ_LONG( R_ECX, R_EAX );
  1526     store_spreg( R_EAX, R_SSR );
  1527 :}
  1528 LDC.L @Rm+, SGR {:  
  1529     load_reg( R_EAX, Rm );
  1530     MOV_r32_r32( R_EAX, R_ECX );
  1531     ADD_imm8s_r32( 4, R_EAX );
  1532     store_reg( R_EAX, Rm );
  1533     MEM_READ_LONG( R_ECX, R_EAX );
  1534     store_spreg( R_EAX, R_SGR );
  1535 :}
  1536 LDC.L @Rm+, SPC {:  
  1537     load_reg( R_EAX, Rm );
  1538     MOV_r32_r32( R_EAX, R_ECX );
  1539     ADD_imm8s_r32( 4, R_EAX );
  1540     store_reg( R_EAX, Rm );
  1541     MEM_READ_LONG( R_ECX, R_EAX );
  1542     store_spreg( R_EAX, R_SPC );
  1543 :}
  1544 LDC.L @Rm+, DBR {:  
  1545     load_reg( R_EAX, Rm );
  1546     MOV_r32_r32( R_EAX, R_ECX );
  1547     ADD_imm8s_r32( 4, R_EAX );
  1548     store_reg( R_EAX, Rm );
  1549     MEM_READ_LONG( R_ECX, R_EAX );
  1550     store_spreg( R_EAX, R_DBR );
  1551 :}
  1552 LDC.L @Rm+, Rn_BANK {:  
  1553     load_reg( R_EAX, Rm );
  1554     MOV_r32_r32( R_EAX, R_ECX );
  1555     ADD_imm8s_r32( 4, R_EAX );
  1556     store_reg( R_EAX, Rm );
  1557     MEM_READ_LONG( R_ECX, R_EAX );
  1558     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  1559 :}
  1560 LDS Rm, FPSCR {:  
  1561     load_reg( R_EAX, Rm );
  1562     store_spreg( R_EAX, R_FPSCR );
  1563 :}
  1564 LDS.L @Rm+, FPSCR {:  
  1565     load_reg( R_EAX, Rm );
  1566     MOV_r32_r32( R_EAX, R_ECX );
  1567     ADD_imm8s_r32( 4, R_EAX );
  1568     store_reg( R_EAX, Rm );
  1569     MEM_READ_LONG( R_ECX, R_EAX );
  1570     store_spreg( R_EAX, R_FPSCR );
  1571 :}
  1572 LDS Rm, FPUL {:  
  1573     load_reg( R_EAX, Rm );
  1574     store_spreg( R_EAX, R_FPUL );
  1575 :}
  1576 LDS.L @Rm+, FPUL {:  
  1577     load_reg( R_EAX, Rm );
  1578     MOV_r32_r32( R_EAX, R_ECX );
  1579     ADD_imm8s_r32( 4, R_EAX );
  1580     store_reg( R_EAX, Rm );
  1581     MEM_READ_LONG( R_ECX, R_EAX );
  1582     store_spreg( R_EAX, R_FPUL );
  1583 :}
  1584 LDS Rm, MACH {: 
  1585     load_reg( R_EAX, Rm );
  1586     store_spreg( R_EAX, R_MACH );
  1587 :}
  1588 LDS.L @Rm+, MACH {:  
  1589     load_reg( R_EAX, Rm );
  1590     MOV_r32_r32( R_EAX, R_ECX );
  1591     ADD_imm8s_r32( 4, R_EAX );
  1592     store_reg( R_EAX, Rm );
  1593     MEM_READ_LONG( R_ECX, R_EAX );
  1594     store_spreg( R_EAX, R_MACH );
  1595 :}
  1596 LDS Rm, MACL {:  
  1597     load_reg( R_EAX, Rm );
  1598     store_spreg( R_EAX, R_MACL );
  1599 :}
  1600 LDS.L @Rm+, MACL {:  
  1601     load_reg( R_EAX, Rm );
  1602     MOV_r32_r32( R_EAX, R_ECX );
  1603     ADD_imm8s_r32( 4, R_EAX );
  1604     store_reg( R_EAX, Rm );
  1605     MEM_READ_LONG( R_ECX, R_EAX );
  1606     store_spreg( R_EAX, R_MACL );
  1607 :}
  1608 LDS Rm, PR {:  
  1609     load_reg( R_EAX, Rm );
  1610     store_spreg( R_EAX, R_PR );
  1611 :}
  1612 LDS.L @Rm+, PR {:  
  1613     load_reg( R_EAX, Rm );
  1614     MOV_r32_r32( R_EAX, R_ECX );
  1615     ADD_imm8s_r32( 4, R_EAX );
  1616     store_reg( R_EAX, Rm );
  1617     MEM_READ_LONG( R_ECX, R_EAX );
  1618     store_spreg( R_EAX, R_PR );
  1619 :}
  1620 LDTLB {:  :}
  1621 OCBI @Rn {:  :}
  1622 OCBP @Rn {:  :}
  1623 OCBWB @Rn {:  :}
  1624 PREF @Rn {:
  1625     load_reg( R_EAX, Rn );
  1626     PUSH_r32( R_EAX );
  1627     AND_imm32_r32( 0xFC000000, R_EAX );
  1628     CMP_imm32_r32( 0xE0000000, R_EAX );
  1629     JNE_rel8(8);
  1630     call_func0( sh4_flush_store_queue );
  1631     ADD_imm8s_r32( -4, R_ESP );
  1632 :}
  1633  SLEEP {: /* TODO */ :}
  1634  STC SR, Rn {:
  1635      call_func0(sh4_read_sr);
  1636      store_reg( R_EAX, Rn );
  1637 :}
  1638 STC GBR, Rn {:  
  1639     load_spreg( R_EAX, R_GBR );
  1640     store_reg( R_EAX, Rn );
  1641 :}
  1642 STC VBR, Rn {:  
  1643     load_spreg( R_EAX, R_VBR );
  1644     store_reg( R_EAX, Rn );
  1645 :}
  1646 STC SSR, Rn {:  
  1647     load_spreg( R_EAX, R_SSR );
  1648     store_reg( R_EAX, Rn );
  1649 :}
  1650 STC SPC, Rn {:  
  1651     load_spreg( R_EAX, R_SPC );
  1652     store_reg( R_EAX, Rn );
  1653 :}
  1654 STC SGR, Rn {:  
  1655     load_spreg( R_EAX, R_SGR );
  1656     store_reg( R_EAX, Rn );
  1657 :}
  1658 STC DBR, Rn {:  
  1659     load_spreg( R_EAX, R_DBR );
  1660     store_reg( R_EAX, Rn );
  1661 :}
  1662 STC Rm_BANK, Rn {:
  1663     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  1664     store_reg( R_EAX, Rn );
  1665 :}
  1666 STC.L SR, @-Rn {:
  1667     load_reg( R_ECX, Rn );
  1668     ADD_imm8s_r32( -4, Rn );
  1669     store_reg( R_ECX, Rn );
  1670     call_func0( sh4_read_sr );
  1671     MEM_WRITE_LONG( R_ECX, R_EAX );
  1672 :}
  1673 STC.L VBR, @-Rn {:  
  1674     load_reg( R_ECX, Rn );
  1675     ADD_imm8s_r32( -4, Rn );
  1676     store_reg( R_ECX, Rn );
  1677     load_spreg( R_EAX, R_VBR );
  1678     MEM_WRITE_LONG( R_ECX, R_EAX );
  1679 :}
  1680 STC.L SSR, @-Rn {:  
  1681     load_reg( R_ECX, Rn );
  1682     ADD_imm8s_r32( -4, Rn );
  1683     store_reg( R_ECX, Rn );
  1684     load_spreg( R_EAX, R_SSR );
  1685     MEM_WRITE_LONG( R_ECX, R_EAX );
  1686 :}
  1687 STC.L SPC, @-Rn {:  
  1688     load_reg( R_ECX, Rn );
  1689     ADD_imm8s_r32( -4, Rn );
  1690     store_reg( R_ECX, Rn );
  1691     load_spreg( R_EAX, R_SPC );
  1692     MEM_WRITE_LONG( R_ECX, R_EAX );
  1693 :}
  1694 STC.L SGR, @-Rn {:  
  1695     load_reg( R_ECX, Rn );
  1696     ADD_imm8s_r32( -4, Rn );
  1697     store_reg( R_ECX, Rn );
  1698     load_spreg( R_EAX, R_SGR );
  1699     MEM_WRITE_LONG( R_ECX, R_EAX );
  1700 :}
  1701 STC.L DBR, @-Rn {:  
  1702     load_reg( R_ECX, Rn );
  1703     ADD_imm8s_r32( -4, Rn );
  1704     store_reg( R_ECX, Rn );
  1705     load_spreg( R_EAX, R_DBR );
  1706     MEM_WRITE_LONG( R_ECX, R_EAX );
  1707 :}
  1708 STC.L Rm_BANK, @-Rn {:  
  1709     load_reg( R_ECX, Rn );
  1710     ADD_imm8s_r32( -4, Rn );
  1711     store_reg( R_ECX, Rn );
  1712     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  1713     MEM_WRITE_LONG( R_ECX, R_EAX );
  1714 :}
  1715 STC.L GBR, @-Rn {:  
  1716     load_reg( R_ECX, Rn );
  1717     ADD_imm8s_r32( -4, Rn );
  1718     store_reg( R_ECX, Rn );
  1719     load_spreg( R_EAX, R_GBR );
  1720     MEM_WRITE_LONG( R_ECX, R_EAX );
  1721 :}
  1722 STS FPSCR, Rn {:  
  1723     load_spreg( R_EAX, R_FPSCR );
  1724     store_reg( R_EAX, Rn );
  1725 :}
  1726 STS.L FPSCR, @-Rn {:  
  1727     load_reg( R_ECX, Rn );
  1728     ADD_imm8s_r32( -4, Rn );
  1729     store_reg( R_ECX, Rn );
  1730     load_spreg( R_EAX, R_FPSCR );
  1731     MEM_WRITE_LONG( R_ECX, R_EAX );
  1732 :}
  1733 STS FPUL, Rn {:  
  1734     load_spreg( R_EAX, R_FPUL );
  1735     store_reg( R_EAX, Rn );
  1736 :}
  1737 STS.L FPUL, @-Rn {:  
  1738     load_reg( R_ECX, Rn );
  1739     ADD_imm8s_r32( -4, Rn );
  1740     store_reg( R_ECX, Rn );
  1741     load_spreg( R_EAX, R_FPUL );
  1742     MEM_WRITE_LONG( R_ECX, R_EAX );
  1743 :}
  1744 STS MACH, Rn {:  
  1745     load_spreg( R_EAX, R_MACH );
  1746     store_reg( R_EAX, Rn );
  1747 :}
  1748 STS.L MACH, @-Rn {:  
  1749     load_reg( R_ECX, Rn );
  1750     ADD_imm8s_r32( -4, Rn );
  1751     store_reg( R_ECX, Rn );
  1752     load_spreg( R_EAX, R_MACH );
  1753     MEM_WRITE_LONG( R_ECX, R_EAX );
  1754 :}
  1755 STS MACL, Rn {:  
  1756     load_spreg( R_EAX, R_MACL );
  1757     store_reg( R_EAX, Rn );
  1758 :}
  1759 STS.L MACL, @-Rn {:  
  1760     load_reg( R_ECX, Rn );
  1761     ADD_imm8s_r32( -4, Rn );
  1762     store_reg( R_ECX, Rn );
  1763     load_spreg( R_EAX, R_MACL );
  1764     MEM_WRITE_LONG( R_ECX, R_EAX );
  1765 :}
  1766 STS PR, Rn {:  
  1767     load_spreg( R_EAX, R_PR );
  1768     store_reg( R_EAX, Rn );
  1769 :}
  1770 STS.L PR, @-Rn {:  
  1771     load_reg( R_ECX, Rn );
  1772     ADD_imm8s_r32( -4, Rn );
  1773     store_reg( R_ECX, Rn );
  1774     load_spreg( R_EAX, R_PR );
  1775     MEM_WRITE_LONG( R_ECX, R_EAX );
  1776 :}
  1778 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
  1779 %%
  1780     INC_r32(R_ESI);
  1781     if( sh4_x86.in_delay_slot ) {
  1782 	sh4_x86.in_delay_slot = FALSE;
  1783 	return 1;
  1785     return 0;
.