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