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