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