Search
lxdream.org :: lxdream/src/sh4/sh4x86.in
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 1065:bc1cc0c54917
prev1008:4c8211637afc
prev584:5c29dd7297df
next1067:d3c00ffccfcd
author nkeynes
date Sun Jul 05 13:52:50 2009 +1000 (14 years ago)
permissions -rw-r--r--
last change No-op merge lxdream-mmu to remove head (actually merged long ago)
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * 
     4  * SH4 => x86 translation. This version does no real optimization, it just
     5  * outputs straight-line x86 code - it mainly exists to provide a baseline
     6  * to test the optimizing versions against.
     7  *
     8  * Copyright (c) 2007 Nathan Keynes.
     9  *
    10  * This program is free software; you can redistribute it and/or modify
    11  * it under the terms of the GNU General Public License as published by
    12  * the Free Software Foundation; either version 2 of the License, or
    13  * (at your option) any later version.
    14  *
    15  * This program is distributed in the hope that it will be useful,
    16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    18  * GNU General Public License for more details.
    19  */
    21 #include <assert.h>
    22 #include <math.h>
    24 #ifndef NDEBUG
    25 #define DEBUG_JUMPS 1
    26 #endif
    28 #include "lxdream.h"
    29 #include "sh4/sh4core.h"
    30 #include "sh4/sh4trans.h"
    31 #include "sh4/sh4stat.h"
    32 #include "sh4/sh4mmio.h"
    33 #include "sh4/mmu.h"
    34 #include "xlat/xltcache.h"
    35 #include "xlat/x86/x86op.h"
    36 #include "clock.h"
    38 #define DEFAULT_BACKPATCH_SIZE 4096
    40 /* Offset of a reg relative to the sh4r structure */
    41 #define REG_OFFSET(reg)  (((char *)&sh4r.reg) - ((char *)&sh4r) - 128)
    43 #define R_T      REG_OFFSET(t)
    44 #define R_Q      REG_OFFSET(q)
    45 #define R_S      REG_OFFSET(s)
    46 #define R_M      REG_OFFSET(m)
    47 #define R_SR     REG_OFFSET(sr)
    48 #define R_GBR    REG_OFFSET(gbr)
    49 #define R_SSR    REG_OFFSET(ssr)
    50 #define R_SPC    REG_OFFSET(spc)
    51 #define R_VBR    REG_OFFSET(vbr)
    52 #define R_MACH   REG_OFFSET(mac)+4
    53 #define R_MACL   REG_OFFSET(mac)
    54 #define R_PC     REG_OFFSET(pc)
    55 #define R_NEW_PC REG_OFFSET(new_pc)
    56 #define R_PR     REG_OFFSET(pr)
    57 #define R_SGR    REG_OFFSET(sgr)
    58 #define R_FPUL   REG_OFFSET(fpul)
    59 #define R_FPSCR  REG_OFFSET(fpscr)
    60 #define R_DBR    REG_OFFSET(dbr)
    61 #define R_R(rn)  REG_OFFSET(r[rn])
    62 #define R_FR(f)  REG_OFFSET(fr[0][(f)^1])
    63 #define R_XF(f)  REG_OFFSET(fr[1][(f)^1])
    64 #define R_DR(f)  REG_OFFSET(fr[(f)&1][(f)&0x0E])
    65 #define R_DRL(f) REG_OFFSET(fr[(f)&1][(f)|0x01])
    66 #define R_DRH(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])
    68 #define DELAY_NONE 0
    69 #define DELAY_PC 1
    70 #define DELAY_PC_PR 2
    72 struct backpatch_record {
    73     uint32_t fixup_offset;
    74     uint32_t fixup_icount;
    75     int32_t exc_code;
    76 };
    78 /** 
    79  * Struct to manage internal translation state. This state is not saved -
    80  * it is only valid between calls to sh4_translate_begin_block() and
    81  * sh4_translate_end_block()
    82  */
    83 struct sh4_x86_state {
    84     int in_delay_slot;
    85     gboolean fpuen_checked; /* true if we've already checked fpu enabled. */
    86     gboolean branch_taken; /* true if we branched unconditionally */
    87     gboolean double_prec; /* true if FPU is in double-precision mode */
    88     gboolean double_size; /* true if FPU is in double-size mode */
    89     gboolean sse3_enabled; /* true if host supports SSE3 instructions */
    90     uint32_t block_start_pc;
    91     uint32_t stack_posn;   /* Trace stack height for alignment purposes */
    92     int tstate;
    94     /* mode flags */
    95     gboolean tlb_on; /* True if tlb translation is active */
    97     /* Allocated memory for the (block-wide) back-patch list */
    98     struct backpatch_record *backpatch_list;
    99     uint32_t backpatch_posn;
   100     uint32_t backpatch_size;
   101 };
   103 static struct sh4_x86_state sh4_x86;
   105 static uint32_t max_int = 0x7FFFFFFF;
   106 static uint32_t min_int = 0x80000000;
   107 static uint32_t save_fcw; /* save value for fpu control word */
   108 static uint32_t trunc_fcw = 0x0F7F; /* fcw value for truncation mode */
   110 gboolean is_sse3_supported()
   111 {
   112     uint32_t features;
   114     __asm__ __volatile__(
   115         "mov $0x01, %%eax\n\t"
   116         "cpuid\n\t" : "=c" (features) : : "eax", "edx", "ebx");
   117     return (features & 1) ? TRUE : FALSE;
   118 }
   120 void sh4_translate_init(void)
   121 {
   122     sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
   123     sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
   124     sh4_x86.sse3_enabled = is_sse3_supported();
   125 }
   128 static void sh4_x86_add_backpatch( uint8_t *fixup_addr, uint32_t fixup_pc, uint32_t exc_code )
   129 {
   130     int reloc_size = 4;
   132     if( exc_code == -2 ) {
   133         reloc_size = sizeof(void *);
   134     }
   136     if( sh4_x86.backpatch_posn == sh4_x86.backpatch_size ) {
   137 	sh4_x86.backpatch_size <<= 1;
   138 	sh4_x86.backpatch_list = realloc( sh4_x86.backpatch_list, 
   139 					  sh4_x86.backpatch_size * sizeof(struct backpatch_record));
   140 	assert( sh4_x86.backpatch_list != NULL );
   141     }
   142     if( sh4_x86.in_delay_slot ) {
   143 	fixup_pc -= 2;
   144     }
   146     sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_offset = 
   147 	(((uint8_t *)fixup_addr) - ((uint8_t *)xlat_current_block->code)) - reloc_size;
   148     sh4_x86.backpatch_list[sh4_x86.backpatch_posn].fixup_icount = (fixup_pc - sh4_x86.block_start_pc)>>1;
   149     sh4_x86.backpatch_list[sh4_x86.backpatch_posn].exc_code = exc_code;
   150     sh4_x86.backpatch_posn++;
   151 }
   153 #define TSTATE_NONE -1
   154 #define TSTATE_O    X86_COND_O
   155 #define TSTATE_C    X86_COND_C
   156 #define TSTATE_E    X86_COND_E
   157 #define TSTATE_NE   X86_COND_NE
   158 #define TSTATE_G    X86_COND_G
   159 #define TSTATE_GE   X86_COND_GE
   160 #define TSTATE_A    X86_COND_A
   161 #define TSTATE_AE   X86_COND_AE
   163 #define MARK_JMP8(x) uint8_t *_mark_jmp_##x = (xlat_output-1)
   164 #define JMP_TARGET(x) *_mark_jmp_##x += (xlat_output - _mark_jmp_##x)
   166 /* Convenience instructions */
   167 #define LDC_t()          CMPB_imms_rbpdisp(1,R_T); CMC()
   168 #define SETE_t()         SETCCB_cc_rbpdisp(X86_COND_E,R_T)
   169 #define SETA_t()         SETCCB_cc_rbpdisp(X86_COND_A,R_T)
   170 #define SETAE_t()        SETCCB_cc_rbpdisp(X86_COND_AE,R_T)
   171 #define SETG_t()         SETCCB_cc_rbpdisp(X86_COND_G,R_T)
   172 #define SETGE_t()        SETCCB_cc_rbpdisp(X86_COND_GE,R_T)
   173 #define SETC_t()         SETCCB_cc_rbpdisp(X86_COND_C,R_T)
   174 #define SETO_t()         SETCCB_cc_rbpdisp(X86_COND_O,R_T)
   175 #define SETNE_t()        SETCCB_cc_rbpdisp(X86_COND_NE,R_T)
   176 #define SETC_r8(r1)      SETCCB_cc_r8(X86_COND_C, r1)
   177 #define JAE_label(label) JCC_cc_rel8(X86_COND_AE,-1); MARK_JMP8(label)
   178 #define JE_label(label)  JCC_cc_rel8(X86_COND_E,-1); MARK_JMP8(label)
   179 #define JGE_label(label) JCC_cc_rel8(X86_COND_GE,-1); MARK_JMP8(label)
   180 #define JNA_label(label) JCC_cc_rel8(X86_COND_NA,-1); MARK_JMP8(label)
   181 #define JNE_label(label) JCC_cc_rel8(X86_COND_NE,-1); MARK_JMP8(label)
   182 #define JNO_label(label) JCC_cc_rel8(X86_COND_NO,-1); MARK_JMP8(label)
   183 #define JS_label(label)  JCC_cc_rel8(X86_COND_S,-1); MARK_JMP8(label)
   184 #define JMP_label(label) JMP_rel8(-1); MARK_JMP8(label)
   185 #define JNE_exc(exc)     JCC_cc_rel32(X86_COND_NE,0); sh4_x86_add_backpatch(xlat_output, pc, exc)
   187 /** Branch if T is set (either in the current cflags, or in sh4r.t) */
   188 #define JT_label(label) if( sh4_x86.tstate == TSTATE_NONE ) { \
   189 	CMPL_imms_rbpdisp( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
   190     JCC_cc_rel8(sh4_x86.tstate,-1); MARK_JMP8(label)
   192 /** Branch if T is clear (either in the current cflags or in sh4r.t) */
   193 #define JF_label(label) if( sh4_x86.tstate == TSTATE_NONE ) { \
   194 	CMPL_imms_rbpdisp( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
   195     JCC_cc_rel8(sh4_x86.tstate^1, -1); MARK_JMP8(label)
   198 #define load_reg(x86reg,sh4reg)     MOVL_rbpdisp_r32( REG_OFFSET(r[sh4reg]), x86reg )
   199 #define store_reg(x86reg,sh4reg)    MOVL_r32_rbpdisp( x86reg, REG_OFFSET(r[sh4reg]) )
   201 /**
   202  * Load an FR register (single-precision floating point) into an integer x86
   203  * register (eg for register-to-register moves)
   204  */
   205 #define load_fr(reg,frm)  MOVL_rbpdisp_r32( REG_OFFSET(fr[0][(frm)^1]), reg )
   206 #define load_xf(reg,frm)  MOVL_rbpdisp_r32( REG_OFFSET(fr[1][(frm)^1]), reg )
   208 /**
   209  * Load the low half of a DR register (DR or XD) into an integer x86 register 
   210  */
   211 #define load_dr0(reg,frm) MOVL_rbpdisp_r32( REG_OFFSET(fr[frm&1][frm|0x01]), reg )
   212 #define load_dr1(reg,frm) MOVL_rbpdisp_r32( REG_OFFSET(fr[frm&1][frm&0x0E]), reg )
   214 /**
   215  * Store an FR register (single-precision floating point) from an integer x86+
   216  * register (eg for register-to-register moves)
   217  */
   218 #define store_fr(reg,frm) MOVL_r32_rbpdisp( reg, REG_OFFSET(fr[0][(frm)^1]) )
   219 #define store_xf(reg,frm) MOVL_r32_rbpdisp( reg, REG_OFFSET(fr[1][(frm)^1]) )
   221 #define store_dr0(reg,frm) MOVL_r32_rbpdisp( reg, REG_OFFSET(fr[frm&1][frm|0x01]) )
   222 #define store_dr1(reg,frm) MOVL_r32_rbpdisp( reg, REG_OFFSET(fr[frm&1][frm&0x0E]) )
   225 #define push_fpul()  FLDF_rbpdisp(R_FPUL)
   226 #define pop_fpul()   FSTPF_rbpdisp(R_FPUL)
   227 #define push_fr(frm) FLDF_rbpdisp( REG_OFFSET(fr[0][(frm)^1]) )
   228 #define pop_fr(frm)  FSTPF_rbpdisp( REG_OFFSET(fr[0][(frm)^1]) )
   229 #define push_xf(frm) FLDF_rbpdisp( REG_OFFSET(fr[1][(frm)^1]) )
   230 #define pop_xf(frm)  FSTPF_rbpdisp( REG_OFFSET(fr[1][(frm)^1]) )
   231 #define push_dr(frm) FLDD_rbpdisp( REG_OFFSET(fr[0][(frm)&0x0E]) )
   232 #define pop_dr(frm)  FSTPD_rbpdisp( REG_OFFSET(fr[0][(frm)&0x0E]) )
   233 #define push_xdr(frm) FLDD_rbpdisp( REG_OFFSET(fr[1][(frm)&0x0E]) )
   234 #define pop_xdr(frm)  FSTPD_rbpdisp( REG_OFFSET(fr[1][(frm)&0x0E]) )
   236 #ifdef ENABLE_SH4STATS
   237 #define COUNT_INST(id) MOVL_imm32_r32( id, REG_EAX ); CALL1_ptr_r32(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE
   238 #else
   239 #define COUNT_INST(id)
   240 #endif
   243 /* Exception checks - Note that all exception checks will clobber EAX */
   245 #define check_priv( ) \
   246     if( (sh4r.xlat_sh4_mode & SR_MD) == 0 ) { \
   247         if( sh4_x86.in_delay_slot ) { \
   248             exit_block_exc(EXC_SLOT_ILLEGAL, (pc-2) ); \
   249         } else { \
   250             exit_block_exc(EXC_ILLEGAL, pc); \
   251         } \
   252         sh4_x86.branch_taken = TRUE; \
   253         sh4_x86.in_delay_slot = DELAY_NONE; \
   254         return 2; \
   255     }
   257 #define check_fpuen( ) \
   258     if( !sh4_x86.fpuen_checked ) {\
   259 	sh4_x86.fpuen_checked = TRUE;\
   260 	MOVL_rbpdisp_r32( R_SR, REG_EAX );\
   261 	ANDL_imms_r32( SR_FD, REG_EAX );\
   262 	if( sh4_x86.in_delay_slot ) {\
   263 	    JNE_exc(EXC_SLOT_FPU_DISABLED);\
   264 	} else {\
   265 	    JNE_exc(EXC_FPU_DISABLED);\
   266 	}\
   267 	sh4_x86.tstate = TSTATE_NONE; \
   268     }
   270 #define check_ralign16( x86reg ) \
   271     TESTL_imms_r32( 0x00000001, x86reg ); \
   272     JNE_exc(EXC_DATA_ADDR_READ)
   274 #define check_walign16( x86reg ) \
   275     TESTL_imms_r32( 0x00000001, x86reg ); \
   276     JNE_exc(EXC_DATA_ADDR_WRITE);
   278 #define check_ralign32( x86reg ) \
   279     TESTL_imms_r32( 0x00000003, x86reg ); \
   280     JNE_exc(EXC_DATA_ADDR_READ)
   282 #define check_walign32( x86reg ) \
   283     TESTL_imms_r32( 0x00000003, x86reg ); \
   284     JNE_exc(EXC_DATA_ADDR_WRITE);
   286 #define check_ralign64( x86reg ) \
   287     TESTL_imms_r32( 0x00000007, x86reg ); \
   288     JNE_exc(EXC_DATA_ADDR_READ)
   290 #define check_walign64( x86reg ) \
   291     TESTL_imms_r32( 0x00000007, x86reg ); \
   292     JNE_exc(EXC_DATA_ADDR_WRITE);
   294 #define address_space() ((sh4r.xlat_sh4_mode&SR_MD) ? (uintptr_t)sh4_address_space : (uintptr_t)sh4_user_address_space)
   296 #define UNDEF(ir)
   297 /* Note: For SR.MD == 1 && MMUCR.AT == 0, there are no memory exceptions, so 
   298  * don't waste the cycles expecting them. Otherwise we need to save the exception pointer.
   299  */
   300 #ifdef HAVE_FRAME_ADDRESS
   301 static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
   302 {
   303     decode_address(address_space(), addr_reg);
   304     if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { 
   305         CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
   306     } else {
   307         if( addr_reg != REG_ARG1 ) {
   308             MOVL_r32_r32( addr_reg, REG_ARG1 );
   309         }
   310         MOVP_immptr_rptr( 0, REG_ARG2 );
   311         sh4_x86_add_backpatch( xlat_output, pc, -2 );
   312         CALL2_r32disp_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2);
   313     }
   314     if( value_reg != REG_RESULT1 ) { 
   315         MOVL_r32_r32( REG_RESULT1, value_reg );
   316     }
   317 }
   319 static void call_write_func(int addr_reg, int value_reg, int offset, int pc)
   320 {
   321     decode_address(address_space(), addr_reg);
   322     if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { 
   323         CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
   324     } else {
   325         if( value_reg != REG_ARG2 ) {
   326             MOVL_r32_r32( value_reg, REG_ARG2 );
   327 	}        
   328         if( addr_reg != REG_ARG1 ) {
   329             MOVL_r32_r32( addr_reg, REG_ARG1 );
   330         }
   331 #if MAX_REG_ARG > 2        
   332         MOVP_immptr_rptr( 0, REG_ARG3 );
   333         sh4_x86_add_backpatch( xlat_output, pc, -2 );
   334         CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, REG_ARG3);
   335 #else
   336         MOVL_imm32_rspdisp( 0, 0 );
   337         sh4_x86_add_backpatch( xlat_output, pc, -2 );
   338         CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, 0);
   339 #endif
   340     }
   341 }
   342 #else
   343 static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
   344 {
   345     decode_address(address_space(), addr_reg);
   346     CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
   347     if( value_reg != REG_RESULT1 ) {
   348         MOVL_r32_r32( REG_RESULT1, value_reg );
   349     }
   350 }     
   352 static void call_write_func(int addr_reg, int value_reg, int offset, int pc)
   353 {
   354     decode_address(address_space(), addr_reg);
   355     CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
   356 }
   357 #endif
   359 #define MEM_REGION_PTR(name) offsetof( struct mem_region_fn, name )
   360 #define MEM_READ_BYTE( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_byte), pc)
   361 #define MEM_READ_BYTE_FOR_WRITE( addr_reg, value_reg ) call_read_func( addr_reg, value_reg, MEM_REGION_PTR(read_byte_for_write), pc) 
   362 #define MEM_READ_WORD( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_word), pc)
   363 #define MEM_READ_LONG( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_long), pc)
   364 #define MEM_WRITE_BYTE( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_byte), pc)
   365 #define MEM_WRITE_WORD( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_word), pc)
   366 #define MEM_WRITE_LONG( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_long), pc)
   367 #define MEM_PREFETCH( addr_reg ) call_read_func(addr_reg, REG_RESULT1, MEM_REGION_PTR(prefetch), pc)
   369 #define SLOTILLEGAL() exit_block_exc(EXC_SLOT_ILLEGAL, pc-2); sh4_x86.in_delay_slot = DELAY_NONE; return 2;
   371 void sh4_translate_begin_block( sh4addr_t pc ) 
   372 {
   373     enter_block();
   374     MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );
   375     sh4_x86.in_delay_slot = FALSE;
   376     sh4_x86.fpuen_checked = FALSE;
   377     sh4_x86.branch_taken = FALSE;
   378     sh4_x86.backpatch_posn = 0;
   379     sh4_x86.block_start_pc = pc;
   380     sh4_x86.tlb_on = IS_TLB_ENABLED();
   381     sh4_x86.tstate = TSTATE_NONE;
   382     sh4_x86.double_prec = sh4r.fpscr & FPSCR_PR;
   383     sh4_x86.double_size = sh4r.fpscr & FPSCR_SZ;
   384 }
   387 uint32_t sh4_translate_end_block_size()
   388 {
   389     if( sh4_x86.backpatch_posn <= 3 ) {
   390         return EPILOGUE_SIZE + (sh4_x86.backpatch_posn*24);
   391     } else {
   392         return EPILOGUE_SIZE + 72 + (sh4_x86.backpatch_posn-3)*27;
   393     }
   394 }
   397 /**
   398  * Embed a breakpoint into the generated code
   399  */
   400 void sh4_translate_emit_breakpoint( sh4vma_t pc )
   401 {
   402     MOVL_imm32_r32( pc, REG_EAX );
   403     CALL1_ptr_r32( sh4_translate_breakpoint_hit, REG_EAX );
   404     sh4_x86.tstate = TSTATE_NONE;
   405 }
   408 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
   410 /**
   411  * Exit the block with sh4r.pc already written
   412  */
   413 void exit_block_pcset( sh4addr_t pc )
   414 {
   415     MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
   416     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
   417     MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
   418     if( sh4_x86.tlb_on ) {
   419         CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
   420     } else {
   421         CALL1_ptr_r32(xlat_get_code,REG_ARG1);
   422     }
   423     exit_block();
   424 }
   426 /**
   427  * Exit the block with sh4r.new_pc written with the target pc
   428  */
   429 void exit_block_newpcset( sh4addr_t pc )
   430 {
   431     MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
   432     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
   433     MOVL_rbpdisp_r32( R_NEW_PC, REG_ARG1 );
   434     MOVL_r32_rbpdisp( REG_ARG1, R_PC );
   435     if( sh4_x86.tlb_on ) {
   436         CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
   437     } else {
   438         CALL1_ptr_r32(xlat_get_code,REG_ARG1);
   439     }
   440     exit_block();
   441 }
   444 /**
   445  * Exit the block to an absolute PC
   446  */
   447 void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )
   448 {
   449     MOVL_imm32_r32( pc, REG_ECX );
   450     MOVL_r32_rbpdisp( REG_ECX, R_PC );
   451     if( IS_IN_ICACHE(pc) ) {
   452         MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
   453         ANDP_imms_rptr( -4, REG_EAX );
   454     } else if( sh4_x86.tlb_on ) {
   455         CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);
   456     } else {
   457         CALL1_ptr_r32(xlat_get_code, REG_ECX);
   458     }
   459     MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
   460     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
   461     exit_block();
   462 }
   464 /**
   465  * Exit the block to a relative PC
   466  */
   467 void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )
   468 {
   469     MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );
   470     ADDL_rbpdisp_r32( R_PC, REG_ECX );
   471     MOVL_r32_rbpdisp( REG_ECX, R_PC );
   472     if( IS_IN_ICACHE(pc) ) {
   473         MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
   474         ANDP_imms_rptr( -4, REG_EAX );
   475     } else if( sh4_x86.tlb_on ) {
   476         CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);
   477     } else {
   478         CALL1_ptr_r32(xlat_get_code, REG_ECX);
   479     }
   480     MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
   481     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
   482     exit_block();
   483 }
   485 /**
   486  * Exit unconditionally with a general exception
   487  */
   488 void exit_block_exc( int code, sh4addr_t pc )
   489 {
   490     MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );
   491     ADDL_r32_rbpdisp( REG_ECX, R_PC );
   492     MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
   493     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
   494     MOVL_imm32_r32( code, REG_ARG1 );
   495     CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );
   496     MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
   497     if( sh4_x86.tlb_on ) {
   498         CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
   499     } else {
   500         CALL1_ptr_r32(xlat_get_code,REG_ARG1);
   501     }
   503     exit_block();
   504 }    
   506 /**
   507  * Embed a call to sh4_execute_instruction for situations that we
   508  * can't translate (just page-crossing delay slots at the moment).
   509  * Caller is responsible for setting new_pc before calling this function.
   510  *
   511  * Performs:
   512  *   Set PC = endpc
   513  *   Set sh4r.in_delay_slot = sh4_x86.in_delay_slot
   514  *   Update slice_cycle for endpc+2 (single step doesn't update slice_cycle)
   515  *   Call sh4_execute_instruction
   516  *   Call xlat_get_code_by_vma / xlat_get_code as for normal exit
   517  */
   518 void exit_block_emu( sh4vma_t endpc )
   519 {
   520     MOVL_imm32_r32( endpc - sh4_x86.block_start_pc, REG_ECX );   // 5
   521     ADDL_r32_rbpdisp( REG_ECX, R_PC );
   523     MOVL_imm32_r32( (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period, REG_ECX ); // 5
   524     ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );     // 6
   525     MOVL_imm32_r32( sh4_x86.in_delay_slot ? 1 : 0, REG_ECX );
   526     MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(in_delay_slot) );
   528     CALL_ptr( sh4_execute_instruction );    
   529     MOVL_rbpdisp_r32( R_PC, REG_EAX );
   530     if( sh4_x86.tlb_on ) {
   531 	CALL1_ptr_r32(xlat_get_code_by_vma,REG_EAX);
   532     } else {
   533 	CALL1_ptr_r32(xlat_get_code,REG_EAX);
   534     }
   535     exit_block();
   536 } 
   538 /**
   539  * Write the block trailer (exception handling block)
   540  */
   541 void sh4_translate_end_block( sh4addr_t pc ) {
   542     if( sh4_x86.branch_taken == FALSE ) {
   543         // Didn't exit unconditionally already, so write the termination here
   544         exit_block_rel( pc, pc );
   545     }
   546     if( sh4_x86.backpatch_posn != 0 ) {
   547         unsigned int i;
   548         // Exception raised - cleanup and exit
   549         uint8_t *end_ptr = xlat_output;
   550         MOVL_r32_r32( REG_EDX, REG_ECX );
   551         ADDL_r32_r32( REG_EDX, REG_ECX );
   552         ADDL_r32_rbpdisp( REG_ECX, R_SPC );
   553         MOVL_moffptr_eax( &sh4_cpu_period );
   554         MULL_r32( REG_EDX );
   555         ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );
   556         MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
   557         if( sh4_x86.tlb_on ) {
   558             CALL1_ptr_r32(xlat_get_code_by_vma, REG_ARG1);
   559         } else {
   560             CALL1_ptr_r32(xlat_get_code, REG_ARG1);
   561         }
   562         exit_block();
   564         for( i=0; i< sh4_x86.backpatch_posn; i++ ) {
   565             uint32_t *fixup_addr = (uint32_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset];
   566             if( sh4_x86.backpatch_list[i].exc_code < 0 ) {
   567                 if( sh4_x86.backpatch_list[i].exc_code == -2 ) {
   568                     *((uintptr_t *)fixup_addr) = (uintptr_t)xlat_output; 
   569                 } else {
   570                     *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;
   571                 }
   572                 MOVL_imm32_r32( sh4_x86.backpatch_list[i].fixup_icount, REG_EDX );
   573                 int rel = end_ptr - xlat_output;
   574                 JMP_prerel(rel);
   575             } else {
   576                 *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;
   577                 MOVL_imm32_r32( sh4_x86.backpatch_list[i].exc_code, REG_ARG1 );
   578                 CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );
   579                 MOVL_imm32_r32( sh4_x86.backpatch_list[i].fixup_icount, REG_EDX );
   580                 int rel = end_ptr - xlat_output;
   581                 JMP_prerel(rel);
   582             }
   583         }
   584     }
   585 }
   587 /**
   588  * Translate a single instruction. Delayed branches are handled specially
   589  * by translating both branch and delayed instruction as a single unit (as
   590  * 
   591  * The instruction MUST be in the icache (assert check)
   592  *
   593  * @return true if the instruction marks the end of a basic block
   594  * (eg a branch or 
   595  */
   596 uint32_t sh4_translate_instruction( sh4vma_t pc )
   597 {
   598     uint32_t ir;
   599     /* Read instruction from icache */
   600     assert( IS_IN_ICACHE(pc) );
   601     ir = *(uint16_t *)GET_ICACHE_PTR(pc);
   603     if( !sh4_x86.in_delay_slot ) {
   604 	sh4_translate_add_recovery( (pc - sh4_x86.block_start_pc)>>1 );
   605     }
   607     /* check for breakpoints at this pc */
   608     for( int i=0; i<sh4_breakpoint_count; i++ ) {
   609         if( sh4_breakpoints[i].address == pc ) {
   610             sh4_translate_emit_breakpoint(pc);
   611             break;
   612         }
   613     }
   614 %%
   615 /* ALU operations */
   616 ADD Rm, Rn {:
   617     COUNT_INST(I_ADD);
   618     load_reg( REG_EAX, Rm );
   619     load_reg( REG_ECX, Rn );
   620     ADDL_r32_r32( REG_EAX, REG_ECX );
   621     store_reg( REG_ECX, Rn );
   622     sh4_x86.tstate = TSTATE_NONE;
   623 :}
   624 ADD #imm, Rn {:  
   625     COUNT_INST(I_ADDI);
   626     ADDL_imms_rbpdisp( imm, REG_OFFSET(r[Rn]) );
   627     sh4_x86.tstate = TSTATE_NONE;
   628 :}
   629 ADDC Rm, Rn {:
   630     COUNT_INST(I_ADDC);
   631     if( sh4_x86.tstate != TSTATE_C ) {
   632         LDC_t();
   633     }
   634     load_reg( REG_EAX, Rm );
   635     load_reg( REG_ECX, Rn );
   636     ADCL_r32_r32( REG_EAX, REG_ECX );
   637     store_reg( REG_ECX, Rn );
   638     SETC_t();
   639     sh4_x86.tstate = TSTATE_C;
   640 :}
   641 ADDV Rm, Rn {:
   642     COUNT_INST(I_ADDV);
   643     load_reg( REG_EAX, Rm );
   644     load_reg( REG_ECX, Rn );
   645     ADDL_r32_r32( REG_EAX, REG_ECX );
   646     store_reg( REG_ECX, Rn );
   647     SETO_t();
   648     sh4_x86.tstate = TSTATE_O;
   649 :}
   650 AND Rm, Rn {:
   651     COUNT_INST(I_AND);
   652     load_reg( REG_EAX, Rm );
   653     load_reg( REG_ECX, Rn );
   654     ANDL_r32_r32( REG_EAX, REG_ECX );
   655     store_reg( REG_ECX, Rn );
   656     sh4_x86.tstate = TSTATE_NONE;
   657 :}
   658 AND #imm, R0 {:  
   659     COUNT_INST(I_ANDI);
   660     load_reg( REG_EAX, 0 );
   661     ANDL_imms_r32(imm, REG_EAX); 
   662     store_reg( REG_EAX, 0 );
   663     sh4_x86.tstate = TSTATE_NONE;
   664 :}
   665 AND.B #imm, @(R0, GBR) {: 
   666     COUNT_INST(I_ANDB);
   667     load_reg( REG_EAX, 0 );
   668     ADDL_rbpdisp_r32( R_GBR, REG_EAX );
   669     MOVL_r32_rspdisp(REG_EAX, 0);
   670     MEM_READ_BYTE_FOR_WRITE( REG_EAX, REG_EDX );
   671     MOVL_rspdisp_r32(0, REG_EAX);
   672     ANDL_imms_r32(imm, REG_EDX );
   673     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
   674     sh4_x86.tstate = TSTATE_NONE;
   675 :}
   676 CMP/EQ Rm, Rn {:  
   677     COUNT_INST(I_CMPEQ);
   678     load_reg( REG_EAX, Rm );
   679     load_reg( REG_ECX, Rn );
   680     CMPL_r32_r32( REG_EAX, REG_ECX );
   681     SETE_t();
   682     sh4_x86.tstate = TSTATE_E;
   683 :}
   684 CMP/EQ #imm, R0 {:  
   685     COUNT_INST(I_CMPEQI);
   686     load_reg( REG_EAX, 0 );
   687     CMPL_imms_r32(imm, REG_EAX);
   688     SETE_t();
   689     sh4_x86.tstate = TSTATE_E;
   690 :}
   691 CMP/GE Rm, Rn {:  
   692     COUNT_INST(I_CMPGE);
   693     load_reg( REG_EAX, Rm );
   694     load_reg( REG_ECX, Rn );
   695     CMPL_r32_r32( REG_EAX, REG_ECX );
   696     SETGE_t();
   697     sh4_x86.tstate = TSTATE_GE;
   698 :}
   699 CMP/GT Rm, Rn {: 
   700     COUNT_INST(I_CMPGT);
   701     load_reg( REG_EAX, Rm );
   702     load_reg( REG_ECX, Rn );
   703     CMPL_r32_r32( REG_EAX, REG_ECX );
   704     SETG_t();
   705     sh4_x86.tstate = TSTATE_G;
   706 :}
   707 CMP/HI Rm, Rn {:  
   708     COUNT_INST(I_CMPHI);
   709     load_reg( REG_EAX, Rm );
   710     load_reg( REG_ECX, Rn );
   711     CMPL_r32_r32( REG_EAX, REG_ECX );
   712     SETA_t();
   713     sh4_x86.tstate = TSTATE_A;
   714 :}
   715 CMP/HS Rm, Rn {: 
   716     COUNT_INST(I_CMPHS);
   717     load_reg( REG_EAX, Rm );
   718     load_reg( REG_ECX, Rn );
   719     CMPL_r32_r32( REG_EAX, REG_ECX );
   720     SETAE_t();
   721     sh4_x86.tstate = TSTATE_AE;
   722  :}
   723 CMP/PL Rn {: 
   724     COUNT_INST(I_CMPPL);
   725     load_reg( REG_EAX, Rn );
   726     CMPL_imms_r32( 0, REG_EAX );
   727     SETG_t();
   728     sh4_x86.tstate = TSTATE_G;
   729 :}
   730 CMP/PZ Rn {:  
   731     COUNT_INST(I_CMPPZ);
   732     load_reg( REG_EAX, Rn );
   733     CMPL_imms_r32( 0, REG_EAX );
   734     SETGE_t();
   735     sh4_x86.tstate = TSTATE_GE;
   736 :}
   737 CMP/STR Rm, Rn {:  
   738     COUNT_INST(I_CMPSTR);
   739     load_reg( REG_EAX, Rm );
   740     load_reg( REG_ECX, Rn );
   741     XORL_r32_r32( REG_ECX, REG_EAX );
   742     TESTB_r8_r8( REG_AL, REG_AL );
   743     JE_label(target1);
   744     TESTB_r8_r8( REG_AH, REG_AH );
   745     JE_label(target2);
   746     SHRL_imm_r32( 16, REG_EAX );
   747     TESTB_r8_r8( REG_AL, REG_AL );
   748     JE_label(target3);
   749     TESTB_r8_r8( REG_AH, REG_AH );
   750     JMP_TARGET(target1);
   751     JMP_TARGET(target2);
   752     JMP_TARGET(target3);
   753     SETE_t();
   754     sh4_x86.tstate = TSTATE_E;
   755 :}
   756 DIV0S Rm, Rn {:
   757     COUNT_INST(I_DIV0S);
   758     load_reg( REG_EAX, Rm );
   759     load_reg( REG_ECX, Rn );
   760     SHRL_imm_r32( 31, REG_EAX );
   761     SHRL_imm_r32( 31, REG_ECX );
   762     MOVL_r32_rbpdisp( REG_EAX, R_M );
   763     MOVL_r32_rbpdisp( REG_ECX, R_Q );
   764     CMPL_r32_r32( REG_EAX, REG_ECX );
   765     SETNE_t();
   766     sh4_x86.tstate = TSTATE_NE;
   767 :}
   768 DIV0U {:  
   769     COUNT_INST(I_DIV0U);
   770     XORL_r32_r32( REG_EAX, REG_EAX );
   771     MOVL_r32_rbpdisp( REG_EAX, R_Q );
   772     MOVL_r32_rbpdisp( REG_EAX, R_M );
   773     MOVL_r32_rbpdisp( REG_EAX, R_T );
   774     sh4_x86.tstate = TSTATE_C; // works for DIV1
   775 :}
   776 DIV1 Rm, Rn {:
   777     COUNT_INST(I_DIV1);
   778     MOVL_rbpdisp_r32( R_M, REG_ECX );
   779     load_reg( REG_EAX, Rn );
   780     if( sh4_x86.tstate != TSTATE_C ) {
   781 	LDC_t();
   782     }
   783     RCLL_imm_r32( 1, REG_EAX );
   784     SETC_r8( REG_DL ); // Q'
   785     CMPL_rbpdisp_r32( R_Q, REG_ECX );
   786     JE_label(mqequal);
   787     ADDL_rbpdisp_r32( REG_OFFSET(r[Rm]), REG_EAX );
   788     JMP_label(end);
   789     JMP_TARGET(mqequal);
   790     SUBL_rbpdisp_r32( REG_OFFSET(r[Rm]), REG_EAX );
   791     JMP_TARGET(end);
   792     store_reg( REG_EAX, Rn ); // Done with Rn now
   793     SETC_r8(REG_AL); // tmp1
   794     XORB_r8_r8( REG_DL, REG_AL ); // Q' = Q ^ tmp1
   795     XORB_r8_r8( REG_AL, REG_CL ); // Q'' = Q' ^ M
   796     MOVL_r32_rbpdisp( REG_ECX, R_Q );
   797     XORL_imms_r32( 1, REG_AL );   // T = !Q'
   798     MOVZXL_r8_r32( REG_AL, REG_EAX );
   799     MOVL_r32_rbpdisp( REG_EAX, R_T );
   800     sh4_x86.tstate = TSTATE_NONE;
   801 :}
   802 DMULS.L Rm, Rn {:  
   803     COUNT_INST(I_DMULS);
   804     load_reg( REG_EAX, Rm );
   805     load_reg( REG_ECX, Rn );
   806     IMULL_r32(REG_ECX);
   807     MOVL_r32_rbpdisp( REG_EDX, R_MACH );
   808     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
   809     sh4_x86.tstate = TSTATE_NONE;
   810 :}
   811 DMULU.L Rm, Rn {:  
   812     COUNT_INST(I_DMULU);
   813     load_reg( REG_EAX, Rm );
   814     load_reg( REG_ECX, Rn );
   815     MULL_r32(REG_ECX);
   816     MOVL_r32_rbpdisp( REG_EDX, R_MACH );
   817     MOVL_r32_rbpdisp( REG_EAX, R_MACL );    
   818     sh4_x86.tstate = TSTATE_NONE;
   819 :}
   820 DT Rn {:  
   821     COUNT_INST(I_DT);
   822     load_reg( REG_EAX, Rn );
   823     ADDL_imms_r32( -1, REG_EAX );
   824     store_reg( REG_EAX, Rn );
   825     SETE_t();
   826     sh4_x86.tstate = TSTATE_E;
   827 :}
   828 EXTS.B Rm, Rn {:  
   829     COUNT_INST(I_EXTSB);
   830     load_reg( REG_EAX, Rm );
   831     MOVSXL_r8_r32( REG_EAX, REG_EAX );
   832     store_reg( REG_EAX, Rn );
   833 :}
   834 EXTS.W Rm, Rn {:  
   835     COUNT_INST(I_EXTSW);
   836     load_reg( REG_EAX, Rm );
   837     MOVSXL_r16_r32( REG_EAX, REG_EAX );
   838     store_reg( REG_EAX, Rn );
   839 :}
   840 EXTU.B Rm, Rn {:  
   841     COUNT_INST(I_EXTUB);
   842     load_reg( REG_EAX, Rm );
   843     MOVZXL_r8_r32( REG_EAX, REG_EAX );
   844     store_reg( REG_EAX, Rn );
   845 :}
   846 EXTU.W Rm, Rn {:  
   847     COUNT_INST(I_EXTUW);
   848     load_reg( REG_EAX, Rm );
   849     MOVZXL_r16_r32( REG_EAX, REG_EAX );
   850     store_reg( REG_EAX, Rn );
   851 :}
   852 MAC.L @Rm+, @Rn+ {:
   853     COUNT_INST(I_MACL);
   854     if( Rm == Rn ) {
   855 	load_reg( REG_EAX, Rm );
   856 	check_ralign32( REG_EAX );
   857 	MEM_READ_LONG( REG_EAX, REG_EAX );
   858 	MOVL_r32_rspdisp(REG_EAX, 0);
   859 	load_reg( REG_EAX, Rm );
   860 	LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
   861 	MEM_READ_LONG( REG_EAX, REG_EAX );
   862         ADDL_imms_rbpdisp( 8, REG_OFFSET(r[Rn]) );
   863     } else {
   864 	load_reg( REG_EAX, Rm );
   865 	check_ralign32( REG_EAX );
   866 	MEM_READ_LONG( REG_EAX, REG_EAX );
   867 	MOVL_r32_rspdisp( REG_EAX, 0 );
   868 	load_reg( REG_EAX, Rn );
   869 	check_ralign32( REG_EAX );
   870 	MEM_READ_LONG( REG_EAX, REG_EAX );
   871 	ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rn]) );
   872 	ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
   873     }
   875     IMULL_rspdisp( 0 );
   876     ADDL_r32_rbpdisp( REG_EAX, R_MACL );
   877     ADCL_r32_rbpdisp( REG_EDX, R_MACH );
   879     MOVL_rbpdisp_r32( R_S, REG_ECX );
   880     TESTL_r32_r32(REG_ECX, REG_ECX);
   881     JE_label( nosat );
   882     CALL_ptr( signsat48 );
   883     JMP_TARGET( nosat );
   884     sh4_x86.tstate = TSTATE_NONE;
   885 :}
   886 MAC.W @Rm+, @Rn+ {:  
   887     COUNT_INST(I_MACW);
   888     if( Rm == Rn ) {
   889 	load_reg( REG_EAX, Rm );
   890 	check_ralign16( REG_EAX );
   891 	MEM_READ_WORD( REG_EAX, REG_EAX );
   892         MOVL_r32_rspdisp( REG_EAX, 0 );
   893 	load_reg( REG_EAX, Rm );
   894 	LEAL_r32disp_r32( REG_EAX, 2, REG_EAX );
   895 	MEM_READ_WORD( REG_EAX, REG_EAX );
   896 	ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rn]) );
   897 	// Note translate twice in case of page boundaries. Maybe worth
   898 	// adding a page-boundary check to skip the second translation
   899     } else {
   900 	load_reg( REG_EAX, Rm );
   901 	check_ralign16( REG_EAX );
   902 	MEM_READ_WORD( REG_EAX, REG_EAX );
   903         MOVL_r32_rspdisp( REG_EAX, 0 );
   904 	load_reg( REG_EAX, Rn );
   905 	check_ralign16( REG_EAX );
   906 	MEM_READ_WORD( REG_EAX, REG_EAX );
   907 	ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rn]) );
   908 	ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rm]) );
   909     }
   910     IMULL_rspdisp( 0 );
   911     MOVL_rbpdisp_r32( R_S, REG_ECX );
   912     TESTL_r32_r32( REG_ECX, REG_ECX );
   913     JE_label( nosat );
   915     ADDL_r32_rbpdisp( REG_EAX, R_MACL );  // 6
   916     JNO_label( end );            // 2
   917     MOVL_imm32_r32( 1, REG_EDX );         // 5
   918     MOVL_r32_rbpdisp( REG_EDX, R_MACH );   // 6
   919     JS_label( positive );        // 2
   920     MOVL_imm32_r32( 0x80000000, REG_EAX );// 5
   921     MOVL_r32_rbpdisp( REG_EAX, R_MACL );   // 6
   922     JMP_label(end2);           // 2
   924     JMP_TARGET(positive);
   925     MOVL_imm32_r32( 0x7FFFFFFF, REG_EAX );// 5
   926     MOVL_r32_rbpdisp( REG_EAX, R_MACL );   // 6
   927     JMP_label(end3);            // 2
   929     JMP_TARGET(nosat);
   930     ADDL_r32_rbpdisp( REG_EAX, R_MACL );  // 6
   931     ADCL_r32_rbpdisp( REG_EDX, R_MACH );  // 6
   932     JMP_TARGET(end);
   933     JMP_TARGET(end2);
   934     JMP_TARGET(end3);
   935     sh4_x86.tstate = TSTATE_NONE;
   936 :}
   937 MOVT Rn {:  
   938     COUNT_INST(I_MOVT);
   939     MOVL_rbpdisp_r32( R_T, REG_EAX );
   940     store_reg( REG_EAX, Rn );
   941 :}
   942 MUL.L Rm, Rn {:  
   943     COUNT_INST(I_MULL);
   944     load_reg( REG_EAX, Rm );
   945     load_reg( REG_ECX, Rn );
   946     MULL_r32( REG_ECX );
   947     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
   948     sh4_x86.tstate = TSTATE_NONE;
   949 :}
   950 MULS.W Rm, Rn {:
   951     COUNT_INST(I_MULSW);
   952     MOVSXL_rbpdisp16_r32( R_R(Rm), REG_EAX );
   953     MOVSXL_rbpdisp16_r32( R_R(Rn), REG_ECX );
   954     MULL_r32( REG_ECX );
   955     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
   956     sh4_x86.tstate = TSTATE_NONE;
   957 :}
   958 MULU.W Rm, Rn {:  
   959     COUNT_INST(I_MULUW);
   960     MOVZXL_rbpdisp16_r32( R_R(Rm), REG_EAX );
   961     MOVZXL_rbpdisp16_r32( R_R(Rn), REG_ECX );
   962     MULL_r32( REG_ECX );
   963     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
   964     sh4_x86.tstate = TSTATE_NONE;
   965 :}
   966 NEG Rm, Rn {:
   967     COUNT_INST(I_NEG);
   968     load_reg( REG_EAX, Rm );
   969     NEGL_r32( REG_EAX );
   970     store_reg( REG_EAX, Rn );
   971     sh4_x86.tstate = TSTATE_NONE;
   972 :}
   973 NEGC Rm, Rn {:  
   974     COUNT_INST(I_NEGC);
   975     load_reg( REG_EAX, Rm );
   976     XORL_r32_r32( REG_ECX, REG_ECX );
   977     LDC_t();
   978     SBBL_r32_r32( REG_EAX, REG_ECX );
   979     store_reg( REG_ECX, Rn );
   980     SETC_t();
   981     sh4_x86.tstate = TSTATE_C;
   982 :}
   983 NOT Rm, Rn {:  
   984     COUNT_INST(I_NOT);
   985     load_reg( REG_EAX, Rm );
   986     NOTL_r32( REG_EAX );
   987     store_reg( REG_EAX, Rn );
   988     sh4_x86.tstate = TSTATE_NONE;
   989 :}
   990 OR Rm, Rn {:  
   991     COUNT_INST(I_OR);
   992     load_reg( REG_EAX, Rm );
   993     load_reg( REG_ECX, Rn );
   994     ORL_r32_r32( REG_EAX, REG_ECX );
   995     store_reg( REG_ECX, Rn );
   996     sh4_x86.tstate = TSTATE_NONE;
   997 :}
   998 OR #imm, R0 {:
   999     COUNT_INST(I_ORI);
  1000     load_reg( REG_EAX, 0 );
  1001     ORL_imms_r32(imm, REG_EAX);
  1002     store_reg( REG_EAX, 0 );
  1003     sh4_x86.tstate = TSTATE_NONE;
  1004 :}
  1005 OR.B #imm, @(R0, GBR) {:  
  1006     COUNT_INST(I_ORB);
  1007     load_reg( REG_EAX, 0 );
  1008     ADDL_rbpdisp_r32( R_GBR, REG_EAX );
  1009     MOVL_r32_rspdisp( REG_EAX, 0 );
  1010     MEM_READ_BYTE_FOR_WRITE( REG_EAX, REG_EDX );
  1011     MOVL_rspdisp_r32( 0, REG_EAX );
  1012     ORL_imms_r32(imm, REG_EDX );
  1013     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1014     sh4_x86.tstate = TSTATE_NONE;
  1015 :}
  1016 ROTCL Rn {:
  1017     COUNT_INST(I_ROTCL);
  1018     load_reg( REG_EAX, Rn );
  1019     if( sh4_x86.tstate != TSTATE_C ) {
  1020 	LDC_t();
  1022     RCLL_imm_r32( 1, REG_EAX );
  1023     store_reg( REG_EAX, Rn );
  1024     SETC_t();
  1025     sh4_x86.tstate = TSTATE_C;
  1026 :}
  1027 ROTCR Rn {:  
  1028     COUNT_INST(I_ROTCR);
  1029     load_reg( REG_EAX, Rn );
  1030     if( sh4_x86.tstate != TSTATE_C ) {
  1031 	LDC_t();
  1033     RCRL_imm_r32( 1, REG_EAX );
  1034     store_reg( REG_EAX, Rn );
  1035     SETC_t();
  1036     sh4_x86.tstate = TSTATE_C;
  1037 :}
  1038 ROTL Rn {:  
  1039     COUNT_INST(I_ROTL);
  1040     load_reg( REG_EAX, Rn );
  1041     ROLL_imm_r32( 1, REG_EAX );
  1042     store_reg( REG_EAX, Rn );
  1043     SETC_t();
  1044     sh4_x86.tstate = TSTATE_C;
  1045 :}
  1046 ROTR Rn {:  
  1047     COUNT_INST(I_ROTR);
  1048     load_reg( REG_EAX, Rn );
  1049     RORL_imm_r32( 1, REG_EAX );
  1050     store_reg( REG_EAX, Rn );
  1051     SETC_t();
  1052     sh4_x86.tstate = TSTATE_C;
  1053 :}
  1054 SHAD Rm, Rn {:
  1055     COUNT_INST(I_SHAD);
  1056     /* Annoyingly enough, not directly convertible */
  1057     load_reg( REG_EAX, Rn );
  1058     load_reg( REG_ECX, Rm );
  1059     CMPL_imms_r32( 0, REG_ECX );
  1060     JGE_label(doshl);
  1062     NEGL_r32( REG_ECX );      // 2
  1063     ANDB_imms_r8( 0x1F, REG_CL ); // 3
  1064     JE_label(emptysar);     // 2
  1065     SARL_cl_r32( REG_EAX );       // 2
  1066     JMP_label(end);          // 2
  1068     JMP_TARGET(emptysar);
  1069     SARL_imm_r32(31, REG_EAX );  // 3
  1070     JMP_label(end2);
  1072     JMP_TARGET(doshl);
  1073     ANDB_imms_r8( 0x1F, REG_CL ); // 3
  1074     SHLL_cl_r32( REG_EAX );       // 2
  1075     JMP_TARGET(end);
  1076     JMP_TARGET(end2);
  1077     store_reg( REG_EAX, Rn );
  1078     sh4_x86.tstate = TSTATE_NONE;
  1079 :}
  1080 SHLD Rm, Rn {:  
  1081     COUNT_INST(I_SHLD);
  1082     load_reg( REG_EAX, Rn );
  1083     load_reg( REG_ECX, Rm );
  1084     CMPL_imms_r32( 0, REG_ECX );
  1085     JGE_label(doshl);
  1087     NEGL_r32( REG_ECX );      // 2
  1088     ANDB_imms_r8( 0x1F, REG_CL ); // 3
  1089     JE_label(emptyshr );
  1090     SHRL_cl_r32( REG_EAX );       // 2
  1091     JMP_label(end);          // 2
  1093     JMP_TARGET(emptyshr);
  1094     XORL_r32_r32( REG_EAX, REG_EAX );
  1095     JMP_label(end2);
  1097     JMP_TARGET(doshl);
  1098     ANDB_imms_r8( 0x1F, REG_CL ); // 3
  1099     SHLL_cl_r32( REG_EAX );       // 2
  1100     JMP_TARGET(end);
  1101     JMP_TARGET(end2);
  1102     store_reg( REG_EAX, Rn );
  1103     sh4_x86.tstate = TSTATE_NONE;
  1104 :}
  1105 SHAL Rn {: 
  1106     COUNT_INST(I_SHAL);
  1107     load_reg( REG_EAX, Rn );
  1108     SHLL_imm_r32( 1, REG_EAX );
  1109     SETC_t();
  1110     store_reg( REG_EAX, Rn );
  1111     sh4_x86.tstate = TSTATE_C;
  1112 :}
  1113 SHAR Rn {:  
  1114     COUNT_INST(I_SHAR);
  1115     load_reg( REG_EAX, Rn );
  1116     SARL_imm_r32( 1, REG_EAX );
  1117     SETC_t();
  1118     store_reg( REG_EAX, Rn );
  1119     sh4_x86.tstate = TSTATE_C;
  1120 :}
  1121 SHLL Rn {:  
  1122     COUNT_INST(I_SHLL);
  1123     load_reg( REG_EAX, Rn );
  1124     SHLL_imm_r32( 1, REG_EAX );
  1125     SETC_t();
  1126     store_reg( REG_EAX, Rn );
  1127     sh4_x86.tstate = TSTATE_C;
  1128 :}
  1129 SHLL2 Rn {:
  1130     COUNT_INST(I_SHLL);
  1131     load_reg( REG_EAX, Rn );
  1132     SHLL_imm_r32( 2, REG_EAX );
  1133     store_reg( REG_EAX, Rn );
  1134     sh4_x86.tstate = TSTATE_NONE;
  1135 :}
  1136 SHLL8 Rn {:  
  1137     COUNT_INST(I_SHLL);
  1138     load_reg( REG_EAX, Rn );
  1139     SHLL_imm_r32( 8, REG_EAX );
  1140     store_reg( REG_EAX, Rn );
  1141     sh4_x86.tstate = TSTATE_NONE;
  1142 :}
  1143 SHLL16 Rn {:  
  1144     COUNT_INST(I_SHLL);
  1145     load_reg( REG_EAX, Rn );
  1146     SHLL_imm_r32( 16, REG_EAX );
  1147     store_reg( REG_EAX, Rn );
  1148     sh4_x86.tstate = TSTATE_NONE;
  1149 :}
  1150 SHLR Rn {:  
  1151     COUNT_INST(I_SHLR);
  1152     load_reg( REG_EAX, Rn );
  1153     SHRL_imm_r32( 1, REG_EAX );
  1154     SETC_t();
  1155     store_reg( REG_EAX, Rn );
  1156     sh4_x86.tstate = TSTATE_C;
  1157 :}
  1158 SHLR2 Rn {:  
  1159     COUNT_INST(I_SHLR);
  1160     load_reg( REG_EAX, Rn );
  1161     SHRL_imm_r32( 2, REG_EAX );
  1162     store_reg( REG_EAX, Rn );
  1163     sh4_x86.tstate = TSTATE_NONE;
  1164 :}
  1165 SHLR8 Rn {:  
  1166     COUNT_INST(I_SHLR);
  1167     load_reg( REG_EAX, Rn );
  1168     SHRL_imm_r32( 8, REG_EAX );
  1169     store_reg( REG_EAX, Rn );
  1170     sh4_x86.tstate = TSTATE_NONE;
  1171 :}
  1172 SHLR16 Rn {:  
  1173     COUNT_INST(I_SHLR);
  1174     load_reg( REG_EAX, Rn );
  1175     SHRL_imm_r32( 16, REG_EAX );
  1176     store_reg( REG_EAX, Rn );
  1177     sh4_x86.tstate = TSTATE_NONE;
  1178 :}
  1179 SUB Rm, Rn {:  
  1180     COUNT_INST(I_SUB);
  1181     load_reg( REG_EAX, Rm );
  1182     load_reg( REG_ECX, Rn );
  1183     SUBL_r32_r32( REG_EAX, REG_ECX );
  1184     store_reg( REG_ECX, Rn );
  1185     sh4_x86.tstate = TSTATE_NONE;
  1186 :}
  1187 SUBC Rm, Rn {:  
  1188     COUNT_INST(I_SUBC);
  1189     load_reg( REG_EAX, Rm );
  1190     load_reg( REG_ECX, Rn );
  1191     if( sh4_x86.tstate != TSTATE_C ) {
  1192 	LDC_t();
  1194     SBBL_r32_r32( REG_EAX, REG_ECX );
  1195     store_reg( REG_ECX, Rn );
  1196     SETC_t();
  1197     sh4_x86.tstate = TSTATE_C;
  1198 :}
  1199 SUBV Rm, Rn {:  
  1200     COUNT_INST(I_SUBV);
  1201     load_reg( REG_EAX, Rm );
  1202     load_reg( REG_ECX, Rn );
  1203     SUBL_r32_r32( REG_EAX, REG_ECX );
  1204     store_reg( REG_ECX, Rn );
  1205     SETO_t();
  1206     sh4_x86.tstate = TSTATE_O;
  1207 :}
  1208 SWAP.B Rm, Rn {:  
  1209     COUNT_INST(I_SWAPB);
  1210     load_reg( REG_EAX, Rm );
  1211     XCHGB_r8_r8( REG_AL, REG_AH ); // NB: does not touch EFLAGS
  1212     store_reg( REG_EAX, Rn );
  1213 :}
  1214 SWAP.W Rm, Rn {:  
  1215     COUNT_INST(I_SWAPB);
  1216     load_reg( REG_EAX, Rm );
  1217     MOVL_r32_r32( REG_EAX, REG_ECX );
  1218     SHLL_imm_r32( 16, REG_ECX );
  1219     SHRL_imm_r32( 16, REG_EAX );
  1220     ORL_r32_r32( REG_EAX, REG_ECX );
  1221     store_reg( REG_ECX, Rn );
  1222     sh4_x86.tstate = TSTATE_NONE;
  1223 :}
  1224 TAS.B @Rn {:  
  1225     COUNT_INST(I_TASB);
  1226     load_reg( REG_EAX, Rn );
  1227     MOVL_r32_rspdisp( REG_EAX, 0 );
  1228     MEM_READ_BYTE_FOR_WRITE( REG_EAX, REG_EDX );
  1229     TESTB_r8_r8( REG_DL, REG_DL );
  1230     SETE_t();
  1231     ORB_imms_r8( 0x80, REG_DL );
  1232     MOVL_rspdisp_r32( 0, REG_EAX );
  1233     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1234     sh4_x86.tstate = TSTATE_NONE;
  1235 :}
  1236 TST Rm, Rn {:  
  1237     COUNT_INST(I_TST);
  1238     load_reg( REG_EAX, Rm );
  1239     load_reg( REG_ECX, Rn );
  1240     TESTL_r32_r32( REG_EAX, REG_ECX );
  1241     SETE_t();
  1242     sh4_x86.tstate = TSTATE_E;
  1243 :}
  1244 TST #imm, R0 {:  
  1245     COUNT_INST(I_TSTI);
  1246     load_reg( REG_EAX, 0 );
  1247     TESTL_imms_r32( imm, REG_EAX );
  1248     SETE_t();
  1249     sh4_x86.tstate = TSTATE_E;
  1250 :}
  1251 TST.B #imm, @(R0, GBR) {:  
  1252     COUNT_INST(I_TSTB);
  1253     load_reg( REG_EAX, 0);
  1254     ADDL_rbpdisp_r32( R_GBR, REG_EAX );
  1255     MEM_READ_BYTE( REG_EAX, REG_EAX );
  1256     TESTB_imms_r8( imm, REG_AL );
  1257     SETE_t();
  1258     sh4_x86.tstate = TSTATE_E;
  1259 :}
  1260 XOR Rm, Rn {:  
  1261     COUNT_INST(I_XOR);
  1262     load_reg( REG_EAX, Rm );
  1263     load_reg( REG_ECX, Rn );
  1264     XORL_r32_r32( REG_EAX, REG_ECX );
  1265     store_reg( REG_ECX, Rn );
  1266     sh4_x86.tstate = TSTATE_NONE;
  1267 :}
  1268 XOR #imm, R0 {:  
  1269     COUNT_INST(I_XORI);
  1270     load_reg( REG_EAX, 0 );
  1271     XORL_imms_r32( imm, REG_EAX );
  1272     store_reg( REG_EAX, 0 );
  1273     sh4_x86.tstate = TSTATE_NONE;
  1274 :}
  1275 XOR.B #imm, @(R0, GBR) {:  
  1276     COUNT_INST(I_XORB);
  1277     load_reg( REG_EAX, 0 );
  1278     ADDL_rbpdisp_r32( R_GBR, REG_EAX ); 
  1279     MOVL_r32_rspdisp( REG_EAX, 0 );
  1280     MEM_READ_BYTE_FOR_WRITE(REG_EAX, REG_EDX);
  1281     MOVL_rspdisp_r32( 0, REG_EAX );
  1282     XORL_imms_r32( imm, REG_EDX );
  1283     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1284     sh4_x86.tstate = TSTATE_NONE;
  1285 :}
  1286 XTRCT Rm, Rn {:
  1287     COUNT_INST(I_XTRCT);
  1288     load_reg( REG_EAX, Rm );
  1289     load_reg( REG_ECX, Rn );
  1290     SHLL_imm_r32( 16, REG_EAX );
  1291     SHRL_imm_r32( 16, REG_ECX );
  1292     ORL_r32_r32( REG_EAX, REG_ECX );
  1293     store_reg( REG_ECX, Rn );
  1294     sh4_x86.tstate = TSTATE_NONE;
  1295 :}
  1297 /* Data move instructions */
  1298 MOV Rm, Rn {:  
  1299     COUNT_INST(I_MOV);
  1300     load_reg( REG_EAX, Rm );
  1301     store_reg( REG_EAX, Rn );
  1302 :}
  1303 MOV #imm, Rn {:  
  1304     COUNT_INST(I_MOVI);
  1305     MOVL_imm32_r32( imm, REG_EAX );
  1306     store_reg( REG_EAX, Rn );
  1307 :}
  1308 MOV.B Rm, @Rn {:  
  1309     COUNT_INST(I_MOVB);
  1310     load_reg( REG_EAX, Rn );
  1311     load_reg( REG_EDX, Rm );
  1312     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1313     sh4_x86.tstate = TSTATE_NONE;
  1314 :}
  1315 MOV.B Rm, @-Rn {:  
  1316     COUNT_INST(I_MOVB);
  1317     load_reg( REG_EAX, Rn );
  1318     LEAL_r32disp_r32( REG_EAX, -1, REG_EAX );
  1319     load_reg( REG_EDX, Rm );
  1320     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1321     ADDL_imms_rbpdisp( -1, REG_OFFSET(r[Rn]) );
  1322     sh4_x86.tstate = TSTATE_NONE;
  1323 :}
  1324 MOV.B Rm, @(R0, Rn) {:  
  1325     COUNT_INST(I_MOVB);
  1326     load_reg( REG_EAX, 0 );
  1327     ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
  1328     load_reg( REG_EDX, Rm );
  1329     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1330     sh4_x86.tstate = TSTATE_NONE;
  1331 :}
  1332 MOV.B R0, @(disp, GBR) {:  
  1333     COUNT_INST(I_MOVB);
  1334     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  1335     ADDL_imms_r32( disp, REG_EAX );
  1336     load_reg( REG_EDX, 0 );
  1337     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1338     sh4_x86.tstate = TSTATE_NONE;
  1339 :}
  1340 MOV.B R0, @(disp, Rn) {:  
  1341     COUNT_INST(I_MOVB);
  1342     load_reg( REG_EAX, Rn );
  1343     ADDL_imms_r32( disp, REG_EAX );
  1344     load_reg( REG_EDX, 0 );
  1345     MEM_WRITE_BYTE( REG_EAX, REG_EDX );
  1346     sh4_x86.tstate = TSTATE_NONE;
  1347 :}
  1348 MOV.B @Rm, Rn {:  
  1349     COUNT_INST(I_MOVB);
  1350     load_reg( REG_EAX, Rm );
  1351     MEM_READ_BYTE( REG_EAX, REG_EAX );
  1352     store_reg( REG_EAX, Rn );
  1353     sh4_x86.tstate = TSTATE_NONE;
  1354 :}
  1355 MOV.B @Rm+, Rn {:  
  1356     COUNT_INST(I_MOVB);
  1357     load_reg( REG_EAX, Rm );
  1358     MEM_READ_BYTE( REG_EAX, REG_EAX );
  1359     if( Rm != Rn ) {
  1360     	ADDL_imms_rbpdisp( 1, REG_OFFSET(r[Rm]) );
  1362     store_reg( REG_EAX, Rn );
  1363     sh4_x86.tstate = TSTATE_NONE;
  1364 :}
  1365 MOV.B @(R0, Rm), Rn {:  
  1366     COUNT_INST(I_MOVB);
  1367     load_reg( REG_EAX, 0 );
  1368     ADDL_rbpdisp_r32( REG_OFFSET(r[Rm]), REG_EAX );
  1369     MEM_READ_BYTE( REG_EAX, REG_EAX );
  1370     store_reg( REG_EAX, Rn );
  1371     sh4_x86.tstate = TSTATE_NONE;
  1372 :}
  1373 MOV.B @(disp, GBR), R0 {:  
  1374     COUNT_INST(I_MOVB);
  1375     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  1376     ADDL_imms_r32( disp, REG_EAX );
  1377     MEM_READ_BYTE( REG_EAX, REG_EAX );
  1378     store_reg( REG_EAX, 0 );
  1379     sh4_x86.tstate = TSTATE_NONE;
  1380 :}
  1381 MOV.B @(disp, Rm), R0 {:  
  1382     COUNT_INST(I_MOVB);
  1383     load_reg( REG_EAX, Rm );
  1384     ADDL_imms_r32( disp, REG_EAX );
  1385     MEM_READ_BYTE( REG_EAX, REG_EAX );
  1386     store_reg( REG_EAX, 0 );
  1387     sh4_x86.tstate = TSTATE_NONE;
  1388 :}
  1389 MOV.L Rm, @Rn {:
  1390     COUNT_INST(I_MOVL);
  1391     load_reg( REG_EAX, Rn );
  1392     check_walign32(REG_EAX);
  1393     MOVL_r32_r32( REG_EAX, REG_ECX );
  1394     ANDL_imms_r32( 0xFC000000, REG_ECX );
  1395     CMPL_imms_r32( 0xE0000000, REG_ECX );
  1396     JNE_label( notsq );
  1397     ANDL_imms_r32( 0x3C, REG_EAX );
  1398     load_reg( REG_EDX, Rm );
  1399     MOVL_r32_sib( REG_EDX, 0, REG_EBP, REG_EAX, REG_OFFSET(store_queue) );
  1400     JMP_label(end);
  1401     JMP_TARGET(notsq);
  1402     load_reg( REG_EDX, Rm );
  1403     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  1404     JMP_TARGET(end);
  1405     sh4_x86.tstate = TSTATE_NONE;
  1406 :}
  1407 MOV.L Rm, @-Rn {:  
  1408     COUNT_INST(I_MOVL);
  1409     load_reg( REG_EAX, Rn );
  1410     ADDL_imms_r32( -4, REG_EAX );
  1411     check_walign32( REG_EAX );
  1412     load_reg( REG_EDX, Rm );
  1413     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  1414     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  1415     sh4_x86.tstate = TSTATE_NONE;
  1416 :}
  1417 MOV.L Rm, @(R0, Rn) {:  
  1418     COUNT_INST(I_MOVL);
  1419     load_reg( REG_EAX, 0 );
  1420     ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
  1421     check_walign32( REG_EAX );
  1422     load_reg( REG_EDX, Rm );
  1423     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  1424     sh4_x86.tstate = TSTATE_NONE;
  1425 :}
  1426 MOV.L R0, @(disp, GBR) {:  
  1427     COUNT_INST(I_MOVL);
  1428     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  1429     ADDL_imms_r32( disp, REG_EAX );
  1430     check_walign32( REG_EAX );
  1431     load_reg( REG_EDX, 0 );
  1432     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  1433     sh4_x86.tstate = TSTATE_NONE;
  1434 :}
  1435 MOV.L Rm, @(disp, Rn) {:  
  1436     COUNT_INST(I_MOVL);
  1437     load_reg( REG_EAX, Rn );
  1438     ADDL_imms_r32( disp, REG_EAX );
  1439     check_walign32( REG_EAX );
  1440     MOVL_r32_r32( REG_EAX, REG_ECX );
  1441     ANDL_imms_r32( 0xFC000000, REG_ECX );
  1442     CMPL_imms_r32( 0xE0000000, REG_ECX );
  1443     JNE_label( notsq );
  1444     ANDL_imms_r32( 0x3C, REG_EAX );
  1445     load_reg( REG_EDX, Rm );
  1446     MOVL_r32_sib( REG_EDX, 0, REG_EBP, REG_EAX, REG_OFFSET(store_queue) );
  1447     JMP_label(end);
  1448     JMP_TARGET(notsq);
  1449     load_reg( REG_EDX, Rm );
  1450     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  1451     JMP_TARGET(end);
  1452     sh4_x86.tstate = TSTATE_NONE;
  1453 :}
  1454 MOV.L @Rm, Rn {:  
  1455     COUNT_INST(I_MOVL);
  1456     load_reg( REG_EAX, Rm );
  1457     check_ralign32( REG_EAX );
  1458     MEM_READ_LONG( REG_EAX, REG_EAX );
  1459     store_reg( REG_EAX, Rn );
  1460     sh4_x86.tstate = TSTATE_NONE;
  1461 :}
  1462 MOV.L @Rm+, Rn {:  
  1463     COUNT_INST(I_MOVL);
  1464     load_reg( REG_EAX, Rm );
  1465     check_ralign32( REG_EAX );
  1466     MEM_READ_LONG( REG_EAX, REG_EAX );
  1467     if( Rm != Rn ) {
  1468     	ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  1470     store_reg( REG_EAX, Rn );
  1471     sh4_x86.tstate = TSTATE_NONE;
  1472 :}
  1473 MOV.L @(R0, Rm), Rn {:  
  1474     COUNT_INST(I_MOVL);
  1475     load_reg( REG_EAX, 0 );
  1476     ADDL_rbpdisp_r32( REG_OFFSET(r[Rm]), REG_EAX );
  1477     check_ralign32( REG_EAX );
  1478     MEM_READ_LONG( REG_EAX, REG_EAX );
  1479     store_reg( REG_EAX, Rn );
  1480     sh4_x86.tstate = TSTATE_NONE;
  1481 :}
  1482 MOV.L @(disp, GBR), R0 {:
  1483     COUNT_INST(I_MOVL);
  1484     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  1485     ADDL_imms_r32( disp, REG_EAX );
  1486     check_ralign32( REG_EAX );
  1487     MEM_READ_LONG( REG_EAX, REG_EAX );
  1488     store_reg( REG_EAX, 0 );
  1489     sh4_x86.tstate = TSTATE_NONE;
  1490 :}
  1491 MOV.L @(disp, PC), Rn {:  
  1492     COUNT_INST(I_MOVLPC);
  1493     if( sh4_x86.in_delay_slot ) {
  1494 	SLOTILLEGAL();
  1495     } else {
  1496 	uint32_t target = (pc & 0xFFFFFFFC) + disp + 4;
  1497 	if( IS_IN_ICACHE(target) ) {
  1498 	    // If the target address is in the same page as the code, it's
  1499 	    // pretty safe to just ref it directly and circumvent the whole
  1500 	    // memory subsystem. (this is a big performance win)
  1502 	    // FIXME: There's a corner-case that's not handled here when
  1503 	    // the current code-page is in the ITLB but not in the UTLB.
  1504 	    // (should generate a TLB miss although need to test SH4 
  1505 	    // behaviour to confirm) Unlikely to be anyone depending on this
  1506 	    // behaviour though.
  1507 	    sh4ptr_t ptr = GET_ICACHE_PTR(target);
  1508 	    MOVL_moffptr_eax( ptr );
  1509 	} else {
  1510 	    // Note: we use sh4r.pc for the calc as we could be running at a
  1511 	    // different virtual address than the translation was done with,
  1512 	    // but we can safely assume that the low bits are the same.
  1513 	    MOVL_imm32_r32( (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03), REG_EAX );
  1514 	    ADDL_rbpdisp_r32( R_PC, REG_EAX );
  1515 	    MEM_READ_LONG( REG_EAX, REG_EAX );
  1516 	    sh4_x86.tstate = TSTATE_NONE;
  1518 	store_reg( REG_EAX, Rn );
  1520 :}
  1521 MOV.L @(disp, Rm), Rn {:  
  1522     COUNT_INST(I_MOVL);
  1523     load_reg( REG_EAX, Rm );
  1524     ADDL_imms_r32( disp, REG_EAX );
  1525     check_ralign32( REG_EAX );
  1526     MEM_READ_LONG( REG_EAX, REG_EAX );
  1527     store_reg( REG_EAX, Rn );
  1528     sh4_x86.tstate = TSTATE_NONE;
  1529 :}
  1530 MOV.W Rm, @Rn {:  
  1531     COUNT_INST(I_MOVW);
  1532     load_reg( REG_EAX, Rn );
  1533     check_walign16( REG_EAX );
  1534     load_reg( REG_EDX, Rm );
  1535     MEM_WRITE_WORD( REG_EAX, REG_EDX );
  1536     sh4_x86.tstate = TSTATE_NONE;
  1537 :}
  1538 MOV.W Rm, @-Rn {:  
  1539     COUNT_INST(I_MOVW);
  1540     load_reg( REG_EAX, Rn );
  1541     check_walign16( REG_EAX );
  1542     LEAL_r32disp_r32( REG_EAX, -2, REG_EAX );
  1543     load_reg( REG_EDX, Rm );
  1544     MEM_WRITE_WORD( REG_EAX, REG_EDX );
  1545     ADDL_imms_rbpdisp( -2, REG_OFFSET(r[Rn]) );
  1546     sh4_x86.tstate = TSTATE_NONE;
  1547 :}
  1548 MOV.W Rm, @(R0, Rn) {:  
  1549     COUNT_INST(I_MOVW);
  1550     load_reg( REG_EAX, 0 );
  1551     ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
  1552     check_walign16( REG_EAX );
  1553     load_reg( REG_EDX, Rm );
  1554     MEM_WRITE_WORD( REG_EAX, REG_EDX );
  1555     sh4_x86.tstate = TSTATE_NONE;
  1556 :}
  1557 MOV.W R0, @(disp, GBR) {:  
  1558     COUNT_INST(I_MOVW);
  1559     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  1560     ADDL_imms_r32( disp, REG_EAX );
  1561     check_walign16( REG_EAX );
  1562     load_reg( REG_EDX, 0 );
  1563     MEM_WRITE_WORD( REG_EAX, REG_EDX );
  1564     sh4_x86.tstate = TSTATE_NONE;
  1565 :}
  1566 MOV.W R0, @(disp, Rn) {:  
  1567     COUNT_INST(I_MOVW);
  1568     load_reg( REG_EAX, Rn );
  1569     ADDL_imms_r32( disp, REG_EAX );
  1570     check_walign16( REG_EAX );
  1571     load_reg( REG_EDX, 0 );
  1572     MEM_WRITE_WORD( REG_EAX, REG_EDX );
  1573     sh4_x86.tstate = TSTATE_NONE;
  1574 :}
  1575 MOV.W @Rm, Rn {:  
  1576     COUNT_INST(I_MOVW);
  1577     load_reg( REG_EAX, Rm );
  1578     check_ralign16( REG_EAX );
  1579     MEM_READ_WORD( REG_EAX, REG_EAX );
  1580     store_reg( REG_EAX, Rn );
  1581     sh4_x86.tstate = TSTATE_NONE;
  1582 :}
  1583 MOV.W @Rm+, Rn {:  
  1584     COUNT_INST(I_MOVW);
  1585     load_reg( REG_EAX, Rm );
  1586     check_ralign16( REG_EAX );
  1587     MEM_READ_WORD( REG_EAX, REG_EAX );
  1588     if( Rm != Rn ) {
  1589         ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rm]) );
  1591     store_reg( REG_EAX, Rn );
  1592     sh4_x86.tstate = TSTATE_NONE;
  1593 :}
  1594 MOV.W @(R0, Rm), Rn {:  
  1595     COUNT_INST(I_MOVW);
  1596     load_reg( REG_EAX, 0 );
  1597     ADDL_rbpdisp_r32( REG_OFFSET(r[Rm]), REG_EAX );
  1598     check_ralign16( REG_EAX );
  1599     MEM_READ_WORD( REG_EAX, REG_EAX );
  1600     store_reg( REG_EAX, Rn );
  1601     sh4_x86.tstate = TSTATE_NONE;
  1602 :}
  1603 MOV.W @(disp, GBR), R0 {:  
  1604     COUNT_INST(I_MOVW);
  1605     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  1606     ADDL_imms_r32( disp, REG_EAX );
  1607     check_ralign16( REG_EAX );
  1608     MEM_READ_WORD( REG_EAX, REG_EAX );
  1609     store_reg( REG_EAX, 0 );
  1610     sh4_x86.tstate = TSTATE_NONE;
  1611 :}
  1612 MOV.W @(disp, PC), Rn {:  
  1613     COUNT_INST(I_MOVW);
  1614     if( sh4_x86.in_delay_slot ) {
  1615 	SLOTILLEGAL();
  1616     } else {
  1617 	// See comments for MOV.L @(disp, PC), Rn
  1618 	uint32_t target = pc + disp + 4;
  1619 	if( IS_IN_ICACHE(target) ) {
  1620 	    sh4ptr_t ptr = GET_ICACHE_PTR(target);
  1621 	    MOVL_moffptr_eax( ptr );
  1622 	    MOVSXL_r16_r32( REG_EAX, REG_EAX );
  1623 	} else {
  1624 	    MOVL_imm32_r32( (pc - sh4_x86.block_start_pc) + disp + 4, REG_EAX );
  1625 	    ADDL_rbpdisp_r32( R_PC, REG_EAX );
  1626 	    MEM_READ_WORD( REG_EAX, REG_EAX );
  1627 	    sh4_x86.tstate = TSTATE_NONE;
  1629 	store_reg( REG_EAX, Rn );
  1631 :}
  1632 MOV.W @(disp, Rm), R0 {:  
  1633     COUNT_INST(I_MOVW);
  1634     load_reg( REG_EAX, Rm );
  1635     ADDL_imms_r32( disp, REG_EAX );
  1636     check_ralign16( REG_EAX );
  1637     MEM_READ_WORD( REG_EAX, REG_EAX );
  1638     store_reg( REG_EAX, 0 );
  1639     sh4_x86.tstate = TSTATE_NONE;
  1640 :}
  1641 MOVA @(disp, PC), R0 {:  
  1642     COUNT_INST(I_MOVA);
  1643     if( sh4_x86.in_delay_slot ) {
  1644 	SLOTILLEGAL();
  1645     } else {
  1646 	MOVL_imm32_r32( (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03), REG_ECX );
  1647 	ADDL_rbpdisp_r32( R_PC, REG_ECX );
  1648 	store_reg( REG_ECX, 0 );
  1649 	sh4_x86.tstate = TSTATE_NONE;
  1651 :}
  1652 MOVCA.L R0, @Rn {:  
  1653     COUNT_INST(I_MOVCA);
  1654     load_reg( REG_EAX, Rn );
  1655     check_walign32( REG_EAX );
  1656     load_reg( REG_EDX, 0 );
  1657     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  1658     sh4_x86.tstate = TSTATE_NONE;
  1659 :}
  1661 /* Control transfer instructions */
  1662 BF disp {:
  1663     COUNT_INST(I_BF);
  1664     if( sh4_x86.in_delay_slot ) {
  1665 	SLOTILLEGAL();
  1666     } else {
  1667 	sh4vma_t target = disp + pc + 4;
  1668 	JT_label( nottaken );
  1669 	exit_block_rel(target, pc+2 );
  1670 	JMP_TARGET(nottaken);
  1671 	return 2;
  1673 :}
  1674 BF/S disp {:
  1675     COUNT_INST(I_BFS);
  1676     if( sh4_x86.in_delay_slot ) {
  1677 	SLOTILLEGAL();
  1678     } else {
  1679 	sh4_x86.in_delay_slot = DELAY_PC;
  1680 	if( UNTRANSLATABLE(pc+2) ) {
  1681 	    MOVL_imm32_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
  1682 	    JT_label(nottaken);
  1683 	    ADDL_imms_r32( disp, REG_EAX );
  1684 	    JMP_TARGET(nottaken);
  1685 	    ADDL_rbpdisp_r32( R_PC, REG_EAX );
  1686 	    MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
  1687 	    exit_block_emu(pc+2);
  1688 	    sh4_x86.branch_taken = TRUE;
  1689 	    return 2;
  1690 	} else {
  1691 	    if( sh4_x86.tstate == TSTATE_NONE ) {
  1692 		CMPL_imms_rbpdisp( 1, R_T );
  1693 		sh4_x86.tstate = TSTATE_E;
  1695 	    sh4vma_t target = disp + pc + 4;
  1696 	    JCC_cc_rel32(sh4_x86.tstate,0);
  1697 	    uint32_t *patch = ((uint32_t *)xlat_output)-1;
  1698 	    int save_tstate = sh4_x86.tstate;
  1699 	    sh4_translate_instruction(pc+2);
  1700 	    exit_block_rel( target, pc+4 );
  1702 	    // not taken
  1703 	    *patch = (xlat_output - ((uint8_t *)patch)) - 4;
  1704 	    sh4_x86.tstate = save_tstate;
  1705 	    sh4_translate_instruction(pc+2);
  1706 	    return 4;
  1709 :}
  1710 BRA disp {:  
  1711     COUNT_INST(I_BRA);
  1712     if( sh4_x86.in_delay_slot ) {
  1713 	SLOTILLEGAL();
  1714     } else {
  1715 	sh4_x86.in_delay_slot = DELAY_PC;
  1716 	sh4_x86.branch_taken = TRUE;
  1717 	if( UNTRANSLATABLE(pc+2) ) {
  1718 	    MOVL_rbpdisp_r32( R_PC, REG_EAX );
  1719 	    ADDL_imms_r32( pc + disp + 4 - sh4_x86.block_start_pc, REG_EAX );
  1720 	    MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
  1721 	    exit_block_emu(pc+2);
  1722 	    return 2;
  1723 	} else {
  1724 	    sh4_translate_instruction( pc + 2 );
  1725 	    exit_block_rel( disp + pc + 4, pc+4 );
  1726 	    return 4;
  1729 :}
  1730 BRAF Rn {:  
  1731     COUNT_INST(I_BRAF);
  1732     if( sh4_x86.in_delay_slot ) {
  1733 	SLOTILLEGAL();
  1734     } else {
  1735 	MOVL_rbpdisp_r32( R_PC, REG_EAX );
  1736 	ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
  1737 	ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
  1738 	MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
  1739 	sh4_x86.in_delay_slot = DELAY_PC;
  1740 	sh4_x86.tstate = TSTATE_NONE;
  1741 	sh4_x86.branch_taken = TRUE;
  1742 	if( UNTRANSLATABLE(pc+2) ) {
  1743 	    exit_block_emu(pc+2);
  1744 	    return 2;
  1745 	} else {
  1746 	    sh4_translate_instruction( pc + 2 );
  1747 	    exit_block_newpcset(pc+4);
  1748 	    return 4;
  1751 :}
  1752 BSR disp {:  
  1753     COUNT_INST(I_BSR);
  1754     if( sh4_x86.in_delay_slot ) {
  1755 	SLOTILLEGAL();
  1756     } else {
  1757 	MOVL_rbpdisp_r32( R_PC, REG_EAX );
  1758 	ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
  1759 	MOVL_r32_rbpdisp( REG_EAX, R_PR );
  1760 	sh4_x86.in_delay_slot = DELAY_PC;
  1761 	sh4_x86.branch_taken = TRUE;
  1762 	sh4_x86.tstate = TSTATE_NONE;
  1763 	if( UNTRANSLATABLE(pc+2) ) {
  1764 	    ADDL_imms_r32( disp, REG_EAX );
  1765 	    MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
  1766 	    exit_block_emu(pc+2);
  1767 	    return 2;
  1768 	} else {
  1769 	    sh4_translate_instruction( pc + 2 );
  1770 	    exit_block_rel( disp + pc + 4, pc+4 );
  1771 	    return 4;
  1774 :}
  1775 BSRF Rn {:  
  1776     COUNT_INST(I_BSRF);
  1777     if( sh4_x86.in_delay_slot ) {
  1778 	SLOTILLEGAL();
  1779     } else {
  1780 	MOVL_rbpdisp_r32( R_PC, REG_EAX );
  1781 	ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
  1782 	MOVL_r32_rbpdisp( REG_EAX, R_PR );
  1783 	ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
  1784 	MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
  1786 	sh4_x86.in_delay_slot = DELAY_PC;
  1787 	sh4_x86.tstate = TSTATE_NONE;
  1788 	sh4_x86.branch_taken = TRUE;
  1789 	if( UNTRANSLATABLE(pc+2) ) {
  1790 	    exit_block_emu(pc+2);
  1791 	    return 2;
  1792 	} else {
  1793 	    sh4_translate_instruction( pc + 2 );
  1794 	    exit_block_newpcset(pc+4);
  1795 	    return 4;
  1798 :}
  1799 BT disp {:
  1800     COUNT_INST(I_BT);
  1801     if( sh4_x86.in_delay_slot ) {
  1802 	SLOTILLEGAL();
  1803     } else {
  1804 	sh4vma_t target = disp + pc + 4;
  1805 	JF_label( nottaken );
  1806 	exit_block_rel(target, pc+2 );
  1807 	JMP_TARGET(nottaken);
  1808 	return 2;
  1810 :}
  1811 BT/S disp {:
  1812     COUNT_INST(I_BTS);
  1813     if( sh4_x86.in_delay_slot ) {
  1814 	SLOTILLEGAL();
  1815     } else {
  1816 	sh4_x86.in_delay_slot = DELAY_PC;
  1817 	if( UNTRANSLATABLE(pc+2) ) {
  1818 	    MOVL_imm32_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
  1819 	    JF_label(nottaken);
  1820 	    ADDL_imms_r32( disp, REG_EAX );
  1821 	    JMP_TARGET(nottaken);
  1822 	    ADDL_rbpdisp_r32( R_PC, REG_EAX );
  1823 	    MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
  1824 	    exit_block_emu(pc+2);
  1825 	    sh4_x86.branch_taken = TRUE;
  1826 	    return 2;
  1827 	} else {
  1828 	    if( sh4_x86.tstate == TSTATE_NONE ) {
  1829 		CMPL_imms_rbpdisp( 1, R_T );
  1830 		sh4_x86.tstate = TSTATE_E;
  1832 	    JCC_cc_rel32(sh4_x86.tstate^1,0);
  1833 	    uint32_t *patch = ((uint32_t *)xlat_output)-1;
  1835 	    int save_tstate = sh4_x86.tstate;
  1836 	    sh4_translate_instruction(pc+2);
  1837 	    exit_block_rel( disp + pc + 4, pc+4 );
  1838 	    // not taken
  1839 	    *patch = (xlat_output - ((uint8_t *)patch)) - 4;
  1840 	    sh4_x86.tstate = save_tstate;
  1841 	    sh4_translate_instruction(pc+2);
  1842 	    return 4;
  1845 :}
  1846 JMP @Rn {:  
  1847     COUNT_INST(I_JMP);
  1848     if( sh4_x86.in_delay_slot ) {
  1849 	SLOTILLEGAL();
  1850     } else {
  1851 	load_reg( REG_ECX, Rn );
  1852 	MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
  1853 	sh4_x86.in_delay_slot = DELAY_PC;
  1854 	sh4_x86.branch_taken = TRUE;
  1855 	if( UNTRANSLATABLE(pc+2) ) {
  1856 	    exit_block_emu(pc+2);
  1857 	    return 2;
  1858 	} else {
  1859 	    sh4_translate_instruction(pc+2);
  1860 	    exit_block_newpcset(pc+4);
  1861 	    return 4;
  1864 :}
  1865 JSR @Rn {:  
  1866     COUNT_INST(I_JSR);
  1867     if( sh4_x86.in_delay_slot ) {
  1868 	SLOTILLEGAL();
  1869     } else {
  1870 	MOVL_rbpdisp_r32( R_PC, REG_EAX );
  1871 	ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
  1872 	MOVL_r32_rbpdisp( REG_EAX, R_PR );
  1873 	load_reg( REG_ECX, Rn );
  1874 	MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
  1875 	sh4_x86.in_delay_slot = DELAY_PC;
  1876 	sh4_x86.branch_taken = TRUE;
  1877 	sh4_x86.tstate = TSTATE_NONE;
  1878 	if( UNTRANSLATABLE(pc+2) ) {
  1879 	    exit_block_emu(pc+2);
  1880 	    return 2;
  1881 	} else {
  1882 	    sh4_translate_instruction(pc+2);
  1883 	    exit_block_newpcset(pc+4);
  1884 	    return 4;
  1887 :}
  1888 RTE {:  
  1889     COUNT_INST(I_RTE);
  1890     if( sh4_x86.in_delay_slot ) {
  1891 	SLOTILLEGAL();
  1892     } else {
  1893 	check_priv();
  1894 	MOVL_rbpdisp_r32( R_SPC, REG_ECX );
  1895 	MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
  1896 	MOVL_rbpdisp_r32( R_SSR, REG_EAX );
  1897 	CALL1_ptr_r32( sh4_write_sr, REG_EAX );
  1898 	sh4_x86.in_delay_slot = DELAY_PC;
  1899 	sh4_x86.fpuen_checked = FALSE;
  1900 	sh4_x86.tstate = TSTATE_NONE;
  1901 	sh4_x86.branch_taken = TRUE;
  1902 	if( UNTRANSLATABLE(pc+2) ) {
  1903 	    exit_block_emu(pc+2);
  1904 	    return 2;
  1905 	} else {
  1906 	    sh4_translate_instruction(pc+2);
  1907 	    exit_block_newpcset(pc+4);
  1908 	    return 4;
  1911 :}
  1912 RTS {:  
  1913     COUNT_INST(I_RTS);
  1914     if( sh4_x86.in_delay_slot ) {
  1915 	SLOTILLEGAL();
  1916     } else {
  1917 	MOVL_rbpdisp_r32( R_PR, REG_ECX );
  1918 	MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
  1919 	sh4_x86.in_delay_slot = DELAY_PC;
  1920 	sh4_x86.branch_taken = TRUE;
  1921 	if( UNTRANSLATABLE(pc+2) ) {
  1922 	    exit_block_emu(pc+2);
  1923 	    return 2;
  1924 	} else {
  1925 	    sh4_translate_instruction(pc+2);
  1926 	    exit_block_newpcset(pc+4);
  1927 	    return 4;
  1930 :}
  1931 TRAPA #imm {:  
  1932     COUNT_INST(I_TRAPA);
  1933     if( sh4_x86.in_delay_slot ) {
  1934 	SLOTILLEGAL();
  1935     } else {
  1936 	MOVL_imm32_r32( pc+2 - sh4_x86.block_start_pc, REG_ECX );   // 5
  1937 	ADDL_r32_rbpdisp( REG_ECX, R_PC );
  1938 	MOVL_imm32_r32( imm, REG_EAX );
  1939 	CALL1_ptr_r32( sh4_raise_trap, REG_EAX );
  1940 	sh4_x86.tstate = TSTATE_NONE;
  1941 	exit_block_pcset(pc+2);
  1942 	sh4_x86.branch_taken = TRUE;
  1943 	return 2;
  1945 :}
  1946 UNDEF {:  
  1947     COUNT_INST(I_UNDEF);
  1948     if( sh4_x86.in_delay_slot ) {
  1949 	exit_block_exc(EXC_SLOT_ILLEGAL, pc-2);    
  1950     } else {
  1951 	exit_block_exc(EXC_ILLEGAL, pc);    
  1952 	return 2;
  1954 :}
  1956 CLRMAC {:  
  1957     COUNT_INST(I_CLRMAC);
  1958     XORL_r32_r32(REG_EAX, REG_EAX);
  1959     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
  1960     MOVL_r32_rbpdisp( REG_EAX, R_MACH );
  1961     sh4_x86.tstate = TSTATE_NONE;
  1962 :}
  1963 CLRS {:
  1964     COUNT_INST(I_CLRS);
  1965     CLC();
  1966     SETCCB_cc_rbpdisp(X86_COND_C, R_S);
  1967     sh4_x86.tstate = TSTATE_NONE;
  1968 :}
  1969 CLRT {:  
  1970     COUNT_INST(I_CLRT);
  1971     CLC();
  1972     SETC_t();
  1973     sh4_x86.tstate = TSTATE_C;
  1974 :}
  1975 SETS {:  
  1976     COUNT_INST(I_SETS);
  1977     STC();
  1978     SETCCB_cc_rbpdisp(X86_COND_C, R_S);
  1979     sh4_x86.tstate = TSTATE_NONE;
  1980 :}
  1981 SETT {:  
  1982     COUNT_INST(I_SETT);
  1983     STC();
  1984     SETC_t();
  1985     sh4_x86.tstate = TSTATE_C;
  1986 :}
  1988 /* Floating point moves */
  1989 FMOV FRm, FRn {:  
  1990     COUNT_INST(I_FMOV1);
  1991     check_fpuen();
  1992     if( sh4_x86.double_size ) {
  1993         load_dr0( REG_EAX, FRm );
  1994         load_dr1( REG_ECX, FRm );
  1995         store_dr0( REG_EAX, FRn );
  1996         store_dr1( REG_ECX, FRn );
  1997     } else {
  1998         load_fr( REG_EAX, FRm ); // SZ=0 branch
  1999         store_fr( REG_EAX, FRn );
  2001 :}
  2002 FMOV FRm, @Rn {: 
  2003     COUNT_INST(I_FMOV2);
  2004     check_fpuen();
  2005     load_reg( REG_EAX, Rn );
  2006     if( sh4_x86.double_size ) {
  2007         check_walign64( REG_EAX );
  2008         load_dr0( REG_EDX, FRm );
  2009         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2010         load_reg( REG_EAX, Rn );
  2011         LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
  2012         load_dr1( REG_EDX, FRm );
  2013         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2014     } else {
  2015         check_walign32( REG_EAX );
  2016         load_fr( REG_EDX, FRm );
  2017         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2019     sh4_x86.tstate = TSTATE_NONE;
  2020 :}
  2021 FMOV @Rm, FRn {:  
  2022     COUNT_INST(I_FMOV5);
  2023     check_fpuen();
  2024     load_reg( REG_EAX, Rm );
  2025     if( sh4_x86.double_size ) {
  2026         check_ralign64( REG_EAX );
  2027         MEM_READ_LONG( REG_EAX, REG_EAX );
  2028         store_dr0( REG_EAX, FRn );
  2029         load_reg( REG_EAX, Rm );
  2030         LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
  2031         MEM_READ_LONG( REG_EAX, REG_EAX );
  2032         store_dr1( REG_EAX, FRn );
  2033     } else {
  2034         check_ralign32( REG_EAX );
  2035         MEM_READ_LONG( REG_EAX, REG_EAX );
  2036         store_fr( REG_EAX, FRn );
  2038     sh4_x86.tstate = TSTATE_NONE;
  2039 :}
  2040 FMOV FRm, @-Rn {:  
  2041     COUNT_INST(I_FMOV3);
  2042     check_fpuen();
  2043     load_reg( REG_EAX, Rn );
  2044     if( sh4_x86.double_size ) {
  2045         check_walign64( REG_EAX );
  2046         LEAL_r32disp_r32( REG_EAX, -8, REG_EAX );
  2047         load_dr0( REG_EDX, FRm );
  2048         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2049         load_reg( REG_EAX, Rn );
  2050         LEAL_r32disp_r32( REG_EAX, -4, REG_EAX );
  2051         load_dr1( REG_EDX, FRm );
  2052         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2053         ADDL_imms_rbpdisp(-8,REG_OFFSET(r[Rn]));
  2054     } else {
  2055         check_walign32( REG_EAX );
  2056         LEAL_r32disp_r32( REG_EAX, -4, REG_EAX );
  2057         load_fr( REG_EDX, FRm );
  2058         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2059         ADDL_imms_rbpdisp(-4,REG_OFFSET(r[Rn]));
  2061     sh4_x86.tstate = TSTATE_NONE;
  2062 :}
  2063 FMOV @Rm+, FRn {:
  2064     COUNT_INST(I_FMOV6);
  2065     check_fpuen();
  2066     load_reg( REG_EAX, Rm );
  2067     if( sh4_x86.double_size ) {
  2068         check_ralign64( REG_EAX );
  2069         MEM_READ_LONG( REG_EAX, REG_EAX );
  2070         store_dr0( REG_EAX, FRn );
  2071         load_reg( REG_EAX, Rm );
  2072         LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
  2073         MEM_READ_LONG( REG_EAX, REG_EAX );
  2074         store_dr1( REG_EAX, FRn );
  2075         ADDL_imms_rbpdisp( 8, REG_OFFSET(r[Rm]) );
  2076     } else {
  2077         check_ralign32( REG_EAX );
  2078         MEM_READ_LONG( REG_EAX, REG_EAX );
  2079         store_fr( REG_EAX, FRn );
  2080         ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2082     sh4_x86.tstate = TSTATE_NONE;
  2083 :}
  2084 FMOV FRm, @(R0, Rn) {:  
  2085     COUNT_INST(I_FMOV4);
  2086     check_fpuen();
  2087     load_reg( REG_EAX, Rn );
  2088     ADDL_rbpdisp_r32( REG_OFFSET(r[0]), REG_EAX );
  2089     if( sh4_x86.double_size ) {
  2090         check_walign64( REG_EAX );
  2091         load_dr0( REG_EDX, FRm );
  2092         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2093         load_reg( REG_EAX, Rn );
  2094         ADDL_rbpdisp_r32( REG_OFFSET(r[0]), REG_EAX );
  2095         LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
  2096         load_dr1( REG_EDX, FRm );
  2097         MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2098     } else {
  2099         check_walign32( REG_EAX );
  2100         load_fr( REG_EDX, FRm );
  2101         MEM_WRITE_LONG( REG_EAX, REG_EDX ); // 12
  2103     sh4_x86.tstate = TSTATE_NONE;
  2104 :}
  2105 FMOV @(R0, Rm), FRn {:  
  2106     COUNT_INST(I_FMOV7);
  2107     check_fpuen();
  2108     load_reg( REG_EAX, Rm );
  2109     ADDL_rbpdisp_r32( REG_OFFSET(r[0]), REG_EAX );
  2110     if( sh4_x86.double_size ) {
  2111         check_ralign64( REG_EAX );
  2112         MEM_READ_LONG( REG_EAX, REG_EAX );
  2113         store_dr0( REG_EAX, FRn );
  2114         load_reg( REG_EAX, Rm );
  2115         ADDL_rbpdisp_r32( REG_OFFSET(r[0]), REG_EAX );
  2116         LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
  2117         MEM_READ_LONG( REG_EAX, REG_EAX );
  2118         store_dr1( REG_EAX, FRn );
  2119     } else {
  2120         check_ralign32( REG_EAX );
  2121         MEM_READ_LONG( REG_EAX, REG_EAX );
  2122         store_fr( REG_EAX, FRn );
  2124     sh4_x86.tstate = TSTATE_NONE;
  2125 :}
  2126 FLDI0 FRn {:  /* IFF PR=0 */
  2127     COUNT_INST(I_FLDI0);
  2128     check_fpuen();
  2129     if( sh4_x86.double_prec == 0 ) {
  2130         XORL_r32_r32( REG_EAX, REG_EAX );
  2131         store_fr( REG_EAX, FRn );
  2133     sh4_x86.tstate = TSTATE_NONE;
  2134 :}
  2135 FLDI1 FRn {:  /* IFF PR=0 */
  2136     COUNT_INST(I_FLDI1);
  2137     check_fpuen();
  2138     if( sh4_x86.double_prec == 0 ) {
  2139         MOVL_imm32_r32( 0x3F800000, REG_EAX );
  2140         store_fr( REG_EAX, FRn );
  2142 :}
  2144 FLOAT FPUL, FRn {:  
  2145     COUNT_INST(I_FLOAT);
  2146     check_fpuen();
  2147     FILD_rbpdisp(R_FPUL);
  2148     if( sh4_x86.double_prec ) {
  2149         pop_dr( FRn );
  2150     } else {
  2151         pop_fr( FRn );
  2153 :}
  2154 FTRC FRm, FPUL {:  
  2155     COUNT_INST(I_FTRC);
  2156     check_fpuen();
  2157     if( sh4_x86.double_prec ) {
  2158         push_dr( FRm );
  2159     } else {
  2160         push_fr( FRm );
  2162     MOVP_immptr_rptr( &max_int, REG_ECX );
  2163     FILD_r32disp( REG_ECX, 0 );
  2164     FCOMIP_st(1);
  2165     JNA_label( sat );
  2166     MOVP_immptr_rptr( &min_int, REG_ECX );
  2167     FILD_r32disp( REG_ECX, 0 );
  2168     FCOMIP_st(1);              
  2169     JAE_label( sat2 );            
  2170     MOVP_immptr_rptr( &save_fcw, REG_EAX );
  2171     FNSTCW_r32disp( REG_EAX, 0 );
  2172     MOVP_immptr_rptr( &trunc_fcw, REG_EDX );
  2173     FLDCW_r32disp( REG_EDX, 0 );
  2174     FISTP_rbpdisp(R_FPUL);             
  2175     FLDCW_r32disp( REG_EAX, 0 );
  2176     JMP_label(end);             
  2178     JMP_TARGET(sat);
  2179     JMP_TARGET(sat2);
  2180     MOVL_r32disp_r32( REG_ECX, 0, REG_ECX ); // 2
  2181     MOVL_r32_rbpdisp( REG_ECX, R_FPUL );
  2182     FPOP_st();
  2183     JMP_TARGET(end);
  2184     sh4_x86.tstate = TSTATE_NONE;
  2185 :}
  2186 FLDS FRm, FPUL {:  
  2187     COUNT_INST(I_FLDS);
  2188     check_fpuen();
  2189     load_fr( REG_EAX, FRm );
  2190     MOVL_r32_rbpdisp( REG_EAX, R_FPUL );
  2191 :}
  2192 FSTS FPUL, FRn {:  
  2193     COUNT_INST(I_FSTS);
  2194     check_fpuen();
  2195     MOVL_rbpdisp_r32( R_FPUL, REG_EAX );
  2196     store_fr( REG_EAX, FRn );
  2197 :}
  2198 FCNVDS FRm, FPUL {:  
  2199     COUNT_INST(I_FCNVDS);
  2200     check_fpuen();
  2201     if( sh4_x86.double_prec ) {
  2202         push_dr( FRm );
  2203         pop_fpul();
  2205 :}
  2206 FCNVSD FPUL, FRn {:  
  2207     COUNT_INST(I_FCNVSD);
  2208     check_fpuen();
  2209     if( sh4_x86.double_prec ) {
  2210         push_fpul();
  2211         pop_dr( FRn );
  2213 :}
  2215 /* Floating point instructions */
  2216 FABS FRn {:  
  2217     COUNT_INST(I_FABS);
  2218     check_fpuen();
  2219     if( sh4_x86.double_prec ) {
  2220         push_dr(FRn);
  2221         FABS_st0();
  2222         pop_dr(FRn);
  2223     } else {
  2224         push_fr(FRn);
  2225         FABS_st0();
  2226         pop_fr(FRn);
  2228 :}
  2229 FADD FRm, FRn {:  
  2230     COUNT_INST(I_FADD);
  2231     check_fpuen();
  2232     if( sh4_x86.double_prec ) {
  2233         push_dr(FRm);
  2234         push_dr(FRn);
  2235         FADDP_st(1);
  2236         pop_dr(FRn);
  2237     } else {
  2238         push_fr(FRm);
  2239         push_fr(FRn);
  2240         FADDP_st(1);
  2241         pop_fr(FRn);
  2243 :}
  2244 FDIV FRm, FRn {:  
  2245     COUNT_INST(I_FDIV);
  2246     check_fpuen();
  2247     if( sh4_x86.double_prec ) {
  2248         push_dr(FRn);
  2249         push_dr(FRm);
  2250         FDIVP_st(1);
  2251         pop_dr(FRn);
  2252     } else {
  2253         push_fr(FRn);
  2254         push_fr(FRm);
  2255         FDIVP_st(1);
  2256         pop_fr(FRn);
  2258 :}
  2259 FMAC FR0, FRm, FRn {:  
  2260     COUNT_INST(I_FMAC);
  2261     check_fpuen();
  2262     if( sh4_x86.double_prec ) {
  2263         push_dr( 0 );
  2264         push_dr( FRm );
  2265         FMULP_st(1);
  2266         push_dr( FRn );
  2267         FADDP_st(1);
  2268         pop_dr( FRn );
  2269     } else {
  2270         push_fr( 0 );
  2271         push_fr( FRm );
  2272         FMULP_st(1);
  2273         push_fr( FRn );
  2274         FADDP_st(1);
  2275         pop_fr( FRn );
  2277 :}
  2279 FMUL FRm, FRn {:  
  2280     COUNT_INST(I_FMUL);
  2281     check_fpuen();
  2282     if( sh4_x86.double_prec ) {
  2283         push_dr(FRm);
  2284         push_dr(FRn);
  2285         FMULP_st(1);
  2286         pop_dr(FRn);
  2287     } else {
  2288         push_fr(FRm);
  2289         push_fr(FRn);
  2290         FMULP_st(1);
  2291         pop_fr(FRn);
  2293 :}
  2294 FNEG FRn {:  
  2295     COUNT_INST(I_FNEG);
  2296     check_fpuen();
  2297     if( sh4_x86.double_prec ) {
  2298         push_dr(FRn);
  2299         FCHS_st0();
  2300         pop_dr(FRn);
  2301     } else {
  2302         push_fr(FRn);
  2303         FCHS_st0();
  2304         pop_fr(FRn);
  2306 :}
  2307 FSRRA FRn {:  
  2308     COUNT_INST(I_FSRRA);
  2309     check_fpuen();
  2310     if( sh4_x86.double_prec == 0 ) {
  2311         FLD1_st0();
  2312         push_fr(FRn);
  2313         FSQRT_st0();
  2314         FDIVP_st(1);
  2315         pop_fr(FRn);
  2317 :}
  2318 FSQRT FRn {:  
  2319     COUNT_INST(I_FSQRT);
  2320     check_fpuen();
  2321     if( sh4_x86.double_prec ) {
  2322         push_dr(FRn);
  2323         FSQRT_st0();
  2324         pop_dr(FRn);
  2325     } else {
  2326         push_fr(FRn);
  2327         FSQRT_st0();
  2328         pop_fr(FRn);
  2330 :}
  2331 FSUB FRm, FRn {:  
  2332     COUNT_INST(I_FSUB);
  2333     check_fpuen();
  2334     if( sh4_x86.double_prec ) {
  2335         push_dr(FRn);
  2336         push_dr(FRm);
  2337         FSUBP_st(1);
  2338         pop_dr(FRn);
  2339     } else {
  2340         push_fr(FRn);
  2341         push_fr(FRm);
  2342         FSUBP_st(1);
  2343         pop_fr(FRn);
  2345 :}
  2347 FCMP/EQ FRm, FRn {:  
  2348     COUNT_INST(I_FCMPEQ);
  2349     check_fpuen();
  2350     if( sh4_x86.double_prec ) {
  2351         push_dr(FRm);
  2352         push_dr(FRn);
  2353     } else {
  2354         push_fr(FRm);
  2355         push_fr(FRn);
  2357     FCOMIP_st(1);
  2358     SETE_t();
  2359     FPOP_st();
  2360     sh4_x86.tstate = TSTATE_E;
  2361 :}
  2362 FCMP/GT FRm, FRn {:  
  2363     COUNT_INST(I_FCMPGT);
  2364     check_fpuen();
  2365     if( sh4_x86.double_prec ) {
  2366         push_dr(FRm);
  2367         push_dr(FRn);
  2368     } else {
  2369         push_fr(FRm);
  2370         push_fr(FRn);
  2372     FCOMIP_st(1);
  2373     SETA_t();
  2374     FPOP_st();
  2375     sh4_x86.tstate = TSTATE_A;
  2376 :}
  2378 FSCA FPUL, FRn {:  
  2379     COUNT_INST(I_FSCA);
  2380     check_fpuen();
  2381     if( sh4_x86.double_prec == 0 ) {
  2382         LEAP_rbpdisp_rptr( REG_OFFSET(fr[0][FRn&0x0E]), REG_EDX );
  2383         MOVL_rbpdisp_r32( R_FPUL, REG_EAX );
  2384         CALL2_ptr_r32_r32( sh4_fsca, REG_EAX, REG_EDX );
  2386     sh4_x86.tstate = TSTATE_NONE;
  2387 :}
  2388 FIPR FVm, FVn {:  
  2389     COUNT_INST(I_FIPR);
  2390     check_fpuen();
  2391     if( sh4_x86.double_prec == 0 ) {
  2392         if( sh4_x86.sse3_enabled ) {
  2393             MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[0][FVm<<2]), 4 );
  2394             MULPS_rbpdisp_xmm( REG_OFFSET(fr[0][FVn<<2]), 4 );
  2395             HADDPS_xmm_xmm( 4, 4 ); 
  2396             HADDPS_xmm_xmm( 4, 4 );
  2397             MOVSS_xmm_rbpdisp( 4, REG_OFFSET(fr[0][(FVn<<2)+2]) );
  2398         } else {
  2399             push_fr( FVm<<2 );
  2400             push_fr( FVn<<2 );
  2401             FMULP_st(1);
  2402             push_fr( (FVm<<2)+1);
  2403             push_fr( (FVn<<2)+1);
  2404             FMULP_st(1);
  2405             FADDP_st(1);
  2406             push_fr( (FVm<<2)+2);
  2407             push_fr( (FVn<<2)+2);
  2408             FMULP_st(1);
  2409             FADDP_st(1);
  2410             push_fr( (FVm<<2)+3);
  2411             push_fr( (FVn<<2)+3);
  2412             FMULP_st(1);
  2413             FADDP_st(1);
  2414             pop_fr( (FVn<<2)+3);
  2417 :}
  2418 FTRV XMTRX, FVn {:  
  2419     COUNT_INST(I_FTRV);
  2420     check_fpuen();
  2421     if( sh4_x86.double_prec == 0 ) {
  2422         if( sh4_x86.sse3_enabled ) {
  2423             MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][0]), 1 ); // M1  M0  M3  M2
  2424             MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][4]), 0 ); // M5  M4  M7  M6
  2425             MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][8]), 3 ); // M9  M8  M11 M10
  2426             MOVAPS_rbpdisp_xmm( REG_OFFSET(fr[1][12]), 2 );// M13 M12 M15 M14
  2428             MOVSLDUP_rbpdisp_xmm( REG_OFFSET(fr[0][FVn<<2]), 4 ); // V1 V1 V3 V3
  2429             MOVSHDUP_rbpdisp_xmm( REG_OFFSET(fr[0][FVn<<2]), 5 ); // V0 V0 V2 V2
  2430             MOV_xmm_xmm( 4, 6 );
  2431             MOV_xmm_xmm( 5, 7 );
  2432             MOVLHPS_xmm_xmm( 4, 4 );  // V1 V1 V1 V1
  2433             MOVHLPS_xmm_xmm( 6, 6 );  // V3 V3 V3 V3
  2434             MOVLHPS_xmm_xmm( 5, 5 );  // V0 V0 V0 V0
  2435             MOVHLPS_xmm_xmm( 7, 7 );  // V2 V2 V2 V2
  2436             MULPS_xmm_xmm( 0, 4 );
  2437             MULPS_xmm_xmm( 1, 5 );
  2438             MULPS_xmm_xmm( 2, 6 );
  2439             MULPS_xmm_xmm( 3, 7 );
  2440             ADDPS_xmm_xmm( 5, 4 );
  2441             ADDPS_xmm_xmm( 7, 6 );
  2442             ADDPS_xmm_xmm( 6, 4 );
  2443             MOVAPS_xmm_rbpdisp( 4, REG_OFFSET(fr[0][FVn<<2]) );
  2444         } else {
  2445             LEAP_rbpdisp_rptr( REG_OFFSET(fr[0][FVn<<2]), REG_EAX );
  2446             CALL1_ptr_r32( sh4_ftrv, REG_EAX );
  2449     sh4_x86.tstate = TSTATE_NONE;
  2450 :}
  2452 FRCHG {:  
  2453     COUNT_INST(I_FRCHG);
  2454     check_fpuen();
  2455     XORL_imms_rbpdisp( FPSCR_FR, R_FPSCR );
  2456     CALL_ptr( sh4_switch_fr_banks );
  2457     sh4_x86.tstate = TSTATE_NONE;
  2458 :}
  2459 FSCHG {:  
  2460     COUNT_INST(I_FSCHG);
  2461     check_fpuen();
  2462     XORL_imms_rbpdisp( FPSCR_SZ, R_FPSCR);
  2463     XORL_imms_rbpdisp( FPSCR_SZ, REG_OFFSET(xlat_sh4_mode) );
  2464     sh4_x86.tstate = TSTATE_NONE;
  2465     sh4_x86.double_size = !sh4_x86.double_size;
  2466 :}
  2468 /* Processor control instructions */
  2469 LDC Rm, SR {:
  2470     COUNT_INST(I_LDCSR);
  2471     if( sh4_x86.in_delay_slot ) {
  2472 	SLOTILLEGAL();
  2473     } else {
  2474 	check_priv();
  2475 	load_reg( REG_EAX, Rm );
  2476 	CALL1_ptr_r32( sh4_write_sr, REG_EAX );
  2477 	sh4_x86.fpuen_checked = FALSE;
  2478 	sh4_x86.tstate = TSTATE_NONE;
  2479 	return 2;
  2481 :}
  2482 LDC Rm, GBR {: 
  2483     COUNT_INST(I_LDC);
  2484     load_reg( REG_EAX, Rm );
  2485     MOVL_r32_rbpdisp( REG_EAX, R_GBR );
  2486 :}
  2487 LDC Rm, VBR {:  
  2488     COUNT_INST(I_LDC);
  2489     check_priv();
  2490     load_reg( REG_EAX, Rm );
  2491     MOVL_r32_rbpdisp( REG_EAX, R_VBR );
  2492     sh4_x86.tstate = TSTATE_NONE;
  2493 :}
  2494 LDC Rm, SSR {:  
  2495     COUNT_INST(I_LDC);
  2496     check_priv();
  2497     load_reg( REG_EAX, Rm );
  2498     MOVL_r32_rbpdisp( REG_EAX, R_SSR );
  2499     sh4_x86.tstate = TSTATE_NONE;
  2500 :}
  2501 LDC Rm, SGR {:  
  2502     COUNT_INST(I_LDC);
  2503     check_priv();
  2504     load_reg( REG_EAX, Rm );
  2505     MOVL_r32_rbpdisp( REG_EAX, R_SGR );
  2506     sh4_x86.tstate = TSTATE_NONE;
  2507 :}
  2508 LDC Rm, SPC {:  
  2509     COUNT_INST(I_LDC);
  2510     check_priv();
  2511     load_reg( REG_EAX, Rm );
  2512     MOVL_r32_rbpdisp( REG_EAX, R_SPC );
  2513     sh4_x86.tstate = TSTATE_NONE;
  2514 :}
  2515 LDC Rm, DBR {:  
  2516     COUNT_INST(I_LDC);
  2517     check_priv();
  2518     load_reg( REG_EAX, Rm );
  2519     MOVL_r32_rbpdisp( REG_EAX, R_DBR );
  2520     sh4_x86.tstate = TSTATE_NONE;
  2521 :}
  2522 LDC Rm, Rn_BANK {:  
  2523     COUNT_INST(I_LDC);
  2524     check_priv();
  2525     load_reg( REG_EAX, Rm );
  2526     MOVL_r32_rbpdisp( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  2527     sh4_x86.tstate = TSTATE_NONE;
  2528 :}
  2529 LDC.L @Rm+, GBR {:  
  2530     COUNT_INST(I_LDCM);
  2531     load_reg( REG_EAX, Rm );
  2532     check_ralign32( REG_EAX );
  2533     MEM_READ_LONG( REG_EAX, REG_EAX );
  2534     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2535     MOVL_r32_rbpdisp( REG_EAX, R_GBR );
  2536     sh4_x86.tstate = TSTATE_NONE;
  2537 :}
  2538 LDC.L @Rm+, SR {:
  2539     COUNT_INST(I_LDCSRM);
  2540     if( sh4_x86.in_delay_slot ) {
  2541 	SLOTILLEGAL();
  2542     } else {
  2543 	check_priv();
  2544 	load_reg( REG_EAX, Rm );
  2545 	check_ralign32( REG_EAX );
  2546 	MEM_READ_LONG( REG_EAX, REG_EAX );
  2547 	ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2548 	CALL1_ptr_r32( sh4_write_sr, REG_EAX );
  2549 	sh4_x86.fpuen_checked = FALSE;
  2550 	sh4_x86.tstate = TSTATE_NONE;
  2551 	return 2;
  2553 :}
  2554 LDC.L @Rm+, VBR {:  
  2555     COUNT_INST(I_LDCM);
  2556     check_priv();
  2557     load_reg( REG_EAX, Rm );
  2558     check_ralign32( REG_EAX );
  2559     MEM_READ_LONG( REG_EAX, REG_EAX );
  2560     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2561     MOVL_r32_rbpdisp( REG_EAX, R_VBR );
  2562     sh4_x86.tstate = TSTATE_NONE;
  2563 :}
  2564 LDC.L @Rm+, SSR {:
  2565     COUNT_INST(I_LDCM);
  2566     check_priv();
  2567     load_reg( REG_EAX, Rm );
  2568     check_ralign32( REG_EAX );
  2569     MEM_READ_LONG( REG_EAX, REG_EAX );
  2570     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2571     MOVL_r32_rbpdisp( REG_EAX, R_SSR );
  2572     sh4_x86.tstate = TSTATE_NONE;
  2573 :}
  2574 LDC.L @Rm+, SGR {:  
  2575     COUNT_INST(I_LDCM);
  2576     check_priv();
  2577     load_reg( REG_EAX, Rm );
  2578     check_ralign32( REG_EAX );
  2579     MEM_READ_LONG( REG_EAX, REG_EAX );
  2580     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2581     MOVL_r32_rbpdisp( REG_EAX, R_SGR );
  2582     sh4_x86.tstate = TSTATE_NONE;
  2583 :}
  2584 LDC.L @Rm+, SPC {:  
  2585     COUNT_INST(I_LDCM);
  2586     check_priv();
  2587     load_reg( REG_EAX, Rm );
  2588     check_ralign32( REG_EAX );
  2589     MEM_READ_LONG( REG_EAX, REG_EAX );
  2590     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2591     MOVL_r32_rbpdisp( REG_EAX, R_SPC );
  2592     sh4_x86.tstate = TSTATE_NONE;
  2593 :}
  2594 LDC.L @Rm+, DBR {:  
  2595     COUNT_INST(I_LDCM);
  2596     check_priv();
  2597     load_reg( REG_EAX, Rm );
  2598     check_ralign32( REG_EAX );
  2599     MEM_READ_LONG( REG_EAX, REG_EAX );
  2600     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2601     MOVL_r32_rbpdisp( REG_EAX, R_DBR );
  2602     sh4_x86.tstate = TSTATE_NONE;
  2603 :}
  2604 LDC.L @Rm+, Rn_BANK {:  
  2605     COUNT_INST(I_LDCM);
  2606     check_priv();
  2607     load_reg( REG_EAX, Rm );
  2608     check_ralign32( REG_EAX );
  2609     MEM_READ_LONG( REG_EAX, REG_EAX );
  2610     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2611     MOVL_r32_rbpdisp( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
  2612     sh4_x86.tstate = TSTATE_NONE;
  2613 :}
  2614 LDS Rm, FPSCR {:
  2615     COUNT_INST(I_LDSFPSCR);
  2616     check_fpuen();
  2617     load_reg( REG_EAX, Rm );
  2618     CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );
  2619     sh4_x86.tstate = TSTATE_NONE;
  2620     return 2;
  2621 :}
  2622 LDS.L @Rm+, FPSCR {:  
  2623     COUNT_INST(I_LDSFPSCRM);
  2624     check_fpuen();
  2625     load_reg( REG_EAX, Rm );
  2626     check_ralign32( REG_EAX );
  2627     MEM_READ_LONG( REG_EAX, REG_EAX );
  2628     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2629     CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );
  2630     sh4_x86.tstate = TSTATE_NONE;
  2631     return 2;
  2632 :}
  2633 LDS Rm, FPUL {:  
  2634     COUNT_INST(I_LDS);
  2635     check_fpuen();
  2636     load_reg( REG_EAX, Rm );
  2637     MOVL_r32_rbpdisp( REG_EAX, R_FPUL );
  2638 :}
  2639 LDS.L @Rm+, FPUL {:  
  2640     COUNT_INST(I_LDSM);
  2641     check_fpuen();
  2642     load_reg( REG_EAX, Rm );
  2643     check_ralign32( REG_EAX );
  2644     MEM_READ_LONG( REG_EAX, REG_EAX );
  2645     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2646     MOVL_r32_rbpdisp( REG_EAX, R_FPUL );
  2647     sh4_x86.tstate = TSTATE_NONE;
  2648 :}
  2649 LDS Rm, MACH {: 
  2650     COUNT_INST(I_LDS);
  2651     load_reg( REG_EAX, Rm );
  2652     MOVL_r32_rbpdisp( REG_EAX, R_MACH );
  2653 :}
  2654 LDS.L @Rm+, MACH {:  
  2655     COUNT_INST(I_LDSM);
  2656     load_reg( REG_EAX, Rm );
  2657     check_ralign32( REG_EAX );
  2658     MEM_READ_LONG( REG_EAX, REG_EAX );
  2659     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2660     MOVL_r32_rbpdisp( REG_EAX, R_MACH );
  2661     sh4_x86.tstate = TSTATE_NONE;
  2662 :}
  2663 LDS Rm, MACL {:  
  2664     COUNT_INST(I_LDS);
  2665     load_reg( REG_EAX, Rm );
  2666     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
  2667 :}
  2668 LDS.L @Rm+, MACL {:  
  2669     COUNT_INST(I_LDSM);
  2670     load_reg( REG_EAX, Rm );
  2671     check_ralign32( REG_EAX );
  2672     MEM_READ_LONG( REG_EAX, REG_EAX );
  2673     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2674     MOVL_r32_rbpdisp( REG_EAX, R_MACL );
  2675     sh4_x86.tstate = TSTATE_NONE;
  2676 :}
  2677 LDS Rm, PR {:  
  2678     COUNT_INST(I_LDS);
  2679     load_reg( REG_EAX, Rm );
  2680     MOVL_r32_rbpdisp( REG_EAX, R_PR );
  2681 :}
  2682 LDS.L @Rm+, PR {:  
  2683     COUNT_INST(I_LDSM);
  2684     load_reg( REG_EAX, Rm );
  2685     check_ralign32( REG_EAX );
  2686     MEM_READ_LONG( REG_EAX, REG_EAX );
  2687     ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
  2688     MOVL_r32_rbpdisp( REG_EAX, R_PR );
  2689     sh4_x86.tstate = TSTATE_NONE;
  2690 :}
  2691 LDTLB {:  
  2692     COUNT_INST(I_LDTLB);
  2693     CALL_ptr( MMU_ldtlb );
  2694     sh4_x86.tstate = TSTATE_NONE;
  2695 :}
  2696 OCBI @Rn {:
  2697     COUNT_INST(I_OCBI);
  2698 :}
  2699 OCBP @Rn {:
  2700     COUNT_INST(I_OCBP);
  2701 :}
  2702 OCBWB @Rn {:
  2703     COUNT_INST(I_OCBWB);
  2704 :}
  2705 PREF @Rn {:
  2706     COUNT_INST(I_PREF);
  2707     load_reg( REG_EAX, Rn );
  2708     MEM_PREFETCH( REG_EAX );
  2709     sh4_x86.tstate = TSTATE_NONE;
  2710 :}
  2711 SLEEP {: 
  2712     COUNT_INST(I_SLEEP);
  2713     check_priv();
  2714     CALL_ptr( sh4_sleep );
  2715     sh4_x86.tstate = TSTATE_NONE;
  2716     sh4_x86.in_delay_slot = DELAY_NONE;
  2717     return 2;
  2718 :}
  2719 STC SR, Rn {:
  2720     COUNT_INST(I_STCSR);
  2721     check_priv();
  2722     CALL_ptr(sh4_read_sr);
  2723     store_reg( REG_EAX, Rn );
  2724     sh4_x86.tstate = TSTATE_NONE;
  2725 :}
  2726 STC GBR, Rn {:  
  2727     COUNT_INST(I_STC);
  2728     MOVL_rbpdisp_r32( R_GBR, REG_EAX );
  2729     store_reg( REG_EAX, Rn );
  2730 :}
  2731 STC VBR, Rn {:  
  2732     COUNT_INST(I_STC);
  2733     check_priv();
  2734     MOVL_rbpdisp_r32( R_VBR, REG_EAX );
  2735     store_reg( REG_EAX, Rn );
  2736     sh4_x86.tstate = TSTATE_NONE;
  2737 :}
  2738 STC SSR, Rn {:  
  2739     COUNT_INST(I_STC);
  2740     check_priv();
  2741     MOVL_rbpdisp_r32( R_SSR, REG_EAX );
  2742     store_reg( REG_EAX, Rn );
  2743     sh4_x86.tstate = TSTATE_NONE;
  2744 :}
  2745 STC SPC, Rn {:  
  2746     COUNT_INST(I_STC);
  2747     check_priv();
  2748     MOVL_rbpdisp_r32( R_SPC, REG_EAX );
  2749     store_reg( REG_EAX, Rn );
  2750     sh4_x86.tstate = TSTATE_NONE;
  2751 :}
  2752 STC SGR, Rn {:  
  2753     COUNT_INST(I_STC);
  2754     check_priv();
  2755     MOVL_rbpdisp_r32( R_SGR, REG_EAX );
  2756     store_reg( REG_EAX, Rn );
  2757     sh4_x86.tstate = TSTATE_NONE;
  2758 :}
  2759 STC DBR, Rn {:  
  2760     COUNT_INST(I_STC);
  2761     check_priv();
  2762     MOVL_rbpdisp_r32( R_DBR, REG_EAX );
  2763     store_reg( REG_EAX, Rn );
  2764     sh4_x86.tstate = TSTATE_NONE;
  2765 :}
  2766 STC Rm_BANK, Rn {:
  2767     COUNT_INST(I_STC);
  2768     check_priv();
  2769     MOVL_rbpdisp_r32( REG_OFFSET(r_bank[Rm_BANK]), REG_EAX );
  2770     store_reg( REG_EAX, Rn );
  2771     sh4_x86.tstate = TSTATE_NONE;
  2772 :}
  2773 STC.L SR, @-Rn {:
  2774     COUNT_INST(I_STCSRM);
  2775     check_priv();
  2776     CALL_ptr( sh4_read_sr );
  2777     MOVL_r32_r32( REG_EAX, REG_EDX );
  2778     load_reg( REG_EAX, Rn );
  2779     check_walign32( REG_EAX );
  2780     LEAL_r32disp_r32( REG_EAX, -4, REG_EAX );
  2781     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2782     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2783     sh4_x86.tstate = TSTATE_NONE;
  2784 :}
  2785 STC.L VBR, @-Rn {:  
  2786     COUNT_INST(I_STCM);
  2787     check_priv();
  2788     load_reg( REG_EAX, Rn );
  2789     check_walign32( REG_EAX );
  2790     ADDL_imms_r32( -4, REG_EAX );
  2791     MOVL_rbpdisp_r32( R_VBR, REG_EDX );
  2792     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2793     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2794     sh4_x86.tstate = TSTATE_NONE;
  2795 :}
  2796 STC.L SSR, @-Rn {:  
  2797     COUNT_INST(I_STCM);
  2798     check_priv();
  2799     load_reg( REG_EAX, Rn );
  2800     check_walign32( REG_EAX );
  2801     ADDL_imms_r32( -4, REG_EAX );
  2802     MOVL_rbpdisp_r32( R_SSR, REG_EDX );
  2803     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2804     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2805     sh4_x86.tstate = TSTATE_NONE;
  2806 :}
  2807 STC.L SPC, @-Rn {:
  2808     COUNT_INST(I_STCM);
  2809     check_priv();
  2810     load_reg( REG_EAX, Rn );
  2811     check_walign32( REG_EAX );
  2812     ADDL_imms_r32( -4, REG_EAX );
  2813     MOVL_rbpdisp_r32( R_SPC, REG_EDX );
  2814     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2815     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2816     sh4_x86.tstate = TSTATE_NONE;
  2817 :}
  2818 STC.L SGR, @-Rn {:  
  2819     COUNT_INST(I_STCM);
  2820     check_priv();
  2821     load_reg( REG_EAX, Rn );
  2822     check_walign32( REG_EAX );
  2823     ADDL_imms_r32( -4, REG_EAX );
  2824     MOVL_rbpdisp_r32( R_SGR, REG_EDX );
  2825     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2826     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2827     sh4_x86.tstate = TSTATE_NONE;
  2828 :}
  2829 STC.L DBR, @-Rn {:  
  2830     COUNT_INST(I_STCM);
  2831     check_priv();
  2832     load_reg( REG_EAX, Rn );
  2833     check_walign32( REG_EAX );
  2834     ADDL_imms_r32( -4, REG_EAX );
  2835     MOVL_rbpdisp_r32( R_DBR, REG_EDX );
  2836     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2837     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2838     sh4_x86.tstate = TSTATE_NONE;
  2839 :}
  2840 STC.L Rm_BANK, @-Rn {:  
  2841     COUNT_INST(I_STCM);
  2842     check_priv();
  2843     load_reg( REG_EAX, Rn );
  2844     check_walign32( REG_EAX );
  2845     ADDL_imms_r32( -4, REG_EAX );
  2846     MOVL_rbpdisp_r32( REG_OFFSET(r_bank[Rm_BANK]), REG_EDX );
  2847     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2848     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2849     sh4_x86.tstate = TSTATE_NONE;
  2850 :}
  2851 STC.L GBR, @-Rn {:  
  2852     COUNT_INST(I_STCM);
  2853     load_reg( REG_EAX, Rn );
  2854     check_walign32( REG_EAX );
  2855     ADDL_imms_r32( -4, REG_EAX );
  2856     MOVL_rbpdisp_r32( R_GBR, REG_EDX );
  2857     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2858     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2859     sh4_x86.tstate = TSTATE_NONE;
  2860 :}
  2861 STS FPSCR, Rn {:  
  2862     COUNT_INST(I_STSFPSCR);
  2863     check_fpuen();
  2864     MOVL_rbpdisp_r32( R_FPSCR, REG_EAX );
  2865     store_reg( REG_EAX, Rn );
  2866 :}
  2867 STS.L FPSCR, @-Rn {:  
  2868     COUNT_INST(I_STSFPSCRM);
  2869     check_fpuen();
  2870     load_reg( REG_EAX, Rn );
  2871     check_walign32( REG_EAX );
  2872     ADDL_imms_r32( -4, REG_EAX );
  2873     MOVL_rbpdisp_r32( R_FPSCR, REG_EDX );
  2874     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2875     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2876     sh4_x86.tstate = TSTATE_NONE;
  2877 :}
  2878 STS FPUL, Rn {:  
  2879     COUNT_INST(I_STS);
  2880     check_fpuen();
  2881     MOVL_rbpdisp_r32( R_FPUL, REG_EAX );
  2882     store_reg( REG_EAX, Rn );
  2883 :}
  2884 STS.L FPUL, @-Rn {:  
  2885     COUNT_INST(I_STSM);
  2886     check_fpuen();
  2887     load_reg( REG_EAX, Rn );
  2888     check_walign32( REG_EAX );
  2889     ADDL_imms_r32( -4, REG_EAX );
  2890     MOVL_rbpdisp_r32( R_FPUL, REG_EDX );
  2891     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2892     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2893     sh4_x86.tstate = TSTATE_NONE;
  2894 :}
  2895 STS MACH, Rn {:  
  2896     COUNT_INST(I_STS);
  2897     MOVL_rbpdisp_r32( R_MACH, REG_EAX );
  2898     store_reg( REG_EAX, Rn );
  2899 :}
  2900 STS.L MACH, @-Rn {:  
  2901     COUNT_INST(I_STSM);
  2902     load_reg( REG_EAX, Rn );
  2903     check_walign32( REG_EAX );
  2904     ADDL_imms_r32( -4, REG_EAX );
  2905     MOVL_rbpdisp_r32( R_MACH, REG_EDX );
  2906     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2907     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2908     sh4_x86.tstate = TSTATE_NONE;
  2909 :}
  2910 STS MACL, Rn {:  
  2911     COUNT_INST(I_STS);
  2912     MOVL_rbpdisp_r32( R_MACL, REG_EAX );
  2913     store_reg( REG_EAX, Rn );
  2914 :}
  2915 STS.L MACL, @-Rn {:  
  2916     COUNT_INST(I_STSM);
  2917     load_reg( REG_EAX, Rn );
  2918     check_walign32( REG_EAX );
  2919     ADDL_imms_r32( -4, REG_EAX );
  2920     MOVL_rbpdisp_r32( R_MACL, REG_EDX );
  2921     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2922     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2923     sh4_x86.tstate = TSTATE_NONE;
  2924 :}
  2925 STS PR, Rn {:  
  2926     COUNT_INST(I_STS);
  2927     MOVL_rbpdisp_r32( R_PR, REG_EAX );
  2928     store_reg( REG_EAX, Rn );
  2929 :}
  2930 STS.L PR, @-Rn {:  
  2931     COUNT_INST(I_STSM);
  2932     load_reg( REG_EAX, Rn );
  2933     check_walign32( REG_EAX );
  2934     ADDL_imms_r32( -4, REG_EAX );
  2935     MOVL_rbpdisp_r32( R_PR, REG_EDX );
  2936     MEM_WRITE_LONG( REG_EAX, REG_EDX );
  2937     ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
  2938     sh4_x86.tstate = TSTATE_NONE;
  2939 :}
  2941 NOP {: 
  2942     COUNT_INST(I_NOP);
  2943     /* Do nothing. Well, we could emit an 0x90, but what would really be the point? */ 
  2944 :}
  2945 %%
  2946     sh4_x86.in_delay_slot = DELAY_NONE;
  2947     return 0;
  2951 /**
  2952  * The unwind methods only work if we compiled with DWARF2 frame information
  2953  * (ie -fexceptions), otherwise we have to use the direct frame scan.
  2954  */
  2955 #ifdef HAVE_EXCEPTIONS
  2956 #include <unwind.h>
  2958 struct UnwindInfo {
  2959     uintptr_t block_start;
  2960     uintptr_t block_end;
  2961     void *pc;
  2962 };
  2964 static _Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )
  2966     struct UnwindInfo *info = arg;
  2967     void *pc = (void *)_Unwind_GetIP(context);
  2968     if( ((uintptr_t)pc) >= info->block_start && ((uintptr_t)pc) < info->block_end ) {
  2969         info->pc = pc;
  2970         return _URC_NORMAL_STOP;
  2972     return _URC_NO_REASON;
  2975 void *xlat_get_native_pc( void *code, uint32_t code_size )
  2977     struct _Unwind_Exception exc;
  2978     struct UnwindInfo info;
  2980     info.pc = NULL;
  2981     info.block_start = (uintptr_t)code;
  2982     info.block_end = info.block_start + code_size;
  2983     void *result = NULL;
  2984     _Unwind_Backtrace( xlat_check_frame, &info );
  2985     return info.pc;
  2987 #else
  2988 /* Assume this is an ia32 build - amd64 should always have dwarf information */
  2989 void *xlat_get_native_pc( void *code, uint32_t code_size )
  2991     void *result = NULL;
  2992     asm(
  2993         "mov %%ebp, %%eax\n\t"
  2994         "mov $0x8, %%ecx\n\t"
  2995         "mov %1, %%edx\n"
  2996         "frame_loop: test %%eax, %%eax\n\t"
  2997         "je frame_not_found\n\t"
  2998         "cmp (%%eax), %%edx\n\t"
  2999         "je frame_found\n\t"
  3000         "sub $0x1, %%ecx\n\t"
  3001         "je frame_not_found\n\t"
  3002         "movl (%%eax), %%eax\n\t"
  3003         "jmp frame_loop\n"
  3004         "frame_found: movl 0x4(%%eax), %0\n"
  3005         "frame_not_found:"
  3006         : "=r" (result)
  3007         : "r" (((uint8_t *)&sh4r) + 128 )
  3008         : "eax", "ecx", "edx" );
  3009     return result;
  3011 #endif
.