Search
lxdream.org :: lxdream/src/sh4/sh4x86.in :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4x86.in
changeset 995:eb9d43e8aa08
prev992:7c15f8a71995
next996:2e8cf0a87243
author nkeynes
date Thu Mar 05 21:42:35 2009 +0000 (15 years ago)
permissions -rw-r--r--
last change Cleanup ABI headers - most of the content made consistent between versions, and moved into sh4x86.in proper
file annotate diff log raw
1.1 --- a/src/sh4/sh4x86.in Wed Mar 04 23:27:59 2009 +0000
1.2 +++ b/src/sh4/sh4x86.in Thu Mar 05 21:42:35 2009 +0000
1.3 @@ -40,24 +40,34 @@
1.4 /* Offset of a reg relative to the sh4r structure */
1.5 #define REG_OFFSET(reg) (((char *)&sh4r.reg) - ((char *)&sh4r) - 128)
1.6
1.7 -#define R_T REG_OFFSET(t)
1.8 -#define R_Q REG_OFFSET(q)
1.9 -#define R_S REG_OFFSET(s)
1.10 -#define R_M REG_OFFSET(m)
1.11 -#define R_SR REG_OFFSET(sr)
1.12 -#define R_GBR REG_OFFSET(gbr)
1.13 -#define R_SSR REG_OFFSET(ssr)
1.14 -#define R_SPC REG_OFFSET(spc)
1.15 -#define R_VBR REG_OFFSET(vbr)
1.16 -#define R_MACH REG_OFFSET(mac)+4
1.17 -#define R_MACL REG_OFFSET(mac)
1.18 -#define R_PC REG_OFFSET(pc)
1.19 +#define R_T REG_OFFSET(t)
1.20 +#define R_Q REG_OFFSET(q)
1.21 +#define R_S REG_OFFSET(s)
1.22 +#define R_M REG_OFFSET(m)
1.23 +#define R_SR REG_OFFSET(sr)
1.24 +#define R_GBR REG_OFFSET(gbr)
1.25 +#define R_SSR REG_OFFSET(ssr)
1.26 +#define R_SPC REG_OFFSET(spc)
1.27 +#define R_VBR REG_OFFSET(vbr)
1.28 +#define R_MACH REG_OFFSET(mac)+4
1.29 +#define R_MACL REG_OFFSET(mac)
1.30 +#define R_PC REG_OFFSET(pc)
1.31 #define R_NEW_PC REG_OFFSET(new_pc)
1.32 -#define R_PR REG_OFFSET(pr)
1.33 -#define R_SGR REG_OFFSET(sgr)
1.34 -#define R_FPUL REG_OFFSET(fpul)
1.35 -#define R_FPSCR REG_OFFSET(fpscr)
1.36 -#define R_DBR REG_OFFSET(dbr)
1.37 +#define R_PR REG_OFFSET(pr)
1.38 +#define R_SGR REG_OFFSET(sgr)
1.39 +#define R_FPUL REG_OFFSET(fpul)
1.40 +#define R_FPSCR REG_OFFSET(fpscr)
1.41 +#define R_DBR REG_OFFSET(dbr)
1.42 +#define R_R(rn) REG_OFFSET(r[rn])
1.43 +#define R_FR(f) REG_OFFSET(fr[0][(f)^1])
1.44 +#define R_XF(f) REG_OFFSET(fr[1][(f)^1])
1.45 +#define R_DR(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])
1.46 +#define R_DRL(f) REG_OFFSET(fr[(f)&1][(f)|0x01])
1.47 +#define R_DRH(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])
1.48 +
1.49 +#define DELAY_NONE 0
1.50 +#define DELAY_PC 1
1.51 +#define DELAY_PC_PR 2
1.52
1.53 struct backpatch_record {
1.54 uint32_t fixup_offset;
1.55 @@ -65,10 +75,6 @@
1.56 int32_t exc_code;
1.57 };
1.58
1.59 -#define DELAY_NONE 0
1.60 -#define DELAY_PC 1
1.61 -#define DELAY_PC_PR 2
1.62 -
1.63 /**
1.64 * Struct to manage internal translation state. This state is not saved -
1.65 * it is only valid between calls to sh4_translate_begin_block() and
1.66 @@ -145,14 +151,14 @@
1.67 }
1.68
1.69 #define TSTATE_NONE -1
1.70 -#define TSTATE_O 0
1.71 -#define TSTATE_C 2
1.72 -#define TSTATE_E 4
1.73 -#define TSTATE_NE 5
1.74 -#define TSTATE_G 0xF
1.75 -#define TSTATE_GE 0xD
1.76 -#define TSTATE_A 7
1.77 -#define TSTATE_AE 3
1.78 +#define TSTATE_O X86_COND_O
1.79 +#define TSTATE_C X86_COND_C
1.80 +#define TSTATE_E X86_COND_E
1.81 +#define TSTATE_NE X86_COND_NE
1.82 +#define TSTATE_G X86_COND_G
1.83 +#define TSTATE_GE X86_COND_GE
1.84 +#define TSTATE_A X86_COND_A
1.85 +#define TSTATE_AE X86_COND_AE
1.86
1.87 #define MARK_JMP8(x) uint8_t *_mark_jmp_##x = (xlat_output-1)
1.88 #define JMP_TARGET(x) *_mark_jmp_##x += (xlat_output - _mark_jmp_##x)
1.89 @@ -188,14 +194,9 @@
1.90 CMPL_imms_rbpdisp( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \
1.91 JCC_cc_rel8(sh4_x86.tstate^1, -1); MARK_JMP8(label)
1.92
1.93 -#define load_reg16s(x86reg,sh4reg) MOVSXL_rbpdisp16_r32( REG_OFFSET(r[sh4reg]), x86reg )
1.94 -#define load_reg16u(x86reg,sh4reg) MOVZXL_rbpdisp16_r32( REG_OFFSET(r[sh4reg]), x86reg )
1.95 -#define load_imm32(x86reg,value) MOVL_imm32_r32(value,x86reg)
1.96 -#define load_imm64(x86reg,value) MOVQ_imm64_r64(value,x86reg)
1.97 +
1.98 #define load_reg(x86reg,sh4reg) MOVL_rbpdisp_r32( REG_OFFSET(r[sh4reg]), x86reg )
1.99 #define store_reg(x86reg,sh4reg) MOVL_r32_rbpdisp( x86reg, REG_OFFSET(r[sh4reg]) )
1.100 -#define load_spreg(x86reg, regoff) MOVL_rbpdisp_r32( regoff, x86reg )
1.101 -#define store_spreg(x86reg, regoff) MOVL_r32_rbpdisp( x86reg, regoff )
1.102
1.103 /**
1.104 * Load an FR register (single-precision floating point) into an integer x86
1.105 @@ -233,7 +234,7 @@
1.106 #define pop_xdr(frm) FSTPD_rbpdisp( REG_OFFSET(fr[1][(frm)&0x0E]) )
1.107
1.108 #ifdef ENABLE_SH4STATS
1.109 -#define COUNT_INST(id) load_imm32(REG_EAX,id); call_func1(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE
1.110 +#define COUNT_INST(id) MOVL_imm32_r32( id, REG_EAX ); CALL1_ptr_r32(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE
1.111 #else
1.112 #define COUNT_INST(id)
1.113 #endif
1.114 @@ -256,7 +257,7 @@
1.115 #define check_fpuen( ) \
1.116 if( !sh4_x86.fpuen_checked ) {\
1.117 sh4_x86.fpuen_checked = TRUE;\
1.118 - load_spreg( REG_EAX, R_SR );\
1.119 + MOVL_rbpdisp_r32( R_SR, REG_EAX );\
1.120 ANDL_imms_r32( SR_FD, REG_EAX );\
1.121 if( sh4_x86.in_delay_slot ) {\
1.122 JNE_exc(EXC_SLOT_FPU_DISABLED);\
1.123 @@ -291,42 +292,80 @@
1.124 JNE_exc(EXC_DATA_ADDR_WRITE);
1.125
1.126 #define UNDEF(ir)
1.127 -#define MEM_REGION_PTR(name) offsetof( struct mem_region_fn, name )
1.128 -#define MEM_RESULT(value_reg) if(value_reg != REG_EAX) { MOVL_r32_r32(REG_EAX,value_reg); }
1.129 /* Note: For SR.MD == 1 && MMUCR.AT == 0, there are no memory exceptions, so
1.130 * don't waste the cycles expecting them. Otherwise we need to save the exception pointer.
1.131 */
1.132 -
1.133 #ifdef HAVE_FRAME_ADDRESS
1.134 -#define _CALL_READ(addr_reg, fn) if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { \
1.135 - call_func1_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg); } else { \
1.136 - call_func1_r32disp8_exc(REG_ECX, MEM_REGION_PTR(fn), addr_reg, pc); }
1.137 -#define _CALL_WRITE(addr_reg, val_reg, fn) if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { \
1.138 - call_func2_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg); } else { \
1.139 - call_func2_r32disp8_exc(REG_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg, pc); }
1.140 -#else
1.141 -#define _CALL_READ(addr_reg, fn) call_func1_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg)
1.142 -#define _CALL_WRITE(addr_reg, val_reg, fn) call_func2_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg)
1.143 +static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
1.144 +{
1.145 + decode_address(addr_reg);
1.146 + if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) {
1.147 + CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
1.148 + } else {
1.149 + if( addr_reg != REG_ARG1 ) {
1.150 + MOVL_r32_r32( addr_reg, REG_ARG1 );
1.151 + }
1.152 + MOVP_immptr_rptr( 0, REG_ARG2 );
1.153 + sh4_x86_add_backpatch( xlat_output, pc, -2 );
1.154 + CALL2_r32disp_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2);
1.155 + }
1.156 + if( value_reg != REG_RESULT1 ) {
1.157 + MOVL_r32_r32( REG_RESULT1, value_reg );
1.158 + }
1.159 +}
1.160 +
1.161 +static void call_write_func(int addr_reg, int value_reg, int offset, int pc)
1.162 +{
1.163 + decode_address(addr_reg);
1.164 + if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) {
1.165 + CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
1.166 + } else {
1.167 + if( value_reg != REG_ARG2 ) {
1.168 + MOVL_r32_r32( value_reg, REG_ARG2 );
1.169 + }
1.170 + if( addr_reg != REG_ARG1 ) {
1.171 + MOVL_r32_r32( addr_reg, REG_ARG1 );
1.172 + }
1.173 +#if MAX_REG_ARG > 2
1.174 + MOVP_immptr_rptr( 0, REG_ARG3 );
1.175 + sh4_x86_add_backpatch( xlat_output, pc, -2 );
1.176 + CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, REG_ARG3);
1.177 +#else
1.178 + MOVL_imm32_rspdisp( 0, 0 );
1.179 + sh4_x86_add_backpatch( xlat_output, pc, -2 );
1.180 + CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, 0);
1.181 +#endif
1.182 + }
1.183 +}
1.184 +#else
1.185 +static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
1.186 +{
1.187 + decode_address(addr_reg);
1.188 + CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
1.189 + if( value_reg != REG_RESULT1 ) {
1.190 + MOVL_r32_r32( REG_RESULT1, value_reg );
1.191 + }
1.192 +}
1.193 +
1.194 +static void call_write_func(int addr_reg, int value_reg, int value_reg, int pc)
1.195 +{
1.196 + decode_address(addr_reg);
1.197 + CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
1.198 +}
1.199 #endif
1.200
1.201 -#define MEM_READ_BYTE( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_byte); MEM_RESULT(value_reg)
1.202 -#define MEM_READ_BYTE_FOR_WRITE( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_byte_for_write); MEM_RESULT(value_reg)
1.203 -#define MEM_READ_WORD( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_word); MEM_RESULT(value_reg)
1.204 -#define MEM_READ_LONG( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_long); MEM_RESULT(value_reg)
1.205 -#define MEM_WRITE_BYTE( addr_reg, value_reg ) decode_address(addr_reg); _CALL_WRITE(addr_reg, value_reg, write_byte)
1.206 -#define MEM_WRITE_WORD( addr_reg, value_reg ) decode_address(addr_reg); _CALL_WRITE(addr_reg, value_reg, write_word)
1.207 -#define MEM_WRITE_LONG( addr_reg, value_reg ) decode_address(addr_reg); _CALL_WRITE(addr_reg, value_reg, write_long)
1.208 -#define MEM_PREFETCH( addr_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, prefetch)
1.209 +#define MEM_REGION_PTR(name) offsetof( struct mem_region_fn, name )
1.210 +#define MEM_READ_BYTE( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_byte), pc)
1.211 +#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)
1.212 +#define MEM_READ_WORD( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_word), pc)
1.213 +#define MEM_READ_LONG( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_long), pc)
1.214 +#define MEM_WRITE_BYTE( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_byte), pc)
1.215 +#define MEM_WRITE_WORD( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_word), pc)
1.216 +#define MEM_WRITE_LONG( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_long), pc)
1.217 +#define MEM_PREFETCH( addr_reg ) call_read_func(addr_reg, REG_RESULT1, MEM_REGION_PTR(prefetch), pc)
1.218
1.219 #define SLOTILLEGAL() exit_block_exc(EXC_SLOT_ILLEGAL, pc-2); sh4_x86.in_delay_slot = DELAY_NONE; return 2;
1.220
1.221 -/****** Import appropriate calling conventions ******/
1.222 -#if SIZEOF_VOID_P == 8
1.223 -#include "xlat/x86/amd64abi.h"
1.224 -#else /* 32-bit system */
1.225 -#include "xlat/x86/ia32abi.h"
1.226 -#endif
1.227 -
1.228 void sh4_translate_begin_block( sh4addr_t pc )
1.229 {
1.230 enter_block();
1.231 @@ -357,8 +396,8 @@
1.232 */
1.233 void sh4_translate_emit_breakpoint( sh4vma_t pc )
1.234 {
1.235 - load_imm32( REG_EAX, pc );
1.236 - call_func1( sh4_translate_breakpoint_hit, REG_EAX );
1.237 + MOVL_imm32_r32( pc, REG_EAX );
1.238 + CALL1_ptr_r32( sh4_translate_breakpoint_hit, REG_EAX );
1.239 sh4_x86.tstate = TSTATE_NONE;
1.240 }
1.241
1.242 @@ -366,6 +405,102 @@
1.243 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
1.244
1.245 /**
1.246 + * Exit the block with sh4r.pc already written
1.247 + */
1.248 +void exit_block_pcset( sh4addr_t pc )
1.249 +{
1.250 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
1.251 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
1.252 + MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
1.253 + if( sh4_x86.tlb_on ) {
1.254 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
1.255 + } else {
1.256 + CALL1_ptr_r32(xlat_get_code,REG_ARG1);
1.257 + }
1.258 + exit_block();
1.259 +}
1.260 +
1.261 +/**
1.262 + * Exit the block with sh4r.new_pc written with the target pc
1.263 + */
1.264 +void exit_block_newpcset( sh4addr_t pc )
1.265 +{
1.266 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
1.267 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
1.268 + MOVL_rbpdisp_r32( R_NEW_PC, REG_ARG1 );
1.269 + MOVL_r32_rbpdisp( REG_ARG1, R_PC );
1.270 + if( sh4_x86.tlb_on ) {
1.271 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
1.272 + } else {
1.273 + CALL1_ptr_r32(xlat_get_code,REG_ARG1);
1.274 + }
1.275 + exit_block();
1.276 +}
1.277 +
1.278 +
1.279 +/**
1.280 + * Exit the block to an absolute PC
1.281 + */
1.282 +void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )
1.283 +{
1.284 + MOVL_imm32_r32( pc, REG_ECX );
1.285 + MOVL_r32_rbpdisp( REG_ECX, R_PC );
1.286 + if( IS_IN_ICACHE(pc) ) {
1.287 + MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
1.288 + ANDP_imms_rptr( -4, REG_EAX );
1.289 + } else if( sh4_x86.tlb_on ) {
1.290 + CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);
1.291 + } else {
1.292 + CALL1_ptr_r32(xlat_get_code, REG_ECX);
1.293 + }
1.294 + MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
1.295 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
1.296 + exit_block();
1.297 +}
1.298 +
1.299 +/**
1.300 + * Exit the block to a relative PC
1.301 + */
1.302 +void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )
1.303 +{
1.304 + MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );
1.305 + ADDL_rbpdisp_r32( R_PC, REG_ECX );
1.306 + MOVL_r32_rbpdisp( REG_ECX, R_PC );
1.307 + if( IS_IN_ICACHE(pc) ) {
1.308 + MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );
1.309 + ANDP_imms_rptr( -4, REG_EAX );
1.310 + } else if( sh4_x86.tlb_on ) {
1.311 + CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);
1.312 + } else {
1.313 + CALL1_ptr_r32(xlat_get_code, REG_ECX);
1.314 + }
1.315 + MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
1.316 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
1.317 + exit_block();
1.318 +}
1.319 +
1.320 +/**
1.321 + * Exit unconditionally with a general exception
1.322 + */
1.323 +void exit_block_exc( int code, sh4addr_t pc )
1.324 +{
1.325 + MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );
1.326 + ADDL_r32_rbpdisp( REG_ECX, R_PC );
1.327 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );
1.328 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );
1.329 + MOVL_imm32_r32( code, REG_ARG1 );
1.330 + CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );
1.331 + MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
1.332 + if( sh4_x86.tlb_on ) {
1.333 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);
1.334 + } else {
1.335 + CALL1_ptr_r32(xlat_get_code,REG_ARG1);
1.336 + }
1.337 +
1.338 + exit_block();
1.339 +}
1.340 +
1.341 +/**
1.342 * Embed a call to sh4_execute_instruction for situations that we
1.343 * can't translate (just page-crossing delay slots at the moment).
1.344 * Caller is responsible for setting new_pc before calling this function.
1.345 @@ -379,25 +514,74 @@
1.346 */
1.347 void exit_block_emu( sh4vma_t endpc )
1.348 {
1.349 - load_imm32( REG_ECX, endpc - sh4_x86.block_start_pc ); // 5
1.350 + MOVL_imm32_r32( endpc - sh4_x86.block_start_pc, REG_ECX ); // 5
1.351 ADDL_r32_rbpdisp( REG_ECX, R_PC );
1.352
1.353 - load_imm32( REG_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 5
1.354 + MOVL_imm32_r32( (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period, REG_ECX ); // 5
1.355 ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
1.356 - load_imm32( REG_ECX, sh4_x86.in_delay_slot ? 1 : 0 );
1.357 - store_spreg( REG_ECX, REG_OFFSET(in_delay_slot) );
1.358 + MOVL_imm32_r32( sh4_x86.in_delay_slot ? 1 : 0, REG_ECX );
1.359 + MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(in_delay_slot) );
1.360
1.361 - call_func0( sh4_execute_instruction );
1.362 - load_spreg( REG_EAX, R_PC );
1.363 + CALL_ptr( sh4_execute_instruction );
1.364 + MOVL_rbpdisp_r32( R_PC, REG_EAX );
1.365 if( sh4_x86.tlb_on ) {
1.366 - call_func1(xlat_get_code_by_vma,REG_EAX);
1.367 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_EAX);
1.368 } else {
1.369 - call_func1(xlat_get_code,REG_EAX);
1.370 + CALL1_ptr_r32(xlat_get_code,REG_EAX);
1.371 }
1.372 exit_block();
1.373 }
1.374
1.375 /**
1.376 + * Write the block trailer (exception handling block)
1.377 + */
1.378 +void sh4_translate_end_block( sh4addr_t pc ) {
1.379 + if( sh4_x86.branch_taken == FALSE ) {
1.380 + // Didn't exit unconditionally already, so write the termination here
1.381 + exit_block_rel( pc, pc );
1.382 + }
1.383 + if( sh4_x86.backpatch_posn != 0 ) {
1.384 + unsigned int i;
1.385 + // Exception raised - cleanup and exit
1.386 + uint8_t *end_ptr = xlat_output;
1.387 + MOVL_r32_r32( REG_EDX, REG_ECX );
1.388 + ADDL_r32_r32( REG_EDX, REG_ECX );
1.389 + ADDL_r32_rbpdisp( REG_ECX, R_SPC );
1.390 + MOVL_moffptr_eax( &sh4_cpu_period );
1.391 + MULL_r32( REG_EDX );
1.392 + ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );
1.393 + MOVL_rbpdisp_r32( R_PC, REG_ARG1 );
1.394 + if( sh4_x86.tlb_on ) {
1.395 + CALL1_ptr_r32(xlat_get_code_by_vma, REG_ARG1);
1.396 + } else {
1.397 + CALL1_ptr_r32(xlat_get_code, REG_ARG1);
1.398 + }
1.399 + exit_block();
1.400 +
1.401 + for( i=0; i< sh4_x86.backpatch_posn; i++ ) {
1.402 + uint32_t *fixup_addr = (uint32_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset];
1.403 + if( sh4_x86.backpatch_list[i].exc_code < 0 ) {
1.404 + if( sh4_x86.backpatch_list[i].exc_code == -2 ) {
1.405 + *((uintptr_t *)fixup_addr) = (uintptr_t)xlat_output;
1.406 + } else {
1.407 + *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;
1.408 + }
1.409 + MOVL_imm32_r32( sh4_x86.backpatch_list[i].fixup_icount, REG_EDX );
1.410 + int rel = end_ptr - xlat_output;
1.411 + JMP_prerel(rel);
1.412 + } else {
1.413 + *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;
1.414 + MOVL_imm32_r32( sh4_x86.backpatch_list[i].exc_code, REG_ARG1 );
1.415 + CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );
1.416 + MOVL_imm32_r32( sh4_x86.backpatch_list[i].fixup_icount, REG_EDX );
1.417 + int rel = end_ptr - xlat_output;
1.418 + JMP_prerel(rel);
1.419 + }
1.420 + }
1.421 + }
1.422 +}
1.423 +
1.424 +/**
1.425 * Translate a single instruction. Delayed branches are handled specially
1.426 * by translating both branch and delayed instruction as a single unit (as
1.427 *
1.428 @@ -564,8 +748,8 @@
1.429 load_reg( REG_ECX, Rn );
1.430 SHRL_imm_r32( 31, REG_EAX );
1.431 SHRL_imm_r32( 31, REG_ECX );
1.432 - store_spreg( REG_EAX, R_M );
1.433 - store_spreg( REG_ECX, R_Q );
1.434 + MOVL_r32_rbpdisp( REG_EAX, R_M );
1.435 + MOVL_r32_rbpdisp( REG_ECX, R_Q );
1.436 CMPL_r32_r32( REG_EAX, REG_ECX );
1.437 SETNE_t();
1.438 sh4_x86.tstate = TSTATE_NE;
1.439 @@ -573,14 +757,14 @@
1.440 DIV0U {:
1.441 COUNT_INST(I_DIV0U);
1.442 XORL_r32_r32( REG_EAX, REG_EAX );
1.443 - store_spreg( REG_EAX, R_Q );
1.444 - store_spreg( REG_EAX, R_M );
1.445 - store_spreg( REG_EAX, R_T );
1.446 + MOVL_r32_rbpdisp( REG_EAX, R_Q );
1.447 + MOVL_r32_rbpdisp( REG_EAX, R_M );
1.448 + MOVL_r32_rbpdisp( REG_EAX, R_T );
1.449 sh4_x86.tstate = TSTATE_C; // works for DIV1
1.450 :}
1.451 DIV1 Rm, Rn {:
1.452 COUNT_INST(I_DIV1);
1.453 - load_spreg( REG_ECX, R_M );
1.454 + MOVL_rbpdisp_r32( R_M, REG_ECX );
1.455 load_reg( REG_EAX, Rn );
1.456 if( sh4_x86.tstate != TSTATE_C ) {
1.457 LDC_t();
1.458 @@ -598,10 +782,10 @@
1.459 SETC_r8(REG_AL); // tmp1
1.460 XORB_r8_r8( REG_DL, REG_AL ); // Q' = Q ^ tmp1
1.461 XORB_r8_r8( REG_AL, REG_CL ); // Q'' = Q' ^ M
1.462 - store_spreg( REG_ECX, R_Q );
1.463 + MOVL_r32_rbpdisp( REG_ECX, R_Q );
1.464 XORL_imms_r32( 1, REG_AL ); // T = !Q'
1.465 MOVZXL_r8_r32( REG_AL, REG_EAX );
1.466 - store_spreg( REG_EAX, R_T );
1.467 + MOVL_r32_rbpdisp( REG_EAX, R_T );
1.468 sh4_x86.tstate = TSTATE_NONE;
1.469 :}
1.470 DMULS.L Rm, Rn {:
1.471 @@ -609,8 +793,8 @@
1.472 load_reg( REG_EAX, Rm );
1.473 load_reg( REG_ECX, Rn );
1.474 IMULL_r32(REG_ECX);
1.475 - store_spreg( REG_EDX, R_MACH );
1.476 - store_spreg( REG_EAX, R_MACL );
1.477 + MOVL_r32_rbpdisp( REG_EDX, R_MACH );
1.478 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.479 sh4_x86.tstate = TSTATE_NONE;
1.480 :}
1.481 DMULU.L Rm, Rn {:
1.482 @@ -618,8 +802,8 @@
1.483 load_reg( REG_EAX, Rm );
1.484 load_reg( REG_ECX, Rn );
1.485 MULL_r32(REG_ECX);
1.486 - store_spreg( REG_EDX, R_MACH );
1.487 - store_spreg( REG_EAX, R_MACL );
1.488 + MOVL_r32_rbpdisp( REG_EDX, R_MACH );
1.489 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.490 sh4_x86.tstate = TSTATE_NONE;
1.491 :}
1.492 DT Rn {:
1.493 @@ -681,10 +865,10 @@
1.494 ADDL_r32_rbpdisp( REG_EAX, R_MACL );
1.495 ADCL_r32_rbpdisp( REG_EDX, R_MACH );
1.496
1.497 - load_spreg( REG_ECX, R_S );
1.498 + MOVL_rbpdisp_r32( R_S, REG_ECX );
1.499 TESTL_r32_r32(REG_ECX, REG_ECX);
1.500 JE_label( nosat );
1.501 - call_func0( signsat48 );
1.502 + CALL_ptr( signsat48 );
1.503 JMP_TARGET( nosat );
1.504 sh4_x86.tstate = TSTATE_NONE;
1.505 :}
1.506 @@ -713,22 +897,22 @@
1.507 ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rm]) );
1.508 }
1.509 IMULL_rspdisp( 0 );
1.510 - load_spreg( REG_ECX, R_S );
1.511 + MOVL_rbpdisp_r32( R_S, REG_ECX );
1.512 TESTL_r32_r32( REG_ECX, REG_ECX );
1.513 JE_label( nosat );
1.514
1.515 ADDL_r32_rbpdisp( REG_EAX, R_MACL ); // 6
1.516 JNO_label( end ); // 2
1.517 - load_imm32( REG_EDX, 1 ); // 5
1.518 - store_spreg( REG_EDX, R_MACH ); // 6
1.519 + MOVL_imm32_r32( 1, REG_EDX ); // 5
1.520 + MOVL_r32_rbpdisp( REG_EDX, R_MACH ); // 6
1.521 JS_label( positive ); // 2
1.522 - load_imm32( REG_EAX, 0x80000000 );// 5
1.523 - store_spreg( REG_EAX, R_MACL ); // 6
1.524 + MOVL_imm32_r32( 0x80000000, REG_EAX );// 5
1.525 + MOVL_r32_rbpdisp( REG_EAX, R_MACL ); // 6
1.526 JMP_label(end2); // 2
1.527
1.528 JMP_TARGET(positive);
1.529 - load_imm32( REG_EAX, 0x7FFFFFFF );// 5
1.530 - store_spreg( REG_EAX, R_MACL ); // 6
1.531 + MOVL_imm32_r32( 0x7FFFFFFF, REG_EAX );// 5
1.532 + MOVL_r32_rbpdisp( REG_EAX, R_MACL ); // 6
1.533 JMP_label(end3); // 2
1.534
1.535 JMP_TARGET(nosat);
1.536 @@ -741,7 +925,7 @@
1.537 :}
1.538 MOVT Rn {:
1.539 COUNT_INST(I_MOVT);
1.540 - load_spreg( REG_EAX, R_T );
1.541 + MOVL_rbpdisp_r32( R_T, REG_EAX );
1.542 store_reg( REG_EAX, Rn );
1.543 :}
1.544 MUL.L Rm, Rn {:
1.545 @@ -749,23 +933,23 @@
1.546 load_reg( REG_EAX, Rm );
1.547 load_reg( REG_ECX, Rn );
1.548 MULL_r32( REG_ECX );
1.549 - store_spreg( REG_EAX, R_MACL );
1.550 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.551 sh4_x86.tstate = TSTATE_NONE;
1.552 :}
1.553 MULS.W Rm, Rn {:
1.554 COUNT_INST(I_MULSW);
1.555 - load_reg16s( REG_EAX, Rm );
1.556 - load_reg16s( REG_ECX, Rn );
1.557 + MOVSXL_rbpdisp16_r32( R_R(Rm), REG_EAX );
1.558 + MOVSXL_rbpdisp16_r32( R_R(Rn), REG_ECX );
1.559 MULL_r32( REG_ECX );
1.560 - store_spreg( REG_EAX, R_MACL );
1.561 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.562 sh4_x86.tstate = TSTATE_NONE;
1.563 :}
1.564 MULU.W Rm, Rn {:
1.565 COUNT_INST(I_MULUW);
1.566 - load_reg16u( REG_EAX, Rm );
1.567 - load_reg16u( REG_ECX, Rn );
1.568 + MOVZXL_rbpdisp16_r32( R_R(Rm), REG_EAX );
1.569 + MOVZXL_rbpdisp16_r32( R_R(Rn), REG_ECX );
1.570 MULL_r32( REG_ECX );
1.571 - store_spreg( REG_EAX, R_MACL );
1.572 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.573 sh4_x86.tstate = TSTATE_NONE;
1.574 :}
1.575 NEG Rm, Rn {:
1.576 @@ -1107,7 +1291,7 @@
1.577 :}
1.578 MOV #imm, Rn {:
1.579 COUNT_INST(I_MOVI);
1.580 - load_imm32( REG_EAX, imm );
1.581 + MOVL_imm32_r32( imm, REG_EAX );
1.582 store_reg( REG_EAX, Rn );
1.583 :}
1.584 MOV.B Rm, @Rn {:
1.585 @@ -1136,7 +1320,7 @@
1.586 :}
1.587 MOV.B R0, @(disp, GBR) {:
1.588 COUNT_INST(I_MOVB);
1.589 - load_spreg( REG_EAX, R_GBR );
1.590 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.591 ADDL_imms_r32( disp, REG_EAX );
1.592 load_reg( REG_EDX, 0 );
1.593 MEM_WRITE_BYTE( REG_EAX, REG_EDX );
1.594 @@ -1177,7 +1361,7 @@
1.595 :}
1.596 MOV.B @(disp, GBR), R0 {:
1.597 COUNT_INST(I_MOVB);
1.598 - load_spreg( REG_EAX, R_GBR );
1.599 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.600 ADDL_imms_r32( disp, REG_EAX );
1.601 MEM_READ_BYTE( REG_EAX, REG_EAX );
1.602 store_reg( REG_EAX, 0 );
1.603 @@ -1230,7 +1414,7 @@
1.604 :}
1.605 MOV.L R0, @(disp, GBR) {:
1.606 COUNT_INST(I_MOVL);
1.607 - load_spreg( REG_EAX, R_GBR );
1.608 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.609 ADDL_imms_r32( disp, REG_EAX );
1.610 check_walign32( REG_EAX );
1.611 load_reg( REG_EDX, 0 );
1.612 @@ -1286,7 +1470,7 @@
1.613 :}
1.614 MOV.L @(disp, GBR), R0 {:
1.615 COUNT_INST(I_MOVL);
1.616 - load_spreg( REG_EAX, R_GBR );
1.617 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.618 ADDL_imms_r32( disp, REG_EAX );
1.619 check_ralign32( REG_EAX );
1.620 MEM_READ_LONG( REG_EAX, REG_EAX );
1.621 @@ -1315,7 +1499,7 @@
1.622 // Note: we use sh4r.pc for the calc as we could be running at a
1.623 // different virtual address than the translation was done with,
1.624 // but we can safely assume that the low bits are the same.
1.625 - load_imm32( REG_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.626 + MOVL_imm32_r32( (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03), REG_EAX );
1.627 ADDL_rbpdisp_r32( R_PC, REG_EAX );
1.628 MEM_READ_LONG( REG_EAX, REG_EAX );
1.629 sh4_x86.tstate = TSTATE_NONE;
1.630 @@ -1361,7 +1545,7 @@
1.631 :}
1.632 MOV.W R0, @(disp, GBR) {:
1.633 COUNT_INST(I_MOVW);
1.634 - load_spreg( REG_EAX, R_GBR );
1.635 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.636 ADDL_imms_r32( disp, REG_EAX );
1.637 check_walign16( REG_EAX );
1.638 load_reg( REG_EDX, 0 );
1.639 @@ -1407,7 +1591,7 @@
1.640 :}
1.641 MOV.W @(disp, GBR), R0 {:
1.642 COUNT_INST(I_MOVW);
1.643 - load_spreg( REG_EAX, R_GBR );
1.644 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.645 ADDL_imms_r32( disp, REG_EAX );
1.646 check_ralign16( REG_EAX );
1.647 MEM_READ_WORD( REG_EAX, REG_EAX );
1.648 @@ -1426,7 +1610,7 @@
1.649 MOVL_moffptr_eax( ptr );
1.650 MOVSXL_r16_r32( REG_EAX, REG_EAX );
1.651 } else {
1.652 - load_imm32( REG_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );
1.653 + MOVL_imm32_r32( (pc - sh4_x86.block_start_pc) + disp + 4, REG_EAX );
1.654 ADDL_rbpdisp_r32( R_PC, REG_EAX );
1.655 MEM_READ_WORD( REG_EAX, REG_EAX );
1.656 sh4_x86.tstate = TSTATE_NONE;
1.657 @@ -1448,7 +1632,7 @@
1.658 if( sh4_x86.in_delay_slot ) {
1.659 SLOTILLEGAL();
1.660 } else {
1.661 - load_imm32( REG_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );
1.662 + MOVL_imm32_r32( (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03), REG_ECX );
1.663 ADDL_rbpdisp_r32( R_PC, REG_ECX );
1.664 store_reg( REG_ECX, 0 );
1.665 sh4_x86.tstate = TSTATE_NONE;
1.666 @@ -1483,12 +1667,12 @@
1.667 } else {
1.668 sh4_x86.in_delay_slot = DELAY_PC;
1.669 if( UNTRANSLATABLE(pc+2) ) {
1.670 - load_imm32( REG_EAX, pc + 4 - sh4_x86.block_start_pc );
1.671 + MOVL_imm32_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
1.672 JT_label(nottaken);
1.673 ADDL_imms_r32( disp, REG_EAX );
1.674 JMP_TARGET(nottaken);
1.675 ADDL_rbpdisp_r32( R_PC, REG_EAX );
1.676 - store_spreg( REG_EAX, R_NEW_PC );
1.677 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
1.678 exit_block_emu(pc+2);
1.679 sh4_x86.branch_taken = TRUE;
1.680 return 2;
1.681 @@ -1520,9 +1704,9 @@
1.682 sh4_x86.in_delay_slot = DELAY_PC;
1.683 sh4_x86.branch_taken = TRUE;
1.684 if( UNTRANSLATABLE(pc+2) ) {
1.685 - load_spreg( REG_EAX, R_PC );
1.686 + MOVL_rbpdisp_r32( R_PC, REG_EAX );
1.687 ADDL_imms_r32( pc + disp + 4 - sh4_x86.block_start_pc, REG_EAX );
1.688 - store_spreg( REG_EAX, R_NEW_PC );
1.689 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
1.690 exit_block_emu(pc+2);
1.691 return 2;
1.692 } else {
1.693 @@ -1537,10 +1721,10 @@
1.694 if( sh4_x86.in_delay_slot ) {
1.695 SLOTILLEGAL();
1.696 } else {
1.697 - load_spreg( REG_EAX, R_PC );
1.698 + MOVL_rbpdisp_r32( R_PC, REG_EAX );
1.699 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
1.700 ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
1.701 - store_spreg( REG_EAX, R_NEW_PC );
1.702 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
1.703 sh4_x86.in_delay_slot = DELAY_PC;
1.704 sh4_x86.tstate = TSTATE_NONE;
1.705 sh4_x86.branch_taken = TRUE;
1.706 @@ -1559,15 +1743,15 @@
1.707 if( sh4_x86.in_delay_slot ) {
1.708 SLOTILLEGAL();
1.709 } else {
1.710 - load_spreg( REG_EAX, R_PC );
1.711 + MOVL_rbpdisp_r32( R_PC, REG_EAX );
1.712 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
1.713 - store_spreg( REG_EAX, R_PR );
1.714 + MOVL_r32_rbpdisp( REG_EAX, R_PR );
1.715 sh4_x86.in_delay_slot = DELAY_PC;
1.716 sh4_x86.branch_taken = TRUE;
1.717 sh4_x86.tstate = TSTATE_NONE;
1.718 if( UNTRANSLATABLE(pc+2) ) {
1.719 ADDL_imms_r32( disp, REG_EAX );
1.720 - store_spreg( REG_EAX, R_NEW_PC );
1.721 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
1.722 exit_block_emu(pc+2);
1.723 return 2;
1.724 } else {
1.725 @@ -1582,11 +1766,11 @@
1.726 if( sh4_x86.in_delay_slot ) {
1.727 SLOTILLEGAL();
1.728 } else {
1.729 - load_spreg( REG_EAX, R_PC );
1.730 + MOVL_rbpdisp_r32( R_PC, REG_EAX );
1.731 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
1.732 - store_spreg( REG_EAX, R_PR );
1.733 + MOVL_r32_rbpdisp( REG_EAX, R_PR );
1.734 ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );
1.735 - store_spreg( REG_EAX, R_NEW_PC );
1.736 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
1.737
1.738 sh4_x86.in_delay_slot = DELAY_PC;
1.739 sh4_x86.tstate = TSTATE_NONE;
1.740 @@ -1620,12 +1804,12 @@
1.741 } else {
1.742 sh4_x86.in_delay_slot = DELAY_PC;
1.743 if( UNTRANSLATABLE(pc+2) ) {
1.744 - load_imm32( REG_EAX, pc + 4 - sh4_x86.block_start_pc );
1.745 + MOVL_imm32_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
1.746 JF_label(nottaken);
1.747 ADDL_imms_r32( disp, REG_EAX );
1.748 JMP_TARGET(nottaken);
1.749 ADDL_rbpdisp_r32( R_PC, REG_EAX );
1.750 - store_spreg( REG_EAX, R_NEW_PC );
1.751 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );
1.752 exit_block_emu(pc+2);
1.753 sh4_x86.branch_taken = TRUE;
1.754 return 2;
1.755 @@ -1654,7 +1838,7 @@
1.756 SLOTILLEGAL();
1.757 } else {
1.758 load_reg( REG_ECX, Rn );
1.759 - store_spreg( REG_ECX, R_NEW_PC );
1.760 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
1.761 sh4_x86.in_delay_slot = DELAY_PC;
1.762 sh4_x86.branch_taken = TRUE;
1.763 if( UNTRANSLATABLE(pc+2) ) {
1.764 @@ -1672,11 +1856,11 @@
1.765 if( sh4_x86.in_delay_slot ) {
1.766 SLOTILLEGAL();
1.767 } else {
1.768 - load_spreg( REG_EAX, R_PC );
1.769 + MOVL_rbpdisp_r32( R_PC, REG_EAX );
1.770 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );
1.771 - store_spreg( REG_EAX, R_PR );
1.772 + MOVL_r32_rbpdisp( REG_EAX, R_PR );
1.773 load_reg( REG_ECX, Rn );
1.774 - store_spreg( REG_ECX, R_NEW_PC );
1.775 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
1.776 sh4_x86.in_delay_slot = DELAY_PC;
1.777 sh4_x86.branch_taken = TRUE;
1.778 sh4_x86.tstate = TSTATE_NONE;
1.779 @@ -1696,10 +1880,10 @@
1.780 SLOTILLEGAL();
1.781 } else {
1.782 check_priv();
1.783 - load_spreg( REG_ECX, R_SPC );
1.784 - store_spreg( REG_ECX, R_NEW_PC );
1.785 - load_spreg( REG_EAX, R_SSR );
1.786 - call_func1( sh4_write_sr, REG_EAX );
1.787 + MOVL_rbpdisp_r32( R_SPC, REG_ECX );
1.788 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
1.789 + MOVL_rbpdisp_r32( R_SSR, REG_EAX );
1.790 + CALL1_ptr_r32( sh4_write_sr, REG_EAX );
1.791 sh4_x86.in_delay_slot = DELAY_PC;
1.792 sh4_x86.fpuen_checked = FALSE;
1.793 sh4_x86.tstate = TSTATE_NONE;
1.794 @@ -1719,8 +1903,8 @@
1.795 if( sh4_x86.in_delay_slot ) {
1.796 SLOTILLEGAL();
1.797 } else {
1.798 - load_spreg( REG_ECX, R_PR );
1.799 - store_spreg( REG_ECX, R_NEW_PC );
1.800 + MOVL_rbpdisp_r32( R_PR, REG_ECX );
1.801 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );
1.802 sh4_x86.in_delay_slot = DELAY_PC;
1.803 sh4_x86.branch_taken = TRUE;
1.804 if( UNTRANSLATABLE(pc+2) ) {
1.805 @@ -1738,10 +1922,10 @@
1.806 if( sh4_x86.in_delay_slot ) {
1.807 SLOTILLEGAL();
1.808 } else {
1.809 - load_imm32( REG_ECX, pc+2 - sh4_x86.block_start_pc ); // 5
1.810 + MOVL_imm32_r32( pc+2 - sh4_x86.block_start_pc, REG_ECX ); // 5
1.811 ADDL_r32_rbpdisp( REG_ECX, R_PC );
1.812 - load_imm32( REG_EAX, imm );
1.813 - call_func1( sh4_raise_trap, REG_EAX );
1.814 + MOVL_imm32_r32( imm, REG_EAX );
1.815 + CALL1_ptr_r32( sh4_raise_trap, REG_EAX );
1.816 sh4_x86.tstate = TSTATE_NONE;
1.817 exit_block_pcset(pc+2);
1.818 sh4_x86.branch_taken = TRUE;
1.819 @@ -1761,8 +1945,8 @@
1.820 CLRMAC {:
1.821 COUNT_INST(I_CLRMAC);
1.822 XORL_r32_r32(REG_EAX, REG_EAX);
1.823 - store_spreg( REG_EAX, R_MACL );
1.824 - store_spreg( REG_EAX, R_MACH );
1.825 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.826 + MOVL_r32_rbpdisp( REG_EAX, R_MACH );
1.827 sh4_x86.tstate = TSTATE_NONE;
1.828 :}
1.829 CLRS {:
1.830 @@ -1941,7 +2125,7 @@
1.831 COUNT_INST(I_FLDI1);
1.832 check_fpuen();
1.833 if( sh4_x86.double_prec == 0 ) {
1.834 - load_imm32(REG_EAX, 0x3F800000);
1.835 + MOVL_imm32_r32( 0x3F800000, REG_EAX );
1.836 store_fr( REG_EAX, FRn );
1.837 }
1.838 :}
1.839 @@ -1964,26 +2148,26 @@
1.840 } else {
1.841 push_fr( FRm );
1.842 }
1.843 - load_ptr( REG_ECX, &max_int );
1.844 + MOVP_immptr_rptr( &max_int, REG_ECX );
1.845 FILD_r32disp( REG_ECX, 0 );
1.846 FCOMIP_st(1);
1.847 JNA_label( sat );
1.848 - load_ptr( REG_ECX, &min_int ); // 5
1.849 - FILD_r32disp( REG_ECX, 0 ); // 2
1.850 - FCOMIP_st(1); // 2
1.851 - JAE_label( sat2 ); // 2
1.852 - load_ptr( REG_EAX, &save_fcw );
1.853 + MOVP_immptr_rptr( &min_int, REG_ECX );
1.854 + FILD_r32disp( REG_ECX, 0 );
1.855 + FCOMIP_st(1);
1.856 + JAE_label( sat2 );
1.857 + MOVP_immptr_rptr( &save_fcw, REG_EAX );
1.858 FNSTCW_r32disp( REG_EAX, 0 );
1.859 - load_ptr( REG_EDX, &trunc_fcw );
1.860 + MOVP_immptr_rptr( &trunc_fcw, REG_EDX );
1.861 FLDCW_r32disp( REG_EDX, 0 );
1.862 - FISTP_rbpdisp(R_FPUL); // 3
1.863 + FISTP_rbpdisp(R_FPUL);
1.864 FLDCW_r32disp( REG_EAX, 0 );
1.865 - JMP_label(end); // 2
1.866 + JMP_label(end);
1.867
1.868 JMP_TARGET(sat);
1.869 JMP_TARGET(sat2);
1.870 MOVL_r32disp_r32( REG_ECX, 0, REG_ECX ); // 2
1.871 - store_spreg( REG_ECX, R_FPUL );
1.872 + MOVL_r32_rbpdisp( REG_ECX, R_FPUL );
1.873 FPOP_st();
1.874 JMP_TARGET(end);
1.875 sh4_x86.tstate = TSTATE_NONE;
1.876 @@ -1992,12 +2176,12 @@
1.877 COUNT_INST(I_FLDS);
1.878 check_fpuen();
1.879 load_fr( REG_EAX, FRm );
1.880 - store_spreg( REG_EAX, R_FPUL );
1.881 + MOVL_r32_rbpdisp( REG_EAX, R_FPUL );
1.882 :}
1.883 FSTS FPUL, FRn {:
1.884 COUNT_INST(I_FSTS);
1.885 check_fpuen();
1.886 - load_spreg( REG_EAX, R_FPUL );
1.887 + MOVL_rbpdisp_r32( R_FPUL, REG_EAX );
1.888 store_fr( REG_EAX, FRn );
1.889 :}
1.890 FCNVDS FRm, FPUL {:
1.891 @@ -2185,8 +2369,8 @@
1.892 check_fpuen();
1.893 if( sh4_x86.double_prec == 0 ) {
1.894 LEAP_rbpdisp_rptr( REG_OFFSET(fr[0][FRn&0x0E]), REG_EDX );
1.895 - load_spreg( REG_EAX, R_FPUL );
1.896 - call_func2( sh4_fsca, REG_EAX, REG_EDX );
1.897 + MOVL_rbpdisp_r32( R_FPUL, REG_EAX );
1.898 + CALL2_ptr_r32_r32( sh4_fsca, REG_EAX, REG_EDX );
1.899 }
1.900 sh4_x86.tstate = TSTATE_NONE;
1.901 :}
1.902 @@ -2248,7 +2432,7 @@
1.903 MOVAPS_xmm_rbpdisp( 4, REG_OFFSET(fr[0][FVn<<2]) );
1.904 } else {
1.905 LEAP_rbpdisp_rptr( REG_OFFSET(fr[0][FVn<<2]), REG_EAX );
1.906 - call_func1( sh4_ftrv, REG_EAX );
1.907 + CALL1_ptr_r32( sh4_ftrv, REG_EAX );
1.908 }
1.909 }
1.910 sh4_x86.tstate = TSTATE_NONE;
1.911 @@ -2258,7 +2442,7 @@
1.912 COUNT_INST(I_FRCHG);
1.913 check_fpuen();
1.914 XORL_imms_rbpdisp( FPSCR_FR, R_FPSCR );
1.915 - call_func0( sh4_switch_fr_banks );
1.916 + CALL_ptr( sh4_switch_fr_banks );
1.917 sh4_x86.tstate = TSTATE_NONE;
1.918 :}
1.919 FSCHG {:
1.920 @@ -2278,7 +2462,7 @@
1.921 } else {
1.922 check_priv();
1.923 load_reg( REG_EAX, Rm );
1.924 - call_func1( sh4_write_sr, REG_EAX );
1.925 + CALL1_ptr_r32( sh4_write_sr, REG_EAX );
1.926 sh4_x86.fpuen_checked = FALSE;
1.927 sh4_x86.tstate = TSTATE_NONE;
1.928 return 2;
1.929 @@ -2287,48 +2471,48 @@
1.930 LDC Rm, GBR {:
1.931 COUNT_INST(I_LDC);
1.932 load_reg( REG_EAX, Rm );
1.933 - store_spreg( REG_EAX, R_GBR );
1.934 + MOVL_r32_rbpdisp( REG_EAX, R_GBR );
1.935 :}
1.936 LDC Rm, VBR {:
1.937 COUNT_INST(I_LDC);
1.938 check_priv();
1.939 load_reg( REG_EAX, Rm );
1.940 - store_spreg( REG_EAX, R_VBR );
1.941 + MOVL_r32_rbpdisp( REG_EAX, R_VBR );
1.942 sh4_x86.tstate = TSTATE_NONE;
1.943 :}
1.944 LDC Rm, SSR {:
1.945 COUNT_INST(I_LDC);
1.946 check_priv();
1.947 load_reg( REG_EAX, Rm );
1.948 - store_spreg( REG_EAX, R_SSR );
1.949 + MOVL_r32_rbpdisp( REG_EAX, R_SSR );
1.950 sh4_x86.tstate = TSTATE_NONE;
1.951 :}
1.952 LDC Rm, SGR {:
1.953 COUNT_INST(I_LDC);
1.954 check_priv();
1.955 load_reg( REG_EAX, Rm );
1.956 - store_spreg( REG_EAX, R_SGR );
1.957 + MOVL_r32_rbpdisp( REG_EAX, R_SGR );
1.958 sh4_x86.tstate = TSTATE_NONE;
1.959 :}
1.960 LDC Rm, SPC {:
1.961 COUNT_INST(I_LDC);
1.962 check_priv();
1.963 load_reg( REG_EAX, Rm );
1.964 - store_spreg( REG_EAX, R_SPC );
1.965 + MOVL_r32_rbpdisp( REG_EAX, R_SPC );
1.966 sh4_x86.tstate = TSTATE_NONE;
1.967 :}
1.968 LDC Rm, DBR {:
1.969 COUNT_INST(I_LDC);
1.970 check_priv();
1.971 load_reg( REG_EAX, Rm );
1.972 - store_spreg( REG_EAX, R_DBR );
1.973 + MOVL_r32_rbpdisp( REG_EAX, R_DBR );
1.974 sh4_x86.tstate = TSTATE_NONE;
1.975 :}
1.976 LDC Rm, Rn_BANK {:
1.977 COUNT_INST(I_LDC);
1.978 check_priv();
1.979 load_reg( REG_EAX, Rm );
1.980 - store_spreg( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.981 + MOVL_r32_rbpdisp( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.982 sh4_x86.tstate = TSTATE_NONE;
1.983 :}
1.984 LDC.L @Rm+, GBR {:
1.985 @@ -2337,7 +2521,7 @@
1.986 check_ralign32( REG_EAX );
1.987 MEM_READ_LONG( REG_EAX, REG_EAX );
1.988 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.989 - store_spreg( REG_EAX, R_GBR );
1.990 + MOVL_r32_rbpdisp( REG_EAX, R_GBR );
1.991 sh4_x86.tstate = TSTATE_NONE;
1.992 :}
1.993 LDC.L @Rm+, SR {:
1.994 @@ -2350,7 +2534,7 @@
1.995 check_ralign32( REG_EAX );
1.996 MEM_READ_LONG( REG_EAX, REG_EAX );
1.997 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.998 - call_func1( sh4_write_sr, REG_EAX );
1.999 + CALL1_ptr_r32( sh4_write_sr, REG_EAX );
1.1000 sh4_x86.fpuen_checked = FALSE;
1.1001 sh4_x86.tstate = TSTATE_NONE;
1.1002 return 2;
1.1003 @@ -2363,7 +2547,7 @@
1.1004 check_ralign32( REG_EAX );
1.1005 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1006 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1007 - store_spreg( REG_EAX, R_VBR );
1.1008 + MOVL_r32_rbpdisp( REG_EAX, R_VBR );
1.1009 sh4_x86.tstate = TSTATE_NONE;
1.1010 :}
1.1011 LDC.L @Rm+, SSR {:
1.1012 @@ -2373,7 +2557,7 @@
1.1013 check_ralign32( REG_EAX );
1.1014 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1015 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1016 - store_spreg( REG_EAX, R_SSR );
1.1017 + MOVL_r32_rbpdisp( REG_EAX, R_SSR );
1.1018 sh4_x86.tstate = TSTATE_NONE;
1.1019 :}
1.1020 LDC.L @Rm+, SGR {:
1.1021 @@ -2383,7 +2567,7 @@
1.1022 check_ralign32( REG_EAX );
1.1023 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1024 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1025 - store_spreg( REG_EAX, R_SGR );
1.1026 + MOVL_r32_rbpdisp( REG_EAX, R_SGR );
1.1027 sh4_x86.tstate = TSTATE_NONE;
1.1028 :}
1.1029 LDC.L @Rm+, SPC {:
1.1030 @@ -2393,7 +2577,7 @@
1.1031 check_ralign32( REG_EAX );
1.1032 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1033 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1034 - store_spreg( REG_EAX, R_SPC );
1.1035 + MOVL_r32_rbpdisp( REG_EAX, R_SPC );
1.1036 sh4_x86.tstate = TSTATE_NONE;
1.1037 :}
1.1038 LDC.L @Rm+, DBR {:
1.1039 @@ -2403,7 +2587,7 @@
1.1040 check_ralign32( REG_EAX );
1.1041 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1042 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1043 - store_spreg( REG_EAX, R_DBR );
1.1044 + MOVL_r32_rbpdisp( REG_EAX, R_DBR );
1.1045 sh4_x86.tstate = TSTATE_NONE;
1.1046 :}
1.1047 LDC.L @Rm+, Rn_BANK {:
1.1048 @@ -2413,14 +2597,14 @@
1.1049 check_ralign32( REG_EAX );
1.1050 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1051 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1052 - store_spreg( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.1053 + MOVL_r32_rbpdisp( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );
1.1054 sh4_x86.tstate = TSTATE_NONE;
1.1055 :}
1.1056 LDS Rm, FPSCR {:
1.1057 COUNT_INST(I_LDSFPSCR);
1.1058 check_fpuen();
1.1059 load_reg( REG_EAX, Rm );
1.1060 - call_func1( sh4_write_fpscr, REG_EAX );
1.1061 + CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );
1.1062 sh4_x86.tstate = TSTATE_NONE;
1.1063 return 2;
1.1064 :}
1.1065 @@ -2431,7 +2615,7 @@
1.1066 check_ralign32( REG_EAX );
1.1067 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1068 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1069 - call_func1( sh4_write_fpscr, REG_EAX );
1.1070 + CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );
1.1071 sh4_x86.tstate = TSTATE_NONE;
1.1072 return 2;
1.1073 :}
1.1074 @@ -2439,7 +2623,7 @@
1.1075 COUNT_INST(I_LDS);
1.1076 check_fpuen();
1.1077 load_reg( REG_EAX, Rm );
1.1078 - store_spreg( REG_EAX, R_FPUL );
1.1079 + MOVL_r32_rbpdisp( REG_EAX, R_FPUL );
1.1080 :}
1.1081 LDS.L @Rm+, FPUL {:
1.1082 COUNT_INST(I_LDSM);
1.1083 @@ -2448,13 +2632,13 @@
1.1084 check_ralign32( REG_EAX );
1.1085 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1086 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1087 - store_spreg( REG_EAX, R_FPUL );
1.1088 + MOVL_r32_rbpdisp( REG_EAX, R_FPUL );
1.1089 sh4_x86.tstate = TSTATE_NONE;
1.1090 :}
1.1091 LDS Rm, MACH {:
1.1092 COUNT_INST(I_LDS);
1.1093 load_reg( REG_EAX, Rm );
1.1094 - store_spreg( REG_EAX, R_MACH );
1.1095 + MOVL_r32_rbpdisp( REG_EAX, R_MACH );
1.1096 :}
1.1097 LDS.L @Rm+, MACH {:
1.1098 COUNT_INST(I_LDSM);
1.1099 @@ -2462,13 +2646,13 @@
1.1100 check_ralign32( REG_EAX );
1.1101 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1102 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1103 - store_spreg( REG_EAX, R_MACH );
1.1104 + MOVL_r32_rbpdisp( REG_EAX, R_MACH );
1.1105 sh4_x86.tstate = TSTATE_NONE;
1.1106 :}
1.1107 LDS Rm, MACL {:
1.1108 COUNT_INST(I_LDS);
1.1109 load_reg( REG_EAX, Rm );
1.1110 - store_spreg( REG_EAX, R_MACL );
1.1111 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.1112 :}
1.1113 LDS.L @Rm+, MACL {:
1.1114 COUNT_INST(I_LDSM);
1.1115 @@ -2476,13 +2660,13 @@
1.1116 check_ralign32( REG_EAX );
1.1117 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1118 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1119 - store_spreg( REG_EAX, R_MACL );
1.1120 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );
1.1121 sh4_x86.tstate = TSTATE_NONE;
1.1122 :}
1.1123 LDS Rm, PR {:
1.1124 COUNT_INST(I_LDS);
1.1125 load_reg( REG_EAX, Rm );
1.1126 - store_spreg( REG_EAX, R_PR );
1.1127 + MOVL_r32_rbpdisp( REG_EAX, R_PR );
1.1128 :}
1.1129 LDS.L @Rm+, PR {:
1.1130 COUNT_INST(I_LDSM);
1.1131 @@ -2490,12 +2674,12 @@
1.1132 check_ralign32( REG_EAX );
1.1133 MEM_READ_LONG( REG_EAX, REG_EAX );
1.1134 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
1.1135 - store_spreg( REG_EAX, R_PR );
1.1136 + MOVL_r32_rbpdisp( REG_EAX, R_PR );
1.1137 sh4_x86.tstate = TSTATE_NONE;
1.1138 :}
1.1139 LDTLB {:
1.1140 COUNT_INST(I_LDTLB);
1.1141 - call_func0( MMU_ldtlb );
1.1142 + CALL_ptr( MMU_ldtlb );
1.1143 sh4_x86.tstate = TSTATE_NONE;
1.1144 :}
1.1145 OCBI @Rn {:
1.1146 @@ -2516,7 +2700,7 @@
1.1147 SLEEP {:
1.1148 COUNT_INST(I_SLEEP);
1.1149 check_priv();
1.1150 - call_func0( sh4_sleep );
1.1151 + CALL_ptr( sh4_sleep );
1.1152 sh4_x86.tstate = TSTATE_NONE;
1.1153 sh4_x86.in_delay_slot = DELAY_NONE;
1.1154 return 2;
1.1155 @@ -2524,61 +2708,61 @@
1.1156 STC SR, Rn {:
1.1157 COUNT_INST(I_STCSR);
1.1158 check_priv();
1.1159 - call_func0(sh4_read_sr);
1.1160 + CALL_ptr(sh4_read_sr);
1.1161 store_reg( REG_EAX, Rn );
1.1162 sh4_x86.tstate = TSTATE_NONE;
1.1163 :}
1.1164 STC GBR, Rn {:
1.1165 COUNT_INST(I_STC);
1.1166 - load_spreg( REG_EAX, R_GBR );
1.1167 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );
1.1168 store_reg( REG_EAX, Rn );
1.1169 :}
1.1170 STC VBR, Rn {:
1.1171 COUNT_INST(I_STC);
1.1172 check_priv();
1.1173 - load_spreg( REG_EAX, R_VBR );
1.1174 + MOVL_rbpdisp_r32( R_VBR, REG_EAX );
1.1175 store_reg( REG_EAX, Rn );
1.1176 sh4_x86.tstate = TSTATE_NONE;
1.1177 :}
1.1178 STC SSR, Rn {:
1.1179 COUNT_INST(I_STC);
1.1180 check_priv();
1.1181 - load_spreg( REG_EAX, R_SSR );
1.1182 + MOVL_rbpdisp_r32( R_SSR, REG_EAX );
1.1183 store_reg( REG_EAX, Rn );
1.1184 sh4_x86.tstate = TSTATE_NONE;
1.1185 :}
1.1186 STC SPC, Rn {:
1.1187 COUNT_INST(I_STC);
1.1188 check_priv();
1.1189 - load_spreg( REG_EAX, R_SPC );
1.1190 + MOVL_rbpdisp_r32( R_SPC, REG_EAX );
1.1191 store_reg( REG_EAX, Rn );
1.1192 sh4_x86.tstate = TSTATE_NONE;
1.1193 :}
1.1194 STC SGR, Rn {:
1.1195 COUNT_INST(I_STC);
1.1196 check_priv();
1.1197 - load_spreg( REG_EAX, R_SGR );
1.1198 + MOVL_rbpdisp_r32( R_SGR, REG_EAX );
1.1199 store_reg( REG_EAX, Rn );
1.1200 sh4_x86.tstate = TSTATE_NONE;
1.1201 :}
1.1202 STC DBR, Rn {:
1.1203 COUNT_INST(I_STC);
1.1204 check_priv();
1.1205 - load_spreg( REG_EAX, R_DBR );
1.1206 + MOVL_rbpdisp_r32( R_DBR, REG_EAX );
1.1207 store_reg( REG_EAX, Rn );
1.1208 sh4_x86.tstate = TSTATE_NONE;
1.1209 :}
1.1210 STC Rm_BANK, Rn {:
1.1211 COUNT_INST(I_STC);
1.1212 check_priv();
1.1213 - load_spreg( REG_EAX, REG_OFFSET(r_bank[Rm_BANK]) );
1.1214 + MOVL_rbpdisp_r32( REG_OFFSET(r_bank[Rm_BANK]), REG_EAX );
1.1215 store_reg( REG_EAX, Rn );
1.1216 sh4_x86.tstate = TSTATE_NONE;
1.1217 :}
1.1218 STC.L SR, @-Rn {:
1.1219 COUNT_INST(I_STCSRM);
1.1220 check_priv();
1.1221 - call_func0( sh4_read_sr );
1.1222 + CALL_ptr( sh4_read_sr );
1.1223 MOVL_r32_r32( REG_EAX, REG_EDX );
1.1224 load_reg( REG_EAX, Rn );
1.1225 check_walign32( REG_EAX );
1.1226 @@ -2593,7 +2777,7 @@
1.1227 load_reg( REG_EAX, Rn );
1.1228 check_walign32( REG_EAX );
1.1229 ADDL_imms_r32( -4, REG_EAX );
1.1230 - load_spreg( REG_EDX, R_VBR );
1.1231 + MOVL_rbpdisp_r32( R_VBR, REG_EDX );
1.1232 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1233 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1234 sh4_x86.tstate = TSTATE_NONE;
1.1235 @@ -2604,7 +2788,7 @@
1.1236 load_reg( REG_EAX, Rn );
1.1237 check_walign32( REG_EAX );
1.1238 ADDL_imms_r32( -4, REG_EAX );
1.1239 - load_spreg( REG_EDX, R_SSR );
1.1240 + MOVL_rbpdisp_r32( R_SSR, REG_EDX );
1.1241 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1242 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1243 sh4_x86.tstate = TSTATE_NONE;
1.1244 @@ -2615,7 +2799,7 @@
1.1245 load_reg( REG_EAX, Rn );
1.1246 check_walign32( REG_EAX );
1.1247 ADDL_imms_r32( -4, REG_EAX );
1.1248 - load_spreg( REG_EDX, R_SPC );
1.1249 + MOVL_rbpdisp_r32( R_SPC, REG_EDX );
1.1250 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1251 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1252 sh4_x86.tstate = TSTATE_NONE;
1.1253 @@ -2626,7 +2810,7 @@
1.1254 load_reg( REG_EAX, Rn );
1.1255 check_walign32( REG_EAX );
1.1256 ADDL_imms_r32( -4, REG_EAX );
1.1257 - load_spreg( REG_EDX, R_SGR );
1.1258 + MOVL_rbpdisp_r32( R_SGR, REG_EDX );
1.1259 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1260 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1261 sh4_x86.tstate = TSTATE_NONE;
1.1262 @@ -2637,7 +2821,7 @@
1.1263 load_reg( REG_EAX, Rn );
1.1264 check_walign32( REG_EAX );
1.1265 ADDL_imms_r32( -4, REG_EAX );
1.1266 - load_spreg( REG_EDX, R_DBR );
1.1267 + MOVL_rbpdisp_r32( R_DBR, REG_EDX );
1.1268 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1269 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1270 sh4_x86.tstate = TSTATE_NONE;
1.1271 @@ -2648,7 +2832,7 @@
1.1272 load_reg( REG_EAX, Rn );
1.1273 check_walign32( REG_EAX );
1.1274 ADDL_imms_r32( -4, REG_EAX );
1.1275 - load_spreg( REG_EDX, REG_OFFSET(r_bank[Rm_BANK]) );
1.1276 + MOVL_rbpdisp_r32( REG_OFFSET(r_bank[Rm_BANK]), REG_EDX );
1.1277 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1278 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1279 sh4_x86.tstate = TSTATE_NONE;
1.1280 @@ -2658,7 +2842,7 @@
1.1281 load_reg( REG_EAX, Rn );
1.1282 check_walign32( REG_EAX );
1.1283 ADDL_imms_r32( -4, REG_EAX );
1.1284 - load_spreg( REG_EDX, R_GBR );
1.1285 + MOVL_rbpdisp_r32( R_GBR, REG_EDX );
1.1286 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1287 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1288 sh4_x86.tstate = TSTATE_NONE;
1.1289 @@ -2666,7 +2850,7 @@
1.1290 STS FPSCR, Rn {:
1.1291 COUNT_INST(I_STSFPSCR);
1.1292 check_fpuen();
1.1293 - load_spreg( REG_EAX, R_FPSCR );
1.1294 + MOVL_rbpdisp_r32( R_FPSCR, REG_EAX );
1.1295 store_reg( REG_EAX, Rn );
1.1296 :}
1.1297 STS.L FPSCR, @-Rn {:
1.1298 @@ -2675,7 +2859,7 @@
1.1299 load_reg( REG_EAX, Rn );
1.1300 check_walign32( REG_EAX );
1.1301 ADDL_imms_r32( -4, REG_EAX );
1.1302 - load_spreg( REG_EDX, R_FPSCR );
1.1303 + MOVL_rbpdisp_r32( R_FPSCR, REG_EDX );
1.1304 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1305 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1306 sh4_x86.tstate = TSTATE_NONE;
1.1307 @@ -2683,7 +2867,7 @@
1.1308 STS FPUL, Rn {:
1.1309 COUNT_INST(I_STS);
1.1310 check_fpuen();
1.1311 - load_spreg( REG_EAX, R_FPUL );
1.1312 + MOVL_rbpdisp_r32( R_FPUL, REG_EAX );
1.1313 store_reg( REG_EAX, Rn );
1.1314 :}
1.1315 STS.L FPUL, @-Rn {:
1.1316 @@ -2692,14 +2876,14 @@
1.1317 load_reg( REG_EAX, Rn );
1.1318 check_walign32( REG_EAX );
1.1319 ADDL_imms_r32( -4, REG_EAX );
1.1320 - load_spreg( REG_EDX, R_FPUL );
1.1321 + MOVL_rbpdisp_r32( R_FPUL, REG_EDX );
1.1322 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1323 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1324 sh4_x86.tstate = TSTATE_NONE;
1.1325 :}
1.1326 STS MACH, Rn {:
1.1327 COUNT_INST(I_STS);
1.1328 - load_spreg( REG_EAX, R_MACH );
1.1329 + MOVL_rbpdisp_r32( R_MACH, REG_EAX );
1.1330 store_reg( REG_EAX, Rn );
1.1331 :}
1.1332 STS.L MACH, @-Rn {:
1.1333 @@ -2707,14 +2891,14 @@
1.1334 load_reg( REG_EAX, Rn );
1.1335 check_walign32( REG_EAX );
1.1336 ADDL_imms_r32( -4, REG_EAX );
1.1337 - load_spreg( REG_EDX, R_MACH );
1.1338 + MOVL_rbpdisp_r32( R_MACH, REG_EDX );
1.1339 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1340 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1341 sh4_x86.tstate = TSTATE_NONE;
1.1342 :}
1.1343 STS MACL, Rn {:
1.1344 COUNT_INST(I_STS);
1.1345 - load_spreg( REG_EAX, R_MACL );
1.1346 + MOVL_rbpdisp_r32( R_MACL, REG_EAX );
1.1347 store_reg( REG_EAX, Rn );
1.1348 :}
1.1349 STS.L MACL, @-Rn {:
1.1350 @@ -2722,14 +2906,14 @@
1.1351 load_reg( REG_EAX, Rn );
1.1352 check_walign32( REG_EAX );
1.1353 ADDL_imms_r32( -4, REG_EAX );
1.1354 - load_spreg( REG_EDX, R_MACL );
1.1355 + MOVL_rbpdisp_r32( R_MACL, REG_EDX );
1.1356 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1357 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1358 sh4_x86.tstate = TSTATE_NONE;
1.1359 :}
1.1360 STS PR, Rn {:
1.1361 COUNT_INST(I_STS);
1.1362 - load_spreg( REG_EAX, R_PR );
1.1363 + MOVL_rbpdisp_r32( R_PR, REG_EAX );
1.1364 store_reg( REG_EAX, Rn );
1.1365 :}
1.1366 STS.L PR, @-Rn {:
1.1367 @@ -2737,7 +2921,7 @@
1.1368 load_reg( REG_EAX, Rn );
1.1369 check_walign32( REG_EAX );
1.1370 ADDL_imms_r32( -4, REG_EAX );
1.1371 - load_spreg( REG_EDX, R_PR );
1.1372 + MOVL_rbpdisp_r32( R_PR, REG_EDX );
1.1373 MEM_WRITE_LONG( REG_EAX, REG_EDX );
1.1374 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );
1.1375 sh4_x86.tstate = TSTATE_NONE;
1.1376 @@ -2751,3 +2935,67 @@
1.1377 sh4_x86.in_delay_slot = DELAY_NONE;
1.1378 return 0;
1.1379 }
1.1380 +
1.1381 +
1.1382 +/**
1.1383 + * The unwind methods only work if we compiled with DWARF2 frame information
1.1384 + * (ie -fexceptions), otherwise we have to use the direct frame scan.
1.1385 + */
1.1386 +#ifdef HAVE_EXCEPTIONS
1.1387 +#include <unwind.h>
1.1388 +
1.1389 +struct UnwindInfo {
1.1390 + uintptr_t block_start;
1.1391 + uintptr_t block_end;
1.1392 + void *pc;
1.1393 +};
1.1394 +
1.1395 +static _Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )
1.1396 +{
1.1397 + struct UnwindInfo *info = arg;
1.1398 + void *pc = (void *)_Unwind_GetIP(context);
1.1399 + if( ((uintptr_t)pc) >= info->block_start && ((uintptr_t)pc) < info->block_end ) {
1.1400 + info->pc = pc;
1.1401 + return _URC_NORMAL_STOP;
1.1402 + }
1.1403 + return _URC_NO_REASON;
1.1404 +}
1.1405 +
1.1406 +void *xlat_get_native_pc( void *code, uint32_t code_size )
1.1407 +{
1.1408 + struct _Unwind_Exception exc;
1.1409 + struct UnwindInfo info;
1.1410 +
1.1411 + info.pc = NULL;
1.1412 + info.block_start = (uintptr_t)code;
1.1413 + info.block_end = info.block_start + code_size;
1.1414 + void *result = NULL;
1.1415 + _Unwind_Backtrace( xlat_check_frame, &info );
1.1416 + return info.pc;
1.1417 +}
1.1418 +#else
1.1419 +/* Assume this is an ia32 build - amd64 should always have dwarf information */
1.1420 +void *xlat_get_native_pc( void *code, uint32_t code_size )
1.1421 +{
1.1422 + void *result = NULL;
1.1423 + asm(
1.1424 + "mov %%ebp, %%eax\n\t"
1.1425 + "mov $0x8, %%ecx\n\t"
1.1426 + "mov %1, %%edx\n"
1.1427 + "frame_loop: test %%eax, %%eax\n\t"
1.1428 + "je frame_not_found\n\t"
1.1429 + "cmp (%%eax), %%edx\n\t"
1.1430 + "je frame_found\n\t"
1.1431 + "sub $0x1, %%ecx\n\t"
1.1432 + "je frame_not_found\n\t"
1.1433 + "movl (%%eax), %%eax\n\t"
1.1434 + "jmp frame_loop\n"
1.1435 + "frame_found: movl 0x4(%%eax), %0\n"
1.1436 + "frame_not_found:"
1.1437 + : "=r" (result)
1.1438 + : "r" (((uint8_t *)&sh4r) + 128 )
1.1439 + : "eax", "ecx", "edx" );
1.1440 + return result;
1.1441 +}
1.1442 +#endif
1.1443 +
.