Search
lxdream.org :: lxdream/src/sh4/sh4xir.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4xir.in
changeset 1012:0b8cc74ac83a
prev1011:fdd58619b760
author nkeynes
date Sun Apr 19 05:14:19 2009 +0000 (15 years ago)
branchxlat-refactor
permissions -rw-r--r--
last change Remove branch instructions and replace with direct modification of PC + EXIT
Add MIN/MAX instructions (for bound checks)
Implement x86_target_is_legal
Correct a few sh4 instructions
view annotate diff log raw
     1 /**
     2  * $Id: sh4xir.in 931 2008-10-31 02:57:59Z nkeynes $
     3  * 
     4  * SH4 => IR conversion.
     5  *
     6  * Copyright (c) 2009 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #include <assert.h>
    21 #include "sh4/sh4core.h"
    22 #include "sh4/mmu.h"
    23 #include "sh4/sh4xir.h"
    24 #include "xlat/xlat.h"
    25 #include "clock.h"
    27 #define REG_OFFSET(reg)  (offsetof( struct sh4_registers, reg))
    29 #define R_R(rn) REG_OFFSET(r[rn])
    30 #define R_R0  R_R(0)
    31 #define R_SR  REG_OFFSET(sr)
    32 #define R_PR  REG_OFFSET(pr)
    33 #define R_PC  REG_OFFSET(pc)
    34 #define R_FPUL REG_OFFSET(fpul)
    35 #define R_T   REG_OFFSET(t)
    36 #define R_M   REG_OFFSET(m)
    37 #define R_Q   REG_OFFSET(q)
    38 #define R_S   REG_OFFSET(s)
    39 #define R_FR(frn) REG_OFFSET(fr[0][(frn)^1])
    40 #define R_DR(frn) REG_OFFSET(fr[0][(frn)&0x0E])
    41 #define R_DRL(f) REG_OFFSET(fr[(f)&1][(f)|0x01])
    42 #define R_DRH(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])
    43 #define R_XF(frn) REG_OFFSET(fr[1][(frn)^1])
    44 #define R_XD(frn) REG_OFFSET(fr[1][(frn)&0x0E])
    45 #define R_FV(fvn) REG_OFFSET(fr[0][fvn<<2])
    46 #define R_XMTRX R_XD(0)
    47 #define R_FPSCR REG_OFFSET(fpscr)
    48 #define R_MAC  REG_OFFSET(mac)
    49 #define R_MACL REG_OFFSET(mac)
    50 #define R_MACH REG_OFFSET(mac)+4
    51 #define R_GBR REG_OFFSET(gbr)
    52 #define R_SSR REG_OFFSET(ssr)
    53 #define R_SPC REG_OFFSET(spc)
    54 #define R_SGR REG_OFFSET(sgr)
    55 #define R_DBR REG_OFFSET(dbr)
    56 #define R_VBR REG_OFFSET(vbr)
    57 #define R_BANK(rn) REG_OFFSET(r_bank[rn])
    58 #define R_NEW_PC REG_OFFSET(new_pc)
    59 #define R_DELAY_SLOT REG_OFFSET(in_delay_slot)
    60 #define R_SLICE_CYCLE REG_OFFSET(slice_cycle)
    61 #define R_SH4_MODE REG_OFFSET(xlat_sh4_mode)
    63 uint32_t sh4_decode_basic_block(xir_basic_block_t xbb);
    65 static const char *sh4_register_names[] = 
    66     {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    67      "sr", "pr", "pc", "fpul", "T", "M", "Q", "S", 
    68      "fr1", "fr0", "fr3", "fr2", "fr5", "fr4", "fr7", "fr6", "fr9", "fr8", "fr11", "fr10", "fr13", "fr11", "fr15", "fr14",
    69      "xf1", "xf0", "xf3", "xf2", "xf5", "xf4", "xf7", "xf6", "xf9", "xf8", "xf11", "xf10", "xf13", "xf11", "xf15", "xf14",
    70      "fpscr", 0, "macl", "mach", "gbr", "ssr", "spc", "sgr", "dbr", "vbr",
    71      "r_bank0", "r_bank1", "r_bank2", "r_bank3", "r_bank4", "r_bank5", "r_bank6", "r_bank7",
    72      "store_queue", 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,  0, 0, 0, 0,
    73      "new_pc", "event_pending", "event_type", "delay_slot", "slice_cycle", "bus_cycle", "state", "xlat_mode" }; 
    75 static const char *sh4_quad_register_names[] = /* From FR1 to MACH */ 
    76     {"dr0", "dr2", "dr4", "dr6", "dr8", "dr10", "dr12", "dr14",
    77      "xd0", "xd2", "xd4", "xd6", "xd8", "xd10", "xd12", "xd14",
    78      NULL, "mac" };
    79 static const char *sh4_vec4_register_names[] = /* From FR1 to XF14 */
    80     {"fv0", "fv4", "fv8", "fv12", "xfv0", "xfv4", "xfv8", "xfv12" };
    82 static const char *sh4_get_register_name( uint32_t reg, xir_type_t ty )
    83 {
    84     switch( ty ) {
    85     case XTY_LONG:
    86     case XTY_FLOAT:
    87         if( reg <= R_SH4_MODE ) {
    88             return sh4_register_names[reg>>2];
    89         }
    90         break;
    91     case XTY_QUAD:
    92     case XTY_DOUBLE:
    93         if( reg >= R_DR(0) && reg <= R_MACH ) {
    94             return sh4_quad_register_names[(reg-R_DR(0))>>3];
    95         }
    96         break;
    97     case XTY_VEC4F:
    98         if( reg >= R_DR(0) && reg <= R_XD(14) ) {
    99             return sh4_vec4_register_names[(reg-R_DR(0))>>4];
   100         }
   101         break;
   102     case XTY_MAT16F:         
   103 	if( reg = R_XMTRX ) {
   104 	    return "xmtrx";
   105 	} else if( reg == R_DR(0) ) {
   106 	    return "mtrx";
   107 	}
   108     }
   109     return NULL;
   110 }
   112 struct xlat_source_machine sh4_source_machine = { "SH4", &sh4r, 
   113     R_PC, R_NEW_PC, R_T, R_M, R_Q, R_S,
   114     sh4_get_register_name, 
   115     sh4_decode_basic_block  };   
   117  /** 
   118  * Struct to manage internal translation state. This state is not saved -
   119  * it is only valid between calls to sh4_translate_begin_block() and
   120  * sh4_translate_end_block()
   121  */
   122 struct sh4_xir_state {
   123     gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
   124     gboolean double_prec; /* true if FPU is in double-precision mode */
   125     gboolean double_size; /* true if FPU is in double-size mode */
   126 };
   128 static struct sh4_xir_state sh4_xir;
   130 /**
   131  * Create a standard exception-taking stub sub-block - updates SPC, slice_cycle, and exits
   132  * @return the first xir_op_t of the exception block. 
   133  */ 
   134 static inline xir_op_t write_exc( xir_basic_block_t xbb, sh4addr_t pc, int exc_code )
   135 {
   136 	xir_op_t start = xbb->ir_ptr;
   137 	XOPCALL1I( sh4_raise_exception, exc_code );
   138 	if( pc != xbb->pc_begin ) {
   139 	    XOP2IS( OP_ADD, pc - xbb->pc_begin, R_SPC );
   140 	}
   141 	XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
   142 	XOP0( OP_EXIT )->next = NULL;
   143 	start->prev = NULL;
   144 	return start;
   145 }
   147 /**
   148  * Create an instruction with a standard post-exception stub sub-block (ie 
   149  * sh4_raise_exception or similar has already been called - update SPC + 
   150  * slice_cycle and exit).
   151  * @return the first xir_op_t of the exception block. 
   152  */ 
   153 static xir_op_t xir_append_op2_exc( xir_basic_block_t xbb, int op, int arg0form, uint32_t arg0, int arg1form, uint32_t arg1, sh4addr_t pc )
   154 {
   155     xir_op_t ins = xir_append_op2( xbb, op, arg0form, arg0, arg1form, arg1 );
   156     ins->exc = xbb->ir_ptr;
   157     ins->exc->prev = ins;
   159     if( pc != xbb->pc_begin ) {
   160         XOP2IS( OP_ADD, pc - xbb->pc_begin, R_SPC );
   161     }
   162     XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
   163     XOP0( OP_EXIT )->next = NULL;
   165     ins->next = xbb->ir_ptr;
   166     xbb->ir_ptr->prev = ins;
   167     return ins;
   168 }
   170 #define XOP1SE( op, arg0 ) xir_append_op2_exc( xbb, op, SOURCE_OPERAND, arg0, NO_OPERAND, 0, (in_delay_slot ? pc-2 : pc))
   171 #define XOP1TE( op, arg0 ) xir_append_op2_exc( xbb, op, TEMP_OPERAND, arg0, NO_OPERAND, 0, (in_delay_slot ? pc-2 : pc))
   172 #define XOP2SSE( op, arg0, arg1 ) xir_append_op2_exc( xbb, op, SOURCE_OPERAND, arg0, SOURCE_OPERAND, arg1, (in_delay_slot ? pc-2 : pc))
   173 #define XOP2STE( op, arg0, arg1 ) xir_append_op2_exc( xbb, op, SOURCE_OPERAND, arg0, TEMP_OPERAND, arg1, (in_delay_slot ? pc-2 : pc))
   174 #define XOP2TSE( op, arg0, arg1 ) xir_append_op2_exc( xbb, op, TEMP_OPERAND, arg0, SOURCE_OPERAND, arg1, (in_delay_slot ? pc-2 : pc))
   175 #define XOP2TTE( op, arg0, arg1 ) xir_append_op2_exc( xbb, op, TEMP_OPERAND, arg0, TEMP_OPERAND, arg1, (in_delay_slot ? pc-2 : pc))
   177 #define ALIGN(m,r,code) do { \
   178 	xir_op_t ins = xir_append_op2(xbb, OP_RAISEMNE, IMMEDIATE_OPERAND, m, SOURCE_OPERAND, r); \
   179 	ins->exc = write_exc(xbb, (in_delay_slot ? pc-2 : pc), code); \
   180 	ins->exc->prev = ins; \
   181 	ins->next = xbb->ir_ptr; \
   182 	xbb->ir_ptr->prev = ins; \
   183     } while(0)
   185 #define SLOTILLEGAL() write_exc(xbb, pc, EXC_SLOT_ILLEGAL)
   186 #define ILLEGAL() write_exc(xbb, pc, EXC_ILLEGAL)
   188 #define UNDEF(ir) if( in_delay_slot ) { SLOTILLEGAL(); return 2; } else { ILLEGAL(); return 2; } 
   189 #define CHECKFPUEN() if( !sh4_xir.fpuen_checked ) { \
   190 	xir_op_t ins = XOP2IS( OP_RAISEMNE, SR_FD, R_SR ); \
   191 	if( in_delay_slot ) { \
   192 	    ins->exc = write_exc(xbb, pc-2, EXC_SLOT_FPU_DISABLED); \
   193 	} else { \
   194 	    ins->exc = write_exc(xbb, pc, EXC_FPU_DISABLED); \
   195 	} \
   196 	ins->exc->prev = ins; \
   197 	ins->next = xbb->ir_ptr; \
   198 	xbb->ir_ptr->prev = ins; \
   199 	sh4_xir.fpuen_checked = TRUE; \
   200     }
   201 #define CHECKPRIV()  if( (sh4r.xlat_sh4_mode & SR_MD) == 0 ) { UNDEF(ir); }
   203 #define RALIGN16(r) ALIGN(0x01,r,EXC_DATA_ADDR_READ)
   204 #define RALIGN32(r) ALIGN(0x03,r,EXC_DATA_ADDR_READ)
   205 #define RALIGN64(r) ALIGN(0x07,r,EXC_DATA_ADDR_READ)
   206 #define WALIGN16(r) ALIGN(0x01,r,EXC_DATA_ADDR_WRITE)
   207 #define WALIGN32(r) ALIGN(0x03,r,EXC_DATA_ADDR_WRITE)
   208 #define WALIGN64(r) ALIGN(0x07,r,EXC_DATA_ADDR_WRITE)
   210 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
   212 #define EMU_DELAY_SLOT() do { \
   213     	XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin), R_PC ); \
   214 	XOP2IS( OP_MOV, 1, R_DELAY_SLOT ); \
   215 	XOP0( OP_BARRIER ); \
   216 	XOPCALL0( sh4_execute_instruction ); \
   217 	XOP0( OP_EXIT ); \
   218     } while(0)
   221 static sh4addr_t sh4_decode_instruction( xir_basic_block_t xbb, sh4addr_t pc, gboolean in_delay_slot )
   222 {
   223     assert( IS_IN_ICACHE(pc) );
   224     uint16_t ir = *(uint16_t *)GET_ICACHE_PTR(pc);
   226 %%
   227 ADD Rm, Rn   {: XOP2SS( OP_ADD, R_R(Rm), R_R(Rn) ); :} 
   228 ADD #imm, Rn {: XOP2IS( OP_ADD, imm, R_R(Rn) ); :}
   229 ADDC Rm, Rn  {:
   230 	XOP1SCC( OP_LD, CC_C, R_T ); 
   231 	XOP2SS( OP_ADDCS, R_R(Rm), R_R(Rn) ); 
   232 	XOP1SCC( OP_ST, CC_C, R_T ); 
   233 :} 
   234 ADDV Rm, Rn  {: XOP2SS( OP_ADDS, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_OV, R_T ); :}
   235 AND Rm, Rn   {: XOP2SS( OP_AND, R_R(Rm), R_R(Rn) ); :}
   236 AND #imm, R0 {: XOP2IS( OP_AND, imm, R_R0 ); :}
   237 CMP/EQ Rm, Rn   {: XOP2SS( OP_CMP, Rm, R_R(Rn) ); XOP1SCC( OP_ST, CC_EQ, R_T ); :}
   238 CMP/EQ #imm, R0 {: XOP2IS( OP_CMP, imm, R_R0 ); XOP1SCC( OP_ST, CC_EQ, R_T ); :}
   239 CMP/GE Rm, Rn   {: XOP2SS( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_SGE, R_T ); :}
   240 CMP/GT Rm, Rn   {: XOP2SS( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_SGT, R_T ); :}
   241 CMP/HI Rm, Rn   {: XOP2SS( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_UGT, R_T ); :}
   242 CMP/HS Rm, Rn   {: XOP2SS( OP_CMP, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_UGE, R_T ); :}
   243 CMP/PL Rn       {: XOP2IS( OP_CMP, 0, R_R(Rn) ); XOP1SCC( OP_ST, CC_SGT, R_T ); :}
   244 CMP/PZ Rn       {: XOP2IS( OP_CMP, 0, R_R(Rn) ); XOP1SCC( OP_ST, CC_SGE, R_T ); :}
   245 CMP/STR Rm, Rn  {: XOP2SS( OP_CMPSTR, R_R(Rm), R_R(Rn) ); :}
   246 DIV0S Rm, Rn    {:
   247         XOP2SS( OP_MOV, R_R(Rm), R_M );
   248         XOP2IS( OP_SLR, 31, R_M );
   249         XOP2SS( OP_MOV, R_R(Rn), R_Q );
   250         XOP2IS( OP_SLR, 31, R_Q );
   251         XOP2SS( OP_CMP, R_M, R_Q );
   252         XOP1SCC( OP_ST, CC_NE, R_T ); 
   253 :}
   254 DIV0U           {:
   255 	XOP2IS( OP_MOV, 0, R_M );
   256 	XOP2IS( OP_MOV, 0, R_Q );
   257 	XOP2IS( OP_MOV, 0, R_T );
   258 :}
   259 DIV1 Rm, Rn     {: XOP2SS( OP_DIV1, R_R(Rm), R_R(Rn) ); :}
   260 DMULS.L Rm, Rn  {:
   261 	XOP2SS( OP_MOVSX32, R_R(Rm), R_MAC );
   262 	XOP2ST( OP_MOVSX32, R_R(Rn), REG_TMP0 );
   263 	XOP2TS( OP_MULQ, REG_TMPQ0, R_MAC );
   264 :}
   265 DMULU.L Rm, Rn  {:
   266 	XOP2SS( OP_MOVZX32, R_R(Rm), R_MAC );
   267 	XOP2ST( OP_MOVZX32, R_R(Rn), REG_TMP0 ) ;
   268 	XOP2TS( OP_MULQ, REG_TMP0, R_MAC ); 
   269 :}
   270 DT Rn {: XOP1S( OP_DEC, R_R(Rn) ); :}
   271 EXTS.B Rm, Rn   {: XOP2SS( OP_MOVSX8, R_R(Rm), R_R(Rn)); :}
   272 EXTS.W Rm, Rn   {: XOP2SS( OP_MOVSX16, R_R(Rm), R_R(Rn)); :}
   273 EXTU.B Rm, Rn   {: XOP2SS( OP_MOVZX8, R_R(Rm), R_R(Rn)); :}
   274 EXTU.W Rm, Rn   {: XOP2SS( OP_MOVZX16, R_R(Rm), R_R(Rn)); :}
   275 MAC.L @Rm+, @Rn+ {:
   276 	RALIGN32(R_R(Rm));
   277 	if( Rm == Rn ) {
   278 	    XOP2STE( OP_LOADL, R_R(Rm), REG_TMP0 );
   279 	    XOP2ST( OP_MOV, R_R(Rm), REG_TMP1 );
   280 	    XOP2IT( OP_ADD, 4, REG_TMP1 );
   281 	    XOP2TTE( OP_LOADL, REG_TMP1, REG_TMP1 );
   282 	    XOP2IS( OP_ADD, 8, R_R(Rm) );
   283 	} else {
   284 	    RALIGN32(R_R(Rn));
   285 	    XOP2STE( OP_LOADL, R_R(Rm), REG_TMP0 );
   286 	    XOP2STE( OP_LOADL, R_R(Rn), REG_TMP1 );
   287 	    XOP2IS( OP_ADD, 4, R_R(Rm) );
   288 	    XOP2IS( OP_ADD, 4, R_R(Rn) );
   289 	}
   290 	XOP2TT( OP_MOVSX32, REG_TMP0, REG_TMPQ0 );
   291 	XOP2TT( OP_MOVSX32, REG_TMP1, REG_TMPQ1 );
   292 	XOP2TT( OP_MULQ, REG_TMPQ0, REG_TMPQ1 );
   293 	XOP2TS( OP_ADDQSAT48, REG_TMPQ1, R_MAC );
   294 :}
   295 MAC.W @Rm+, @Rn+ {:
   296 	RALIGN32(R_R(Rm)); 
   297 	if( Rm == Rn ) {
   298 	    XOP2STE( OP_LOADW, R_R(Rm), REG_TMP0 );
   299 	    XOP2ST( OP_MOV, R_R(Rm), REG_TMP1 );
   300 	    XOP2IT( OP_ADD, 2, REG_TMP1 );
   301 	    XOP2TTE( OP_LOADW, REG_TMP1, REG_TMP1 );
   302 	    XOP2IS( OP_ADD, 4, R_R(Rm) );
   303 	} else {
   304 	    RALIGN32(Rn);
   305 	    XOP2STE( OP_LOADW, R_R(Rm), REG_TMP0 );
   306 	    XOP2STE( OP_LOADW, R_R(Rn), REG_TMP1 );
   307 	    XOP2IS( OP_ADD, 2, R_R(Rm) );
   308 	    XOP2IS( OP_ADD, 2, R_R(Rn) );
   309 	}
   310 	XOP2TT( OP_MOVSX32, REG_TMP0, REG_TMPQ0 );
   311 	XOP2TT( OP_MOVSX32, REG_TMP1, REG_TMPQ1 );
   312 	XOP2TT( OP_MULQ, REG_TMPQ0, REG_TMPQ1 );
   313 	XOP2TS( OP_ADDQSAT32, REG_TMPQ1, R_MAC );
   314 :}
   315 MOVT Rn         {: XOP2SS( OP_MOV, R_R(Rn), R_T ); :}
   316 MUL.L Rm, Rn    {:  
   317 	XOP2SS( OP_MOV, R_R(Rm), R_MACL );
   318 	XOP2SS( OP_MUL, R_R(Rn), R_MACL );
   319 :}
   320 MULS.W Rm, Rn   {: 
   321 	XOP2ST( OP_MOVSX16, R_R(Rm), REG_TMP0 );
   322 	XOP2SS( OP_MOVSX16, R_R(Rn), R_MACL );
   323 	XOP2TS( OP_MUL, REG_TMP0, R_MACL );
   324 :}
   325 MULU.W Rm, Rn   {:
   326 	XOP2ST( OP_MOVZX16, R_R(Rm), REG_TMP0 );
   327 	XOP2SS( OP_MOVZX16, R_R(Rn), R_MACL );
   328 	XOP2TS( OP_MUL, REG_TMP0, R_MACL );
   329 :}
   330 NEG Rm, Rn      {: 
   331 	XOP2SS( OP_NEG, R_R(Rm), R_R(Rn) );
   332 :}
   333 NEGC Rm, Rn     {:
   334 	XOP1SCC( OP_LD, CC_C, R_T );
   335 	if( Rm == Rn ) {
   336 	    XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   337 	    XOP2IS(OP_MOV, 0, R_R(Rn) );
   338 	    XOP2TS( OP_SUBBS, REG_TMP0, R_R(Rn) );
   339 	} else {
   340 	    XOP2IS(OP_MOV, 0, R_R(Rn) );
   341 	    XOP2SS( OP_SUBBS, R_R(Rm), R_R(Rn) );
   342 	}
   343 	XOP1SCC( OP_ST, CC_C, R_T );
   344 :}
   345 NOT Rm, Rn      {:
   346 	XOP2SS( OP_NOT, R_R(Rm), R_R(Rn) );
   347 :}
   348 OR Rm, Rn       {: XOP2SS( OP_OR, R_R(Rm), R_R(Rn) ); :}  
   349 OR #imm, R0     {: XOP2IS( OP_OR, imm, R_R0 ); :}
   350 ROTCL Rn        {: XOP1SCC( OP_LD, CC_C, R_T ); XOP2IS( OP_RCL, 1, R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T); :}
   351 ROTCR Rn        {: XOP1SCC( OP_LD, CC_C, R_T ); XOP2IS( OP_RCR, 1, R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T); :}  
   352 ROTL Rn         {: XOP2IS( OP_ROL, 1, R_R(Rn) ); :}
   353 ROTR Rn         {: XOP2IS( OP_ROR, 1, R_R(Rn) ); :}
   354 SHAD Rm, Rn     {: XOP2SS( OP_SHAD, R_R(Rm), R_R(Rn) ); :}
   355 SHLD Rm, Rn     {: XOP2SS( OP_SHLD, R_R(Rm), R_R(Rn) ); :}  
   356 SHAL Rn         {: XOP2IS( OP_SLLS, 1, R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T); :} 
   357 SHAR Rn         {: XOP2IS( OP_SARS, 1, R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T); :}
   358 SHLL Rn         {: XOP2IS( OP_SLLS, 1, R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T); :}
   359 SHLL2 Rn        {: XOP2IS( OP_SLL, 2, R_R(Rn) ); :}
   360 SHLL8 Rn        {: XOP2IS( OP_SLL, 8, R_R(Rn) ); :}
   361 SHLL16 Rn       {: XOP2IS( OP_SLL, 16, R_R(Rn) ); :}
   362 SHLR Rn         {: XOP2IS( OP_SLRS, 1, R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T); :}
   363 SHLR2 Rn        {: XOP2IS( OP_SLR, 2, R_R(Rn) ); :}
   364 SHLR8 Rn        {: XOP2IS( OP_SLR, 8, R_R(Rn) ); :}
   365 SHLR16 Rn       {: XOP2IS( OP_SLR, 16, R_R(Rn) ); :}
   366 SUB Rm, Rn      {:
   367 	if( Rm == Rn ) {
   368 	    /* Break false dependence */
   369 	    XOP2IS( OP_MOV, 0, R_R(Rn) );
   370 	} else {
   371 	    XOP2SS( OP_SUB, R_R(Rm), R_R(Rn) );
   372 	} 
   373 :}
   374 SUBC Rm, Rn     {: XOP1SCC( OP_LD, CC_C, R_T ); XOP2SS( OP_SUBBS, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_C, R_T ); :}
   375 SUBV Rm, Rn     {: XOP2SS( OP_SUB, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_OV, R_T ); :}
   376 SWAP.B Rm, Rn   {:
   377 	if( Rm != Rn ) {
   378 	    XOP2SS( OP_MOV, R_R(Rm), R_R(Rn) );
   379 	}
   380 	XOP2IS( OP_SHUFFLE, 0x1243, R_R(Rn) );  
   381 :}  
   382 SWAP.W Rm, Rn   {:
   383 	if( Rm != Rn ) { 
   384 	    XOP2SS( OP_MOV, R_R(Rm), R_R(Rn) );
   385 	}
   386 	XOP2IS( OP_SHUFFLE, 0x3412, R_R(Rn) );
   387 :}
   388 TST Rm, Rn      {: XOP2SS( OP_TST, R_R(Rm), R_R(Rn) ); XOP1SCC( OP_ST, CC_EQ, R_T ); :}  
   389 TST #imm, R0    {: XOP2IS( OP_TST, imm, R_R0 ); XOP1SCC( OP_ST, CC_EQ, R_T ); :}  
   390 XOR Rm, Rn      {: 
   391 	if( Rm == Rn ) {
   392 	    /* Break false dependence */
   393 	    XOP2IS( OP_MOV, 0, R_R(Rn) );
   394 	} else {
   395 	    XOP2SS( OP_XOR, R_R(Rm), R_R(Rn) );
   396 	} 
   397 :}
   398 XOR #imm, R0    {: XOP2IS( OP_XOR, imm, R_R0 ); :}
   399 XTRCT Rm, Rn    {: 
   400 	XOP2ST( OP_MOV, R_R(Rm), REG_TMP0 );
   401 	XOP2IT( OP_SLL, 16, REG_TMP0 );
   402 	XOP2IS( OP_SLR, 16, R_R(Rn) );
   403 	XOP2TS( OP_OR, REG_TMP0, R_R(Rn) );
   404 :}
   405 MOV Rm, Rn      {: XOP2SS( OP_MOV, R_R(Rm), R_R(Rn) ); :}  
   406 MOV #imm, Rn    {: XOP2IS( OP_MOV, imm, R_R(Rn) ); :}  
   408 AND.B #imm, @(R0, GBR) {:
   409 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   410 	XOP2ST( OP_ADD, R_GBR, REG_TMP0 );
   411 	XOP2TTE( OP_LOADBFW, REG_TMP0, REG_TMP1 );
   412 	XOP2IT( OP_AND, imm, REG_TMP1 );
   413 	XOP2TTE( OP_STOREB, REG_TMP0, REG_TMP1 );
   414 :}
   415 OR.B #imm, @(R0, GBR) {: 
   416 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   417 	XOP2ST( OP_ADD, R_GBR, REG_TMP0 );
   418 	XOP2TTE( OP_LOADBFW, REG_TMP0, REG_TMP1 );
   419 	XOP2IT( OP_OR, imm, REG_TMP1 );
   420 	XOP2TTE( OP_STOREB, REG_TMP0, REG_TMP1 );
   421 :}
   422 TAS.B @Rn {:  
   423 	XOP1S( OP_OCBP, R_R(Rn) );
   424 	XOP2STE( OP_LOADBFW, R_R(Rn), REG_TMP0 );
   425 	XOP2IT( OP_CMP, 0, REG_TMP0 );
   426 	XOP1SCC(OP_ST, CC_EQ, R_T );  
   427 	XOP2IT( OP_OR, 0x80, REG_TMP0 );
   428 	XOP2STE( OP_STOREB, R_R(Rn), REG_TMP0 );
   429 :}
   430 TST.B #imm, @(R0, GBR) {:  
   431 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   432 	XOP2ST( OP_ADD, R_GBR, REG_TMP0 );
   433 	XOP2TTE( OP_LOADB, REG_TMP0, REG_TMP0 );
   434 	XOP2IT( OP_TST, imm, REG_TMP0 );
   435 :}
   436 XOR.B #imm, @(R0, GBR) {:  
   437 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   438 	XOP2ST( OP_ADD, R_GBR, REG_TMP0 );
   439 	XOP2TTE( OP_LOADBFW, REG_TMP0, REG_TMP1 );
   440 	XOP2IT( OP_XOR, imm, REG_TMP1 );
   441 	XOP2TTE( OP_STOREB, REG_TMP0, REG_TMP1 );
   442 :}
   444 MOV.B Rm, @Rn {:  
   445 	XOP2SSE( OP_STOREB, R_R(Rn), R_R(Rm) );
   446 :}
   447 MOV.B Rm, @-Rn {:
   448 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   449 	XOP2IT( OP_ADD, -1, REG_TMP0 );
   450 	XOP2TSE( OP_STOREB, REG_TMP0, R_R(Rm) );
   451 	XOP2IS( OP_ADD, -1, R_R(Rn) );
   452 :}
   453 MOV.B Rm, @(R0, Rn) {:
   454 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   455 	XOP2ST( OP_ADD, R_R0, REG_TMP0 );
   456 	XOP2TSE( OP_STOREB, REG_TMP0, R_R(Rm) );
   457 :}
   458 MOV.B R0, @(disp, GBR) {:
   459 	XOP2ST( OP_MOV, R_GBR, REG_TMP0 );
   460 	XOP2IT( OP_ADD, disp, REG_TMP0 );
   461 	XOP2TSE( OP_STOREB, REG_TMP0, R_R0 );
   462 :}
   463 MOV.B R0, @(disp, Rn) {:
   464 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   465 	XOP2IT( OP_ADD, disp, REG_TMP0 );
   466 	XOP2TSE( OP_STOREB, REG_TMP0, R_R0 );
   467 :}
   468 MOV.B @Rm, Rn {:
   469 	XOP2SSE( OP_LOADB, R_R(Rm), R_R(Rn) );
   470 :}
   471 MOV.B @Rm+, Rn {:
   472 	XOP2SSE( OP_LOADB, R_R(Rm), R_R(Rn) );
   473 	if( Rm != Rn ) {
   474 	    XOP2IS( OP_ADD, 1, R_R(Rm) );
   475 	}
   476 :}
   477 MOV.B @(R0, Rm), Rn {:
   478 	XOP2ST( OP_MOV, R_R(Rm), REG_TMP0 );
   479 	XOP2ST( OP_ADD, R_R0, REG_TMP0 );
   480 	XOP2TSE(OP_LOADB, REG_TMP0, R_R(Rn) );  
   481 :}
   482 MOV.B @(disp, GBR), R0 {:
   483 	XOP2ST( OP_MOV, R_GBR, REG_TMP0 );
   484 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   485 	XOP2TSE(OP_LOADB, REG_TMP0, R_R0 );
   486 :}
   487 MOV.B @(disp, Rm), R0 {:  
   488 	XOP2ST( OP_MOV, R_R(Rm), REG_TMP0 );
   489 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   490 	XOP2TSE(OP_LOADB, REG_TMP0, R_R0 );
   491 :}
   492 MOV.L Rm, @Rn {:
   493 	WALIGN32( R_R(Rn) );
   494 	XOP2SSE( OP_STOREL, R_R(Rn), R_R(Rm) );
   495 :}
   496 MOV.L Rm, @-Rn {:
   497 	WALIGN32( R_R(Rn) );
   498 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   499 	XOP2IT(OP_ADD, -4, REG_TMP0 );
   500 	XOP2TS( OP_STOREL, REG_TMP0, R_R(Rm) );
   501 	XOP2IS(OP_ADD, -4, R_R(Rn) );
   502 :}
   503 MOV.L Rm, @(R0, Rn) {:  
   504 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   505 	XOP2ST( OP_ADD, R_R0, REG_TMP0 );
   506 	WALIGN32( REG_TMP0 );
   507 	XOP2TSE(OP_STOREL, REG_TMP0, R_R(Rm) );
   508 :}
   509 MOV.L R0, @(disp, GBR) {:  
   510 	XOP2ST( OP_MOV, R_GBR, REG_TMP0 );
   511 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   512 	WALIGN32( REG_TMP0 );
   513 	XOP2TSE(OP_STOREL, REG_TMP0, R_R0 );
   514 :}
   515 MOV.L Rm, @(disp, Rn) {:  
   516 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   517 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   518 	WALIGN32( REG_TMP0 );
   519 	XOP2TSE(OP_STOREL, REG_TMP0, R_R(Rm) );
   520 :}
   521 MOV.L @Rm, Rn {: 
   522 	RALIGN32( R_R(Rm) );
   523 	XOP2SSE(OP_LOADL, R_R(Rm), R_R(Rn) ); 
   524 :}
   525 MOV.L @Rm+, Rn {:
   526         RALIGN32( R_R(Rm) );
   527 	XOP2SSE( OP_LOADL, R_R(Rm), R_R(Rn) );
   528 	if( R_R(Rm) != R_R(Rn) ) {
   529 	    XOP2IS( OP_ADD, 4, R_R(Rm) );
   530 	} 
   531 :}
   532 MOV.L @(R0, Rm), Rn {:
   533 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   534 	XOP2ST( OP_ADD, R_R(Rm), REG_TMP0 );
   535 	RALIGN32( REG_TMP0 );
   536 	XOP2TSE(OP_LOADL, REG_TMP0, R_R(Rn) );	  
   537 :}
   538 MOV.L @(disp, GBR), R0 {:
   539 	XOP2ST( OP_MOV, R_GBR, REG_TMP0 );
   540 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   541 	RALIGN32( REG_TMP0 );
   542 	XOP2TSE(OP_LOADL, REG_TMP0, R_R0 );
   543 :}
   544 MOV.L @(disp, PC), Rn {:
   545 	if( in_delay_slot ) {
   546 	    SLOTILLEGAL();
   547 	    return 2;
   548 	} else {
   549 	    uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
   550 	    if( IS_IN_ICACHE(target) ) {
   551 	    // If the target address is in the same page as the code, it's
   552 	    // pretty safe to just ref it directly and circumvent the whole
   553 	    // memory subsystem. (this is a big performance win)
   555 	    // FIXME: There's a corner-case that's not handled here when
   556 	    // the current code-page is in the ITLB but not in the UTLB.
   557 	    // (should generate a TLB miss although need to test SH4 
   558 	    // behaviour to confirm) Unlikely to be anyone depending on this
   559 	    // behaviour though.
   560 	        sh4ptr_t ptr = GET_ICACHE_PTR(target);
   561 	        XOP2PS( OP_LOADPTRL, ptr, R_R(Rn) );
   562 	    } else {
   563 	    // Note: we use sh4r.pc for the calc as we could be running at a
   564 	    // different virtual address than the translation was done with,
   565 	    // but we can safely assume that the low bits are the same.
   566 	        XOP2ST( OP_MOV, R_PC, REG_TMP0 );
   567 	        XOP2IT( OP_ADD, (pc-xbb->pc_begin) + disp + 4 - (pc&0x03), REG_TMP0 );
   568 	        XOP2TSE(OP_LOADL, REG_TMP0, R_R(Rn) );
   569 	    }
   570 	}
   571 :}
   572 MOV.L @(disp, Rm), Rn {:  
   573 	XOP2ST( OP_MOV, R_R(Rm), REG_TMP0 );
   574 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   575 	RALIGN32( REG_TMP0 );
   576 	XOP2TSE(OP_LOADL, REG_TMP0, R_R(Rn) );
   577 :}
   578 MOV.W Rm, @Rn {:  
   579 	WALIGN16( R_R(Rn) );
   580 	XOP2SSE(OP_STOREW, R_R(Rn), R_R(Rm) );
   581 :}
   582 MOV.W Rm, @-Rn {: 
   583 	WALIGN16( R_R(Rn) );
   584 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   585 	XOP2IT(OP_ADD, -2, REG_TMP0 );
   586 	XOP2TSE(OP_STOREW, REG_TMP0, R_R(Rm) );
   587 	XOP2IS(OP_ADD, -2, R_R(Rn) );
   588 :}
   589 MOV.W Rm, @(R0, Rn) {: 
   590 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   591 	XOP2ST( OP_ADD, R_R(Rn), REG_TMP0 );
   592 	WALIGN16( REG_TMP0 );
   593 	XOP2TSE(OP_STOREW, REG_TMP0, R_R(Rm) );
   594 :}
   595 MOV.W R0, @(disp, GBR) {:  
   596 	XOP2ST( OP_MOV, R_GBR, REG_TMP0 );
   597 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   598 	WALIGN16( REG_TMP0 );
   599 	XOP2TS( OP_STOREW, REG_TMP0, R_R0 );
   600 :}
   601 MOV.W R0, @(disp, Rn) {:  
   602 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   603 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   604 	WALIGN16( REG_TMP0 );
   605 	XOP2TSE(OP_STOREW, REG_TMP0, R_R0 );
   606 :}
   607 MOV.W @Rm, Rn {: 
   608 	RALIGN16( R_R(Rm) );
   609 	XOP2SSE(OP_LOADW, R_R(Rm), R_R(Rn) );
   610 :}
   611 MOV.W @Rm+, Rn {: 
   612 	RALIGN16( R_R(Rm) );
   613 	XOP2SSE(OP_LOADW, R_R(Rm), R_R(Rn) );
   614 	if( Rm != Rn ) {
   615 	    XOP2IS( OP_ADD, 2, R_R(Rm) );
   616 	}
   617 :}
   618 MOV.W @(R0, Rm), Rn {:  
   619 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   620 	XOP2ST( OP_ADD, R_R(Rm), REG_TMP0 );
   621 	RALIGN16( REG_TMP0 );
   622 	XOP2TSE(OP_LOADW, REG_TMP0, R_R(Rn) );
   623 :}
   624 MOV.W @(disp, GBR), R0 {:  
   625 	XOP2ST( OP_MOV, R_GBR, REG_TMP0 );
   626 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   627 	RALIGN16( REG_TMP0 );
   628 	XOP2TSE(OP_LOADW, REG_TMP0, R_R0 );
   629 :}
   630 MOV.W @(disp, PC), Rn {:  
   631 	if( in_delay_slot ) {
   632 	    SLOTILLEGAL();
   633 	    return 2;
   634 	} else {
   635 	    uint32_t target = pc + disp + 4;
   636 	    if( IS_IN_ICACHE(target) ) {
   637 	    // If the target address is in the same page as the code, it's
   638 	    // pretty safe to just ref it directly and circumvent the whole
   639 	    // memory subsystem. (this is a big performance win)
   641 	    // FIXME: There's a corner-case that's not handled here when
   642 	    // the current code-page is in the ITLB but not in the UTLB.
   643 	    // (should generate a TLB miss although need to test SH4 
   644 	    // behaviour to confirm) Unlikely to be anyone depending on this
   645 	    // behaviour though.
   646 	        sh4ptr_t ptr = GET_ICACHE_PTR(target);
   647 	        XOP2PT( OP_LOADPTRW, ptr, REG_TMP0 );
   648 	    } else {
   649 	    // Note: we use sh4r.pc for the calc as we could be running at a
   650 	    // different virtual address than the translation was done with,
   651 	    // but we can safely assume that the low bits are the same.
   652 	        XOP2ST( OP_MOV, R_PC, REG_TMP0 );
   653 	        XOP2IT( OP_ADD, (pc - xbb->pc_begin) + disp + 4, REG_TMP0 );
   654 	        XOP2TSE(OP_LOADW, REG_TMP0, R_R(Rn) );
   655 	    }
   656 	}
   657 :}
   658 MOV.W @(disp, Rm), R0 {:  
   659 	XOP2ST( OP_MOV, R_R(Rm), REG_TMP0 );
   660 	XOP2IT(OP_ADD, disp, REG_TMP0 );
   661 	RALIGN16( REG_TMP0 );
   662 	XOP2TSE(OP_LOADW, REG_TMP0, R_R0 );
   663 :}
   664 MOVA @(disp, PC), R0 {: 
   665 	if( in_delay_slot ) {
   666 	    SLOTILLEGAL();
   667 	    return 2;
   668 	} else {
   669 	    XOP2SS(  OP_MOV, R_PC, R_R0 );
   670 	    XOP2IS( OP_ADD, (pc - xbb->pc_begin) + disp + 4 - (pc&0x03), R_R0 );
   671 	}
   672 :}
   673 MOVCA.L R0, @Rn {:
   674 	XOP2SSE(OP_STORELCA, R_R(Rn), R_R0 );   
   675 :}
   676 LDTLB {:
   677 	CHECKPRIV();
   678 	XOPCALL0( MMU_ldtlb );
   679 :}
   680 OCBI @Rn  {: XOP1SE( OP_OCBI, R_R(Rn) ); :}
   681 OCBP @Rn  {: XOP1SE( OP_OCBP, R_R(Rn) ); :}
   682 OCBWB @Rn {: XOP1SE( OP_OCBWB, R_R(Rn) ); :}
   683 PREF @Rn  {: XOP1SE( OP_PREF, R_R(Rn) ); :}
   685 CLRMAC {: 
   686 	XOP2IS( OP_MOV, 0, R_MACL );
   687 	XOP2IS( OP_MOV, 0, R_MACH );
   688 :}
   689 CLRS {: XOP2IS( OP_MOV, 0, R_S ); :}
   690 CLRT {: XOP2IS( OP_MOV, 0, R_T ); :}
   691 SETS {: XOP2IS( OP_MOV, 1, R_S ); :}
   692 SETT {: XOP2IS( OP_MOV, 1, R_T ); :}
   693 FMOV FRm, FRn {:
   694 	CHECKFPUEN();  
   695 	if( sh4_xir.double_size ) {
   696 	    XOP2SS( OP_MOVQ, (FRm&1) ? R_XD(FRm) : R_DR(FRm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
   697 	} else { 
   698 	    XOP2SS( OP_MOV, R_FR(FRm), R_FR(FRn) );
   699 	}	
   700 :}
   701 FMOV FRm, @Rn {:
   702 	CHECKFPUEN();  
   703 	if( sh4_xir.double_size ) {
   704 	    WALIGN64( R_R(Rn) );
   705 	    XOP2SSE( OP_STOREQ, R_R(Rn), (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
   706 	} else {
   707 	    WALIGN32( R_R(Rn) );
   708 	    XOP2SSE( OP_STOREL, R_R(Rn), R_FR(FRm) );
   709 	} 
   710 :}
   711 FMOV @Rm, FRn {:
   712 	CHECKFPUEN();  
   713 	if( sh4_xir.double_size ) {
   714 	    RALIGN64( R_R(Rm) );
   715 	    XOP2SSE( OP_LOADQ, R_R(Rm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
   716 	} else {
   717 	    RALIGN32( R_R(Rm) );
   718 	    XOP2SSE( OP_LOADL, R_R(Rm), R_FR(FRn) );
   719 	}
   720 :}
   721 FMOV FRm, @-Rn {:
   722 	CHECKFPUEN();  
   723 	if( sh4_xir.double_size ) {
   724 	    WALIGN64( R_R(Rn) );
   725 	    XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   726 	    XOP2IT(OP_ADD, -8, REG_TMP0 );
   727 	    XOP2TSE(OP_STOREQ, REG_TMP0, (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
   728 	    XOP2IS(OP_ADD, -8, R_R(Rn) );
   729 	} else {
   730 	    WALIGN32( R_R(Rn) );
   731 	    XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
   732 	    XOP2IT(OP_ADD, -4, REG_TMP0 );
   733 	    XOP2TSE(OP_STOREL, REG_TMP0, R_FR(FRm) );
   734 	    XOP2IS(OP_ADD, -4, R_R(Rn) );
   735 	}
   736 :}
   737 FMOV @Rm+, FRn {:
   738 	CHECKFPUEN();  
   739 	if( sh4_xir.double_size ) {
   740 	    RALIGN64( R_R(Rm) );
   741 	    XOP2SSE(  OP_LOADQ, R_R(Rm), (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
   742 	    XOP2IS( OP_ADD, 8, R_R(Rm) );
   743 	} else {
   744 	    RALIGN32( R_R(Rm) );
   745 	    XOP2SSE(  OP_LOADL, R_R(Rm), R_FR(FRn) );
   746 	    XOP2IS( OP_ADD, 4, R_R(Rm) );
   747 	}
   748 :}
   749 FMOV FRm, @(R0, Rn) {: 
   750 	CHECKFPUEN();
   751 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   752 	XOP2ST( OP_ADD, R_R(Rn), REG_TMP0 );
   753 	if( sh4_xir.double_size ) {
   754 	    WALIGN64( REG_TMP0 );
   755 	    XOP2TSE( OP_STOREQ, REG_TMP0, (FRm&1) ? R_XD(FRm) : R_DR(FRm) );
   756 	} else {
   757 	    WALIGN32( REG_TMP0 );
   758 	    XOP2TSE( OP_STOREL, REG_TMP0, R_FR(FRm) );
   759 	}
   760 :}
   761 FMOV @(R0, Rm), FRn {:  
   762 	CHECKFPUEN();
   763 	XOP2ST( OP_MOV, R_R0, REG_TMP0 );
   764 	XOP2ST( OP_ADD, R_R(Rm), REG_TMP0 );
   765 	if( sh4_xir.double_size ) {
   766 	    RALIGN64( REG_TMP0 );
   767 	    XOP2TSE( OP_LOADQ, REG_TMP0, (FRn&1) ? R_XD(FRn) : R_DR(FRn) );
   768 	} else {
   769 	    RALIGN32( REG_TMP0 );
   770 	    XOP2TSE( OP_LOADL, REG_TMP0, R_FR(FRn) );
   771 	}
   772 :}
   773 FLDI0 FRn {:  /* IFF PR=0 */
   774 	CHECKFPUEN();
   775 	if( sh4_xir.double_prec == 0 ) {
   776 	    XOP2FS( OP_MOV, 0.0, R_FR(FRn) );
   777 	} 
   778 :}
   779 FLDI1 FRn {:  /* IFF PR=0 */
   780 	CHECKFPUEN();
   781 	if( sh4_xir.double_prec == 0 ) {
   782 	    XOP2FS( OP_MOV, 1.0, R_FR(FRn) );
   783 	}
   784 :}
   785 FLOAT FPUL, FRn {:
   786 	CHECKFPUEN();
   787 	if( sh4_xir.double_prec ) {
   788 	    XOP2SS( OP_ITOD, R_FPUL, R_DR(FRn) );
   789 	} else {
   790 	    XOP2SS( OP_ITOF, R_FPUL, R_FR(FRn) );
   791 	}  
   792 :}
   793 FTRC FRm, FPUL {: 
   794 	CHECKFPUEN();
   795 	if( sh4_xir.double_prec ) {
   796 	    XOP2SS( OP_MOVQ, R_DR(FRm), REG_TMPD0 );
   797 	    XOP2FS( OP_MAXD, (double)0x8000000000000000, REG_TMPD0 ); 
   798 	    XOP2FS( OP_MIND, (double)0x7FFFFFFFFFFFFFFF, REG_TMPD0 ); 
   799 	    XOP2SS( OP_DTOI, REG_TMPD0, R_FPUL );
   800 	} else {
   801 	    XOP2SS( OP_MOV, R_FR(FRm), REG_TMPF0 );
   802 	    XOP2FS( OP_MAXF, (double)0x80000000, REG_TMPF0 ); 
   803 	    XOP2FS( OP_MINF, (double)0x7FFFFFFF, REG_TMPF0 ); 
   804 	    XOP2SS( OP_FTOI, REG_TMPF0, R_FPUL );
   805 	}
   806 :}
   807 FLDS FRm, FPUL {:
   808 	CHECKFPUEN();
   809 	XOP2SS( OP_MOV, R_FR(FRm), R_FPUL );  
   810 :}
   811 FSTS FPUL, FRn {:  
   812 	CHECKFPUEN();
   813 	XOP2SS( OP_MOV, R_FPUL, R_FR(FRn) );
   814 :}
   815 FCNVDS FRm, FPUL {:  
   816 	CHECKFPUEN();
   817 	if( sh4_xir.double_prec && !sh4_xir.double_size ) {
   818 	    XOP2SS( OP_DTOF, R_DR(FRm), R_FPUL );
   819 	}
   820 :}
   821 FCNVSD FPUL, FRn {:  
   822 	CHECKFPUEN();
   823 	if( sh4_xir.double_prec && !sh4_xir.double_size ) {
   824 	    XOP2SS( OP_FTOD, R_FPUL, R_DR(FRn) );
   825 	}
   826 :}
   827 FABS FRn {: 
   828 	CHECKFPUEN();
   829 	if( sh4_xir.double_prec ) {
   830 	    XOP2SS( OP_ABSD, R_DR(FRn), R_DR(FRn) );
   831 	} else {
   832 	    XOP2SS( OP_ABSF, R_FR(FRn), R_FR(FRn) );
   833 	} 
   834 :}
   835 FADD FRm, FRn {: 
   836 	CHECKFPUEN();
   837 	if( sh4_xir.double_prec ) {
   838 	    XOP2SS( OP_ADDD, R_DR(FRm), R_DR(FRn) );
   839 	} else {
   840 	    XOP2SS( OP_ADDF, R_FR(FRm), R_FR(FRn) );
   841 	} 
   842 :}
   843 FDIV FRm, FRn {:
   844 	CHECKFPUEN();
   845 	if( sh4_xir.double_prec ) {
   846 	    XOP2SS( OP_DIVD, R_DR(FRm), R_DR(FRn) );
   847 	} else {
   848 	    XOP2SS( OP_DIVF, R_FR(FRm), R_FR(FRn) );
   849 	}  
   850 :}
   851 FMAC FR0, FRm, FRn {:  
   852 	CHECKFPUEN();
   853 	if( sh4_xir.double_prec == 0 ) {
   854 	    XOP2ST( OP_MOV, R_FR(0), REG_TMP0 );
   855 	    XOP2ST( OP_MULF, R_FR(FRm), REG_TMP0 );
   856 	    XOP2TS( OP_ADDF, REG_TMP0, R_FR(FRn) );
   857 	}
   858 :}
   859 FMUL FRm, FRn {:
   860 	CHECKFPUEN();
   861 	if( sh4_xir.double_prec ) {
   862 	    XOP2SS( OP_MULD, R_DR(FRm), R_DR(FRn) );
   863 	} else {
   864 	    XOP2SS( OP_MULF, R_FR(FRm), R_FR(FRn) );
   865 	}  
   866 :}
   867 FNEG FRn {: 
   868 	CHECKFPUEN();
   869 	if( sh4_xir.double_prec ) {
   870 	    XOP2SS( OP_NEGD, R_DR(FRn), R_DR(FRn) );
   871 	} else {
   872 	    XOP2SS( OP_NEGF, R_FR(FRn), R_FR(FRn) );
   873 	}
   874 :}
   875 FSRRA FRn {:
   876 	CHECKFPUEN();  
   877 	if( sh4_xir.double_prec == 0 ) {
   878 	    XOP2SS( OP_RSQRTF, R_FR(FRn), R_FR(FRn) );
   879 	}
   880 :}
   881 FSQRT FRn {:  
   882 	CHECKFPUEN();
   883 	if( sh4_xir.double_prec ) {
   884 	    XOP2SS( OP_SQRTD, R_DR(FRn), R_DR(FRn) );
   885 	} else {
   886 	    XOP2SS( OP_SQRTF, R_FR(FRn), R_FR(FRn) );
   887 	}
   888 :}
   889 FSUB FRm, FRn {:
   890  	CHECKFPUEN();
   891  	if( sh4_xir.double_prec ) {
   892  	    XOP2SS( OP_SUBD, R_DR(FRm), R_DR(FRn) );
   893  	} else {
   894  	    XOP2SS( OP_SUBF, R_FR(FRm), R_FR(FRn) );
   895  	}
   896 :}
   897 FCMP/EQ FRm, FRn {:
   898 	CHECKFPUEN();
   899 	if( sh4_xir.double_prec ) {
   900 	    XOP2SS( OP_CMPD, R_DR(FRm), R_DR(FRn) ); 
   901 	} else {
   902 	    XOP2SS( OP_CMPF, R_FR(FRm), R_FR(FRn) );
   903 	}   
   904 	XOP1SCC( OP_ST, CC_EQ, R_T );
   905 :}
   906 FCMP/GT FRm, FRn {:
   907 	CHECKFPUEN();
   908 	if( sh4_xir.double_prec ) {
   909 	    XOP2SS( OP_CMPD, R_DR(FRm), R_DR(FRn) );
   910 	} else {
   911 	    XOP2SS( OP_CMPF, R_FR(FRm), R_FR(FRn) );
   912 	}	      
   913 	XOP1SCC( OP_ST, CC_SGT, R_T );
   914 :}
   915 FSCA FPUL, FRn {:  
   916 	CHECKFPUEN();
   917 	if( sh4_xir.double_prec == 0 ) {
   918 	    XOP2SS( OP_SINCOSF, R_FPUL, R_DR(FRn) );
   919 	}
   920 :}
   921 FIPR FVm, FVn {:
   922 	CHECKFPUEN();
   923 	if( sh4_xir.double_prec == 0 ) {
   924 	    XOP2SS( OP_DOTPRODV, R_FV(FVm), R_FV(FVn) );
   925 	}
   926 :}
   927 FTRV XMTRX, FVn {: 
   928 	CHECKFPUEN();
   929 	if( sh4_xir.double_prec == 0 ) {
   930 	    XOP2SS( OP_MATMULV, R_XMTRX, R_FV(FVn) );
   931 	}
   932 :}
   933 FRCHG {: 
   934 	CHECKFPUEN();
   935 	XOP2IS( OP_XOR, FPSCR_FR, R_FPSCR );
   936 	XOPCALL0( sh4_switch_fr_banks );
   937 :}
   938 FSCHG {: 
   939 	CHECKFPUEN();
   940 	XOP2IS( OP_XOR, FPSCR_SZ, R_FPSCR );
   941 	XOP2IS( OP_XOR, FPSCR_SZ, R_SH4_MODE ); 
   942 	sh4_xir.double_size = !sh4_xir.double_size;
   943 :}
   944 LDC Rm, SR {:
   945 	if( in_delay_slot ) {
   946 	    SLOTILLEGAL();
   947 	} else {
   948 	    CHECKPRIV();
   949 	    XOPCALL1S( sh4_write_sr, R_R(Rm) );
   950 	}
   951 	return 2; 
   952 :}
   953 LDC Rm, GBR {: XOP2SS( OP_MOV, R_R(Rm), R_GBR ); :}
   954 LDC Rm, VBR {: CHECKPRIV(); XOP2SS( OP_MOV, R_R(Rm), R_VBR ); :}
   955 LDC Rm, SSR {: CHECKPRIV(); XOP2SS( OP_MOV, R_R(Rm), R_SSR ); :}
   956 LDC Rm, SGR {: CHECKPRIV(); XOP2SS( OP_MOV, R_R(Rm), R_SGR ); :}
   957 LDC Rm, SPC {: CHECKPRIV(); XOP2SS( OP_MOV, R_R(Rm), R_SPC ); :}
   958 LDC Rm, DBR {: CHECKPRIV(); XOP2SS( OP_MOV, R_R(Rm), R_DBR ); :}
   959 LDC Rm, Rn_BANK {: CHECKPRIV(); XOP2SS( OP_MOV, R_R(Rm), R_BANK(Rn_BANK) ); :}
   960 LDC.L @Rm+, GBR {: 
   961 	XOP2SSE( OP_LOADL, R_R(Rm), R_GBR );
   962 	XOP2IS( OP_ADD, 4, R_R(Rm) );
   963 :}
   964 LDC.L @Rm+, SR {:
   965 	if( in_delay_slot ) {
   966 	    SLOTILLEGAL();
   967 	} else {
   968 	    CHECKPRIV();
   969 	    RALIGN32( R_R(Rm) );
   970 	    XOP2STE( OP_LOADL, R_R(Rm), REG_TMP0 );
   971 	    XOP2IS( OP_ADD, 4, R_R(Rm) );
   972 	    XOPCALL1T( sh4_write_sr, REG_TMP0 );
   973 	}
   974 	return 2;
   975 :}
   976 LDC.L @Rm+, VBR {:  
   977 	CHECKPRIV();
   978 	RALIGN32( R_R(Rm) );
   979 	XOP2SSE( OP_LOADL, R_R(Rm), R_VBR );
   980 	XOP2IS( OP_ADD, 4, R_R(Rm) );
   981 :}
   982 LDC.L @Rm+, SSR {:
   983 	CHECKPRIV();
   984 	RALIGN32( R_R(Rm) );
   985 	XOP2SSE( OP_LOADL, R_R(Rm), R_SSR );
   986 	XOP2IS( OP_ADD, 4, R_R(Rm) );
   987 :}
   988 LDC.L @Rm+, SGR {:  
   989 	CHECKPRIV();
   990 	RALIGN32( R_R(Rm) );
   991 	XOP2SSE( OP_LOADL, R_R(Rm), R_SGR );
   992 	XOP2IS( OP_ADD, 4, R_R(Rm) );
   993 :}
   994 LDC.L @Rm+, SPC {:  
   995 	CHECKPRIV();
   996 	RALIGN32( R_R(Rm) );
   997 	XOP2SSE( OP_LOADL, R_R(Rm), R_SPC );
   998 	XOP2IS( OP_ADD, 4, R_R(Rm) );
   999 :}
  1000 LDC.L @Rm+, DBR {:  
  1001 	CHECKPRIV();
  1002 	RALIGN32( R_R(Rm) );
  1003 	XOP2SSE( OP_LOADL, R_R(Rm), R_DBR );
  1004 	XOP2IS( OP_ADD, 4, R_R(Rm) );
  1005 :}
  1006 LDC.L @Rm+, Rn_BANK {:  
  1007 	CHECKPRIV();
  1008 	RALIGN32( R_R(Rm) );
  1009 	XOP2SSE( OP_LOADL, R_R(Rm), R_BANK(Rn_BANK) );
  1010 	XOP2IS( OP_ADD, 4, R_R(Rm) );
  1011 :}
  1012 LDS Rm, FPSCR {:
  1013 	CHECKFPUEN();
  1014 	XOPCALL1S( sh4_write_fpscr, R_R(Rm) );
  1015 	return 2;
  1016 :}
  1017 LDS Rm, FPUL  {:
  1018 	CHECKFPUEN(); 
  1019 	XOP2SS( OP_MOV, R_R(Rm), R_FPUL ); 
  1020 :}
  1021 LDS Rm, MACH  {: XOP2SS( OP_MOV, R_R(Rm), R_MACH ); :}
  1022 LDS Rm, MACL  {: XOP2SS( OP_MOV, R_R(Rm), R_MACL ); :}
  1023 LDS Rm, PR    {: XOP2SS( OP_MOV, R_R(Rm), R_PR ); :}
  1024 LDS.L @Rm+, FPSCR {:
  1025 	CHECKFPUEN();
  1026 	RALIGN32( R_R(Rm) );
  1027 	XOP2STE( OP_LOADL, R_R(Rm), REG_TMP0 );
  1028 	XOP2IS( OP_ADD, 4, R_R(Rm) );
  1029 	XOPCALL1T( sh4_write_fpscr, REG_TMP0 );
  1030 	return 2;
  1031 :}
  1032 LDS.L @Rm+, FPUL {:
  1033 	CHECKFPUEN();
  1034 	RALIGN32( R_R(Rm) );
  1035 	XOP2SSE( OP_LOADL, R_R(Rm), R_FPUL );
  1036 	XOP2IS( OP_ADD, 4, R_R(Rm) );  
  1037 :}
  1038 LDS.L @Rm+, MACH {:  
  1039 	RALIGN32( R_R(Rm) );
  1040 	XOP2SSE( OP_LOADL, R_R(Rm), R_MACH );
  1041 	XOP2IS( OP_ADD, 4, R_R(Rm) );  
  1042 :}
  1043 LDS.L @Rm+, MACL {:  
  1044 	RALIGN32( R_R(Rm) );
  1045 	XOP2SSE( OP_LOADL, R_R(Rm), R_MACL );
  1046 	XOP2IS( OP_ADD, 4, R_R(Rm) );  
  1047 :}
  1048 LDS.L @Rm+, PR {:  
  1049 	RALIGN32( R_R(Rm) );
  1050 	XOP2SSE( OP_LOADL, R_R(Rm), R_PR );
  1051 	XOP2IS( OP_ADD, 4, R_R(Rm) );  
  1052 :}
  1053 STC SR, Rn {:
  1054 	CHECKPRIV();
  1055 	XOPCALLRS( sh4_read_sr, R_R(Rn) );
  1056 :}
  1057 STC GBR, Rn {: XOP2SS( OP_MOV, R_GBR, R_R(Rn) ); :}
  1058 STC VBR, Rn {: CHECKPRIV(); XOP2SS( OP_MOV, R_VBR, R_R(Rn) ); :}  
  1059 STC SSR, Rn {: CHECKPRIV(); XOP2SS( OP_MOV, R_SSR, R_R(Rn) ); :}
  1060 STC SPC, Rn {: CHECKPRIV(); XOP2SS( OP_MOV, R_SPC, R_R(Rn) ); :}
  1061 STC SGR, Rn {: CHECKPRIV(); XOP2SS( OP_MOV, R_SGR, R_R(Rn) ); :}
  1062 STC DBR, Rn {: CHECKPRIV(); XOP2SS( OP_MOV, R_DBR, R_R(Rn) ); :}
  1063 STC Rm_BANK, Rn {: CHECKPRIV(); XOP2SS( OP_MOV, R_BANK(Rm_BANK), R_R(Rn) ); :}
  1064 STC.L SR, @-Rn {:
  1065 	CHECKPRIV();
  1066 	XOPCALLRT( sh4_read_sr, REG_TMP1 );
  1067 	WALIGN32( R_R(Rn) );
  1068 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1069 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1070 	XOP2TTE(OP_STOREL, REG_TMP0, REG_TMP1 );
  1071 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1072 :}
  1073 STC.L VBR, @-Rn {:
  1074 	CHECKPRIV();
  1075 	WALIGN32( R_R(Rn) );
  1076 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1077 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1078 	XOP2TSE(OP_STOREL, REG_TMP0, R_VBR ); 
  1079 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1080 :}
  1081 STC.L SSR, @-Rn {:  
  1082 	CHECKPRIV();
  1083 	WALIGN32( R_R(Rn) );
  1084 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1085 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1086 	XOP2TSE(OP_STOREL, REG_TMP0, R_SSR ); 
  1087 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1088 :}
  1089 STC.L SPC, @-Rn {:
  1090 	CHECKPRIV();
  1091 	WALIGN32( R_R(Rn) );
  1092 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1093 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1094 	XOP2TSE(OP_STOREL, REG_TMP0, R_SPC ); 
  1095 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1096 :}
  1097 STC.L SGR, @-Rn {:  
  1098 	CHECKPRIV();
  1099 	WALIGN32( R_R(Rn) );
  1100 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1101 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1102 	XOP2TSE(OP_STOREL, REG_TMP0, R_SGR ); 
  1103 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1104 :}
  1105 STC.L DBR, @-Rn {:  
  1106 	CHECKPRIV();
  1107 	WALIGN32( R_R(Rn) );
  1108 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1109 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1110 	XOP2TSE(OP_STOREL, REG_TMP0, R_DBR ); 
  1111 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1112 :}
  1113 STC.L Rm_BANK, @-Rn {:  
  1114 	CHECKPRIV();
  1115 	WALIGN32( R_R(Rn) );
  1116 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1117 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1118 	XOP2TSE(OP_STOREL, REG_TMP0, R_BANK(Rm_BANK) ); 
  1119 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1120 :}
  1121 STC.L GBR, @-Rn {:
  1122 	WALIGN32( R_R(Rn) );
  1123 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1124 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1125 	XOP2TSE(OP_STOREL, REG_TMP0, R_GBR ); 
  1126 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1127 :}
  1128 STS FPSCR, Rn {: 
  1129 	CHECKFPUEN();
  1130 	XOP2SS( OP_MOV, R_FPSCR, R_R(Rn) );
  1131 :}
  1132 STS FPUL, Rn {:  
  1133 	CHECKFPUEN();
  1134 	XOP2SS( OP_MOV, R_FPUL, R_R(Rn) );
  1135 :}
  1136 STS MACH, Rn {:  
  1137 	XOP2SS( OP_MOV, R_MACH, R_R(Rn) );
  1138 :}
  1139 STS MACL, Rn {:  
  1140 	XOP2SS( OP_MOV, R_MACL, R_R(Rn) );
  1141 :}
  1142 STS PR, Rn {:  
  1143 	XOP2SS( OP_MOV, R_PR, R_R(Rn) );
  1144 :}
  1145 STS.L FPSCR, @-Rn {:  
  1146 	CHECKFPUEN();
  1147 	WALIGN32( R_R(Rn) );
  1148 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1149 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1150 	XOP2TSE(OP_STOREL, REG_TMP0, R_FPSCR );
  1151 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1152 :}
  1153 STS.L FPUL, @-Rn {:  
  1154 	CHECKFPUEN();
  1155 	WALIGN32( R_R(Rn) );
  1156 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1157 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1158 	XOP2TSE(OP_STOREL, REG_TMP0, R_FPUL );
  1159 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1160 :}
  1161 STS.L MACH, @-Rn {:  
  1162 	WALIGN32( R_R(Rn) );
  1163 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1164 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1165 	XOP2TSE(OP_STOREL, REG_TMP0, R_MACH );
  1166 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1167 :}
  1168 STS.L MACL, @-Rn {:  
  1169 	WALIGN32( R_R(Rn) );
  1170 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1171 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1172 	XOP2TSE(OP_STOREL, REG_TMP0, R_MACL );
  1173 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1174 :}
  1175 STS.L PR, @-Rn {:  
  1176 	WALIGN32( R_R(Rn) );
  1177 	XOP2ST( OP_MOV, R_R(Rn), REG_TMP0 );
  1178 	XOP2IT(OP_ADD, -4, REG_TMP0 );
  1179 	XOP2TSE(OP_STOREL, REG_TMP0, R_PR );
  1180 	XOP2IS(OP_ADD, -4, R_R(Rn) );
  1181 :}
  1183 BF disp {:
  1184 	if( in_delay_slot ) {
  1185 	    SLOTILLEGAL();
  1186 	} else {
  1187 	    XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1188 	    XOP2IS( OP_CMP, 0, R_T );
  1189             XOP2ISCC( OP_ADD, CC_EQ, disp+pc+4-xbb->pc_begin, R_PC );
  1190             XOP2ISCC( OP_ADD, CC_NE, pc+2-xbb->pc_begin, R_PC );
  1191             XOP0( OP_EXIT );
  1193 	return 2;
  1194 :}
  1195 BF/S disp {:
  1196 	if( in_delay_slot ) {
  1197 	    SLOTILLEGAL();
  1198 	    return 2;
  1199 	} else {
  1200 	    if( UNTRANSLATABLE(pc+2 ) ) {
  1201 	        XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1202 	        XOP2SS( OP_MOV, R_PC, R_NEW_PC );
  1203 	        XOP2IS( OP_CMP, 0, R_T );
  1204 	        XOP2ISCC( OP_ADD, CC_EQ, disp+pc+4-xbb->pc_begin, R_NEW_PC );
  1205 	        XOP2ISCC( OP_ADD, CC_NE, pc+4-xbb->pc_begin, R_NEW_PC );
  1206 	    	EMU_DELAY_SLOT();
  1207 	    	return 2;
  1208 	    } else {
  1209 	    	XOP2ST( OP_MOV, R_T, REG_TMP2 );
  1210 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1211 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {	        
  1212 	            XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1213 	            XOP2IT( OP_CMP, 0, REG_TMP2 );
  1214 	            XOP2ISCC( OP_ADD, CC_EQ, disp+pc+4-xbb->pc_begin, R_PC );
  1215 	            XOP2ISCC( OP_ADD, CC_NE, pc+4-xbb->pc_begin, R_PC );
  1216 	            XOP0( OP_EXIT );
  1218 	        return 4;
  1221 :}
  1222 BT disp {:
  1223 	if( in_delay_slot ) {
  1224 	    SLOTILLEGAL();
  1225 	} else {
  1226 	    XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1227 	    XOP2IS( OP_CMP, 1, R_T );
  1228 	    XOP2ISCC( OP_ADD, CC_EQ, disp+pc+4-xbb->pc_begin, R_PC );
  1229 	    XOP2ISCC( OP_ADD, CC_NE, pc+2-xbb->pc_begin, R_PC );
  1230 	    XOP0( OP_EXIT );
  1232 	return 2;
  1233 :}
  1234 BT/S disp {:
  1235 	if( in_delay_slot ) {
  1236 	    SLOTILLEGAL();
  1237 	    return 2;
  1238 	} else {
  1239 	    if( UNTRANSLATABLE(pc+2 ) ) {
  1240 	        XOP2IS( OP_ADD, (pc+2 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1241 	        XOP2SS( OP_MOV, R_PC, R_NEW_PC );
  1242 	        XOP2IS( OP_CMP, 1, R_T );
  1243 	        XOP2ISCC( OP_ADD, CC_EQ, disp+pc+4-xbb->pc_begin, R_NEW_PC );
  1244 	        XOP2ISCC( OP_ADD, CC_NE, pc+4-xbb->pc_begin, R_NEW_PC );
  1245 	    	EMU_DELAY_SLOT();
  1246 	    	return 2;
  1247 	    } else {
  1248 	    	XOP2ST( OP_MOV, R_T, REG_TMP2 );
  1249 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1250 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {	        
  1251 	            XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1252 	            XOP2IT( OP_CMP, 1, REG_TMP2 );
  1253 	            XOP2ISCC( OP_ADD, CC_EQ, disp+pc+4-xbb->pc_begin, R_PC );
  1254 	            XOP2ISCC( OP_ADD, CC_NE, pc+4-xbb->pc_begin, R_PC );
  1255 	            XOP0( OP_EXIT );
  1257 	        return 4;
  1260 :}
  1261 BRA disp {:
  1262 	if( in_delay_slot ) {
  1263 	    SLOTILLEGAL();
  1264 	    return 2;
  1265 	} else {
  1266 	    if( UNTRANSLATABLE(pc+2) ) {
  1267 	        XOP2SS( OP_MOV, R_PC, R_NEW_PC );
  1268 	        XOP2IS( OP_ADD, pc+disp+4-xbb->pc_begin, R_NEW_PC );
  1269 	        EMU_DELAY_SLOT();
  1270 	        return 2;
  1271 	    } else {
  1272 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1273 	        if( xbb->ir_ptr->prev == NULL || !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1274 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1275 	            XOP2IS( OP_ADD, pc+disp+4-xbb->pc_begin, R_PC );
  1276 	            XOP0( OP_EXIT );
  1278 	        return 4;
  1281 :}
  1282 BRAF Rn {:
  1283 	if( in_delay_slot ) {
  1284 	    SLOTILLEGAL();
  1285 	    return 2;
  1286 	} else {
  1287 	    XOP2ST( OP_MOV, R_PC, REG_TMP2 );
  1288 	    XOP2IT( OP_ADD, pc - xbb->pc_begin + 4, REG_TMP2 );
  1289 	    XOP2ST( OP_ADD, R_R(Rn), REG_TMP2 );
  1290 	    if( UNTRANSLATABLE(pc+2) ) {
  1291 	        XOP2TS( OP_MOV, REG_TMP2, R_NEW_PC );
  1292 	        EMU_DELAY_SLOT();
  1293 	        return 2;
  1294 	    } else {
  1295 	        sh4_decode_instruction( xbb, pc + 2, TRUE );
  1296 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {	        
  1297 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1298 	            XOP2TS( OP_MOV, REG_TMP2, R_PC );
  1299 	            XOP0( OP_EXIT );
  1301 	        return 4;
  1304 :}
  1305 BSR disp {: 
  1306 	if( in_delay_slot ) {
  1307 	    SLOTILLEGAL();
  1308 	    return 2;
  1309 	} else {
  1310 	    XOP2SS( OP_MOV, R_PC, R_PR );
  1311 	    XOP2IS( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
  1312 	    if( UNTRANSLATABLE(pc+2) ) {
  1313 	        XOP2SS( OP_MOV, R_PC, R_NEW_PC );
  1314 	        XOP2IS( OP_ADD, pc+disp+4-xbb->pc_begin, R_NEW_PC );
  1315 	        EMU_DELAY_SLOT();
  1316 	        return 2;
  1317 	    } else {
  1318 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1319 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1320 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1321 	            XOP2IS( OP_ADD, pc+disp+4-xbb->pc_begin, R_PC );
  1322 	            XOP0( OP_EXIT );
  1324 	        return 4;
  1327 :}
  1328 BSRF Rn {:  
  1329 	if( in_delay_slot ) {
  1330 	    SLOTILLEGAL();
  1331 	    return 2;
  1332 	} else {
  1333 	    XOP2SS( OP_MOV, R_PC, R_PR );
  1334 	    XOP2IS( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
  1335 	    XOP2ST( OP_MOV, R_R(Rn), REG_TMP2 );
  1336 	    XOP2ST( OP_ADD, R_PC, REG_TMP2 );
  1337 	    XOP2IT( OP_ADD, pc - xbb->pc_begin + 4, REG_TMP2 );
  1338 	    if( UNTRANSLATABLE(pc+2) ) {
  1339 	        XOP2TS( OP_MOV, REG_TMP2, R_NEW_PC );
  1340 	        EMU_DELAY_SLOT();
  1341 	        return 2;
  1342 	    } else {
  1343 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1344 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1345 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1346 	            XOP2TS( OP_ADD, REG_TMP2, R_PC );
  1347 	            XOP0( OP_EXIT );
  1349 	        return 4;
  1352 :}
  1353 JMP @Rn {:  
  1354 	if( in_delay_slot ) {
  1355 	    SLOTILLEGAL();
  1356 	    return 2;
  1357 	} else {
  1358 	    if( UNTRANSLATABLE(pc+2) ) {
  1359 	        XOP2SS( OP_MOV, R_R(Rn), R_NEW_PC );
  1360 	        EMU_DELAY_SLOT();
  1361 	        return 2;
  1362 	    } else {
  1363 	        XOP2ST( OP_MOV, R_R(Rn), REG_TMP2 );
  1364 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1365 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1366 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1367 	            XOP2TS( OP_MOV, REG_TMP2, R_PC );
  1368 	            XOP0( OP_EXIT );
  1370 	        return 4;
  1373 :}
  1374 JSR @Rn {:  
  1375 	if( in_delay_slot ) {
  1376 	    SLOTILLEGAL();
  1377 	    return 2;
  1378 	} else {
  1379 	    XOP2SS( OP_MOV, R_PC, R_PR );
  1380 	    XOP2IS( OP_ADD, pc - xbb->pc_begin + 4, R_PR );
  1381 	    if( UNTRANSLATABLE(pc+2) ) {
  1382 	        XOP2SS( OP_MOV, R_R(Rn), R_NEW_PC );
  1383 	        EMU_DELAY_SLOT();
  1384 	        return 2;
  1385 	    } else { 
  1386 	        XOP2ST( OP_MOV, R_R(Rn), REG_TMP2 );
  1387 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1388 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1389 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1390 	            XOP2TS( OP_MOV, REG_TMP2, R_PC );
  1391 	            XOP0( OP_EXIT );
  1393 	        return 4;
  1396 :}
  1397 RTE {:  
  1398 	CHECKPRIV();
  1399 	if( in_delay_slot ) {
  1400 	    SLOTILLEGAL();
  1401 	    return 2;
  1402 	} else {
  1403 	    if( UNTRANSLATABLE(pc+2) ) {
  1404 	        XOP2SS( OP_MOV, R_SPC, R_NEW_PC );
  1405 	        EMU_DELAY_SLOT();
  1406 	        return 2;
  1407 	    } else {
  1408 	        XOP2ST( OP_MOV, R_SPC, REG_TMP2 );
  1409 	        XOPCALL1S( sh4_write_sr, R_SSR );
  1410 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1411 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1412 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1413 	            XOP2TS( OP_MOV, REG_TMP2, R_PC );
  1414 	            XOP0( OP_EXIT );
  1416 	        return 4;
  1419 :}
  1420 RTS {:  
  1421 	if( in_delay_slot ) {
  1422 	    SLOTILLEGAL();
  1423 	    return 2;
  1424 	} else {
  1425 	    if( UNTRANSLATABLE(pc+2) ) {
  1426 	        XOP2SS( OP_MOV, R_PR, R_NEW_PC );
  1427 	        EMU_DELAY_SLOT();
  1428 	        return 2;
  1429 	    } else {
  1430 	        XOP2ST( OP_MOV, R_PR, REG_TMP2 );
  1431 	        sh4_decode_instruction( xbb, pc+2, TRUE );
  1432 	        if( !XOP_IS_TERMINATOR( xbb->ir_ptr->prev ) ) {
  1433 		    XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1434 	            XOP2TS( OP_MOV, REG_TMP2, R_PC );
  1435 	            XOP0( OP_EXIT );
  1437 	        return 4;
  1440 :}
  1441 TRAPA #imm {:
  1442 	XOP2IS( OP_ADD, (pc+4 - xbb->pc_begin) * sh4_cpu_period, R_SLICE_CYCLE );
  1443         XOP2IS( OP_ADD, pc+4-xbb->pc_begin, R_PC );
  1444 	XOPCALL1I( sh4_raise_trap, imm ); 
  1445 	XOP0( OP_EXIT ); 
  1446 	return 2; 
  1447 :} 
  1448 SLEEP      {: 
  1449 	XOPCALL0( sh4_sleep ); 
  1450 	XOP0( OP_EXIT); 
  1451 	return 2; 
  1452 :} 
  1453 UNDEF      {: UNDEF(ir); :}
  1454 NOP        {: /* Do nothing */ :}
  1456 %% 
  1457     return 0; 
  1461 sh4addr_t sh4_decode_basic_block( xir_basic_block_t xbb )
  1463     sh4addr_t pc;
  1465     sh4_xir.fpuen_checked = FALSE;
  1466     sh4_xir.double_prec = sh4r.fpscr & FPSCR_PR;
  1467     sh4_xir.double_size = sh4r.fpscr & FPSCR_SZ;
  1468     xbb->address_space = (sh4r.xlat_sh4_mode&SR_MD) ? sh4_address_space : sh4_user_address_space;
  1470     xbb->ir_alloc_begin->prev = NULL;
  1471     XOP1I( OP_ENTER, 0 );    
  1472     for( pc = xbb->pc_begin; pc < xbb->pc_end; pc += 2 ) {
  1473 	int done = sh4_decode_instruction( xbb, pc, FALSE );
  1474 	if( done ) {
  1475 	    pc += done;
  1476 	    break;
  1479     xbb->ir_end = xbb->ir_ptr-1;
  1480     xbb->ir_end->next = NULL;
  1481     xbb->pc_end = pc;
  1482     return pc;
.