Search
lxdream.org :: lxdream/src/sh4/sh4x86.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 377:fa18743f6905
prev375:4627600f7f8e
next380:2e8166bf6832
author nkeynes
date Wed Sep 12 09:17:52 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Fill in most of the FP operations and fix the stack adjustments
view annotate diff log raw
     1 /**
     2  * $Id: sh4x86.in,v 1.6 2007-09-12 09:17:24 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 FPUL (as a 32-bit float) onto the FPU stack
   184  */
   185 static inline void push_fpul( )
   186 {
   187     OP(0xD9); OP(0x45); OP(R_FPUL);
   188 }
   190 /**
   191  * Pop FPUL (as a 32-bit float) from the FPU stack
   192  */
   193 static inline void pop_fpul( )
   194 {
   195     OP(0xD9); OP(0x5D); OP(R_FPUL);
   196 }
   198 /**
   199  * Push a 32-bit float onto the FPU stack, with bankreg previously loaded
   200  * with the location of the current fp bank.
   201  */
   202 static inline void push_fr( int bankreg, int frm ) 
   203 {
   204     OP(0xD9); OP(0x40 + bankreg); OP((frm^1)<<2);  // FLD.S [bankreg + frm^1*4]
   205 }
   207 /**
   208  * Pop a 32-bit float from the FPU stack and store it back into the fp bank, 
   209  * with bankreg previously loaded with the location of the current fp bank.
   210  */
   211 static inline void pop_fr( int bankreg, int frm )
   212 {
   213     OP(0xD9); OP(0x58 + bankreg); OP((frm^1)<<2); // FST.S [bankreg + frm^1*4]
   214 }
   216 /**
   217  * Push a 64-bit double onto the FPU stack, with bankreg previously loaded
   218  * with the location of the current fp bank.
   219  */
   220 static inline void push_dr( int bankreg, int frm )
   221 {
   222     OP(0xDD); OP(0x40 + bankreg); OP(frm<<2); // FLD.D [bankreg + frm*4]
   223 }
   225 static inline void pop_dr( int bankreg, int frm )
   226 {
   227     OP(0xDD); OP(0x58 + bankreg); OP(frm<<2); // FST.D [bankreg + frm*4]
   228 }
   230 /**
   231  * Note: clobbers EAX to make the indirect call - this isn't usually
   232  * a problem since the callee will usually clobber it anyway.
   233  */
   234 static inline void call_func0( void *ptr )
   235 {
   236     load_imm32(R_EAX, (uint32_t)ptr);
   237     CALL_r32(R_EAX);
   238 }
   240 static inline void call_func1( void *ptr, int arg1 )
   241 {
   242     PUSH_r32(arg1);
   243     call_func0(ptr);
   244     ADD_imm8s_r32( 4, R_ESP );
   245 }
   247 static inline void call_func2( void *ptr, int arg1, int arg2 )
   248 {
   249     PUSH_r32(arg2);
   250     PUSH_r32(arg1);
   251     call_func0(ptr);
   252     ADD_imm8s_r32( 8, R_ESP );
   253 }
   255 /**
   256  * Write a double (64-bit) value into memory, with the first word in arg2a, and
   257  * the second in arg2b
   258  * NB: 30 bytes
   259  */
   260 static inline void MEM_WRITE_DOUBLE( int addr, int arg2a, int arg2b )
   261 {
   262     ADD_imm8s_r32( 4, addr );
   263     PUSH_r32(addr);
   264     PUSH_r32(arg2b);
   265     ADD_imm8s_r32( -4, addr );
   266     PUSH_r32(addr);
   267     PUSH_r32(arg2a);
   268     call_func0(sh4_write_long);
   269     ADD_imm8s_r32( 8, R_ESP );
   270     call_func0(sh4_write_long);
   271     ADD_imm8s_r32( 8, R_ESP );
   272 }
   274 /**
   275  * Read a double (64-bit) value from memory, writing the first word into arg2a
   276  * and the second into arg2b. The addr must not be in EAX
   277  * NB: 27 bytes
   278  */
   279 static inline void MEM_READ_DOUBLE( int addr, int arg2a, int arg2b )
   280 {
   281     PUSH_r32(addr);
   282     call_func0(sh4_read_long);
   283     POP_r32(addr);
   284     PUSH_r32(R_EAX);
   285     ADD_imm8s_r32( 4, addr );
   286     PUSH_r32(addr);
   287     call_func0(sh4_read_long);
   288     ADD_imm8s_r32( 4, R_ESP );
   289     MOV_r32_r32( R_EAX, arg2b );
   290     POP_r32(arg2a);
   291 }
   293 /* Exception checks - Note that all exception checks will clobber EAX */
   294 static void check_priv( )
   295 {
   296     if( !sh4_x86.priv_checked ) {
   297 	sh4_x86.priv_checked = TRUE;
   298 	load_spreg( R_EAX, R_SR );
   299 	AND_imm32_r32( SR_MD, R_EAX );
   300 	if( sh4_x86.in_delay_slot ) {
   301 	    JE_exit( EXIT_SLOT_ILLEGAL );
   302 	} else {
   303 	    JE_exit( EXIT_ILLEGAL );
   304 	}
   305     }
   306 }
   308 static void check_fpuen( )
   309 {
   310     if( !sh4_x86.fpuen_checked ) {
   311 	sh4_x86.fpuen_checked = TRUE;
   312 	load_spreg( R_EAX, R_SR );
   313 	AND_imm32_r32( SR_FD, R_EAX );
   314 	if( sh4_x86.in_delay_slot ) {
   315 	    JNE_exit(EXIT_SLOT_FPU_DISABLED);
   316 	} else {
   317 	    JNE_exit(EXIT_FPU_DISABLED);
   318 	}
   319     }
   320 }
   322 static void check_ralign16( int x86reg )
   323 {
   324     TEST_imm32_r32( 0x00000001, x86reg );
   325     JNE_exit(EXIT_DATA_ADDR_READ);
   326 }
   328 static void check_walign16( int x86reg )
   329 {
   330     TEST_imm32_r32( 0x00000001, x86reg );
   331     JNE_exit(EXIT_DATA_ADDR_WRITE);
   332 }
   334 static void check_ralign32( int x86reg )
   335 {
   336     TEST_imm32_r32( 0x00000003, x86reg );
   337     JNE_exit(EXIT_DATA_ADDR_READ);
   338 }
   339 static void check_walign32( int x86reg )
   340 {
   341     TEST_imm32_r32( 0x00000003, x86reg );
   342     JNE_exit(EXIT_DATA_ADDR_WRITE);
   343 }
   346 #define UNDEF()
   347 #define MEM_RESULT(value_reg) if(value_reg != R_EAX) { MOV_r32_r32(R_EAX,value_reg); }
   348 #define MEM_READ_BYTE( addr_reg, value_reg ) call_func1(sh4_read_byte, addr_reg ); MEM_RESULT(value_reg)
   349 #define MEM_READ_WORD( addr_reg, value_reg ) call_func1(sh4_read_word, addr_reg ); MEM_RESULT(value_reg)
   350 #define MEM_READ_LONG( addr_reg, value_reg ) call_func1(sh4_read_long, addr_reg ); MEM_RESULT(value_reg)
   351 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_func2(sh4_write_byte, addr_reg, value_reg)
   352 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_func2(sh4_write_word, addr_reg, value_reg)
   353 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_func2(sh4_write_long, addr_reg, value_reg)
   355 #define RAISE_EXCEPTION( exc ) call_func1(sh4_raise_exception, exc);
   356 #define SLOTILLEGAL() RAISE_EXCEPTION(EXC_SLOT_ILLEGAL); return 1
   360 /**
   361  * Emit the 'start of block' assembly. Sets up the stack frame and save
   362  * SI/DI as required
   363  */
   364 void sh4_translate_begin_block() 
   365 {
   366     PUSH_r32(R_EBP);
   367     /* mov &sh4r, ebp */
   368     load_imm32( R_EBP, (uint32_t)&sh4r );
   369     PUSH_r32(R_EDI);
   370     PUSH_r32(R_ESI);
   372     sh4_x86.in_delay_slot = FALSE;
   373     sh4_x86.priv_checked = FALSE;
   374     sh4_x86.fpuen_checked = FALSE;
   375     sh4_x86.backpatch_posn = 0;
   376 }
   378 /**
   379  * Exit the block early (ie branch out), conditionally or otherwise
   380  */
   381 void exit_block( )
   382 {
   383     store_spreg( R_EDI, REG_OFFSET(pc) );
   384     MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
   385     load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   386     MUL_r32( R_ESI );
   387     ADD_r32_r32( R_EAX, R_ECX );
   388     store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   389     XOR_r32_r32( R_EAX, R_EAX );
   390     POP_r32(R_ESI);
   391     POP_r32(R_EDI);
   392     POP_r32(R_EBP);
   393     RET();
   394 }
   396 /**
   397  * Flush any open regs back to memory, restore SI/DI/, update PC, etc
   398  */
   399 void sh4_translate_end_block( sh4addr_t pc ) {
   400     assert( !sh4_x86.in_delay_slot ); // should never stop here
   401     // Normal termination - save PC, cycle count
   402     exit_block( );
   404     uint8_t *end_ptr = xlat_output;
   405     // Exception termination. Jump block for various exception codes:
   406     PUSH_imm32( EXC_DATA_ADDR_READ );
   407     JMP_rel8( 33 );
   408     PUSH_imm32( EXC_DATA_ADDR_WRITE );
   409     JMP_rel8( 26 );
   410     PUSH_imm32( EXC_ILLEGAL );
   411     JMP_rel8( 19 );
   412     PUSH_imm32( EXC_SLOT_ILLEGAL ); 
   413     JMP_rel8( 12 );
   414     PUSH_imm32( EXC_FPU_DISABLED ); 
   415     JMP_rel8( 5 );                 
   416     PUSH_imm32( EXC_SLOT_FPU_DISABLED );
   417     // target
   418     load_spreg( R_ECX, REG_OFFSET(pc) );
   419     ADD_r32_r32( R_ESI, R_ECX );
   420     ADD_r32_r32( R_ESI, R_ECX );
   421     store_spreg( R_ECX, REG_OFFSET(pc) );
   422     MOV_moff32_EAX( (uint32_t)&sh4_cpu_period );
   423     load_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   424     MUL_r32( R_ESI );
   425     ADD_r32_r32( R_EAX, R_ECX );
   426     store_spreg( R_ECX, REG_OFFSET(slice_cycle) );
   428     load_imm32( R_EAX, (uint32_t)sh4_raise_exception ); // 6
   429     CALL_r32( R_EAX ); // 2
   430     POP_r32(R_EBP);
   431     RET();
   433     sh4_x86_do_backpatch( end_ptr );
   434 }
   436 /**
   437  * Translate a single instruction. Delayed branches are handled specially
   438  * by translating both branch and delayed instruction as a single unit (as
   439  * 
   440  *
   441  * @return true if the instruction marks the end of a basic block
   442  * (eg a branch or 
   443  */
   444 uint32_t sh4_x86_translate_instruction( uint32_t pc )
   445 {
   446     uint16_t ir = sh4_read_word( pc );
   448 %%
   449 /* ALU operations */
   450 ADD Rm, Rn {:
   451     load_reg( R_EAX, Rm );
   452     load_reg( R_ECX, Rn );
   453     ADD_r32_r32( R_EAX, R_ECX );
   454     store_reg( R_ECX, Rn );
   455 :}
   456 ADD #imm, Rn {:  
   457     load_reg( R_EAX, Rn );
   458     ADD_imm8s_r32( imm, R_EAX );
   459     store_reg( R_EAX, Rn );
   460 :}
   461 ADDC Rm, Rn {:
   462     load_reg( R_EAX, Rm );
   463     load_reg( R_ECX, Rn );
   464     LDC_t();
   465     ADC_r32_r32( R_EAX, R_ECX );
   466     store_reg( R_ECX, Rn );
   467     SETC_t();
   468 :}
   469 ADDV Rm, Rn {:
   470     load_reg( R_EAX, Rm );
   471     load_reg( R_ECX, Rn );
   472     ADD_r32_r32( R_EAX, R_ECX );
   473     store_reg( R_ECX, Rn );
   474     SETO_t();
   475 :}
   476 AND Rm, Rn {:
   477     load_reg( R_EAX, Rm );
   478     load_reg( R_ECX, Rn );
   479     AND_r32_r32( R_EAX, R_ECX );
   480     store_reg( R_ECX, Rn );
   481 :}
   482 AND #imm, R0 {:  
   483     load_reg( R_EAX, 0 );
   484     AND_imm32_r32(imm, R_EAX); 
   485     store_reg( R_EAX, 0 );
   486 :}
   487 AND.B #imm, @(R0, GBR) {: 
   488     load_reg( R_EAX, 0 );
   489     load_spreg( R_ECX, R_GBR );
   490     ADD_r32_r32( R_EAX, R_ECX );
   491     MEM_READ_BYTE( R_ECX, R_EAX );
   492     AND_imm32_r32(imm, R_ECX );
   493     MEM_WRITE_BYTE( R_ECX, R_EAX );
   494 :}
   495 CMP/EQ Rm, Rn {:  
   496     load_reg( R_EAX, Rm );
   497     load_reg( R_ECX, Rn );
   498     CMP_r32_r32( R_EAX, R_ECX );
   499     SETE_t();
   500 :}
   501 CMP/EQ #imm, R0 {:  
   502     load_reg( R_EAX, 0 );
   503     CMP_imm8s_r32(imm, R_EAX);
   504     SETE_t();
   505 :}
   506 CMP/GE Rm, Rn {:  
   507     load_reg( R_EAX, Rm );
   508     load_reg( R_ECX, Rn );
   509     CMP_r32_r32( R_EAX, R_ECX );
   510     SETGE_t();
   511 :}
   512 CMP/GT Rm, Rn {: 
   513     load_reg( R_EAX, Rm );
   514     load_reg( R_ECX, Rn );
   515     CMP_r32_r32( R_EAX, R_ECX );
   516     SETG_t();
   517 :}
   518 CMP/HI Rm, Rn {:  
   519     load_reg( R_EAX, Rm );
   520     load_reg( R_ECX, Rn );
   521     CMP_r32_r32( R_EAX, R_ECX );
   522     SETA_t();
   523 :}
   524 CMP/HS Rm, Rn {: 
   525     load_reg( R_EAX, Rm );
   526     load_reg( R_ECX, Rn );
   527     CMP_r32_r32( R_EAX, R_ECX );
   528     SETAE_t();
   529  :}
   530 CMP/PL Rn {: 
   531     load_reg( R_EAX, Rn );
   532     CMP_imm8s_r32( 0, R_EAX );
   533     SETG_t();
   534 :}
   535 CMP/PZ Rn {:  
   536     load_reg( R_EAX, Rn );
   537     CMP_imm8s_r32( 0, R_EAX );
   538     SETGE_t();
   539 :}
   540 CMP/STR Rm, Rn {:  
   541     load_reg( R_EAX, Rm );
   542     load_reg( R_ECX, Rn );
   543     XOR_r32_r32( R_ECX, R_EAX );
   544     TEST_r8_r8( R_AL, R_AL );
   545     JE_rel8(13);
   546     TEST_r8_r8( R_AH, R_AH ); // 2
   547     JE_rel8(9);
   548     SHR_imm8_r32( 16, R_EAX ); // 3
   549     TEST_r8_r8( R_AL, R_AL ); // 2
   550     JE_rel8(2);
   551     TEST_r8_r8( R_AH, R_AH ); // 2
   552     SETE_t();
   553 :}
   554 DIV0S Rm, Rn {:
   555     load_reg( R_EAX, Rm );
   556     load_reg( R_ECX, Rm );
   557     SHR_imm8_r32( 31, R_EAX );
   558     SHR_imm8_r32( 31, R_ECX );
   559     store_spreg( R_EAX, R_M );
   560     store_spreg( R_ECX, R_Q );
   561     CMP_r32_r32( R_EAX, R_ECX );
   562     SETE_t();
   563 :}
   564 DIV0U {:  
   565     XOR_r32_r32( R_EAX, R_EAX );
   566     store_spreg( R_EAX, R_Q );
   567     store_spreg( R_EAX, R_M );
   568     store_spreg( R_EAX, R_T );
   569 :}
   570 DIV1 Rm, Rn {:  
   571     load_reg( R_ECX, Rn );
   572     LDC_t();
   573     RCL1_r32( R_ECX ); // OP2
   574     SETC_r32( R_EDX ); // Q
   575     load_spreg( R_EAX, R_Q );
   576     CMP_sh4r_r32( R_M, R_EAX );
   577     JE_rel8(8);
   578     ADD_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
   579     JMP_rel8(3);
   580     SUB_sh4r_r32( REG_OFFSET(r[Rm]), R_ECX );
   581     // TODO
   582 :}
   583 DMULS.L Rm, Rn {:  
   584     load_reg( R_EAX, Rm );
   585     load_reg( R_ECX, Rn );
   586     IMUL_r32(R_ECX);
   587     store_spreg( R_EDX, R_MACH );
   588     store_spreg( R_EAX, R_MACL );
   589 :}
   590 DMULU.L Rm, Rn {:  
   591     load_reg( R_EAX, Rm );
   592     load_reg( R_ECX, Rn );
   593     MUL_r32(R_ECX);
   594     store_spreg( R_EDX, R_MACH );
   595     store_spreg( R_EAX, R_MACL );    
   596 :}
   597 DT Rn {:  
   598     load_reg( R_EAX, Rn );
   599     ADD_imm8s_r32( -1, Rn );
   600     store_reg( R_EAX, Rn );
   601     SETE_t();
   602 :}
   603 EXTS.B Rm, Rn {:  
   604     load_reg( R_EAX, Rm );
   605     MOVSX_r8_r32( R_EAX, R_EAX );
   606     store_reg( R_EAX, Rn );
   607 :}
   608 EXTS.W Rm, Rn {:  
   609     load_reg( R_EAX, Rm );
   610     MOVSX_r16_r32( R_EAX, R_EAX );
   611     store_reg( R_EAX, Rn );
   612 :}
   613 EXTU.B Rm, Rn {:  
   614     load_reg( R_EAX, Rm );
   615     MOVZX_r8_r32( R_EAX, R_EAX );
   616     store_reg( R_EAX, Rn );
   617 :}
   618 EXTU.W Rm, Rn {:  
   619     load_reg( R_EAX, Rm );
   620     MOVZX_r16_r32( R_EAX, R_EAX );
   621     store_reg( R_EAX, Rn );
   622 :}
   623 MAC.L @Rm+, @Rn+ {:  :}
   624 MAC.W @Rm+, @Rn+ {:  :}
   625 MOVT Rn {:  
   626     load_spreg( R_EAX, R_T );
   627     store_reg( R_EAX, Rn );
   628 :}
   629 MUL.L Rm, Rn {:  
   630     load_reg( R_EAX, Rm );
   631     load_reg( R_ECX, Rn );
   632     MUL_r32( R_ECX );
   633     store_spreg( R_EAX, R_MACL );
   634 :}
   635 MULS.W Rm, Rn {:
   636     load_reg16s( R_EAX, Rm );
   637     load_reg16s( R_ECX, Rn );
   638     MUL_r32( R_ECX );
   639     store_spreg( R_EAX, R_MACL );
   640 :}
   641 MULU.W Rm, Rn {:  
   642     load_reg16u( R_EAX, Rm );
   643     load_reg16u( R_ECX, Rn );
   644     MUL_r32( R_ECX );
   645     store_spreg( R_EAX, R_MACL );
   646 :}
   647 NEG Rm, Rn {:
   648     load_reg( R_EAX, Rm );
   649     NEG_r32( R_EAX );
   650     store_reg( R_EAX, Rn );
   651 :}
   652 NEGC Rm, Rn {:  
   653     load_reg( R_EAX, Rm );
   654     XOR_r32_r32( R_ECX, R_ECX );
   655     LDC_t();
   656     SBB_r32_r32( R_EAX, R_ECX );
   657     store_reg( R_ECX, Rn );
   658     SETC_t();
   659 :}
   660 NOT Rm, Rn {:  
   661     load_reg( R_EAX, Rm );
   662     NOT_r32( R_EAX );
   663     store_reg( R_EAX, Rn );
   664 :}
   665 OR Rm, Rn {:  
   666     load_reg( R_EAX, Rm );
   667     load_reg( R_ECX, Rn );
   668     OR_r32_r32( R_EAX, R_ECX );
   669     store_reg( R_ECX, Rn );
   670 :}
   671 OR #imm, R0 {:
   672     load_reg( R_EAX, 0 );
   673     OR_imm32_r32(imm, R_EAX);
   674     store_reg( R_EAX, 0 );
   675 :}
   676 OR.B #imm, @(R0, GBR) {:  
   677     load_reg( R_EAX, 0 );
   678     load_spreg( R_ECX, R_GBR );
   679     ADD_r32_r32( R_EAX, R_ECX );
   680     MEM_READ_BYTE( R_ECX, R_EAX );
   681     OR_imm32_r32(imm, R_ECX );
   682     MEM_WRITE_BYTE( R_ECX, R_EAX );
   683 :}
   684 ROTCL Rn {:
   685     load_reg( R_EAX, Rn );
   686     LDC_t();
   687     RCL1_r32( R_EAX );
   688     store_reg( R_EAX, Rn );
   689     SETC_t();
   690 :}
   691 ROTCR Rn {:  
   692     load_reg( R_EAX, Rn );
   693     LDC_t();
   694     RCR1_r32( R_EAX );
   695     store_reg( R_EAX, Rn );
   696     SETC_t();
   697 :}
   698 ROTL Rn {:  
   699     load_reg( R_EAX, Rn );
   700     ROL1_r32( R_EAX );
   701     store_reg( R_EAX, Rn );
   702     SETC_t();
   703 :}
   704 ROTR Rn {:  
   705     load_reg( R_EAX, Rn );
   706     ROR1_r32( R_EAX );
   707     store_reg( R_EAX, Rn );
   708     SETC_t();
   709 :}
   710 SHAD Rm, Rn {:
   711     /* Annoyingly enough, not directly convertible */
   712     load_reg( R_EAX, Rn );
   713     load_reg( R_ECX, Rm );
   714     CMP_imm32_r32( 0, R_ECX );
   715     JAE_rel8(9);
   717     NEG_r32( R_ECX );      // 2
   718     AND_imm8_r8( 0x1F, R_CL ); // 3
   719     SAR_r32_CL( R_EAX );       // 2
   720     JMP_rel8(5);               // 2
   722     AND_imm8_r8( 0x1F, R_CL ); // 3
   723     SHL_r32_CL( R_EAX );       // 2
   725     store_reg( R_EAX, Rn );
   726 :}
   727 SHLD Rm, Rn {:  
   728     load_reg( R_EAX, Rn );
   729     load_reg( R_ECX, Rm );
   731     MOV_r32_r32( R_EAX, R_EDX );
   732     SHL_r32_CL( R_EAX );
   733     NEG_r32( R_ECX );
   734     SHR_r32_CL( R_EDX );
   735     CMP_imm8s_r32( 0, R_ECX );
   736     CMOVAE_r32_r32( R_EDX,  R_EAX );
   737     store_reg( R_EAX, Rn );
   738 :}
   739 SHAL Rn {: 
   740     load_reg( R_EAX, Rn );
   741     SHL1_r32( R_EAX );
   742     store_reg( R_EAX, Rn );
   743 :}
   744 SHAR Rn {:  
   745     load_reg( R_EAX, Rn );
   746     SAR1_r32( R_EAX );
   747     store_reg( R_EAX, Rn );
   748 :}
   749 SHLL Rn {:  
   750     load_reg( R_EAX, Rn );
   751     SHL1_r32( R_EAX );
   752     store_reg( R_EAX, Rn );
   753 :}
   754 SHLL2 Rn {:
   755     load_reg( R_EAX, Rn );
   756     SHL_imm8_r32( 2, R_EAX );
   757     store_reg( R_EAX, Rn );
   758 :}
   759 SHLL8 Rn {:  
   760     load_reg( R_EAX, Rn );
   761     SHL_imm8_r32( 8, R_EAX );
   762     store_reg( R_EAX, Rn );
   763 :}
   764 SHLL16 Rn {:  
   765     load_reg( R_EAX, Rn );
   766     SHL_imm8_r32( 16, R_EAX );
   767     store_reg( R_EAX, Rn );
   768 :}
   769 SHLR Rn {:  
   770     load_reg( R_EAX, Rn );
   771     SHR1_r32( R_EAX );
   772     store_reg( R_EAX, Rn );
   773 :}
   774 SHLR2 Rn {:  
   775     load_reg( R_EAX, Rn );
   776     SHR_imm8_r32( 2, R_EAX );
   777     store_reg( R_EAX, Rn );
   778 :}
   779 SHLR8 Rn {:  
   780     load_reg( R_EAX, Rn );
   781     SHR_imm8_r32( 8, R_EAX );
   782     store_reg( R_EAX, Rn );
   783 :}
   784 SHLR16 Rn {:  
   785     load_reg( R_EAX, Rn );
   786     SHR_imm8_r32( 16, R_EAX );
   787     store_reg( R_EAX, Rn );
   788 :}
   789 SUB Rm, Rn {:  
   790     load_reg( R_EAX, Rm );
   791     load_reg( R_ECX, Rn );
   792     SUB_r32_r32( R_EAX, R_ECX );
   793     store_reg( R_ECX, Rn );
   794 :}
   795 SUBC Rm, Rn {:  
   796     load_reg( R_EAX, Rm );
   797     load_reg( R_ECX, Rn );
   798     LDC_t();
   799     SBB_r32_r32( R_EAX, R_ECX );
   800     store_reg( R_ECX, Rn );
   801 :}
   802 SUBV Rm, Rn {:  
   803     load_reg( R_EAX, Rm );
   804     load_reg( R_ECX, Rn );
   805     SUB_r32_r32( R_EAX, R_ECX );
   806     store_reg( R_ECX, Rn );
   807     SETO_t();
   808 :}
   809 SWAP.B Rm, Rn {:  
   810     load_reg( R_EAX, Rm );
   811     XCHG_r8_r8( R_AL, R_AH );
   812     store_reg( R_EAX, Rn );
   813 :}
   814 SWAP.W Rm, Rn {:  
   815     load_reg( R_EAX, Rm );
   816     MOV_r32_r32( R_EAX, R_ECX );
   817     SHL_imm8_r32( 16, R_ECX );
   818     SHR_imm8_r32( 16, R_EAX );
   819     OR_r32_r32( R_EAX, R_ECX );
   820     store_reg( R_ECX, Rn );
   821 :}
   822 TAS.B @Rn {:  
   823     load_reg( R_ECX, Rn );
   824     MEM_READ_BYTE( R_ECX, R_EAX );
   825     TEST_r8_r8( R_AL, R_AL );
   826     SETE_t();
   827     OR_imm8_r8( 0x80, R_AL );
   828     MEM_WRITE_BYTE( R_ECX, R_EAX );
   829 :}
   830 TST Rm, Rn {:  
   831     load_reg( R_EAX, Rm );
   832     load_reg( R_ECX, Rn );
   833     TEST_r32_r32( R_EAX, R_ECX );
   834     SETE_t();
   835 :}
   836 TST #imm, R0 {:  
   837     load_reg( R_EAX, 0 );
   838     TEST_imm32_r32( imm, R_EAX );
   839     SETE_t();
   840 :}
   841 TST.B #imm, @(R0, GBR) {:  
   842     load_reg( R_EAX, 0);
   843     load_reg( R_ECX, R_GBR);
   844     ADD_r32_r32( R_EAX, R_ECX );
   845     MEM_READ_BYTE( R_ECX, R_EAX );
   846     TEST_imm8_r8( imm, R_EAX );
   847     SETE_t();
   848 :}
   849 XOR Rm, Rn {:  
   850     load_reg( R_EAX, Rm );
   851     load_reg( R_ECX, Rn );
   852     XOR_r32_r32( R_EAX, R_ECX );
   853     store_reg( R_ECX, Rn );
   854 :}
   855 XOR #imm, R0 {:  
   856     load_reg( R_EAX, 0 );
   857     XOR_imm32_r32( imm, R_EAX );
   858     store_reg( R_EAX, 0 );
   859 :}
   860 XOR.B #imm, @(R0, GBR) {:  
   861     load_reg( R_EAX, 0 );
   862     load_spreg( R_ECX, R_GBR );
   863     ADD_r32_r32( R_EAX, R_ECX );
   864     MEM_READ_BYTE( R_ECX, R_EAX );
   865     XOR_imm32_r32( imm, R_EAX );
   866     MEM_WRITE_BYTE( R_ECX, R_EAX );
   867 :}
   868 XTRCT Rm, Rn {:
   869     load_reg( R_EAX, Rm );
   870     MOV_r32_r32( R_EAX, R_ECX );
   871     SHR_imm8_r32( 16, R_EAX );
   872     SHL_imm8_r32( 16, R_ECX );
   873     OR_r32_r32( R_EAX, R_ECX );
   874     store_reg( R_ECX, Rn );
   875 :}
   877 /* Data move instructions */
   878 MOV Rm, Rn {:  
   879     load_reg( R_EAX, Rm );
   880     store_reg( R_EAX, Rn );
   881 :}
   882 MOV #imm, Rn {:  
   883     load_imm32( R_EAX, imm );
   884     store_reg( R_EAX, Rn );
   885 :}
   886 MOV.B Rm, @Rn {:  
   887     load_reg( R_EAX, Rm );
   888     load_reg( R_ECX, Rn );
   889     MEM_WRITE_BYTE( R_ECX, R_EAX );
   890 :}
   891 MOV.B Rm, @-Rn {:  
   892     load_reg( R_EAX, Rm );
   893     load_reg( R_ECX, Rn );
   894     ADD_imm8s_r32( -1, Rn );
   895     store_reg( R_ECX, Rn );
   896     MEM_WRITE_BYTE( R_ECX, R_EAX );
   897 :}
   898 MOV.B Rm, @(R0, Rn) {:  
   899     load_reg( R_EAX, 0 );
   900     load_reg( R_ECX, Rn );
   901     ADD_r32_r32( R_EAX, R_ECX );
   902     load_reg( R_EAX, Rm );
   903     MEM_WRITE_BYTE( R_ECX, R_EAX );
   904 :}
   905 MOV.B R0, @(disp, GBR) {:  
   906     load_reg( R_EAX, 0 );
   907     load_spreg( R_ECX, R_GBR );
   908     ADD_imm32_r32( disp, R_ECX );
   909     MEM_WRITE_BYTE( R_ECX, R_EAX );
   910 :}
   911 MOV.B R0, @(disp, Rn) {:  
   912     load_reg( R_EAX, 0 );
   913     load_reg( R_ECX, Rn );
   914     ADD_imm32_r32( disp, R_ECX );
   915     MEM_WRITE_BYTE( R_ECX, R_EAX );
   916 :}
   917 MOV.B @Rm, Rn {:  
   918     load_reg( R_ECX, Rm );
   919     MEM_READ_BYTE( R_ECX, R_EAX );
   920     store_reg( R_ECX, Rn );
   921 :}
   922 MOV.B @Rm+, Rn {:  
   923     load_reg( R_ECX, Rm );
   924     MOV_r32_r32( R_ECX, R_EAX );
   925     ADD_imm8s_r32( 1, R_EAX );
   926     store_reg( R_EAX, Rm );
   927     MEM_READ_BYTE( R_ECX, R_EAX );
   928     store_reg( R_EAX, Rn );
   929 :}
   930 MOV.B @(R0, Rm), Rn {:  
   931     load_reg( R_EAX, 0 );
   932     load_reg( R_ECX, Rm );
   933     ADD_r32_r32( R_EAX, R_ECX );
   934     MEM_READ_BYTE( R_ECX, R_EAX );
   935     store_reg( R_EAX, Rn );
   936 :}
   937 MOV.B @(disp, GBR), R0 {:  
   938     load_spreg( R_ECX, R_GBR );
   939     ADD_imm32_r32( disp, R_ECX );
   940     MEM_READ_BYTE( R_ECX, R_EAX );
   941     store_reg( R_EAX, 0 );
   942 :}
   943 MOV.B @(disp, Rm), R0 {:  
   944     load_reg( R_ECX, Rm );
   945     ADD_imm32_r32( disp, R_ECX );
   946     MEM_READ_BYTE( R_ECX, R_EAX );
   947     store_reg( R_EAX, 0 );
   948 :}
   949 MOV.L Rm, @Rn {:
   950     load_reg( R_EAX, Rm );
   951     load_reg( R_ECX, Rn );
   952     check_walign32(R_ECX);
   953     MEM_WRITE_LONG( R_ECX, R_EAX );
   954 :}
   955 MOV.L Rm, @-Rn {:  
   956     load_reg( R_EAX, Rm );
   957     load_reg( R_ECX, Rn );
   958     check_walign32( R_ECX );
   959     ADD_imm8s_r32( -4, R_ECX );
   960     store_reg( R_ECX, Rn );
   961     MEM_WRITE_LONG( R_ECX, R_EAX );
   962 :}
   963 MOV.L Rm, @(R0, Rn) {:  
   964     load_reg( R_EAX, 0 );
   965     load_reg( R_ECX, Rn );
   966     ADD_r32_r32( R_EAX, R_ECX );
   967     check_walign32( R_ECX );
   968     load_reg( R_EAX, Rm );
   969     MEM_WRITE_LONG( R_ECX, R_EAX );
   970 :}
   971 MOV.L R0, @(disp, GBR) {:  
   972     load_spreg( R_ECX, R_GBR );
   973     load_reg( R_EAX, 0 );
   974     ADD_imm32_r32( disp, R_ECX );
   975     check_walign32( R_ECX );
   976     MEM_WRITE_LONG( R_ECX, R_EAX );
   977 :}
   978 MOV.L Rm, @(disp, Rn) {:  
   979     load_reg( R_ECX, Rn );
   980     load_reg( R_EAX, Rm );
   981     ADD_imm32_r32( disp, R_ECX );
   982     check_walign32( R_ECX );
   983     MEM_WRITE_LONG( R_ECX, R_EAX );
   984 :}
   985 MOV.L @Rm, Rn {:  
   986     load_reg( R_ECX, Rm );
   987     check_ralign32( R_ECX );
   988     MEM_READ_LONG( R_ECX, R_EAX );
   989     store_reg( R_EAX, Rn );
   990 :}
   991 MOV.L @Rm+, Rn {:  
   992     load_reg( R_EAX, Rm );
   993     check_ralign32( R_ECX );
   994     MOV_r32_r32( R_EAX, R_ECX );
   995     ADD_imm8s_r32( 4, R_EAX );
   996     store_reg( R_EAX, Rm );
   997     MEM_READ_LONG( R_ECX, R_EAX );
   998     store_reg( R_EAX, Rn );
   999 :}
  1000 MOV.L @(R0, Rm), Rn {:  
  1001     load_reg( R_EAX, 0 );
  1002     load_reg( R_ECX, Rm );
  1003     ADD_r32_r32( R_EAX, R_ECX );
  1004     check_ralign32( R_ECX );
  1005     MEM_READ_LONG( R_ECX, R_EAX );
  1006     store_reg( R_EAX, Rn );
  1007 :}
  1008 MOV.L @(disp, GBR), R0 {:
  1009     load_spreg( R_ECX, R_GBR );
  1010     ADD_imm32_r32( disp, R_ECX );
  1011     check_ralign32( R_ECX );
  1012     MEM_READ_LONG( R_ECX, R_EAX );
  1013     store_reg( R_EAX, 0 );
  1014 :}
  1015 MOV.L @(disp, PC), Rn {:  
  1016     if( sh4_x86.in_delay_slot ) {
  1017 	SLOTILLEGAL();
  1018     } else {
  1019 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1020 	MEM_READ_LONG( R_ECX, R_EAX );
  1021 	store_reg( R_EAX, 0 );
  1023 :}
  1024 MOV.L @(disp, Rm), Rn {:  
  1025     load_reg( R_ECX, Rm );
  1026     ADD_imm8s_r32( disp, R_ECX );
  1027     check_ralign32( R_ECX );
  1028     MEM_READ_LONG( R_ECX, R_EAX );
  1029     store_reg( R_EAX, Rn );
  1030 :}
  1031 MOV.W Rm, @Rn {:  
  1032     load_reg( R_ECX, Rn );
  1033     check_walign16( R_ECX );
  1034     MEM_READ_WORD( R_ECX, R_EAX );
  1035     store_reg( R_EAX, Rn );
  1036 :}
  1037 MOV.W Rm, @-Rn {:  
  1038     load_reg( R_ECX, Rn );
  1039     check_walign16( R_ECX );
  1040     load_reg( R_EAX, Rm );
  1041     ADD_imm8s_r32( -2, R_ECX );
  1042     MEM_WRITE_WORD( R_ECX, R_EAX );
  1043 :}
  1044 MOV.W Rm, @(R0, Rn) {:  
  1045     load_reg( R_EAX, 0 );
  1046     load_reg( R_ECX, Rn );
  1047     ADD_r32_r32( R_EAX, R_ECX );
  1048     check_walign16( R_ECX );
  1049     load_reg( R_EAX, Rm );
  1050     MEM_WRITE_WORD( R_ECX, R_EAX );
  1051 :}
  1052 MOV.W R0, @(disp, GBR) {:  
  1053     load_spreg( R_ECX, R_GBR );
  1054     load_reg( R_EAX, 0 );
  1055     ADD_imm32_r32( disp, R_ECX );
  1056     check_walign16( R_ECX );
  1057     MEM_WRITE_WORD( R_ECX, R_EAX );
  1058 :}
  1059 MOV.W R0, @(disp, Rn) {:  
  1060     load_reg( R_ECX, Rn );
  1061     load_reg( R_EAX, 0 );
  1062     ADD_imm32_r32( disp, R_ECX );
  1063     check_walign16( R_ECX );
  1064     MEM_WRITE_WORD( R_ECX, R_EAX );
  1065 :}
  1066 MOV.W @Rm, Rn {:  
  1067     load_reg( R_ECX, Rm );
  1068     check_ralign16( R_ECX );
  1069     MEM_READ_WORD( R_ECX, R_EAX );
  1070     store_reg( R_EAX, Rn );
  1071 :}
  1072 MOV.W @Rm+, Rn {:  
  1073     load_reg( R_EAX, Rm );
  1074     check_ralign16( R_EAX );
  1075     MOV_r32_r32( R_EAX, R_ECX );
  1076     ADD_imm8s_r32( 2, R_EAX );
  1077     store_reg( R_EAX, Rm );
  1078     MEM_READ_WORD( R_ECX, R_EAX );
  1079     store_reg( R_EAX, Rn );
  1080 :}
  1081 MOV.W @(R0, Rm), Rn {:  
  1082     load_reg( R_EAX, 0 );
  1083     load_reg( R_ECX, Rm );
  1084     ADD_r32_r32( R_EAX, R_ECX );
  1085     check_ralign16( R_ECX );
  1086     MEM_READ_WORD( R_ECX, R_EAX );
  1087     store_reg( R_EAX, Rn );
  1088 :}
  1089 MOV.W @(disp, GBR), R0 {:  
  1090     load_spreg( R_ECX, R_GBR );
  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 MOV.W @(disp, PC), Rn {:  
  1097     if( sh4_x86.in_delay_slot ) {
  1098 	SLOTILLEGAL();
  1099     } else {
  1100 	load_imm32( R_ECX, pc + disp + 4 );
  1101 	MEM_READ_WORD( R_ECX, R_EAX );
  1102 	store_reg( R_EAX, Rn );
  1104 :}
  1105 MOV.W @(disp, Rm), R0 {:  
  1106     load_reg( R_ECX, Rm );
  1107     ADD_imm32_r32( disp, R_ECX );
  1108     check_ralign16( R_ECX );
  1109     MEM_READ_WORD( R_ECX, R_EAX );
  1110     store_reg( R_EAX, 0 );
  1111 :}
  1112 MOVA @(disp, PC), R0 {:  
  1113     if( sh4_x86.in_delay_slot ) {
  1114 	SLOTILLEGAL();
  1115     } else {
  1116 	load_imm32( R_ECX, (pc & 0xFFFFFFFC) + disp + 4 );
  1117 	store_reg( R_ECX, 0 );
  1119 :}
  1120 MOVCA.L R0, @Rn {:  
  1121     load_reg( R_EAX, 0 );
  1122     load_reg( R_ECX, Rn );
  1123     check_walign32( R_ECX );
  1124     MEM_WRITE_LONG( R_ECX, R_EAX );
  1125 :}
  1127 /* Control transfer instructions */
  1128 BF disp {:
  1129     if( sh4_x86.in_delay_slot ) {
  1130 	SLOTILLEGAL();
  1131     } else {
  1132 	load_imm32( R_EDI, pc + 2 );
  1133 	CMP_imm8s_sh4r( 0, R_T );
  1134 	JNE_rel8( 5 );
  1135 	load_imm32( R_EDI, disp + pc + 4 );
  1136 	INC_r32(R_ESI);
  1137 	return 1;
  1139 :}
  1140 BF/S disp {:
  1141     if( sh4_x86.in_delay_slot ) {
  1142 	SLOTILLEGAL();
  1143     } else {
  1144 	load_imm32( R_EDI, pc + 2 );
  1145 	CMP_imm8s_sh4r( 0, R_T );
  1146 	JNE_rel8( 5 );
  1147 	load_imm32( R_EDI, disp + pc + 4 );
  1148 	sh4_x86.in_delay_slot = TRUE;
  1149 	INC_r32(R_ESI);
  1150 	return 0;
  1152 :}
  1153 BRA disp {:  
  1154     if( sh4_x86.in_delay_slot ) {
  1155 	SLOTILLEGAL();
  1156     } else {
  1157 	load_imm32( R_EDI, disp + pc + 4 );
  1158 	sh4_x86.in_delay_slot = TRUE;
  1159 	INC_r32(R_ESI);
  1160 	return 0;
  1162 :}
  1163 BRAF Rn {:  
  1164     if( sh4_x86.in_delay_slot ) {
  1165 	SLOTILLEGAL();
  1166     } else {
  1167 	load_reg( R_EDI, Rn );
  1168 	sh4_x86.in_delay_slot = TRUE;
  1169 	INC_r32(R_ESI);
  1170 	return 0;
  1172 :}
  1173 BSR disp {:  
  1174     if( sh4_x86.in_delay_slot ) {
  1175 	SLOTILLEGAL();
  1176     } else {
  1177 	load_imm32( R_EAX, pc + 4 );
  1178 	store_spreg( R_EAX, R_PR );
  1179 	load_imm32( R_EDI, disp + pc + 4 );
  1180 	sh4_x86.in_delay_slot = TRUE;
  1181 	INC_r32(R_ESI);
  1182 	return 0;
  1184 :}
  1185 BSRF Rn {:  
  1186     if( sh4_x86.in_delay_slot ) {
  1187 	SLOTILLEGAL();
  1188     } else {
  1189 	load_imm32( R_EAX, pc + 4 );
  1190 	store_spreg( R_EAX, R_PR );
  1191 	load_reg( R_EDI, Rn );
  1192 	ADD_r32_r32( R_EAX, R_EDI );
  1193 	sh4_x86.in_delay_slot = TRUE;
  1194 	INC_r32(R_ESI);
  1195 	return 0;
  1197 :}
  1198 BT disp {:
  1199     if( sh4_x86.in_delay_slot ) {
  1200 	SLOTILLEGAL();
  1201     } else {
  1202 	load_imm32( R_EDI, pc + 2 );
  1203 	CMP_imm8s_sh4r( 0, R_T );
  1204 	JE_rel8( 5 );
  1205 	load_imm32( R_EDI, disp + pc + 4 );
  1206 	INC_r32(R_ESI);
  1207 	return 1;
  1209 :}
  1210 BT/S disp {:
  1211     if( sh4_x86.in_delay_slot ) {
  1212 	SLOTILLEGAL();
  1213     } else {
  1214 	load_imm32( R_EDI, pc + 2 );
  1215 	CMP_imm8s_sh4r( 0, R_T );
  1216 	JE_rel8( 5 );
  1217 	load_imm32( R_EDI, disp + pc + 4 );
  1218 	sh4_x86.in_delay_slot = TRUE;
  1219 	INC_r32(R_ESI);
  1220 	return 0;
  1222 :}
  1223 JMP @Rn {:  
  1224     if( sh4_x86.in_delay_slot ) {
  1225 	SLOTILLEGAL();
  1226     } else {
  1227 	load_reg( R_EDI, Rn );
  1228 	sh4_x86.in_delay_slot = TRUE;
  1229 	INC_r32(R_ESI);
  1230 	return 0;
  1232 :}
  1233 JSR @Rn {:  
  1234     if( sh4_x86.in_delay_slot ) {
  1235 	SLOTILLEGAL();
  1236     } else {
  1237 	load_imm32( R_EAX, pc + 4 );
  1238 	store_spreg( R_EAX, R_PR );
  1239 	load_reg( R_EDI, Rn );
  1240 	sh4_x86.in_delay_slot = TRUE;
  1241 	INC_r32(R_ESI);
  1242 	return 0;
  1244 :}
  1245 RTE {:  
  1246     check_priv();
  1247     if( sh4_x86.in_delay_slot ) {
  1248 	SLOTILLEGAL();
  1249     } else {
  1250 	load_spreg( R_EDI, R_PR );
  1251 	load_spreg( R_EAX, R_SSR );
  1252 	call_func1( sh4_write_sr, R_EAX );
  1253 	sh4_x86.in_delay_slot = TRUE;
  1254 	sh4_x86.priv_checked = FALSE;
  1255 	sh4_x86.fpuen_checked = FALSE;
  1256 	INC_r32(R_ESI);
  1257 	return 0;
  1259 :}
  1260 RTS {:  
  1261     if( sh4_x86.in_delay_slot ) {
  1262 	SLOTILLEGAL();
  1263     } else {
  1264 	load_spreg( R_EDI, R_PR );
  1265 	sh4_x86.in_delay_slot = TRUE;
  1266 	INC_r32(R_ESI);
  1267 	return 0;
  1269 :}
  1270 TRAPA #imm {:  
  1271     if( sh4_x86.in_delay_slot ) {
  1272 	SLOTILLEGAL();
  1273     } else {
  1274 	// TODO: Write TRA 
  1275 	RAISE_EXCEPTION(EXC_TRAP);
  1277 :}
  1278 UNDEF {:  
  1279     if( sh4_x86.in_delay_slot ) {
  1280 	RAISE_EXCEPTION(EXC_SLOT_ILLEGAL);
  1281     } else {
  1282 	RAISE_EXCEPTION(EXC_ILLEGAL);
  1284     return 1;
  1285 :}
  1287 CLRMAC {:  
  1288     XOR_r32_r32(R_EAX, R_EAX);
  1289     store_spreg( R_EAX, R_MACL );
  1290     store_spreg( R_EAX, R_MACH );
  1291 :}
  1292 CLRS {:
  1293     CLC();
  1294     SETC_sh4r(R_S);
  1295 :}
  1296 CLRT {:  
  1297     CLC();
  1298     SETC_t();
  1299 :}
  1300 SETS {:  
  1301     STC();
  1302     SETC_sh4r(R_S);
  1303 :}
  1304 SETT {:  
  1305     STC();
  1306     SETC_t();
  1307 :}
  1309 /* Floating point moves */
  1310 FMOV FRm, FRn {:  
  1311     /* As horrible as this looks, it's actually covering 5 separate cases:
  1312      * 1. 32-bit fr-to-fr (PR=0)
  1313      * 2. 64-bit dr-to-dr (PR=1, FRm&1 == 0, FRn&1 == 0 )
  1314      * 3. 64-bit dr-to-xd (PR=1, FRm&1 == 0, FRn&1 == 1 )
  1315      * 4. 64-bit xd-to-dr (PR=1, FRm&1 == 1, FRn&1 == 0 )
  1316      * 5. 64-bit xd-to-xd (PR=1, FRm&1 == 1, FRn&1 == 1 )
  1317      */
  1318     check_fpuen();
  1319     load_spreg( R_ECX, R_FPSCR );
  1320     load_fr_bank( R_EDX );
  1321     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1322     JNE_rel8(8);
  1323     load_fr( R_EDX, R_EAX, FRm ); // PR=0 branch
  1324     store_fr( R_EDX, R_EAX, FRn );
  1325     if( FRm&1 ) {
  1326 	JMP_rel8(22);
  1327 	load_xf_bank( R_ECX ); 
  1328 	load_fr( R_ECX, R_EAX, FRm-1 );
  1329 	if( FRn&1 ) {
  1330 	    load_fr( R_ECX, R_EDX, FRm );
  1331 	    store_fr( R_ECX, R_EAX, FRn-1 );
  1332 	    store_fr( R_ECX, R_EDX, FRn );
  1333 	} else /* FRn&1 == 0 */ {
  1334 	    load_fr( R_ECX, R_ECX, FRm );
  1335 	    store_fr( R_EDX, R_EAX, FRn-1 );
  1336 	    store_fr( R_EDX, R_ECX, FRn );
  1338     } else /* FRm&1 == 0 */ {
  1339 	if( FRn&1 ) {
  1340 	    JMP_rel8(22);
  1341 	    load_xf_bank( R_ECX );
  1342 	    load_fr( R_EDX, R_EAX, FRm );
  1343 	    load_fr( R_EDX, R_EDX, FRm+1 );
  1344 	    store_fr( R_ECX, R_EAX, FRn-1 );
  1345 	    store_fr( R_ECX, R_EDX, FRn );
  1346 	} else /* FRn&1 == 0 */ {
  1347 	    JMP_rel8(12);
  1348 	    load_fr( R_EDX, R_EAX, FRm );
  1349 	    load_fr( R_EDX, R_ECX, FRm+1 );
  1350 	    store_fr( R_EDX, R_EAX, FRn );
  1351 	    store_fr( R_EDX, R_ECX, FRn+1 );
  1354 :}
  1355 FMOV FRm, @Rn {:  
  1356     check_fpuen();
  1357     load_reg( R_EDX, Rn );
  1358     check_walign32( R_EDX );
  1359     load_spreg( R_ECX, R_FPSCR );
  1360     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1361     JNE_rel8(20);
  1362     load_fr_bank( R_ECX );
  1363     load_fr( R_ECX, R_EAX, FRm );
  1364     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1365     if( FRm&1 ) {
  1366 	JMP_rel8( 46 );
  1367 	load_xf_bank( R_ECX );
  1368     } else {
  1369 	JMP_rel8( 39 );
  1370 	load_fr_bank( R_ECX );
  1372     load_fr( R_ECX, R_EAX, FRm&0x0E );
  1373     load_fr( R_ECX, R_ECX, FRm|0x01 );
  1374     MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1375 :}
  1376 FMOV @Rm, FRn {:  
  1377     check_fpuen();
  1378     load_reg( R_EDX, Rm );
  1379     check_ralign32( R_EDX );
  1380     load_spreg( R_ECX, R_FPSCR );
  1381     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1382     JNE_rel8(19);
  1383     MEM_READ_LONG( R_EDX, R_EAX );
  1384     load_fr_bank( R_ECX );
  1385     store_fr( R_ECX, R_EAX, FRn );
  1386     if( FRn&1 ) {
  1387 	JMP_rel8(46);
  1388 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1389 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1390 	load_xf_bank( R_ECX );
  1391     } else {
  1392 	JMP_rel8(36);
  1393 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1394 	load_fr_bank( R_ECX );
  1396     store_fr( R_ECX, R_EAX, FRn&0x0E );
  1397     store_fr( R_ECX, R_EDX, FRn|0x01 );
  1398 :}
  1399 FMOV FRm, @-Rn {:  
  1400     check_fpuen();
  1401     load_reg( R_EDX, Rn );
  1402     check_walign32( R_EDX );
  1403     load_spreg( R_ECX, R_FPSCR );
  1404     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1405     JNE_rel8(20);
  1406     load_fr_bank( R_ECX );
  1407     load_fr( R_ECX, R_EAX, FRm );
  1408     ADD_imm8s_r32(-4,R_EDX);
  1409     store_reg( R_EDX, Rn );
  1410     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1411     if( FRm&1 ) {
  1412 	JMP_rel8( 46 );
  1413 	load_xf_bank( R_ECX );
  1414     } else {
  1415 	JMP_rel8( 39 );
  1416 	load_fr_bank( R_ECX );
  1418     load_fr( R_ECX, R_EAX, FRm&0x0E );
  1419     load_fr( R_ECX, R_ECX, FRm|0x01 );
  1420     ADD_imm8s_r32(-8,R_EDX);
  1421     store_reg( R_EDX, Rn );
  1422     MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1423 :}
  1424 FMOV @Rm+, FRn {:  
  1425     check_fpuen();
  1426     load_reg( R_EDX, Rm );
  1427     check_ralign32( R_EDX );
  1428     MOV_r32_r32( R_EDX, R_EAX );
  1429     load_spreg( R_ECX, R_FPSCR );
  1430     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1431     JNE_rel8(25);
  1432     ADD_imm8s_r32( 4, R_EAX );
  1433     store_reg( R_EAX, Rm );
  1434     MEM_READ_LONG( R_EDX, R_EAX );
  1435     load_fr_bank( R_ECX );
  1436     store_fr( R_ECX, R_EAX, FRn );
  1437     if( FRn&1 ) {
  1438 	JMP_rel8(52);
  1439 	ADD_imm8s_r32( 8, R_EAX );
  1440 	store_reg(R_EAX, Rm);
  1441 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1442 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1443 	load_xf_bank( R_ECX );
  1444     } else {
  1445 	JMP_rel8(42);
  1446 	ADD_imm8s_r32( 8, R_EAX );
  1447 	store_reg(R_EAX, Rm);
  1448 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1449 	load_fr_bank( R_ECX );
  1451     store_fr( R_ECX, R_EAX, FRn&0x0E );
  1452     store_fr( R_ECX, R_EDX, FRn|0x01 );
  1453 :}
  1454 FMOV FRm, @(R0, Rn) {:  
  1455     check_fpuen();
  1456     load_reg( R_EDX, Rn );
  1457     ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
  1458     check_walign32( R_EDX );
  1459     load_spreg( R_ECX, R_FPSCR );
  1460     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1461     JNE_rel8(20);
  1462     load_fr_bank( R_ECX );
  1463     load_fr( R_ECX, R_EAX, FRm );
  1464     MEM_WRITE_LONG( R_EDX, R_EAX ); // 12
  1465     if( FRm&1 ) {
  1466 	JMP_rel8( 46 );
  1467 	load_xf_bank( R_ECX );
  1468     } else {
  1469 	JMP_rel8( 39 );
  1470 	load_fr_bank( R_ECX );
  1472     load_fr( R_ECX, R_EAX, FRm&0x0E );
  1473     load_fr( R_ECX, R_ECX, FRm|0x01 );
  1474     MEM_WRITE_DOUBLE( R_EDX, R_EAX, R_ECX );
  1475 :}
  1476 FMOV @(R0, Rm), FRn {:  
  1477     check_fpuen();
  1478     load_reg( R_EDX, Rm );
  1479     ADD_sh4r_r32( REG_OFFSET(r[0]), R_EDX );
  1480     check_ralign32( R_EDX );
  1481     load_spreg( R_ECX, R_FPSCR );
  1482     TEST_imm32_r32( FPSCR_SZ, R_ECX );
  1483     JNE_rel8(19);
  1484     MEM_READ_LONG( R_EDX, R_EAX );
  1485     load_fr_bank( R_ECX );
  1486     store_fr( R_ECX, R_EAX, FRn );
  1487     if( FRn&1 ) {
  1488 	JMP_rel8(46);
  1489 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1490 	load_spreg( R_ECX, R_FPSCR ); // assume read_long clobbered it
  1491 	load_xf_bank( R_ECX );
  1492     } else {
  1493 	JMP_rel8(36);
  1494 	MEM_READ_DOUBLE( R_EDX, R_EAX, R_EDX );
  1495 	load_fr_bank( R_ECX );
  1497     store_fr( R_ECX, R_EAX, FRn&0x0E );
  1498     store_fr( R_ECX, R_EDX, FRn|0x01 );
  1499 :}
  1500 FLDI0 FRn {:  /* IFF PR=0 */
  1501     check_fpuen();
  1502     load_spreg( R_ECX, R_FPSCR );
  1503     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1504     JNE_rel8(8);
  1505     XOR_r32_r32( R_EAX, R_EAX );
  1506     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1507     store_fr( R_ECX, R_EAX, FRn );
  1508 :}
  1509 FLDI1 FRn {:  /* IFF PR=0 */
  1510     check_fpuen();
  1511     load_spreg( R_ECX, R_FPSCR );
  1512     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1513     JNE_rel8(11);
  1514     load_imm32(R_EAX, 0x3F800000);
  1515     load_spreg( R_ECX, REG_OFFSET(fr_bank) );
  1516     store_fr( R_ECX, R_EAX, FRn );
  1517 :}
  1519 FLOAT FPUL, FRn {:  
  1520     check_fpuen();
  1521     load_spreg( R_ECX, R_FPSCR );
  1522     load_spreg(R_EDX, REG_OFFSET(fr_bank));
  1523     FILD_sh4r(R_FPUL);
  1524     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1525     JNE_rel8(5);
  1526     pop_fr( R_EDX, FRn );
  1527     JMP_rel8(3);
  1528     pop_dr( R_EDX, FRn );
  1529 :}
  1530 FTRC FRm, FPUL {:  
  1531     check_fpuen();
  1532     // TODO
  1533 :}
  1534 FLDS FRm, FPUL {:  
  1535     check_fpuen();
  1536     load_fr_bank( R_ECX );
  1537     load_fr( R_ECX, R_EAX, FRm );
  1538     store_spreg( R_EAX, R_FPUL );
  1539 :}
  1540 FSTS FPUL, FRn {:  
  1541     check_fpuen();
  1542     load_fr_bank( R_ECX );
  1543     load_spreg( R_EAX, R_FPUL );
  1544     store_fr( R_ECX, R_EAX, FRn );
  1545 :}
  1546 FCNVDS FRm, FPUL {:  
  1547     check_fpuen();
  1548     load_spreg( R_ECX, R_FPSCR );
  1549     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1550     JE_rel8(9); // only when PR=1
  1551     load_fr_bank( R_ECX );
  1552     push_dr( R_ECX, FRm );
  1553     pop_fpul();
  1554 :}
  1555 FCNVSD FPUL, FRn {:  
  1556     check_fpuen();
  1557     check_fpuen();
  1558     load_spreg( R_ECX, R_FPSCR );
  1559     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1560     JE_rel8(9); // only when PR=1
  1561     load_fr_bank( R_ECX );
  1562     push_fpul();
  1563     pop_dr( R_ECX, FRn );
  1564 :}
  1566 /* Floating point instructions */
  1567 FABS FRn {:  
  1568     check_fpuen();
  1569     load_spreg( R_ECX, R_FPSCR );
  1570     load_fr_bank( R_EDX );
  1571     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1572     JNE_rel8(10);
  1573     push_fr(R_EDX, FRn); // 3
  1574     FABS_st0(); // 2
  1575     pop_fr( R_EDX, FRn); //3
  1576     JMP_rel8(8); // 2
  1577     push_dr(R_EDX, FRn);
  1578     FABS_st0();
  1579     pop_dr(R_EDX, FRn);
  1580 :}
  1581 FADD FRm, FRn {:  
  1582     check_fpuen();
  1583     load_spreg( R_ECX, R_FPSCR );
  1584     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1585     load_fr_bank( R_EDX );
  1586     JNE_rel8(13);
  1587     push_fr(R_EDX, FRm);
  1588     push_fr(R_EDX, FRn);
  1589     FADDP_st(1);
  1590     pop_fr(R_EDX, FRn);
  1591     JMP_rel8(11);
  1592     push_dr(R_EDX, FRm);
  1593     push_dr(R_EDX, FRn);
  1594     FADDP_st(1);
  1595     pop_dr(R_EDX, FRn);
  1596 :}
  1597 FDIV FRm, FRn {:  
  1598     check_fpuen();
  1599     load_spreg( R_ECX, R_FPSCR );
  1600     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1601     load_fr_bank( R_EDX );
  1602     JNE_rel8(13);
  1603     push_fr(R_EDX, FRn);
  1604     push_fr(R_EDX, FRm);
  1605     FDIVP_st(1);
  1606     pop_fr(R_EDX, FRn);
  1607     JMP_rel8(11);
  1608     push_dr(R_EDX, FRn);
  1609     push_dr(R_EDX, FRm);
  1610     FDIVP_st(1);
  1611     pop_dr(R_EDX, FRn);
  1612 :}
  1613 FMAC FR0, FRm, FRn {:  
  1614     check_fpuen();
  1615     load_spreg( R_ECX, R_FPSCR );
  1616     load_spreg( R_EDX, REG_OFFSET(fr_bank));
  1617     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1618     JNE_rel8(18);
  1619     push_fr( R_EDX, 0 );
  1620     push_fr( R_EDX, FRm );
  1621     FMULP_st(1);
  1622     push_fr( R_EDX, FRn );
  1623     FADDP_st(1);
  1624     pop_fr( R_EDX, FRn );
  1625     JMP_rel8(16);
  1626     push_dr( R_EDX, 0 );
  1627     push_dr( R_EDX, FRm );
  1628     FMULP_st(1);
  1629     push_dr( R_EDX, FRn );
  1630     FADDP_st(1);
  1631     pop_dr( R_EDX, FRn );
  1632 :}
  1634 FMUL FRm, FRn {:  
  1635     check_fpuen();
  1636     load_spreg( R_ECX, R_FPSCR );
  1637     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1638     load_fr_bank( R_EDX );
  1639     JNE_rel8(13);
  1640     push_fr(R_EDX, FRm);
  1641     push_fr(R_EDX, FRn);
  1642     FMULP_st(1);
  1643     pop_fr(R_EDX, FRn);
  1644     JMP_rel8(11);
  1645     push_dr(R_EDX, FRm);
  1646     push_dr(R_EDX, FRn);
  1647     FMULP_st(1);
  1648     pop_dr(R_EDX, FRn);
  1649 :}
  1650 FNEG FRn {:  
  1651     check_fpuen();
  1652     load_spreg( R_ECX, R_FPSCR );
  1653     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1654     load_fr_bank( R_EDX );
  1655     JNE_rel8(10);
  1656     push_fr(R_EDX, FRn);
  1657     FCHS_st0();
  1658     pop_fr(R_EDX, FRn);
  1659     JMP_rel8(8);
  1660     push_dr(R_EDX, FRn);
  1661     FCHS_st0();
  1662     pop_dr(R_EDX, FRn);
  1663 :}
  1664 FSRRA FRn {:  
  1665     check_fpuen();
  1666     load_spreg( R_ECX, R_FPSCR );
  1667     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1668     load_fr_bank( R_EDX );
  1669     JNE_rel8(12); // PR=0 only
  1670     FLD1_st0();
  1671     push_fr(R_EDX, FRn);
  1672     FSQRT_st0();
  1673     FDIVP_st(1);
  1674     pop_fr(R_EDX, FRn);
  1675 :}
  1676 FSQRT FRn {:  
  1677     check_fpuen();
  1678     load_spreg( R_ECX, R_FPSCR );
  1679     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1680     load_fr_bank( R_EDX );
  1681     JNE_rel8(10);
  1682     push_fr(R_EDX, FRn);
  1683     FSQRT_st0();
  1684     pop_fr(R_EDX, FRn);
  1685     JMP_rel8(8);
  1686     push_dr(R_EDX, FRn);
  1687     FSQRT_st0();
  1688     pop_dr(R_EDX, FRn);
  1689 :}
  1690 FSUB FRm, FRn {:  
  1691     check_fpuen();
  1692     load_spreg( R_ECX, R_FPSCR );
  1693     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1694     load_fr_bank( R_EDX );
  1695     JNE_rel8(13);
  1696     push_fr(R_EDX, FRn);
  1697     push_fr(R_EDX, FRm);
  1698     FMULP_st(1);
  1699     pop_fr(R_EDX, FRn);
  1700     JMP_rel8(11);
  1701     push_dr(R_EDX, FRn);
  1702     push_dr(R_EDX, FRm);
  1703     FMULP_st(1);
  1704     pop_dr(R_EDX, FRn);
  1705 :}
  1707 FCMP/EQ FRm, FRn {:  
  1708     check_fpuen();
  1709     load_spreg( R_ECX, R_FPSCR );
  1710     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1711     load_fr_bank( R_EDX );
  1712     JNE_rel8(8);
  1713     push_fr(R_EDX, FRm);
  1714     push_fr(R_EDX, FRn);
  1715     JMP_rel8(6);
  1716     push_dr(R_EDX, FRm);
  1717     push_dr(R_EDX, FRn);
  1718     FCOMIP_st(1);
  1719     SETE_t();
  1720     FPOP_st();
  1721 :}
  1722 FCMP/GT FRm, FRn {:  
  1723     check_fpuen();
  1724     load_spreg( R_ECX, R_FPSCR );
  1725     TEST_imm32_r32( FPSCR_PR, R_ECX );
  1726     load_fr_bank( R_EDX );
  1727     JNE_rel8(8);
  1728     push_fr(R_EDX, FRm);
  1729     push_fr(R_EDX, FRn);
  1730     JMP_rel8(6);
  1731     push_dr(R_EDX, FRm);
  1732     push_dr(R_EDX, FRn);
  1733     FCOMIP_st(1);
  1734     SETA_t();
  1735     FPOP_st();
  1736 :}
  1738 FSCA FPUL, FRn {:  
  1739     check_fpuen();
  1740 :}
  1741 FIPR FVm, FVn {:  
  1742     check_fpuen();
  1743 :}
  1744 FTRV XMTRX, FVn {:  
  1745     check_fpuen();
  1746 :}
  1748 FRCHG {:  
  1749     check_fpuen();
  1750     load_spreg( R_ECX, R_FPSCR );
  1751     XOR_imm32_r32( FPSCR_FR, R_ECX );
  1752     store_spreg( R_ECX, R_FPSCR );
  1754 :}
  1755 FSCHG {:  
  1756     check_fpuen();
  1757     load_spreg( R_ECX, R_FPSCR );
  1758     XOR_imm32_r32( FPSCR_SZ, R_ECX );
  1759     store_spreg( R_ECX, R_FPSCR );
  1760 :}
  1762 /* Processor control instructions */
  1763 LDC Rm, SR {:
  1764     load_reg( R_EAX, Rm );
  1765     call_func1( sh4_write_sr, R_EAX );
  1766     sh4_x86.priv_checked = FALSE;
  1767     sh4_x86.fpuen_checked = FALSE;
  1768 :}
  1769 LDC Rm, GBR {: 
  1770     load_reg( R_EAX, Rm );
  1771     store_spreg( R_EAX, R_GBR );
  1772 :}
  1773 LDC Rm, VBR {:  
  1774     load_reg( R_EAX, Rm );
  1775     store_spreg( R_EAX, R_VBR );
  1776 :}
  1777 LDC Rm, SSR {:  
  1778     load_reg( R_EAX, Rm );
  1779     store_spreg( R_EAX, R_SSR );
  1780 :}
  1781 LDC Rm, SGR {:  
  1782     load_reg( R_EAX, Rm );
  1783     store_spreg( R_EAX, R_SGR );
  1784 :}
  1785 LDC Rm, SPC {:  
  1786     load_reg( R_EAX, Rm );
  1787     store_spreg( R_EAX, R_SPC );
  1788 :}
  1789 LDC Rm, DBR {:  
  1790     load_reg( R_EAX, Rm );
  1791     store_spreg( R_EAX, R_DBR );
  1792 :}
  1793 LDC Rm, Rn_BANK {:  
  1794     load_reg( R_EAX, Rm );
  1795     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  1796 :}
  1797 LDC.L @Rm+, GBR {:  
  1798     load_reg( R_EAX, Rm );
  1799     MOV_r32_r32( R_EAX, R_ECX );
  1800     ADD_imm8s_r32( 4, R_EAX );
  1801     store_reg( R_EAX, Rm );
  1802     MEM_READ_LONG( R_ECX, R_EAX );
  1803     store_spreg( R_EAX, R_GBR );
  1804 :}
  1805 LDC.L @Rm+, SR {:
  1806     load_reg( R_EAX, Rm );
  1807     MOV_r32_r32( R_EAX, R_ECX );
  1808     ADD_imm8s_r32( 4, R_EAX );
  1809     store_reg( R_EAX, Rm );
  1810     MEM_READ_LONG( R_ECX, R_EAX );
  1811     call_func1( sh4_write_sr, R_EAX );
  1812     sh4_x86.priv_checked = FALSE;
  1813     sh4_x86.fpuen_checked = FALSE;
  1814 :}
  1815 LDC.L @Rm+, VBR {:  
  1816     load_reg( R_EAX, Rm );
  1817     MOV_r32_r32( R_EAX, R_ECX );
  1818     ADD_imm8s_r32( 4, R_EAX );
  1819     store_reg( R_EAX, Rm );
  1820     MEM_READ_LONG( R_ECX, R_EAX );
  1821     store_spreg( R_EAX, R_VBR );
  1822 :}
  1823 LDC.L @Rm+, SSR {:
  1824     load_reg( R_EAX, Rm );
  1825     MOV_r32_r32( R_EAX, R_ECX );
  1826     ADD_imm8s_r32( 4, R_EAX );
  1827     store_reg( R_EAX, Rm );
  1828     MEM_READ_LONG( R_ECX, R_EAX );
  1829     store_spreg( R_EAX, R_SSR );
  1830 :}
  1831 LDC.L @Rm+, SGR {:  
  1832     load_reg( R_EAX, Rm );
  1833     MOV_r32_r32( R_EAX, R_ECX );
  1834     ADD_imm8s_r32( 4, R_EAX );
  1835     store_reg( R_EAX, Rm );
  1836     MEM_READ_LONG( R_ECX, R_EAX );
  1837     store_spreg( R_EAX, R_SGR );
  1838 :}
  1839 LDC.L @Rm+, SPC {:  
  1840     load_reg( R_EAX, Rm );
  1841     MOV_r32_r32( R_EAX, R_ECX );
  1842     ADD_imm8s_r32( 4, R_EAX );
  1843     store_reg( R_EAX, Rm );
  1844     MEM_READ_LONG( R_ECX, R_EAX );
  1845     store_spreg( R_EAX, R_SPC );
  1846 :}
  1847 LDC.L @Rm+, DBR {:  
  1848     load_reg( R_EAX, Rm );
  1849     MOV_r32_r32( R_EAX, R_ECX );
  1850     ADD_imm8s_r32( 4, R_EAX );
  1851     store_reg( R_EAX, Rm );
  1852     MEM_READ_LONG( R_ECX, R_EAX );
  1853     store_spreg( R_EAX, R_DBR );
  1854 :}
  1855 LDC.L @Rm+, Rn_BANK {:  
  1856     load_reg( R_EAX, Rm );
  1857     MOV_r32_r32( R_EAX, R_ECX );
  1858     ADD_imm8s_r32( 4, R_EAX );
  1859     store_reg( R_EAX, Rm );
  1860     MEM_READ_LONG( R_ECX, R_EAX );
  1861     store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  1862 :}
  1863 LDS Rm, FPSCR {:  
  1864     load_reg( R_EAX, Rm );
  1865     store_spreg( R_EAX, R_FPSCR );
  1866 :}
  1867 LDS.L @Rm+, FPSCR {:  
  1868     load_reg( R_EAX, Rm );
  1869     MOV_r32_r32( R_EAX, R_ECX );
  1870     ADD_imm8s_r32( 4, R_EAX );
  1871     store_reg( R_EAX, Rm );
  1872     MEM_READ_LONG( R_ECX, R_EAX );
  1873     store_spreg( R_EAX, R_FPSCR );
  1874 :}
  1875 LDS Rm, FPUL {:  
  1876     load_reg( R_EAX, Rm );
  1877     store_spreg( R_EAX, R_FPUL );
  1878 :}
  1879 LDS.L @Rm+, FPUL {:  
  1880     load_reg( R_EAX, Rm );
  1881     MOV_r32_r32( R_EAX, R_ECX );
  1882     ADD_imm8s_r32( 4, R_EAX );
  1883     store_reg( R_EAX, Rm );
  1884     MEM_READ_LONG( R_ECX, R_EAX );
  1885     store_spreg( R_EAX, R_FPUL );
  1886 :}
  1887 LDS Rm, MACH {: 
  1888     load_reg( R_EAX, Rm );
  1889     store_spreg( R_EAX, R_MACH );
  1890 :}
  1891 LDS.L @Rm+, MACH {:  
  1892     load_reg( R_EAX, Rm );
  1893     MOV_r32_r32( R_EAX, R_ECX );
  1894     ADD_imm8s_r32( 4, R_EAX );
  1895     store_reg( R_EAX, Rm );
  1896     MEM_READ_LONG( R_ECX, R_EAX );
  1897     store_spreg( R_EAX, R_MACH );
  1898 :}
  1899 LDS Rm, MACL {:  
  1900     load_reg( R_EAX, Rm );
  1901     store_spreg( R_EAX, R_MACL );
  1902 :}
  1903 LDS.L @Rm+, MACL {:  
  1904     load_reg( R_EAX, Rm );
  1905     MOV_r32_r32( R_EAX, R_ECX );
  1906     ADD_imm8s_r32( 4, R_EAX );
  1907     store_reg( R_EAX, Rm );
  1908     MEM_READ_LONG( R_ECX, R_EAX );
  1909     store_spreg( R_EAX, R_MACL );
  1910 :}
  1911 LDS Rm, PR {:  
  1912     load_reg( R_EAX, Rm );
  1913     store_spreg( R_EAX, R_PR );
  1914 :}
  1915 LDS.L @Rm+, PR {:  
  1916     load_reg( R_EAX, Rm );
  1917     MOV_r32_r32( R_EAX, R_ECX );
  1918     ADD_imm8s_r32( 4, R_EAX );
  1919     store_reg( R_EAX, Rm );
  1920     MEM_READ_LONG( R_ECX, R_EAX );
  1921     store_spreg( R_EAX, R_PR );
  1922 :}
  1923 LDTLB {:  :}
  1924 OCBI @Rn {:  :}
  1925 OCBP @Rn {:  :}
  1926 OCBWB @Rn {:  :}
  1927 PREF @Rn {:
  1928     load_reg( R_EAX, Rn );
  1929     PUSH_r32( R_EAX );
  1930     AND_imm32_r32( 0xFC000000, R_EAX );
  1931     CMP_imm32_r32( 0xE0000000, R_EAX );
  1932     JNE_rel8(8);
  1933     call_func0( sh4_flush_store_queue );
  1934     ADD_imm8s_r32( 4, R_ESP );
  1935 :}
  1936  SLEEP {: /* TODO */ :}
  1937  STC SR, Rn {:
  1938      call_func0(sh4_read_sr);
  1939      store_reg( R_EAX, Rn );
  1940 :}
  1941 STC GBR, Rn {:  
  1942     load_spreg( R_EAX, R_GBR );
  1943     store_reg( R_EAX, Rn );
  1944 :}
  1945 STC VBR, Rn {:  
  1946     load_spreg( R_EAX, R_VBR );
  1947     store_reg( R_EAX, Rn );
  1948 :}
  1949 STC SSR, Rn {:  
  1950     load_spreg( R_EAX, R_SSR );
  1951     store_reg( R_EAX, Rn );
  1952 :}
  1953 STC SPC, Rn {:  
  1954     load_spreg( R_EAX, R_SPC );
  1955     store_reg( R_EAX, Rn );
  1956 :}
  1957 STC SGR, Rn {:  
  1958     load_spreg( R_EAX, R_SGR );
  1959     store_reg( R_EAX, Rn );
  1960 :}
  1961 STC DBR, Rn {:  
  1962     load_spreg( R_EAX, R_DBR );
  1963     store_reg( R_EAX, Rn );
  1964 :}
  1965 STC Rm_BANK, Rn {:
  1966     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  1967     store_reg( R_EAX, Rn );
  1968 :}
  1969 STC.L SR, @-Rn {:
  1970     load_reg( R_ECX, Rn );
  1971     ADD_imm8s_r32( -4, Rn );
  1972     store_reg( R_ECX, Rn );
  1973     call_func0( sh4_read_sr );
  1974     MEM_WRITE_LONG( R_ECX, R_EAX );
  1975 :}
  1976 STC.L VBR, @-Rn {:  
  1977     load_reg( R_ECX, Rn );
  1978     ADD_imm8s_r32( -4, Rn );
  1979     store_reg( R_ECX, Rn );
  1980     load_spreg( R_EAX, R_VBR );
  1981     MEM_WRITE_LONG( R_ECX, R_EAX );
  1982 :}
  1983 STC.L SSR, @-Rn {:  
  1984     load_reg( R_ECX, Rn );
  1985     ADD_imm8s_r32( -4, Rn );
  1986     store_reg( R_ECX, Rn );
  1987     load_spreg( R_EAX, R_SSR );
  1988     MEM_WRITE_LONG( R_ECX, R_EAX );
  1989 :}
  1990 STC.L SPC, @-Rn {:  
  1991     load_reg( R_ECX, Rn );
  1992     ADD_imm8s_r32( -4, Rn );
  1993     store_reg( R_ECX, Rn );
  1994     load_spreg( R_EAX, R_SPC );
  1995     MEM_WRITE_LONG( R_ECX, R_EAX );
  1996 :}
  1997 STC.L SGR, @-Rn {:  
  1998     load_reg( R_ECX, Rn );
  1999     ADD_imm8s_r32( -4, Rn );
  2000     store_reg( R_ECX, Rn );
  2001     load_spreg( R_EAX, R_SGR );
  2002     MEM_WRITE_LONG( R_ECX, R_EAX );
  2003 :}
  2004 STC.L DBR, @-Rn {:  
  2005     load_reg( R_ECX, Rn );
  2006     ADD_imm8s_r32( -4, Rn );
  2007     store_reg( R_ECX, Rn );
  2008     load_spreg( R_EAX, R_DBR );
  2009     MEM_WRITE_LONG( R_ECX, R_EAX );
  2010 :}
  2011 STC.L Rm_BANK, @-Rn {:  
  2012     load_reg( R_ECX, Rn );
  2013     ADD_imm8s_r32( -4, Rn );
  2014     store_reg( R_ECX, Rn );
  2015     load_spreg( R_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
  2016     MEM_WRITE_LONG( R_ECX, R_EAX );
  2017 :}
  2018 STC.L GBR, @-Rn {:  
  2019     load_reg( R_ECX, Rn );
  2020     ADD_imm8s_r32( -4, Rn );
  2021     store_reg( R_ECX, Rn );
  2022     load_spreg( R_EAX, R_GBR );
  2023     MEM_WRITE_LONG( R_ECX, R_EAX );
  2024 :}
  2025 STS FPSCR, Rn {:  
  2026     load_spreg( R_EAX, R_FPSCR );
  2027     store_reg( R_EAX, Rn );
  2028 :}
  2029 STS.L FPSCR, @-Rn {:  
  2030     load_reg( R_ECX, Rn );
  2031     ADD_imm8s_r32( -4, Rn );
  2032     store_reg( R_ECX, Rn );
  2033     load_spreg( R_EAX, R_FPSCR );
  2034     MEM_WRITE_LONG( R_ECX, R_EAX );
  2035 :}
  2036 STS FPUL, Rn {:  
  2037     load_spreg( R_EAX, R_FPUL );
  2038     store_reg( R_EAX, Rn );
  2039 :}
  2040 STS.L FPUL, @-Rn {:  
  2041     load_reg( R_ECX, Rn );
  2042     ADD_imm8s_r32( -4, Rn );
  2043     store_reg( R_ECX, Rn );
  2044     load_spreg( R_EAX, R_FPUL );
  2045     MEM_WRITE_LONG( R_ECX, R_EAX );
  2046 :}
  2047 STS MACH, Rn {:  
  2048     load_spreg( R_EAX, R_MACH );
  2049     store_reg( R_EAX, Rn );
  2050 :}
  2051 STS.L MACH, @-Rn {:  
  2052     load_reg( R_ECX, Rn );
  2053     ADD_imm8s_r32( -4, Rn );
  2054     store_reg( R_ECX, Rn );
  2055     load_spreg( R_EAX, R_MACH );
  2056     MEM_WRITE_LONG( R_ECX, R_EAX );
  2057 :}
  2058 STS MACL, Rn {:  
  2059     load_spreg( R_EAX, R_MACL );
  2060     store_reg( R_EAX, Rn );
  2061 :}
  2062 STS.L MACL, @-Rn {:  
  2063     load_reg( R_ECX, Rn );
  2064     ADD_imm8s_r32( -4, Rn );
  2065     store_reg( R_ECX, Rn );
  2066     load_spreg( R_EAX, R_MACL );
  2067     MEM_WRITE_LONG( R_ECX, R_EAX );
  2068 :}
  2069 STS PR, Rn {:  
  2070     load_spreg( R_EAX, R_PR );
  2071     store_reg( R_EAX, Rn );
  2072 :}
  2073 STS.L PR, @-Rn {:  
  2074     load_reg( R_ECX, Rn );
  2075     ADD_imm8s_r32( -4, Rn );
  2076     store_reg( R_ECX, Rn );
  2077     load_spreg( R_EAX, R_PR );
  2078     MEM_WRITE_LONG( R_ECX, R_EAX );
  2079 :}
  2081 NOP {: /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ :}
  2082 %%
  2083     INC_r32(R_ESI);
  2084     if( sh4_x86.in_delay_slot ) {
  2085 	sh4_x86.in_delay_slot = FALSE;
  2086 	return 1;
  2088     return 0;
.