revision 995:eb9d43e8aa08
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 995:eb9d43e8aa08 |
parent | 994:a92d433f1be8 |
child | 996:2e8cf0a87243 |
author | nkeynes |
date | Thu Mar 05 21:42:35 2009 +0000 (15 years ago) |
Cleanup ABI headers - most of the content made consistent between versions, and moved into sh4x86.in proper
1.1 --- a/src/sh4/mmux86.c Thu Mar 05 21:37:44 2009 +00001.2 +++ b/src/sh4/mmux86.c Thu Mar 05 21:42:35 2009 +00001.3 @@ -25,8 +25,6 @@1.4 #include "xlat/x86/x86op.h"1.6 #if SIZEOF_VOID_P == 81.7 -#define ARG1 REG_RDI1.8 -#define ARG2 REG_RSI1.9 #define XLAT(addr_space, reg) \1.10 MOVQ_imm64_r64( (uintptr_t)addr_space, REG_RAX ); \1.11 MOVP_sib_rptr( 3, reg, REG_RAX, 0, reg );1.12 @@ -34,8 +32,6 @@1.13 MOVQ_imm64_r64((uintptr_t)p, REG_EAX ); \1.14 ADDL_imms_r32disp(imm, REG_EAX, 0);1.15 #else1.16 -#define ARG1 REG_EAX1.17 -#define ARG2 R_EDX1.18 #define XLAT(addr_space, reg) \1.19 MOVP_sib_rptr( 2, reg, -1, (uintptr_t)addr_space, reg );1.20 #define ADDP_imms_ptr(imm,p) \1.21 @@ -68,13 +64,13 @@1.22 if( i != 9 ) { /* read_byte_for_write doesn't increment mmu_urc, everything else does */1.23 ADDP_imms_ptr(1, &mmu_urc);1.24 }1.25 - ADDL_imms_r32( ppn-vpn, ARG1 ); // 61.26 + ADDL_imms_r32( ppn-vpn, REG_ARG1 ); // 61.27 if( ent->mask >= 0xFFFFF000 ) {1.28 // Maps to a single page, so jump directly there1.29 int rel = (*fn - xlat_output);1.30 JMP_prerel( rel ); // 51.31 } else {1.32 - MOVL_r32_r32( ARG1, REG_ECX ); // 21.33 + MOVL_r32_r32( REG_ARG1, REG_ECX ); // 21.34 SHRL_imm_r32( 12, REG_ECX ); // 31.35 XLAT(addr_space, REG_ECX); // 141.36 JMP_r32disp(REG_ECX, (((uintptr_t)out) - ((uintptr_t)&page->fn)) ); // 31.37 @@ -96,7 +92,7 @@1.39 page->fn.prefetch = (mem_prefetch_fn_t)xlat_output;1.40 ADDP_imms_ptr(1, &mmu_urc);1.41 - ADDL_imms_r32( ppn-vpn, ARG1 );1.42 + ADDL_imms_r32( ppn-vpn, REG_ARG1 );1.43 int rel = ((uint8_t *)ccn_storequeue_prefetch_tlb) - xlat_output;1.44 JMP_prerel( rel );1.45 }1.46 @@ -109,7 +105,7 @@1.48 for( i=0; i<9; i++, out++ ) {1.49 *out = xlat_output;1.50 - MOVL_r32_r32( ARG1, REG_ECX );1.51 + MOVL_r32_r32( REG_ARG1, REG_ECX );1.52 SHRL_imm_r32( 10, REG_ECX );1.53 ANDL_imms_r32( 0x3, REG_ECX );1.54 XLAT( (uintptr_t)&entry->subpages[0], REG_ECX );1.55 @@ -119,7 +115,7 @@1.56 out = (uint8_t **)&entry->user_fn;1.57 for( i=0; i<9; i++, out++ ) {1.58 *out = xlat_output;1.59 - MOVL_r32_r32( ARG1, REG_ECX );1.60 + MOVL_r32_r32( REG_ARG1, REG_ECX );1.61 SHRL_imm_r32( 10, REG_ECX );1.62 ANDL_imms_r32( 0x3, REG_ECX );1.63 XLAT( (uintptr_t)&entry->user_subpages[0], REG_ECX );
2.1 --- a/src/sh4/sh4x86.in Thu Mar 05 21:37:44 2009 +00002.2 +++ b/src/sh4/sh4x86.in Thu Mar 05 21:42:35 2009 +00002.3 @@ -40,24 +40,34 @@2.4 /* Offset of a reg relative to the sh4r structure */2.5 #define REG_OFFSET(reg) (((char *)&sh4r.reg) - ((char *)&sh4r) - 128)2.7 -#define R_T REG_OFFSET(t)2.8 -#define R_Q REG_OFFSET(q)2.9 -#define R_S REG_OFFSET(s)2.10 -#define R_M REG_OFFSET(m)2.11 -#define R_SR REG_OFFSET(sr)2.12 -#define R_GBR REG_OFFSET(gbr)2.13 -#define R_SSR REG_OFFSET(ssr)2.14 -#define R_SPC REG_OFFSET(spc)2.15 -#define R_VBR REG_OFFSET(vbr)2.16 -#define R_MACH REG_OFFSET(mac)+42.17 -#define R_MACL REG_OFFSET(mac)2.18 -#define R_PC REG_OFFSET(pc)2.19 +#define R_T REG_OFFSET(t)2.20 +#define R_Q REG_OFFSET(q)2.21 +#define R_S REG_OFFSET(s)2.22 +#define R_M REG_OFFSET(m)2.23 +#define R_SR REG_OFFSET(sr)2.24 +#define R_GBR REG_OFFSET(gbr)2.25 +#define R_SSR REG_OFFSET(ssr)2.26 +#define R_SPC REG_OFFSET(spc)2.27 +#define R_VBR REG_OFFSET(vbr)2.28 +#define R_MACH REG_OFFSET(mac)+42.29 +#define R_MACL REG_OFFSET(mac)2.30 +#define R_PC REG_OFFSET(pc)2.31 #define R_NEW_PC REG_OFFSET(new_pc)2.32 -#define R_PR REG_OFFSET(pr)2.33 -#define R_SGR REG_OFFSET(sgr)2.34 -#define R_FPUL REG_OFFSET(fpul)2.35 -#define R_FPSCR REG_OFFSET(fpscr)2.36 -#define R_DBR REG_OFFSET(dbr)2.37 +#define R_PR REG_OFFSET(pr)2.38 +#define R_SGR REG_OFFSET(sgr)2.39 +#define R_FPUL REG_OFFSET(fpul)2.40 +#define R_FPSCR REG_OFFSET(fpscr)2.41 +#define R_DBR REG_OFFSET(dbr)2.42 +#define R_R(rn) REG_OFFSET(r[rn])2.43 +#define R_FR(f) REG_OFFSET(fr[0][(f)^1])2.44 +#define R_XF(f) REG_OFFSET(fr[1][(f)^1])2.45 +#define R_DR(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])2.46 +#define R_DRL(f) REG_OFFSET(fr[(f)&1][(f)|0x01])2.47 +#define R_DRH(f) REG_OFFSET(fr[(f)&1][(f)&0x0E])2.48 +2.49 +#define DELAY_NONE 02.50 +#define DELAY_PC 12.51 +#define DELAY_PC_PR 22.53 struct backpatch_record {2.54 uint32_t fixup_offset;2.55 @@ -65,10 +75,6 @@2.56 int32_t exc_code;2.57 };2.59 -#define DELAY_NONE 02.60 -#define DELAY_PC 12.61 -#define DELAY_PC_PR 22.62 -2.63 /**2.64 * Struct to manage internal translation state. This state is not saved -2.65 * it is only valid between calls to sh4_translate_begin_block() and2.66 @@ -145,14 +151,14 @@2.67 }2.69 #define TSTATE_NONE -12.70 -#define TSTATE_O 02.71 -#define TSTATE_C 22.72 -#define TSTATE_E 42.73 -#define TSTATE_NE 52.74 -#define TSTATE_G 0xF2.75 -#define TSTATE_GE 0xD2.76 -#define TSTATE_A 72.77 -#define TSTATE_AE 32.78 +#define TSTATE_O X86_COND_O2.79 +#define TSTATE_C X86_COND_C2.80 +#define TSTATE_E X86_COND_E2.81 +#define TSTATE_NE X86_COND_NE2.82 +#define TSTATE_G X86_COND_G2.83 +#define TSTATE_GE X86_COND_GE2.84 +#define TSTATE_A X86_COND_A2.85 +#define TSTATE_AE X86_COND_AE2.87 #define MARK_JMP8(x) uint8_t *_mark_jmp_##x = (xlat_output-1)2.88 #define JMP_TARGET(x) *_mark_jmp_##x += (xlat_output - _mark_jmp_##x)2.89 @@ -188,14 +194,9 @@2.90 CMPL_imms_rbpdisp( 1, R_T ); sh4_x86.tstate = TSTATE_E; } \2.91 JCC_cc_rel8(sh4_x86.tstate^1, -1); MARK_JMP8(label)2.93 -#define load_reg16s(x86reg,sh4reg) MOVSXL_rbpdisp16_r32( REG_OFFSET(r[sh4reg]), x86reg )2.94 -#define load_reg16u(x86reg,sh4reg) MOVZXL_rbpdisp16_r32( REG_OFFSET(r[sh4reg]), x86reg )2.95 -#define load_imm32(x86reg,value) MOVL_imm32_r32(value,x86reg)2.96 -#define load_imm64(x86reg,value) MOVQ_imm64_r64(value,x86reg)2.97 +2.98 #define load_reg(x86reg,sh4reg) MOVL_rbpdisp_r32( REG_OFFSET(r[sh4reg]), x86reg )2.99 #define store_reg(x86reg,sh4reg) MOVL_r32_rbpdisp( x86reg, REG_OFFSET(r[sh4reg]) )2.100 -#define load_spreg(x86reg, regoff) MOVL_rbpdisp_r32( regoff, x86reg )2.101 -#define store_spreg(x86reg, regoff) MOVL_r32_rbpdisp( x86reg, regoff )2.103 /**2.104 * Load an FR register (single-precision floating point) into an integer x862.105 @@ -233,7 +234,7 @@2.106 #define pop_xdr(frm) FSTPD_rbpdisp( REG_OFFSET(fr[1][(frm)&0x0E]) )2.108 #ifdef ENABLE_SH4STATS2.109 -#define COUNT_INST(id) load_imm32(REG_EAX,id); call_func1(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE2.110 +#define COUNT_INST(id) MOVL_imm32_r32( id, REG_EAX ); CALL1_ptr_r32(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE2.111 #else2.112 #define COUNT_INST(id)2.113 #endif2.114 @@ -256,7 +257,7 @@2.115 #define check_fpuen( ) \2.116 if( !sh4_x86.fpuen_checked ) {\2.117 sh4_x86.fpuen_checked = TRUE;\2.118 - load_spreg( REG_EAX, R_SR );\2.119 + MOVL_rbpdisp_r32( R_SR, REG_EAX );\2.120 ANDL_imms_r32( SR_FD, REG_EAX );\2.121 if( sh4_x86.in_delay_slot ) {\2.122 JNE_exc(EXC_SLOT_FPU_DISABLED);\2.123 @@ -291,42 +292,80 @@2.124 JNE_exc(EXC_DATA_ADDR_WRITE);2.126 #define UNDEF(ir)2.127 -#define MEM_REGION_PTR(name) offsetof( struct mem_region_fn, name )2.128 -#define MEM_RESULT(value_reg) if(value_reg != REG_EAX) { MOVL_r32_r32(REG_EAX,value_reg); }2.129 /* Note: For SR.MD == 1 && MMUCR.AT == 0, there are no memory exceptions, so2.130 * don't waste the cycles expecting them. Otherwise we need to save the exception pointer.2.131 */2.132 -2.133 #ifdef HAVE_FRAME_ADDRESS2.134 -#define _CALL_READ(addr_reg, fn) if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { \2.135 - call_func1_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg); } else { \2.136 - call_func1_r32disp8_exc(REG_ECX, MEM_REGION_PTR(fn), addr_reg, pc); }2.137 -#define _CALL_WRITE(addr_reg, val_reg, fn) if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) { \2.138 - call_func2_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg); } else { \2.139 - call_func2_r32disp8_exc(REG_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg, pc); }2.140 -#else2.141 -#define _CALL_READ(addr_reg, fn) call_func1_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg)2.142 -#define _CALL_WRITE(addr_reg, val_reg, fn) call_func2_r32disp8(REG_ECX, MEM_REGION_PTR(fn), addr_reg, val_reg)2.143 +static void call_read_func(int addr_reg, int value_reg, int offset, int pc)2.144 +{2.145 + decode_address(addr_reg);2.146 + if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) {2.147 + CALL1_r32disp_r32(REG_ECX, offset, addr_reg);2.148 + } else {2.149 + if( addr_reg != REG_ARG1 ) {2.150 + MOVL_r32_r32( addr_reg, REG_ARG1 );2.151 + }2.152 + MOVP_immptr_rptr( 0, REG_ARG2 );2.153 + sh4_x86_add_backpatch( xlat_output, pc, -2 );2.154 + CALL2_r32disp_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2);2.155 + }2.156 + if( value_reg != REG_RESULT1 ) {2.157 + MOVL_r32_r32( REG_RESULT1, value_reg );2.158 + }2.159 +}2.160 +2.161 +static void call_write_func(int addr_reg, int value_reg, int offset, int pc)2.162 +{2.163 + decode_address(addr_reg);2.164 + if( !sh4_x86.tlb_on && (sh4r.xlat_sh4_mode & SR_MD) ) {2.165 + CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);2.166 + } else {2.167 + if( value_reg != REG_ARG2 ) {2.168 + MOVL_r32_r32( value_reg, REG_ARG2 );2.169 + }2.170 + if( addr_reg != REG_ARG1 ) {2.171 + MOVL_r32_r32( addr_reg, REG_ARG1 );2.172 + }2.173 +#if MAX_REG_ARG > 22.174 + MOVP_immptr_rptr( 0, REG_ARG3 );2.175 + sh4_x86_add_backpatch( xlat_output, pc, -2 );2.176 + CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, REG_ARG3);2.177 +#else2.178 + MOVL_imm32_rspdisp( 0, 0 );2.179 + sh4_x86_add_backpatch( xlat_output, pc, -2 );2.180 + CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, 0);2.181 +#endif2.182 + }2.183 +}2.184 +#else2.185 +static void call_read_func(int addr_reg, int value_reg, int offset, int pc)2.186 +{2.187 + decode_address(addr_reg);2.188 + CALL1_r32disp_r32(REG_ECX, offset, addr_reg);2.189 + if( value_reg != REG_RESULT1 ) {2.190 + MOVL_r32_r32( REG_RESULT1, value_reg );2.191 + }2.192 +}2.193 +2.194 +static void call_write_func(int addr_reg, int value_reg, int value_reg, int pc)2.195 +{2.196 + decode_address(addr_reg);2.197 + CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);2.198 +}2.199 #endif2.201 -#define MEM_READ_BYTE( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_byte); MEM_RESULT(value_reg)2.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)2.203 -#define MEM_READ_WORD( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_word); MEM_RESULT(value_reg)2.204 -#define MEM_READ_LONG( addr_reg, value_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, read_long); MEM_RESULT(value_reg)2.205 -#define MEM_WRITE_BYTE( addr_reg, value_reg ) decode_address(addr_reg); _CALL_WRITE(addr_reg, value_reg, write_byte)2.206 -#define MEM_WRITE_WORD( addr_reg, value_reg ) decode_address(addr_reg); _CALL_WRITE(addr_reg, value_reg, write_word)2.207 -#define MEM_WRITE_LONG( addr_reg, value_reg ) decode_address(addr_reg); _CALL_WRITE(addr_reg, value_reg, write_long)2.208 -#define MEM_PREFETCH( addr_reg ) decode_address(addr_reg); _CALL_READ(addr_reg, prefetch)2.209 +#define MEM_REGION_PTR(name) offsetof( struct mem_region_fn, name )2.210 +#define MEM_READ_BYTE( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_byte), pc)2.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)2.212 +#define MEM_READ_WORD( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_word), pc)2.213 +#define MEM_READ_LONG( addr_reg, value_reg ) call_read_func(addr_reg, value_reg, MEM_REGION_PTR(read_long), pc)2.214 +#define MEM_WRITE_BYTE( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_byte), pc)2.215 +#define MEM_WRITE_WORD( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_word), pc)2.216 +#define MEM_WRITE_LONG( addr_reg, value_reg ) call_write_func(addr_reg, value_reg, MEM_REGION_PTR(write_long), pc)2.217 +#define MEM_PREFETCH( addr_reg ) call_read_func(addr_reg, REG_RESULT1, MEM_REGION_PTR(prefetch), pc)2.219 #define SLOTILLEGAL() exit_block_exc(EXC_SLOT_ILLEGAL, pc-2); sh4_x86.in_delay_slot = DELAY_NONE; return 2;2.221 -/****** Import appropriate calling conventions ******/2.222 -#if SIZEOF_VOID_P == 82.223 -#include "xlat/x86/amd64abi.h"2.224 -#else /* 32-bit system */2.225 -#include "xlat/x86/ia32abi.h"2.226 -#endif2.227 -2.228 void sh4_translate_begin_block( sh4addr_t pc )2.229 {2.230 enter_block();2.231 @@ -357,8 +396,8 @@2.232 */2.233 void sh4_translate_emit_breakpoint( sh4vma_t pc )2.234 {2.235 - load_imm32( REG_EAX, pc );2.236 - call_func1( sh4_translate_breakpoint_hit, REG_EAX );2.237 + MOVL_imm32_r32( pc, REG_EAX );2.238 + CALL1_ptr_r32( sh4_translate_breakpoint_hit, REG_EAX );2.239 sh4_x86.tstate = TSTATE_NONE;2.240 }2.242 @@ -366,6 +405,102 @@2.243 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)2.245 /**2.246 + * Exit the block with sh4r.pc already written2.247 + */2.248 +void exit_block_pcset( sh4addr_t pc )2.249 +{2.250 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );2.251 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );2.252 + MOVL_rbpdisp_r32( R_PC, REG_ARG1 );2.253 + if( sh4_x86.tlb_on ) {2.254 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);2.255 + } else {2.256 + CALL1_ptr_r32(xlat_get_code,REG_ARG1);2.257 + }2.258 + exit_block();2.259 +}2.260 +2.261 +/**2.262 + * Exit the block with sh4r.new_pc written with the target pc2.263 + */2.264 +void exit_block_newpcset( sh4addr_t pc )2.265 +{2.266 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );2.267 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );2.268 + MOVL_rbpdisp_r32( R_NEW_PC, REG_ARG1 );2.269 + MOVL_r32_rbpdisp( REG_ARG1, R_PC );2.270 + if( sh4_x86.tlb_on ) {2.271 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);2.272 + } else {2.273 + CALL1_ptr_r32(xlat_get_code,REG_ARG1);2.274 + }2.275 + exit_block();2.276 +}2.277 +2.278 +2.279 +/**2.280 + * Exit the block to an absolute PC2.281 + */2.282 +void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )2.283 +{2.284 + MOVL_imm32_r32( pc, REG_ECX );2.285 + MOVL_r32_rbpdisp( REG_ECX, R_PC );2.286 + if( IS_IN_ICACHE(pc) ) {2.287 + MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );2.288 + ANDP_imms_rptr( -4, REG_EAX );2.289 + } else if( sh4_x86.tlb_on ) {2.290 + CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);2.291 + } else {2.292 + CALL1_ptr_r32(xlat_get_code, REG_ECX);2.293 + }2.294 + MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );2.295 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );2.296 + exit_block();2.297 +}2.298 +2.299 +/**2.300 + * Exit the block to a relative PC2.301 + */2.302 +void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )2.303 +{2.304 + MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );2.305 + ADDL_rbpdisp_r32( R_PC, REG_ECX );2.306 + MOVL_r32_rbpdisp( REG_ECX, R_PC );2.307 + if( IS_IN_ICACHE(pc) ) {2.308 + MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) );2.309 + ANDP_imms_rptr( -4, REG_EAX );2.310 + } else if( sh4_x86.tlb_on ) {2.311 + CALL1_ptr_r32(xlat_get_code_by_vma, REG_ECX);2.312 + } else {2.313 + CALL1_ptr_r32(xlat_get_code, REG_ECX);2.314 + }2.315 + MOVL_imm32_r32( ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );2.316 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );2.317 + exit_block();2.318 +}2.319 +2.320 +/**2.321 + * Exit unconditionally with a general exception2.322 + */2.323 +void exit_block_exc( int code, sh4addr_t pc )2.324 +{2.325 + MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ECX );2.326 + ADDL_r32_rbpdisp( REG_ECX, R_PC );2.327 + MOVL_imm32_r32( ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period, REG_ECX );2.328 + ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) );2.329 + MOVL_imm32_r32( code, REG_ARG1 );2.330 + CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );2.331 + MOVL_rbpdisp_r32( R_PC, REG_ARG1 );2.332 + if( sh4_x86.tlb_on ) {2.333 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_ARG1);2.334 + } else {2.335 + CALL1_ptr_r32(xlat_get_code,REG_ARG1);2.336 + }2.337 +2.338 + exit_block();2.339 +}2.340 +2.341 +/**2.342 * Embed a call to sh4_execute_instruction for situations that we2.343 * can't translate (just page-crossing delay slots at the moment).2.344 * Caller is responsible for setting new_pc before calling this function.2.345 @@ -379,25 +514,74 @@2.346 */2.347 void exit_block_emu( sh4vma_t endpc )2.348 {2.349 - load_imm32( REG_ECX, endpc - sh4_x86.block_start_pc ); // 52.350 + MOVL_imm32_r32( endpc - sh4_x86.block_start_pc, REG_ECX ); // 52.351 ADDL_r32_rbpdisp( REG_ECX, R_PC );2.353 - load_imm32( REG_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 52.354 + MOVL_imm32_r32( (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period, REG_ECX ); // 52.355 ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 62.356 - load_imm32( REG_ECX, sh4_x86.in_delay_slot ? 1 : 0 );2.357 - store_spreg( REG_ECX, REG_OFFSET(in_delay_slot) );2.358 + MOVL_imm32_r32( sh4_x86.in_delay_slot ? 1 : 0, REG_ECX );2.359 + MOVL_r32_rbpdisp( REG_ECX, REG_OFFSET(in_delay_slot) );2.361 - call_func0( sh4_execute_instruction );2.362 - load_spreg( REG_EAX, R_PC );2.363 + CALL_ptr( sh4_execute_instruction );2.364 + MOVL_rbpdisp_r32( R_PC, REG_EAX );2.365 if( sh4_x86.tlb_on ) {2.366 - call_func1(xlat_get_code_by_vma,REG_EAX);2.367 + CALL1_ptr_r32(xlat_get_code_by_vma,REG_EAX);2.368 } else {2.369 - call_func1(xlat_get_code,REG_EAX);2.370 + CALL1_ptr_r32(xlat_get_code,REG_EAX);2.371 }2.372 exit_block();2.373 }2.375 /**2.376 + * Write the block trailer (exception handling block)2.377 + */2.378 +void sh4_translate_end_block( sh4addr_t pc ) {2.379 + if( sh4_x86.branch_taken == FALSE ) {2.380 + // Didn't exit unconditionally already, so write the termination here2.381 + exit_block_rel( pc, pc );2.382 + }2.383 + if( sh4_x86.backpatch_posn != 0 ) {2.384 + unsigned int i;2.385 + // Exception raised - cleanup and exit2.386 + uint8_t *end_ptr = xlat_output;2.387 + MOVL_r32_r32( REG_EDX, REG_ECX );2.388 + ADDL_r32_r32( REG_EDX, REG_ECX );2.389 + ADDL_r32_rbpdisp( REG_ECX, R_SPC );2.390 + MOVL_moffptr_eax( &sh4_cpu_period );2.391 + MULL_r32( REG_EDX );2.392 + ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );2.393 + MOVL_rbpdisp_r32( R_PC, REG_ARG1 );2.394 + if( sh4_x86.tlb_on ) {2.395 + CALL1_ptr_r32(xlat_get_code_by_vma, REG_ARG1);2.396 + } else {2.397 + CALL1_ptr_r32(xlat_get_code, REG_ARG1);2.398 + }2.399 + exit_block();2.400 +2.401 + for( i=0; i< sh4_x86.backpatch_posn; i++ ) {2.402 + uint32_t *fixup_addr = (uint32_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset];2.403 + if( sh4_x86.backpatch_list[i].exc_code < 0 ) {2.404 + if( sh4_x86.backpatch_list[i].exc_code == -2 ) {2.405 + *((uintptr_t *)fixup_addr) = (uintptr_t)xlat_output;2.406 + } else {2.407 + *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;2.408 + }2.409 + MOVL_imm32_r32( sh4_x86.backpatch_list[i].fixup_icount, REG_EDX );2.410 + int rel = end_ptr - xlat_output;2.411 + JMP_prerel(rel);2.412 + } else {2.413 + *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;2.414 + MOVL_imm32_r32( sh4_x86.backpatch_list[i].exc_code, REG_ARG1 );2.415 + CALL1_ptr_r32( sh4_raise_exception, REG_ARG1 );2.416 + MOVL_imm32_r32( sh4_x86.backpatch_list[i].fixup_icount, REG_EDX );2.417 + int rel = end_ptr - xlat_output;2.418 + JMP_prerel(rel);2.419 + }2.420 + }2.421 + }2.422 +}2.423 +2.424 +/**2.425 * Translate a single instruction. Delayed branches are handled specially2.426 * by translating both branch and delayed instruction as a single unit (as2.427 *2.428 @@ -564,8 +748,8 @@2.429 load_reg( REG_ECX, Rn );2.430 SHRL_imm_r32( 31, REG_EAX );2.431 SHRL_imm_r32( 31, REG_ECX );2.432 - store_spreg( REG_EAX, R_M );2.433 - store_spreg( REG_ECX, R_Q );2.434 + MOVL_r32_rbpdisp( REG_EAX, R_M );2.435 + MOVL_r32_rbpdisp( REG_ECX, R_Q );2.436 CMPL_r32_r32( REG_EAX, REG_ECX );2.437 SETNE_t();2.438 sh4_x86.tstate = TSTATE_NE;2.439 @@ -573,14 +757,14 @@2.440 DIV0U {:2.441 COUNT_INST(I_DIV0U);2.442 XORL_r32_r32( REG_EAX, REG_EAX );2.443 - store_spreg( REG_EAX, R_Q );2.444 - store_spreg( REG_EAX, R_M );2.445 - store_spreg( REG_EAX, R_T );2.446 + MOVL_r32_rbpdisp( REG_EAX, R_Q );2.447 + MOVL_r32_rbpdisp( REG_EAX, R_M );2.448 + MOVL_r32_rbpdisp( REG_EAX, R_T );2.449 sh4_x86.tstate = TSTATE_C; // works for DIV12.450 :}2.451 DIV1 Rm, Rn {:2.452 COUNT_INST(I_DIV1);2.453 - load_spreg( REG_ECX, R_M );2.454 + MOVL_rbpdisp_r32( R_M, REG_ECX );2.455 load_reg( REG_EAX, Rn );2.456 if( sh4_x86.tstate != TSTATE_C ) {2.457 LDC_t();2.458 @@ -598,10 +782,10 @@2.459 SETC_r8(REG_AL); // tmp12.460 XORB_r8_r8( REG_DL, REG_AL ); // Q' = Q ^ tmp12.461 XORB_r8_r8( REG_AL, REG_CL ); // Q'' = Q' ^ M2.462 - store_spreg( REG_ECX, R_Q );2.463 + MOVL_r32_rbpdisp( REG_ECX, R_Q );2.464 XORL_imms_r32( 1, REG_AL ); // T = !Q'2.465 MOVZXL_r8_r32( REG_AL, REG_EAX );2.466 - store_spreg( REG_EAX, R_T );2.467 + MOVL_r32_rbpdisp( REG_EAX, R_T );2.468 sh4_x86.tstate = TSTATE_NONE;2.469 :}2.470 DMULS.L Rm, Rn {:2.471 @@ -609,8 +793,8 @@2.472 load_reg( REG_EAX, Rm );2.473 load_reg( REG_ECX, Rn );2.474 IMULL_r32(REG_ECX);2.475 - store_spreg( REG_EDX, R_MACH );2.476 - store_spreg( REG_EAX, R_MACL );2.477 + MOVL_r32_rbpdisp( REG_EDX, R_MACH );2.478 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.479 sh4_x86.tstate = TSTATE_NONE;2.480 :}2.481 DMULU.L Rm, Rn {:2.482 @@ -618,8 +802,8 @@2.483 load_reg( REG_EAX, Rm );2.484 load_reg( REG_ECX, Rn );2.485 MULL_r32(REG_ECX);2.486 - store_spreg( REG_EDX, R_MACH );2.487 - store_spreg( REG_EAX, R_MACL );2.488 + MOVL_r32_rbpdisp( REG_EDX, R_MACH );2.489 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.490 sh4_x86.tstate = TSTATE_NONE;2.491 :}2.492 DT Rn {:2.493 @@ -681,10 +865,10 @@2.494 ADDL_r32_rbpdisp( REG_EAX, R_MACL );2.495 ADCL_r32_rbpdisp( REG_EDX, R_MACH );2.497 - load_spreg( REG_ECX, R_S );2.498 + MOVL_rbpdisp_r32( R_S, REG_ECX );2.499 TESTL_r32_r32(REG_ECX, REG_ECX);2.500 JE_label( nosat );2.501 - call_func0( signsat48 );2.502 + CALL_ptr( signsat48 );2.503 JMP_TARGET( nosat );2.504 sh4_x86.tstate = TSTATE_NONE;2.505 :}2.506 @@ -713,22 +897,22 @@2.507 ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rm]) );2.508 }2.509 IMULL_rspdisp( 0 );2.510 - load_spreg( REG_ECX, R_S );2.511 + MOVL_rbpdisp_r32( R_S, REG_ECX );2.512 TESTL_r32_r32( REG_ECX, REG_ECX );2.513 JE_label( nosat );2.515 ADDL_r32_rbpdisp( REG_EAX, R_MACL ); // 62.516 JNO_label( end ); // 22.517 - load_imm32( REG_EDX, 1 ); // 52.518 - store_spreg( REG_EDX, R_MACH ); // 62.519 + MOVL_imm32_r32( 1, REG_EDX ); // 52.520 + MOVL_r32_rbpdisp( REG_EDX, R_MACH ); // 62.521 JS_label( positive ); // 22.522 - load_imm32( REG_EAX, 0x80000000 );// 52.523 - store_spreg( REG_EAX, R_MACL ); // 62.524 + MOVL_imm32_r32( 0x80000000, REG_EAX );// 52.525 + MOVL_r32_rbpdisp( REG_EAX, R_MACL ); // 62.526 JMP_label(end2); // 22.528 JMP_TARGET(positive);2.529 - load_imm32( REG_EAX, 0x7FFFFFFF );// 52.530 - store_spreg( REG_EAX, R_MACL ); // 62.531 + MOVL_imm32_r32( 0x7FFFFFFF, REG_EAX );// 52.532 + MOVL_r32_rbpdisp( REG_EAX, R_MACL ); // 62.533 JMP_label(end3); // 22.535 JMP_TARGET(nosat);2.536 @@ -741,7 +925,7 @@2.537 :}2.538 MOVT Rn {:2.539 COUNT_INST(I_MOVT);2.540 - load_spreg( REG_EAX, R_T );2.541 + MOVL_rbpdisp_r32( R_T, REG_EAX );2.542 store_reg( REG_EAX, Rn );2.543 :}2.544 MUL.L Rm, Rn {:2.545 @@ -749,23 +933,23 @@2.546 load_reg( REG_EAX, Rm );2.547 load_reg( REG_ECX, Rn );2.548 MULL_r32( REG_ECX );2.549 - store_spreg( REG_EAX, R_MACL );2.550 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.551 sh4_x86.tstate = TSTATE_NONE;2.552 :}2.553 MULS.W Rm, Rn {:2.554 COUNT_INST(I_MULSW);2.555 - load_reg16s( REG_EAX, Rm );2.556 - load_reg16s( REG_ECX, Rn );2.557 + MOVSXL_rbpdisp16_r32( R_R(Rm), REG_EAX );2.558 + MOVSXL_rbpdisp16_r32( R_R(Rn), REG_ECX );2.559 MULL_r32( REG_ECX );2.560 - store_spreg( REG_EAX, R_MACL );2.561 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.562 sh4_x86.tstate = TSTATE_NONE;2.563 :}2.564 MULU.W Rm, Rn {:2.565 COUNT_INST(I_MULUW);2.566 - load_reg16u( REG_EAX, Rm );2.567 - load_reg16u( REG_ECX, Rn );2.568 + MOVZXL_rbpdisp16_r32( R_R(Rm), REG_EAX );2.569 + MOVZXL_rbpdisp16_r32( R_R(Rn), REG_ECX );2.570 MULL_r32( REG_ECX );2.571 - store_spreg( REG_EAX, R_MACL );2.572 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.573 sh4_x86.tstate = TSTATE_NONE;2.574 :}2.575 NEG Rm, Rn {:2.576 @@ -1107,7 +1291,7 @@2.577 :}2.578 MOV #imm, Rn {:2.579 COUNT_INST(I_MOVI);2.580 - load_imm32( REG_EAX, imm );2.581 + MOVL_imm32_r32( imm, REG_EAX );2.582 store_reg( REG_EAX, Rn );2.583 :}2.584 MOV.B Rm, @Rn {:2.585 @@ -1136,7 +1320,7 @@2.586 :}2.587 MOV.B R0, @(disp, GBR) {:2.588 COUNT_INST(I_MOVB);2.589 - load_spreg( REG_EAX, R_GBR );2.590 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.591 ADDL_imms_r32( disp, REG_EAX );2.592 load_reg( REG_EDX, 0 );2.593 MEM_WRITE_BYTE( REG_EAX, REG_EDX );2.594 @@ -1177,7 +1361,7 @@2.595 :}2.596 MOV.B @(disp, GBR), R0 {:2.597 COUNT_INST(I_MOVB);2.598 - load_spreg( REG_EAX, R_GBR );2.599 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.600 ADDL_imms_r32( disp, REG_EAX );2.601 MEM_READ_BYTE( REG_EAX, REG_EAX );2.602 store_reg( REG_EAX, 0 );2.603 @@ -1230,7 +1414,7 @@2.604 :}2.605 MOV.L R0, @(disp, GBR) {:2.606 COUNT_INST(I_MOVL);2.607 - load_spreg( REG_EAX, R_GBR );2.608 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.609 ADDL_imms_r32( disp, REG_EAX );2.610 check_walign32( REG_EAX );2.611 load_reg( REG_EDX, 0 );2.612 @@ -1286,7 +1470,7 @@2.613 :}2.614 MOV.L @(disp, GBR), R0 {:2.615 COUNT_INST(I_MOVL);2.616 - load_spreg( REG_EAX, R_GBR );2.617 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.618 ADDL_imms_r32( disp, REG_EAX );2.619 check_ralign32( REG_EAX );2.620 MEM_READ_LONG( REG_EAX, REG_EAX );2.621 @@ -1315,7 +1499,7 @@2.622 // Note: we use sh4r.pc for the calc as we could be running at a2.623 // different virtual address than the translation was done with,2.624 // but we can safely assume that the low bits are the same.2.625 - load_imm32( REG_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );2.626 + MOVL_imm32_r32( (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03), REG_EAX );2.627 ADDL_rbpdisp_r32( R_PC, REG_EAX );2.628 MEM_READ_LONG( REG_EAX, REG_EAX );2.629 sh4_x86.tstate = TSTATE_NONE;2.630 @@ -1361,7 +1545,7 @@2.631 :}2.632 MOV.W R0, @(disp, GBR) {:2.633 COUNT_INST(I_MOVW);2.634 - load_spreg( REG_EAX, R_GBR );2.635 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.636 ADDL_imms_r32( disp, REG_EAX );2.637 check_walign16( REG_EAX );2.638 load_reg( REG_EDX, 0 );2.639 @@ -1407,7 +1591,7 @@2.640 :}2.641 MOV.W @(disp, GBR), R0 {:2.642 COUNT_INST(I_MOVW);2.643 - load_spreg( REG_EAX, R_GBR );2.644 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.645 ADDL_imms_r32( disp, REG_EAX );2.646 check_ralign16( REG_EAX );2.647 MEM_READ_WORD( REG_EAX, REG_EAX );2.648 @@ -1426,7 +1610,7 @@2.649 MOVL_moffptr_eax( ptr );2.650 MOVSXL_r16_r32( REG_EAX, REG_EAX );2.651 } else {2.652 - load_imm32( REG_EAX, (pc - sh4_x86.block_start_pc) + disp + 4 );2.653 + MOVL_imm32_r32( (pc - sh4_x86.block_start_pc) + disp + 4, REG_EAX );2.654 ADDL_rbpdisp_r32( R_PC, REG_EAX );2.655 MEM_READ_WORD( REG_EAX, REG_EAX );2.656 sh4_x86.tstate = TSTATE_NONE;2.657 @@ -1448,7 +1632,7 @@2.658 if( sh4_x86.in_delay_slot ) {2.659 SLOTILLEGAL();2.660 } else {2.661 - load_imm32( REG_ECX, (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );2.662 + MOVL_imm32_r32( (pc - sh4_x86.block_start_pc) + disp + 4 - (pc&0x03), REG_ECX );2.663 ADDL_rbpdisp_r32( R_PC, REG_ECX );2.664 store_reg( REG_ECX, 0 );2.665 sh4_x86.tstate = TSTATE_NONE;2.666 @@ -1483,12 +1667,12 @@2.667 } else {2.668 sh4_x86.in_delay_slot = DELAY_PC;2.669 if( UNTRANSLATABLE(pc+2) ) {2.670 - load_imm32( REG_EAX, pc + 4 - sh4_x86.block_start_pc );2.671 + MOVL_imm32_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );2.672 JT_label(nottaken);2.673 ADDL_imms_r32( disp, REG_EAX );2.674 JMP_TARGET(nottaken);2.675 ADDL_rbpdisp_r32( R_PC, REG_EAX );2.676 - store_spreg( REG_EAX, R_NEW_PC );2.677 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );2.678 exit_block_emu(pc+2);2.679 sh4_x86.branch_taken = TRUE;2.680 return 2;2.681 @@ -1520,9 +1704,9 @@2.682 sh4_x86.in_delay_slot = DELAY_PC;2.683 sh4_x86.branch_taken = TRUE;2.684 if( UNTRANSLATABLE(pc+2) ) {2.685 - load_spreg( REG_EAX, R_PC );2.686 + MOVL_rbpdisp_r32( R_PC, REG_EAX );2.687 ADDL_imms_r32( pc + disp + 4 - sh4_x86.block_start_pc, REG_EAX );2.688 - store_spreg( REG_EAX, R_NEW_PC );2.689 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );2.690 exit_block_emu(pc+2);2.691 return 2;2.692 } else {2.693 @@ -1537,10 +1721,10 @@2.694 if( sh4_x86.in_delay_slot ) {2.695 SLOTILLEGAL();2.696 } else {2.697 - load_spreg( REG_EAX, R_PC );2.698 + MOVL_rbpdisp_r32( R_PC, REG_EAX );2.699 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );2.700 ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );2.701 - store_spreg( REG_EAX, R_NEW_PC );2.702 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );2.703 sh4_x86.in_delay_slot = DELAY_PC;2.704 sh4_x86.tstate = TSTATE_NONE;2.705 sh4_x86.branch_taken = TRUE;2.706 @@ -1559,15 +1743,15 @@2.707 if( sh4_x86.in_delay_slot ) {2.708 SLOTILLEGAL();2.709 } else {2.710 - load_spreg( REG_EAX, R_PC );2.711 + MOVL_rbpdisp_r32( R_PC, REG_EAX );2.712 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );2.713 - store_spreg( REG_EAX, R_PR );2.714 + MOVL_r32_rbpdisp( REG_EAX, R_PR );2.715 sh4_x86.in_delay_slot = DELAY_PC;2.716 sh4_x86.branch_taken = TRUE;2.717 sh4_x86.tstate = TSTATE_NONE;2.718 if( UNTRANSLATABLE(pc+2) ) {2.719 ADDL_imms_r32( disp, REG_EAX );2.720 - store_spreg( REG_EAX, R_NEW_PC );2.721 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );2.722 exit_block_emu(pc+2);2.723 return 2;2.724 } else {2.725 @@ -1582,11 +1766,11 @@2.726 if( sh4_x86.in_delay_slot ) {2.727 SLOTILLEGAL();2.728 } else {2.729 - load_spreg( REG_EAX, R_PC );2.730 + MOVL_rbpdisp_r32( R_PC, REG_EAX );2.731 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );2.732 - store_spreg( REG_EAX, R_PR );2.733 + MOVL_r32_rbpdisp( REG_EAX, R_PR );2.734 ADDL_rbpdisp_r32( REG_OFFSET(r[Rn]), REG_EAX );2.735 - store_spreg( REG_EAX, R_NEW_PC );2.736 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );2.738 sh4_x86.in_delay_slot = DELAY_PC;2.739 sh4_x86.tstate = TSTATE_NONE;2.740 @@ -1620,12 +1804,12 @@2.741 } else {2.742 sh4_x86.in_delay_slot = DELAY_PC;2.743 if( UNTRANSLATABLE(pc+2) ) {2.744 - load_imm32( REG_EAX, pc + 4 - sh4_x86.block_start_pc );2.745 + MOVL_imm32_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );2.746 JF_label(nottaken);2.747 ADDL_imms_r32( disp, REG_EAX );2.748 JMP_TARGET(nottaken);2.749 ADDL_rbpdisp_r32( R_PC, REG_EAX );2.750 - store_spreg( REG_EAX, R_NEW_PC );2.751 + MOVL_r32_rbpdisp( REG_EAX, R_NEW_PC );2.752 exit_block_emu(pc+2);2.753 sh4_x86.branch_taken = TRUE;2.754 return 2;2.755 @@ -1654,7 +1838,7 @@2.756 SLOTILLEGAL();2.757 } else {2.758 load_reg( REG_ECX, Rn );2.759 - store_spreg( REG_ECX, R_NEW_PC );2.760 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );2.761 sh4_x86.in_delay_slot = DELAY_PC;2.762 sh4_x86.branch_taken = TRUE;2.763 if( UNTRANSLATABLE(pc+2) ) {2.764 @@ -1672,11 +1856,11 @@2.765 if( sh4_x86.in_delay_slot ) {2.766 SLOTILLEGAL();2.767 } else {2.768 - load_spreg( REG_EAX, R_PC );2.769 + MOVL_rbpdisp_r32( R_PC, REG_EAX );2.770 ADDL_imms_r32( pc + 4 - sh4_x86.block_start_pc, REG_EAX );2.771 - store_spreg( REG_EAX, R_PR );2.772 + MOVL_r32_rbpdisp( REG_EAX, R_PR );2.773 load_reg( REG_ECX, Rn );2.774 - store_spreg( REG_ECX, R_NEW_PC );2.775 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );2.776 sh4_x86.in_delay_slot = DELAY_PC;2.777 sh4_x86.branch_taken = TRUE;2.778 sh4_x86.tstate = TSTATE_NONE;2.779 @@ -1696,10 +1880,10 @@2.780 SLOTILLEGAL();2.781 } else {2.782 check_priv();2.783 - load_spreg( REG_ECX, R_SPC );2.784 - store_spreg( REG_ECX, R_NEW_PC );2.785 - load_spreg( REG_EAX, R_SSR );2.786 - call_func1( sh4_write_sr, REG_EAX );2.787 + MOVL_rbpdisp_r32( R_SPC, REG_ECX );2.788 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );2.789 + MOVL_rbpdisp_r32( R_SSR, REG_EAX );2.790 + CALL1_ptr_r32( sh4_write_sr, REG_EAX );2.791 sh4_x86.in_delay_slot = DELAY_PC;2.792 sh4_x86.fpuen_checked = FALSE;2.793 sh4_x86.tstate = TSTATE_NONE;2.794 @@ -1719,8 +1903,8 @@2.795 if( sh4_x86.in_delay_slot ) {2.796 SLOTILLEGAL();2.797 } else {2.798 - load_spreg( REG_ECX, R_PR );2.799 - store_spreg( REG_ECX, R_NEW_PC );2.800 + MOVL_rbpdisp_r32( R_PR, REG_ECX );2.801 + MOVL_r32_rbpdisp( REG_ECX, R_NEW_PC );2.802 sh4_x86.in_delay_slot = DELAY_PC;2.803 sh4_x86.branch_taken = TRUE;2.804 if( UNTRANSLATABLE(pc+2) ) {2.805 @@ -1738,10 +1922,10 @@2.806 if( sh4_x86.in_delay_slot ) {2.807 SLOTILLEGAL();2.808 } else {2.809 - load_imm32( REG_ECX, pc+2 - sh4_x86.block_start_pc ); // 52.810 + MOVL_imm32_r32( pc+2 - sh4_x86.block_start_pc, REG_ECX ); // 52.811 ADDL_r32_rbpdisp( REG_ECX, R_PC );2.812 - load_imm32( REG_EAX, imm );2.813 - call_func1( sh4_raise_trap, REG_EAX );2.814 + MOVL_imm32_r32( imm, REG_EAX );2.815 + CALL1_ptr_r32( sh4_raise_trap, REG_EAX );2.816 sh4_x86.tstate = TSTATE_NONE;2.817 exit_block_pcset(pc+2);2.818 sh4_x86.branch_taken = TRUE;2.819 @@ -1761,8 +1945,8 @@2.820 CLRMAC {:2.821 COUNT_INST(I_CLRMAC);2.822 XORL_r32_r32(REG_EAX, REG_EAX);2.823 - store_spreg( REG_EAX, R_MACL );2.824 - store_spreg( REG_EAX, R_MACH );2.825 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.826 + MOVL_r32_rbpdisp( REG_EAX, R_MACH );2.827 sh4_x86.tstate = TSTATE_NONE;2.828 :}2.829 CLRS {:2.830 @@ -1941,7 +2125,7 @@2.831 COUNT_INST(I_FLDI1);2.832 check_fpuen();2.833 if( sh4_x86.double_prec == 0 ) {2.834 - load_imm32(REG_EAX, 0x3F800000);2.835 + MOVL_imm32_r32( 0x3F800000, REG_EAX );2.836 store_fr( REG_EAX, FRn );2.837 }2.838 :}2.839 @@ -1964,26 +2148,26 @@2.840 } else {2.841 push_fr( FRm );2.842 }2.843 - load_ptr( REG_ECX, &max_int );2.844 + MOVP_immptr_rptr( &max_int, REG_ECX );2.845 FILD_r32disp( REG_ECX, 0 );2.846 FCOMIP_st(1);2.847 JNA_label( sat );2.848 - load_ptr( REG_ECX, &min_int ); // 52.849 - FILD_r32disp( REG_ECX, 0 ); // 22.850 - FCOMIP_st(1); // 22.851 - JAE_label( sat2 ); // 22.852 - load_ptr( REG_EAX, &save_fcw );2.853 + MOVP_immptr_rptr( &min_int, REG_ECX );2.854 + FILD_r32disp( REG_ECX, 0 );2.855 + FCOMIP_st(1);2.856 + JAE_label( sat2 );2.857 + MOVP_immptr_rptr( &save_fcw, REG_EAX );2.858 FNSTCW_r32disp( REG_EAX, 0 );2.859 - load_ptr( REG_EDX, &trunc_fcw );2.860 + MOVP_immptr_rptr( &trunc_fcw, REG_EDX );2.861 FLDCW_r32disp( REG_EDX, 0 );2.862 - FISTP_rbpdisp(R_FPUL); // 32.863 + FISTP_rbpdisp(R_FPUL);2.864 FLDCW_r32disp( REG_EAX, 0 );2.865 - JMP_label(end); // 22.866 + JMP_label(end);2.868 JMP_TARGET(sat);2.869 JMP_TARGET(sat2);2.870 MOVL_r32disp_r32( REG_ECX, 0, REG_ECX ); // 22.871 - store_spreg( REG_ECX, R_FPUL );2.872 + MOVL_r32_rbpdisp( REG_ECX, R_FPUL );2.873 FPOP_st();2.874 JMP_TARGET(end);2.875 sh4_x86.tstate = TSTATE_NONE;2.876 @@ -1992,12 +2176,12 @@2.877 COUNT_INST(I_FLDS);2.878 check_fpuen();2.879 load_fr( REG_EAX, FRm );2.880 - store_spreg( REG_EAX, R_FPUL );2.881 + MOVL_r32_rbpdisp( REG_EAX, R_FPUL );2.882 :}2.883 FSTS FPUL, FRn {:2.884 COUNT_INST(I_FSTS);2.885 check_fpuen();2.886 - load_spreg( REG_EAX, R_FPUL );2.887 + MOVL_rbpdisp_r32( R_FPUL, REG_EAX );2.888 store_fr( REG_EAX, FRn );2.889 :}2.890 FCNVDS FRm, FPUL {:2.891 @@ -2185,8 +2369,8 @@2.892 check_fpuen();2.893 if( sh4_x86.double_prec == 0 ) {2.894 LEAP_rbpdisp_rptr( REG_OFFSET(fr[0][FRn&0x0E]), REG_EDX );2.895 - load_spreg( REG_EAX, R_FPUL );2.896 - call_func2( sh4_fsca, REG_EAX, REG_EDX );2.897 + MOVL_rbpdisp_r32( R_FPUL, REG_EAX );2.898 + CALL2_ptr_r32_r32( sh4_fsca, REG_EAX, REG_EDX );2.899 }2.900 sh4_x86.tstate = TSTATE_NONE;2.901 :}2.902 @@ -2248,7 +2432,7 @@2.903 MOVAPS_xmm_rbpdisp( 4, REG_OFFSET(fr[0][FVn<<2]) );2.904 } else {2.905 LEAP_rbpdisp_rptr( REG_OFFSET(fr[0][FVn<<2]), REG_EAX );2.906 - call_func1( sh4_ftrv, REG_EAX );2.907 + CALL1_ptr_r32( sh4_ftrv, REG_EAX );2.908 }2.909 }2.910 sh4_x86.tstate = TSTATE_NONE;2.911 @@ -2258,7 +2442,7 @@2.912 COUNT_INST(I_FRCHG);2.913 check_fpuen();2.914 XORL_imms_rbpdisp( FPSCR_FR, R_FPSCR );2.915 - call_func0( sh4_switch_fr_banks );2.916 + CALL_ptr( sh4_switch_fr_banks );2.917 sh4_x86.tstate = TSTATE_NONE;2.918 :}2.919 FSCHG {:2.920 @@ -2278,7 +2462,7 @@2.921 } else {2.922 check_priv();2.923 load_reg( REG_EAX, Rm );2.924 - call_func1( sh4_write_sr, REG_EAX );2.925 + CALL1_ptr_r32( sh4_write_sr, REG_EAX );2.926 sh4_x86.fpuen_checked = FALSE;2.927 sh4_x86.tstate = TSTATE_NONE;2.928 return 2;2.929 @@ -2287,48 +2471,48 @@2.930 LDC Rm, GBR {:2.931 COUNT_INST(I_LDC);2.932 load_reg( REG_EAX, Rm );2.933 - store_spreg( REG_EAX, R_GBR );2.934 + MOVL_r32_rbpdisp( REG_EAX, R_GBR );2.935 :}2.936 LDC Rm, VBR {:2.937 COUNT_INST(I_LDC);2.938 check_priv();2.939 load_reg( REG_EAX, Rm );2.940 - store_spreg( REG_EAX, R_VBR );2.941 + MOVL_r32_rbpdisp( REG_EAX, R_VBR );2.942 sh4_x86.tstate = TSTATE_NONE;2.943 :}2.944 LDC Rm, SSR {:2.945 COUNT_INST(I_LDC);2.946 check_priv();2.947 load_reg( REG_EAX, Rm );2.948 - store_spreg( REG_EAX, R_SSR );2.949 + MOVL_r32_rbpdisp( REG_EAX, R_SSR );2.950 sh4_x86.tstate = TSTATE_NONE;2.951 :}2.952 LDC Rm, SGR {:2.953 COUNT_INST(I_LDC);2.954 check_priv();2.955 load_reg( REG_EAX, Rm );2.956 - store_spreg( REG_EAX, R_SGR );2.957 + MOVL_r32_rbpdisp( REG_EAX, R_SGR );2.958 sh4_x86.tstate = TSTATE_NONE;2.959 :}2.960 LDC Rm, SPC {:2.961 COUNT_INST(I_LDC);2.962 check_priv();2.963 load_reg( REG_EAX, Rm );2.964 - store_spreg( REG_EAX, R_SPC );2.965 + MOVL_r32_rbpdisp( REG_EAX, R_SPC );2.966 sh4_x86.tstate = TSTATE_NONE;2.967 :}2.968 LDC Rm, DBR {:2.969 COUNT_INST(I_LDC);2.970 check_priv();2.971 load_reg( REG_EAX, Rm );2.972 - store_spreg( REG_EAX, R_DBR );2.973 + MOVL_r32_rbpdisp( REG_EAX, R_DBR );2.974 sh4_x86.tstate = TSTATE_NONE;2.975 :}2.976 LDC Rm, Rn_BANK {:2.977 COUNT_INST(I_LDC);2.978 check_priv();2.979 load_reg( REG_EAX, Rm );2.980 - store_spreg( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );2.981 + MOVL_r32_rbpdisp( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );2.982 sh4_x86.tstate = TSTATE_NONE;2.983 :}2.984 LDC.L @Rm+, GBR {:2.985 @@ -2337,7 +2521,7 @@2.986 check_ralign32( REG_EAX );2.987 MEM_READ_LONG( REG_EAX, REG_EAX );2.988 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.989 - store_spreg( REG_EAX, R_GBR );2.990 + MOVL_r32_rbpdisp( REG_EAX, R_GBR );2.991 sh4_x86.tstate = TSTATE_NONE;2.992 :}2.993 LDC.L @Rm+, SR {:2.994 @@ -2350,7 +2534,7 @@2.995 check_ralign32( REG_EAX );2.996 MEM_READ_LONG( REG_EAX, REG_EAX );2.997 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.998 - call_func1( sh4_write_sr, REG_EAX );2.999 + CALL1_ptr_r32( sh4_write_sr, REG_EAX );2.1000 sh4_x86.fpuen_checked = FALSE;2.1001 sh4_x86.tstate = TSTATE_NONE;2.1002 return 2;2.1003 @@ -2363,7 +2547,7 @@2.1004 check_ralign32( REG_EAX );2.1005 MEM_READ_LONG( REG_EAX, REG_EAX );2.1006 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1007 - store_spreg( REG_EAX, R_VBR );2.1008 + MOVL_r32_rbpdisp( REG_EAX, R_VBR );2.1009 sh4_x86.tstate = TSTATE_NONE;2.1010 :}2.1011 LDC.L @Rm+, SSR {:2.1012 @@ -2373,7 +2557,7 @@2.1013 check_ralign32( REG_EAX );2.1014 MEM_READ_LONG( REG_EAX, REG_EAX );2.1015 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1016 - store_spreg( REG_EAX, R_SSR );2.1017 + MOVL_r32_rbpdisp( REG_EAX, R_SSR );2.1018 sh4_x86.tstate = TSTATE_NONE;2.1019 :}2.1020 LDC.L @Rm+, SGR {:2.1021 @@ -2383,7 +2567,7 @@2.1022 check_ralign32( REG_EAX );2.1023 MEM_READ_LONG( REG_EAX, REG_EAX );2.1024 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1025 - store_spreg( REG_EAX, R_SGR );2.1026 + MOVL_r32_rbpdisp( REG_EAX, R_SGR );2.1027 sh4_x86.tstate = TSTATE_NONE;2.1028 :}2.1029 LDC.L @Rm+, SPC {:2.1030 @@ -2393,7 +2577,7 @@2.1031 check_ralign32( REG_EAX );2.1032 MEM_READ_LONG( REG_EAX, REG_EAX );2.1033 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1034 - store_spreg( REG_EAX, R_SPC );2.1035 + MOVL_r32_rbpdisp( REG_EAX, R_SPC );2.1036 sh4_x86.tstate = TSTATE_NONE;2.1037 :}2.1038 LDC.L @Rm+, DBR {:2.1039 @@ -2403,7 +2587,7 @@2.1040 check_ralign32( REG_EAX );2.1041 MEM_READ_LONG( REG_EAX, REG_EAX );2.1042 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1043 - store_spreg( REG_EAX, R_DBR );2.1044 + MOVL_r32_rbpdisp( REG_EAX, R_DBR );2.1045 sh4_x86.tstate = TSTATE_NONE;2.1046 :}2.1047 LDC.L @Rm+, Rn_BANK {:2.1048 @@ -2413,14 +2597,14 @@2.1049 check_ralign32( REG_EAX );2.1050 MEM_READ_LONG( REG_EAX, REG_EAX );2.1051 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1052 - store_spreg( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );2.1053 + MOVL_r32_rbpdisp( REG_EAX, REG_OFFSET(r_bank[Rn_BANK]) );2.1054 sh4_x86.tstate = TSTATE_NONE;2.1055 :}2.1056 LDS Rm, FPSCR {:2.1057 COUNT_INST(I_LDSFPSCR);2.1058 check_fpuen();2.1059 load_reg( REG_EAX, Rm );2.1060 - call_func1( sh4_write_fpscr, REG_EAX );2.1061 + CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );2.1062 sh4_x86.tstate = TSTATE_NONE;2.1063 return 2;2.1064 :}2.1065 @@ -2431,7 +2615,7 @@2.1066 check_ralign32( REG_EAX );2.1067 MEM_READ_LONG( REG_EAX, REG_EAX );2.1068 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1069 - call_func1( sh4_write_fpscr, REG_EAX );2.1070 + CALL1_ptr_r32( sh4_write_fpscr, REG_EAX );2.1071 sh4_x86.tstate = TSTATE_NONE;2.1072 return 2;2.1073 :}2.1074 @@ -2439,7 +2623,7 @@2.1075 COUNT_INST(I_LDS);2.1076 check_fpuen();2.1077 load_reg( REG_EAX, Rm );2.1078 - store_spreg( REG_EAX, R_FPUL );2.1079 + MOVL_r32_rbpdisp( REG_EAX, R_FPUL );2.1080 :}2.1081 LDS.L @Rm+, FPUL {:2.1082 COUNT_INST(I_LDSM);2.1083 @@ -2448,13 +2632,13 @@2.1084 check_ralign32( REG_EAX );2.1085 MEM_READ_LONG( REG_EAX, REG_EAX );2.1086 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1087 - store_spreg( REG_EAX, R_FPUL );2.1088 + MOVL_r32_rbpdisp( REG_EAX, R_FPUL );2.1089 sh4_x86.tstate = TSTATE_NONE;2.1090 :}2.1091 LDS Rm, MACH {:2.1092 COUNT_INST(I_LDS);2.1093 load_reg( REG_EAX, Rm );2.1094 - store_spreg( REG_EAX, R_MACH );2.1095 + MOVL_r32_rbpdisp( REG_EAX, R_MACH );2.1096 :}2.1097 LDS.L @Rm+, MACH {:2.1098 COUNT_INST(I_LDSM);2.1099 @@ -2462,13 +2646,13 @@2.1100 check_ralign32( REG_EAX );2.1101 MEM_READ_LONG( REG_EAX, REG_EAX );2.1102 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1103 - store_spreg( REG_EAX, R_MACH );2.1104 + MOVL_r32_rbpdisp( REG_EAX, R_MACH );2.1105 sh4_x86.tstate = TSTATE_NONE;2.1106 :}2.1107 LDS Rm, MACL {:2.1108 COUNT_INST(I_LDS);2.1109 load_reg( REG_EAX, Rm );2.1110 - store_spreg( REG_EAX, R_MACL );2.1111 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.1112 :}2.1113 LDS.L @Rm+, MACL {:2.1114 COUNT_INST(I_LDSM);2.1115 @@ -2476,13 +2660,13 @@2.1116 check_ralign32( REG_EAX );2.1117 MEM_READ_LONG( REG_EAX, REG_EAX );2.1118 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1119 - store_spreg( REG_EAX, R_MACL );2.1120 + MOVL_r32_rbpdisp( REG_EAX, R_MACL );2.1121 sh4_x86.tstate = TSTATE_NONE;2.1122 :}2.1123 LDS Rm, PR {:2.1124 COUNT_INST(I_LDS);2.1125 load_reg( REG_EAX, Rm );2.1126 - store_spreg( REG_EAX, R_PR );2.1127 + MOVL_r32_rbpdisp( REG_EAX, R_PR );2.1128 :}2.1129 LDS.L @Rm+, PR {:2.1130 COUNT_INST(I_LDSM);2.1131 @@ -2490,12 +2674,12 @@2.1132 check_ralign32( REG_EAX );2.1133 MEM_READ_LONG( REG_EAX, REG_EAX );2.1134 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );2.1135 - store_spreg( REG_EAX, R_PR );2.1136 + MOVL_r32_rbpdisp( REG_EAX, R_PR );2.1137 sh4_x86.tstate = TSTATE_NONE;2.1138 :}2.1139 LDTLB {:2.1140 COUNT_INST(I_LDTLB);2.1141 - call_func0( MMU_ldtlb );2.1142 + CALL_ptr( MMU_ldtlb );2.1143 sh4_x86.tstate = TSTATE_NONE;2.1144 :}2.1145 OCBI @Rn {:2.1146 @@ -2516,7 +2700,7 @@2.1147 SLEEP {:2.1148 COUNT_INST(I_SLEEP);2.1149 check_priv();2.1150 - call_func0( sh4_sleep );2.1151 + CALL_ptr( sh4_sleep );2.1152 sh4_x86.tstate = TSTATE_NONE;2.1153 sh4_x86.in_delay_slot = DELAY_NONE;2.1154 return 2;2.1155 @@ -2524,61 +2708,61 @@2.1156 STC SR, Rn {:2.1157 COUNT_INST(I_STCSR);2.1158 check_priv();2.1159 - call_func0(sh4_read_sr);2.1160 + CALL_ptr(sh4_read_sr);2.1161 store_reg( REG_EAX, Rn );2.1162 sh4_x86.tstate = TSTATE_NONE;2.1163 :}2.1164 STC GBR, Rn {:2.1165 COUNT_INST(I_STC);2.1166 - load_spreg( REG_EAX, R_GBR );2.1167 + MOVL_rbpdisp_r32( R_GBR, REG_EAX );2.1168 store_reg( REG_EAX, Rn );2.1169 :}2.1170 STC VBR, Rn {:2.1171 COUNT_INST(I_STC);2.1172 check_priv();2.1173 - load_spreg( REG_EAX, R_VBR );2.1174 + MOVL_rbpdisp_r32( R_VBR, REG_EAX );2.1175 store_reg( REG_EAX, Rn );2.1176 sh4_x86.tstate = TSTATE_NONE;2.1177 :}2.1178 STC SSR, Rn {:2.1179 COUNT_INST(I_STC);2.1180 check_priv();2.1181 - load_spreg( REG_EAX, R_SSR );2.1182 + MOVL_rbpdisp_r32( R_SSR, REG_EAX );2.1183 store_reg( REG_EAX, Rn );2.1184 sh4_x86.tstate = TSTATE_NONE;2.1185 :}2.1186 STC SPC, Rn {:2.1187 COUNT_INST(I_STC);2.1188 check_priv();2.1189 - load_spreg( REG_EAX, R_SPC );2.1190 + MOVL_rbpdisp_r32( R_SPC, REG_EAX );2.1191 store_reg( REG_EAX, Rn );2.1192 sh4_x86.tstate = TSTATE_NONE;2.1193 :}2.1194 STC SGR, Rn {:2.1195 COUNT_INST(I_STC);2.1196 check_priv();2.1197 - load_spreg( REG_EAX, R_SGR );2.1198 + MOVL_rbpdisp_r32( R_SGR, REG_EAX );2.1199 store_reg( REG_EAX, Rn );2.1200 sh4_x86.tstate = TSTATE_NONE;2.1201 :}2.1202 STC DBR, Rn {:2.1203 COUNT_INST(I_STC);2.1204 check_priv();2.1205 - load_spreg( REG_EAX, R_DBR );2.1206 + MOVL_rbpdisp_r32( R_DBR, REG_EAX );2.1207 store_reg( REG_EAX, Rn );2.1208 sh4_x86.tstate = TSTATE_NONE;2.1209 :}2.1210 STC Rm_BANK, Rn {:2.1211 COUNT_INST(I_STC);2.1212 check_priv();2.1213 - load_spreg( REG_EAX, REG_OFFSET(r_bank[Rm_BANK]) );2.1214 + MOVL_rbpdisp_r32( REG_OFFSET(r_bank[Rm_BANK]), REG_EAX );2.1215 store_reg( REG_EAX, Rn );2.1216 sh4_x86.tstate = TSTATE_NONE;2.1217 :}2.1218 STC.L SR, @-Rn {:2.1219 COUNT_INST(I_STCSRM);2.1220 check_priv();2.1221 - call_func0( sh4_read_sr );2.1222 + CALL_ptr( sh4_read_sr );2.1223 MOVL_r32_r32( REG_EAX, REG_EDX );2.1224 load_reg( REG_EAX, Rn );2.1225 check_walign32( REG_EAX );2.1226 @@ -2593,7 +2777,7 @@2.1227 load_reg( REG_EAX, Rn );2.1228 check_walign32( REG_EAX );2.1229 ADDL_imms_r32( -4, REG_EAX );2.1230 - load_spreg( REG_EDX, R_VBR );2.1231 + MOVL_rbpdisp_r32( R_VBR, REG_EDX );2.1232 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1233 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1234 sh4_x86.tstate = TSTATE_NONE;2.1235 @@ -2604,7 +2788,7 @@2.1236 load_reg( REG_EAX, Rn );2.1237 check_walign32( REG_EAX );2.1238 ADDL_imms_r32( -4, REG_EAX );2.1239 - load_spreg( REG_EDX, R_SSR );2.1240 + MOVL_rbpdisp_r32( R_SSR, REG_EDX );2.1241 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1242 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1243 sh4_x86.tstate = TSTATE_NONE;2.1244 @@ -2615,7 +2799,7 @@2.1245 load_reg( REG_EAX, Rn );2.1246 check_walign32( REG_EAX );2.1247 ADDL_imms_r32( -4, REG_EAX );2.1248 - load_spreg( REG_EDX, R_SPC );2.1249 + MOVL_rbpdisp_r32( R_SPC, REG_EDX );2.1250 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1251 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1252 sh4_x86.tstate = TSTATE_NONE;2.1253 @@ -2626,7 +2810,7 @@2.1254 load_reg( REG_EAX, Rn );2.1255 check_walign32( REG_EAX );2.1256 ADDL_imms_r32( -4, REG_EAX );2.1257 - load_spreg( REG_EDX, R_SGR );2.1258 + MOVL_rbpdisp_r32( R_SGR, REG_EDX );2.1259 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1260 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1261 sh4_x86.tstate = TSTATE_NONE;2.1262 @@ -2637,7 +2821,7 @@2.1263 load_reg( REG_EAX, Rn );2.1264 check_walign32( REG_EAX );2.1265 ADDL_imms_r32( -4, REG_EAX );2.1266 - load_spreg( REG_EDX, R_DBR );2.1267 + MOVL_rbpdisp_r32( R_DBR, REG_EDX );2.1268 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1269 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1270 sh4_x86.tstate = TSTATE_NONE;2.1271 @@ -2648,7 +2832,7 @@2.1272 load_reg( REG_EAX, Rn );2.1273 check_walign32( REG_EAX );2.1274 ADDL_imms_r32( -4, REG_EAX );2.1275 - load_spreg( REG_EDX, REG_OFFSET(r_bank[Rm_BANK]) );2.1276 + MOVL_rbpdisp_r32( REG_OFFSET(r_bank[Rm_BANK]), REG_EDX );2.1277 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1278 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1279 sh4_x86.tstate = TSTATE_NONE;2.1280 @@ -2658,7 +2842,7 @@2.1281 load_reg( REG_EAX, Rn );2.1282 check_walign32( REG_EAX );2.1283 ADDL_imms_r32( -4, REG_EAX );2.1284 - load_spreg( REG_EDX, R_GBR );2.1285 + MOVL_rbpdisp_r32( R_GBR, REG_EDX );2.1286 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1287 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1288 sh4_x86.tstate = TSTATE_NONE;2.1289 @@ -2666,7 +2850,7 @@2.1290 STS FPSCR, Rn {:2.1291 COUNT_INST(I_STSFPSCR);2.1292 check_fpuen();2.1293 - load_spreg( REG_EAX, R_FPSCR );2.1294 + MOVL_rbpdisp_r32( R_FPSCR, REG_EAX );2.1295 store_reg( REG_EAX, Rn );2.1296 :}2.1297 STS.L FPSCR, @-Rn {:2.1298 @@ -2675,7 +2859,7 @@2.1299 load_reg( REG_EAX, Rn );2.1300 check_walign32( REG_EAX );2.1301 ADDL_imms_r32( -4, REG_EAX );2.1302 - load_spreg( REG_EDX, R_FPSCR );2.1303 + MOVL_rbpdisp_r32( R_FPSCR, REG_EDX );2.1304 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1305 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1306 sh4_x86.tstate = TSTATE_NONE;2.1307 @@ -2683,7 +2867,7 @@2.1308 STS FPUL, Rn {:2.1309 COUNT_INST(I_STS);2.1310 check_fpuen();2.1311 - load_spreg( REG_EAX, R_FPUL );2.1312 + MOVL_rbpdisp_r32( R_FPUL, REG_EAX );2.1313 store_reg( REG_EAX, Rn );2.1314 :}2.1315 STS.L FPUL, @-Rn {:2.1316 @@ -2692,14 +2876,14 @@2.1317 load_reg( REG_EAX, Rn );2.1318 check_walign32( REG_EAX );2.1319 ADDL_imms_r32( -4, REG_EAX );2.1320 - load_spreg( REG_EDX, R_FPUL );2.1321 + MOVL_rbpdisp_r32( R_FPUL, REG_EDX );2.1322 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1323 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1324 sh4_x86.tstate = TSTATE_NONE;2.1325 :}2.1326 STS MACH, Rn {:2.1327 COUNT_INST(I_STS);2.1328 - load_spreg( REG_EAX, R_MACH );2.1329 + MOVL_rbpdisp_r32( R_MACH, REG_EAX );2.1330 store_reg( REG_EAX, Rn );2.1331 :}2.1332 STS.L MACH, @-Rn {:2.1333 @@ -2707,14 +2891,14 @@2.1334 load_reg( REG_EAX, Rn );2.1335 check_walign32( REG_EAX );2.1336 ADDL_imms_r32( -4, REG_EAX );2.1337 - load_spreg( REG_EDX, R_MACH );2.1338 + MOVL_rbpdisp_r32( R_MACH, REG_EDX );2.1339 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1340 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1341 sh4_x86.tstate = TSTATE_NONE;2.1342 :}2.1343 STS MACL, Rn {:2.1344 COUNT_INST(I_STS);2.1345 - load_spreg( REG_EAX, R_MACL );2.1346 + MOVL_rbpdisp_r32( R_MACL, REG_EAX );2.1347 store_reg( REG_EAX, Rn );2.1348 :}2.1349 STS.L MACL, @-Rn {:2.1350 @@ -2722,14 +2906,14 @@2.1351 load_reg( REG_EAX, Rn );2.1352 check_walign32( REG_EAX );2.1353 ADDL_imms_r32( -4, REG_EAX );2.1354 - load_spreg( REG_EDX, R_MACL );2.1355 + MOVL_rbpdisp_r32( R_MACL, REG_EDX );2.1356 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1357 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1358 sh4_x86.tstate = TSTATE_NONE;2.1359 :}2.1360 STS PR, Rn {:2.1361 COUNT_INST(I_STS);2.1362 - load_spreg( REG_EAX, R_PR );2.1363 + MOVL_rbpdisp_r32( R_PR, REG_EAX );2.1364 store_reg( REG_EAX, Rn );2.1365 :}2.1366 STS.L PR, @-Rn {:2.1367 @@ -2737,7 +2921,7 @@2.1368 load_reg( REG_EAX, Rn );2.1369 check_walign32( REG_EAX );2.1370 ADDL_imms_r32( -4, REG_EAX );2.1371 - load_spreg( REG_EDX, R_PR );2.1372 + MOVL_rbpdisp_r32( R_PR, REG_EDX );2.1373 MEM_WRITE_LONG( REG_EAX, REG_EDX );2.1374 ADDL_imms_rbpdisp( -4, REG_OFFSET(r[Rn]) );2.1375 sh4_x86.tstate = TSTATE_NONE;2.1376 @@ -2751,3 +2935,67 @@2.1377 sh4_x86.in_delay_slot = DELAY_NONE;2.1378 return 0;2.1379 }2.1380 +2.1381 +2.1382 +/**2.1383 + * The unwind methods only work if we compiled with DWARF2 frame information2.1384 + * (ie -fexceptions), otherwise we have to use the direct frame scan.2.1385 + */2.1386 +#ifdef HAVE_EXCEPTIONS2.1387 +#include <unwind.h>2.1388 +2.1389 +struct UnwindInfo {2.1390 + uintptr_t block_start;2.1391 + uintptr_t block_end;2.1392 + void *pc;2.1393 +};2.1394 +2.1395 +static _Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )2.1396 +{2.1397 + struct UnwindInfo *info = arg;2.1398 + void *pc = (void *)_Unwind_GetIP(context);2.1399 + if( ((uintptr_t)pc) >= info->block_start && ((uintptr_t)pc) < info->block_end ) {2.1400 + info->pc = pc;2.1401 + return _URC_NORMAL_STOP;2.1402 + }2.1403 + return _URC_NO_REASON;2.1404 +}2.1405 +2.1406 +void *xlat_get_native_pc( void *code, uint32_t code_size )2.1407 +{2.1408 + struct _Unwind_Exception exc;2.1409 + struct UnwindInfo info;2.1410 +2.1411 + info.pc = NULL;2.1412 + info.block_start = (uintptr_t)code;2.1413 + info.block_end = info.block_start + code_size;2.1414 + void *result = NULL;2.1415 + _Unwind_Backtrace( xlat_check_frame, &info );2.1416 + return info.pc;2.1417 +}2.1418 +#else2.1419 +/* Assume this is an ia32 build - amd64 should always have dwarf information */2.1420 +void *xlat_get_native_pc( void *code, uint32_t code_size )2.1421 +{2.1422 + void *result = NULL;2.1423 + asm(2.1424 + "mov %%ebp, %%eax\n\t"2.1425 + "mov $0x8, %%ecx\n\t"2.1426 + "mov %1, %%edx\n"2.1427 + "frame_loop: test %%eax, %%eax\n\t"2.1428 + "je frame_not_found\n\t"2.1429 + "cmp (%%eax), %%edx\n\t"2.1430 + "je frame_found\n\t"2.1431 + "sub $0x1, %%ecx\n\t"2.1432 + "je frame_not_found\n\t"2.1433 + "movl (%%eax), %%eax\n\t"2.1434 + "jmp frame_loop\n"2.1435 + "frame_found: movl 0x4(%%eax), %0\n"2.1436 + "frame_not_found:"2.1437 + : "=r" (result)2.1438 + : "r" (((uint8_t *)&sh4r) + 128 )2.1439 + : "eax", "ecx", "edx" );2.1440 + return result;2.1441 +}2.1442 +#endif2.1443 +
3.1 --- a/src/xlat/x86/amd64abi.h Thu Mar 05 21:37:44 2009 +00003.2 +++ b/src/xlat/x86/amd64abi.h Thu Mar 05 21:42:35 2009 +00003.3 @@ -17,97 +17,93 @@3.4 * GNU General Public License for more details.3.5 */3.7 -#ifndef lxdream_ia64abi_H3.8 -#define lxdream_ia64abi_H 13.9 -3.10 -#include <unwind.h>3.11 -3.12 -#define load_ptr( reg, ptr ) load_imm64( reg, (uint64_t)ptr );3.13 +#define REG_ARG1 REG_RDI3.14 +#define REG_ARG2 REG_RSI3.15 +#define REG_ARG3 REG_RDX3.16 +#define REG_RESULT1 REG_RAX3.17 +#define MAX_REG_ARG 3 /* There's more, but we don't use more than 3 here anyway */3.19 static inline void decode_address( int addr_reg )3.20 {3.21 uintptr_t base = (sh4r.xlat_sh4_mode&SR_MD) ? (uintptr_t)sh4_address_space : (uintptr_t)sh4_user_address_space;3.22 - MOVL_r32_r32( addr_reg, REG_RCX );3.23 - SHRL_imm_r32( 12, REG_RCX );3.24 + MOVL_r32_r32( addr_reg, REG_ECX );3.25 + SHRL_imm_r32( 12, REG_ECX );3.26 MOVP_immptr_rptr( base, REG_RDI );3.27 - MOVP_sib_rptr(3, REG_RCX, REG_RDI, 0, REG_RCX);3.28 + MOVP_sib_rptr( 3, REG_RCX, REG_RDI, 0, REG_RCX );3.29 }3.31 /**3.32 - * Note: clobbers EAX to make the indirect call - this isn't usually3.33 - * a problem since the callee will usually clobber it anyway.3.34 + * Note: clobbers ECX to make the indirect call - this isn't usually3.35 + * a problem since the callee will generally clobber it anyway.3.36 * Size: 12 bytes3.37 */3.38 -#define CALL_FUNC0_SIZE 123.39 -static inline void call_func0( void *ptr )3.40 +static inline void CALL_ptr( void *ptr )3.41 {3.42 - MOVQ_imm64_r64((uint64_t)ptr, REG_RAX);3.43 - CALL_r32(REG_RAX);3.44 + MOVP_immptr_rptr( (uintptr_t)ptr, REG_ECX );3.45 + CALL_r32(REG_ECX);3.46 }3.48 -static inline void call_func1( void *ptr, int arg1 )3.49 +static inline void CALL1_ptr_r32( void *ptr, int arg1 )3.50 {3.51 - MOVQ_r64_r64(arg1, REG_RDI);3.52 - call_func0(ptr);3.53 + if( arg1 != REG_ARG1 ) {3.54 + MOVQ_r64_r64( arg1, REG_ARG1 );3.55 + }3.56 + CALL_ptr(ptr);3.57 }3.59 -static inline void call_func1_exc( void *ptr, int arg1, int pc )3.60 +static inline void CALL1_r32disp_r32( int preg, uint32_t disp, int arg1 )3.61 {3.62 - MOVQ_r64_r64(arg1, REG_RDI);3.63 - MOVP_immptr_rptr(0, REG_RSI);3.64 - sh4_x86_add_backpatch( xlat_output, pc, -2 );3.65 - call_func0(ptr);3.66 + if( arg1 != REG_ARG1 ) {3.67 + MOVQ_r64_r64( arg1, REG_ARG1 );3.68 + }3.69 + CALL_r32disp(preg, disp);3.70 }3.72 -static inline void call_func1_r32disp8( int preg, uint32_t disp8, int arg1 )3.73 +static inline void CALL2_ptr_r32_r32( void *ptr, int arg1, int arg2 )3.74 {3.75 - MOVQ_r64_r64(arg1, REG_RDI);3.76 - CALL_r32disp(preg, disp8);3.77 + if( arg2 != REG_ARG2 ) {3.78 + MOVQ_r64_r64( arg2, REG_ARG2 );3.79 + }3.80 + if( arg1 != REG_ARG1 ) {3.81 + MOVQ_r64_r64( arg1, REG_ARG1 );3.82 + }3.83 + CALL_ptr(ptr);3.84 }3.86 -static inline void call_func1_r32disp8_exc( int preg, uint32_t disp8, int arg1, int pc )3.87 +static inline void CALL2_r32disp_r32_r32( int preg, uint32_t disp, int arg1, int arg2 )3.88 {3.89 - MOVQ_r64_r64(arg1, REG_RDI);3.90 - MOVP_immptr_rptr(0, REG_RSI);3.91 - sh4_x86_add_backpatch( xlat_output, pc, -2 );3.92 - CALL_r32disp(preg, disp8);3.93 + if( arg2 != REG_ARG2 ) {3.94 + MOVQ_r64_r64( arg2, REG_ARG2 );3.95 + }3.96 + if( arg1 != REG_ARG1 ) {3.97 + MOVQ_r64_r64( arg1, REG_ARG1 );3.98 + }3.99 + CALL_r32disp(preg, disp);3.100 }3.102 -static inline void call_func2( void *ptr, int arg1, int arg2 )3.103 +static inline void CALL3_r32disp_r32_r32_r32( int preg, uint32_t disp, int arg1, int arg2, int arg3 )3.104 {3.105 - MOVQ_r64_r64(arg1, REG_RDI);3.106 - MOVQ_r64_r64(arg2, REG_RSI);3.107 - call_func0(ptr);3.108 + if( arg3 != REG_ARG3 ) {3.109 + MOVQ_r64_r64( arg3, REG_ARG3 );3.110 + }3.111 + if( arg2 != REG_ARG2 ) {3.112 + MOVQ_r64_r64( arg2, REG_ARG2 );3.113 + }3.114 + if( arg1 != REG_ARG1 ) {3.115 + MOVQ_r64_r64( arg1, REG_ARG1 );3.116 + }3.117 + CALL_r32disp(preg, disp);3.118 }3.120 -static inline void call_func2_r32disp8( int preg, uint32_t disp8, int arg1, int arg2 )3.121 -{3.122 - MOVQ_r64_r64(arg1, REG_RDI);3.123 - MOVQ_r64_r64(arg2, REG_RSI);3.124 - CALL_r32disp(preg, disp8);3.125 -}3.126 -3.127 -static inline void call_func2_r32disp8_exc( int preg, uint32_t disp8, int arg1, int arg2, int pc )3.128 -{3.129 - MOVQ_r64_r64(arg1, REG_RDI);3.130 - MOVQ_r64_r64(arg2, REG_RSI);3.131 - MOVP_immptr_rptr(0, REG_RDX);3.132 - sh4_x86_add_backpatch( xlat_output, pc, -2 );3.133 - CALL_r32disp(preg, disp8);3.134 -}3.135 -3.136 -3.137 -3.138 /**3.139 * Emit the 'start of block' assembly. Sets up the stack frame and save3.140 * SI/DI as required3.141 */3.142 -void enter_block( )3.143 +static inline void enter_block( )3.144 {3.145 PUSH_r32(REG_RBP);3.146 - load_ptr( REG_RBP, ((uint8_t *)&sh4r) + 128 );3.147 - // Minimum aligned allocation is 16 bytes3.148 - SUBQ_imms_r64( 16, REG_RSP );3.149 + MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );3.150 + SUBQ_imms_r64( 16, REG_RSP );3.151 }3.153 static inline void exit_block( )3.154 @@ -116,203 +112,3 @@3.155 POP_r32(REG_RBP);3.156 RET();3.157 }3.158 -3.159 -/**3.160 - * Exit the block with sh4r.pc already written3.161 - */3.162 -void exit_block_pcset( sh4addr_t pc )3.163 -{3.164 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 53.165 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 63.166 - load_spreg( REG_RAX, R_PC );3.167 - if( sh4_x86.tlb_on ) {3.168 - call_func1(xlat_get_code_by_vma,REG_RAX);3.169 - } else {3.170 - call_func1(xlat_get_code,REG_RAX);3.171 - }3.172 - exit_block();3.173 -}3.174 -3.175 -/**3.176 - * Exit the block with sh4r.new_pc written with the target address3.177 - */3.178 -void exit_block_newpcset( sh4addr_t pc )3.179 -{3.180 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 53.181 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 63.182 - load_spreg( REG_RAX, R_NEW_PC );3.183 - store_spreg( REG_RAX, R_PC );3.184 - if( sh4_x86.tlb_on ) {3.185 - call_func1(xlat_get_code_by_vma,REG_RAX);3.186 - } else {3.187 - call_func1(xlat_get_code,REG_RAX);3.188 - }3.189 - exit_block();3.190 -}3.191 -3.192 -#define EXIT_BLOCK_SIZE(pc) (25 + (IS_IN_ICACHE(pc)?10:CALL_FUNC1_SIZE))3.193 -/**3.194 - * Exit the block to an absolute PC3.195 - */3.196 -void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )3.197 -{3.198 - load_imm32( REG_RCX, pc ); // 53.199 - store_spreg( REG_RCX, REG_OFFSET(pc) ); // 33.200 - if( IS_IN_ICACHE(pc) ) {3.201 - MOVP_moffptr_rax( xlat_get_lut_entry(pc) );3.202 - ANDQ_imms_r64( 0xFFFFFFFC, REG_RAX ); // 43.203 - } else if( sh4_x86.tlb_on ) {3.204 - call_func1(xlat_get_code_by_vma, REG_RCX);3.205 - } else {3.206 - call_func1(xlat_get_code,REG_RCX);3.207 - }3.208 - load_imm32( REG_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 53.209 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 63.210 - exit_block();3.211 -}3.212 -3.213 -3.214 -#define EXIT_BLOCK_REL_SIZE(pc) (28 + (IS_IN_ICACHE(pc)?10:CALL_FUNC1_SIZE))3.215 -3.216 -/**3.217 - * Exit the block to a relative PC3.218 - */3.219 -void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )3.220 -{3.221 - load_imm32( REG_ECX, pc - sh4_x86.block_start_pc ); // 53.222 - ADDL_rbpdisp_r32( R_PC, REG_ECX );3.223 - store_spreg( REG_ECX, REG_OFFSET(pc) ); // 33.224 - if( IS_IN_ICACHE(pc) ) {3.225 - MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 53.226 - ANDQ_imms_r64( 0xFFFFFFFC, REG_RAX ); // 43.227 - } else if( sh4_x86.tlb_on ) {3.228 - call_func1(xlat_get_code_by_vma,REG_RCX);3.229 - } else {3.230 - call_func1(xlat_get_code,REG_RCX);3.231 - }3.232 - load_imm32( REG_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 53.233 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 63.234 - exit_block();3.235 -}3.236 -3.237 -/**3.238 - * Exit unconditionally with a general exception3.239 - */3.240 -void exit_block_exc( int code, sh4addr_t pc )3.241 -{3.242 - load_imm32( REG_ECX, pc - sh4_x86.block_start_pc ); // 53.243 - ADDL_r32_rbpdisp( REG_ECX, R_PC );3.244 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 53.245 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 63.246 - load_imm32( REG_RAX, code );3.247 - call_func1( sh4_raise_exception, REG_RAX );3.248 -3.249 - load_spreg( REG_RAX, R_PC );3.250 - if( sh4_x86.tlb_on ) {3.251 - call_func1(xlat_get_code_by_vma,REG_RAX);3.252 - } else {3.253 - call_func1(xlat_get_code,REG_RAX);3.254 - }3.255 -3.256 - exit_block();3.257 -}3.258 -3.259 -3.260 -/**3.261 - * Write the block trailer (exception handling block)3.262 - */3.263 -void sh4_translate_end_block( sh4addr_t pc ) {3.264 - if( sh4_x86.branch_taken == FALSE ) {3.265 - // Didn't exit unconditionally already, so write the termination here3.266 - exit_block_rel( pc, pc );3.267 - }3.268 - if( sh4_x86.backpatch_posn != 0 ) {3.269 - unsigned int i;3.270 - // Raise exception3.271 - uint8_t *end_ptr = xlat_output;3.272 - MOVL_r32_r32( REG_RDX, REG_RCX );3.273 - ADDL_r32_r32( REG_RDX, REG_RCX );3.274 - ADDL_r32_rbpdisp( REG_RCX, R_PC );3.275 - MOVL_moffptr_eax( &sh4_cpu_period );3.276 - MULL_r32( REG_RDX );3.277 - ADDL_r32_rbpdisp( REG_RAX, REG_OFFSET(slice_cycle) );3.278 -3.279 - call_func0( sh4_raise_exception );3.280 - load_spreg( REG_RAX, R_PC );3.281 - if( sh4_x86.tlb_on ) {3.282 - call_func1(xlat_get_code_by_vma,REG_RAX);3.283 - } else {3.284 - call_func1(xlat_get_code,REG_RAX);3.285 - }3.286 - exit_block();3.287 -3.288 - // Exception already raised - just cleanup3.289 - uint8_t *preexc_ptr = xlat_output;3.290 - MOVL_r32_r32( REG_EDX, REG_ECX );3.291 - ADDL_r32_r32( REG_EDX, REG_ECX );3.292 - ADDL_r32_rbpdisp( REG_ECX, R_SPC );3.293 - MOVL_moffptr_eax( &sh4_cpu_period );3.294 - MULL_r32( REG_EDX );3.295 - ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );3.296 - load_spreg( REG_RDI, R_PC );3.297 - if( sh4_x86.tlb_on ) {3.298 - call_func0(xlat_get_code_by_vma);3.299 - } else {3.300 - call_func0(xlat_get_code);3.301 - }3.302 - exit_block();3.303 -3.304 - for( i=0; i< sh4_x86.backpatch_posn; i++ ) {3.305 - uint32_t *fixup_addr = (uint32_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset];3.306 - if( sh4_x86.backpatch_list[i].exc_code < 0 ) {3.307 - if( sh4_x86.backpatch_list[i].exc_code == -2 ) {3.308 - *((uintptr_t *)fixup_addr) = (uintptr_t)xlat_output;3.309 - } else {3.310 - *fixup_addr = xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;3.311 - }3.312 - load_imm32( REG_RDX, sh4_x86.backpatch_list[i].fixup_icount );3.313 - int rel = preexc_ptr - xlat_output;3.314 - JMP_prerel(rel);3.315 - } else {3.316 - *fixup_addr = xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;3.317 - load_imm32( REG_RDI, sh4_x86.backpatch_list[i].exc_code );3.318 - load_imm32( REG_RDX, sh4_x86.backpatch_list[i].fixup_icount );3.319 - int rel = end_ptr - xlat_output;3.320 - JMP_prerel(rel);3.321 - }3.322 - }3.323 - }3.324 -}3.325 -3.326 -struct UnwindInfo {3.327 - uintptr_t block_start;3.328 - uintptr_t block_end;3.329 - void *pc;3.330 -};3.331 -3.332 -_Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )3.333 -{3.334 - struct UnwindInfo *info = arg;3.335 - void *pc = (void *)_Unwind_GetIP(context);3.336 - if( ((uintptr_t)pc) >= info->block_start && ((uintptr_t)pc) < info->block_end ) {3.337 - info->pc = pc;3.338 - return _URC_NORMAL_STOP;3.339 - }3.340 -3.341 - return _URC_NO_REASON;3.342 -}3.343 -3.344 -void *xlat_get_native_pc( void *code, uint32_t code_size )3.345 -{3.346 - struct _Unwind_Exception exc;3.347 - struct UnwindInfo info;3.348 -3.349 - info.pc = NULL;3.350 - info.block_start = (uintptr_t)code;3.351 - info.block_end = info.block_start + code_size;3.352 - void *result = NULL;3.353 - _Unwind_Backtrace( xlat_check_frame, &info );3.354 - return info.pc;3.355 -}3.356 -3.357 -#endif /* !lxdream_ia64abi_H */
4.1 --- a/src/xlat/x86/ia32abi.h Thu Mar 05 21:37:44 2009 +00004.2 +++ b/src/xlat/x86/ia32abi.h Thu Mar 05 21:42:35 2009 +00004.3 @@ -5,6 +5,8 @@4.4 * (eg prologue, epilogue, and calling conventions). Stack frame is4.5 * aligned on 16-byte boundaries for the benefit of OS X (which4.6 * requires it).4.7 + *4.8 + * Note: These should only be included from x86op.h4.9 *4.10 * Copyright (c) 2007 Nathan Keynes.4.11 *4.12 @@ -19,156 +21,113 @@4.13 * GNU General Public License for more details.4.14 */4.16 -#ifndef lxdream_ia32mac_H4.17 -#define lxdream_ia32mac_H 14.18 -4.19 -#define load_ptr( reg, ptr ) load_imm32( reg, (uint32_t)ptr );4.20 +#define REG_ARG1 REG_EAX4.21 +#define REG_ARG2 REG_EDX4.22 +#define REG_RESULT1 REG_EAX4.23 +#define MAX_REG_ARG 24.25 static inline void decode_address( int addr_reg )4.26 {4.27 uintptr_t base = (sh4r.xlat_sh4_mode&SR_MD) ? (uintptr_t)sh4_address_space : (uintptr_t)sh4_user_address_space;4.28 - MOVL_r32_r32( addr_reg, REG_ECX );4.29 + MOVL_r32_r32( addr_reg, REG_ECX );4.30 SHRL_imm_r32( 12, REG_ECX );4.31 MOVP_sib_rptr( 2, REG_ECX, -1, base, REG_ECX );4.32 }4.34 /**4.35 - * Note: clobbers EAX to make the indirect call - this isn't usually4.36 - * a problem since the callee will usually clobber it anyway.4.37 + * Note: clobbers ECX to make the indirect call - this isn't usually4.38 + * a problem since the callee will generally clobber it anyway.4.39 */4.40 -static inline void call_func0( void *ptr )4.41 +static inline void CALL_ptr( void *ptr )4.42 {4.43 - load_imm32(REG_ECX, (uint32_t)ptr);4.44 + MOVP_immptr_rptr( (uintptr_t)ptr, REG_ECX );4.45 CALL_r32(REG_ECX);4.46 }4.48 #ifdef HAVE_FASTCALL4.49 -static inline void call_func1( void *ptr, int arg1 )4.50 +static inline void CALL1_ptr_r32( void *ptr, int arg1 )4.51 {4.52 - if( arg1 != REG_EAX ) {4.53 - MOVL_r32_r32( arg1, REG_EAX );4.54 + if( arg1 != REG_ARG1 ) {4.55 + MOVL_r32_r32( arg1, REG_ARG1 );4.56 }4.57 - MOVP_immptr_rptr((uintptr_t)ptr, REG_ECX);4.58 - CALL_r32(REG_ECX);4.59 + CALL_ptr(ptr);4.60 }4.62 -static inline void call_func1_r32( int addr_reg, int arg1 )4.63 +static inline void CALL1_r32disp_r32( int preg, uint32_t disp, int arg1 )4.64 {4.65 - if( arg1 != REG_EAX ) {4.66 - MOVL_r32_r32( arg1, REG_EAX );4.67 + if( arg1 != REG_ARG1 ) {4.68 + MOVL_r32_r32( arg1, REG_ARG1 );4.69 }4.70 - CALL_r32(addr_reg);4.71 + CALL_r32disp(preg, disp);4.72 }4.74 -static inline void call_func1_r32disp8( int preg, uint32_t disp8, int arg1 )4.75 +static inline void CALL2_ptr_r32_r32( void *ptr, int arg1, int arg2 )4.76 {4.77 - if( arg1 != REG_EAX ) {4.78 - MOVL_r32_r32( arg1, REG_EAX );4.79 + if( arg2 != REG_ARG2 ) {4.80 + MOVL_r32_r32( arg2, REG_ARG2 );4.81 }4.82 - CALL_r32disp(preg, disp8);4.83 + if( arg1 != REG_ARG1 ) {4.84 + MOVL_r32_r32( arg1, REG_ARG1 );4.85 + }4.86 + CALL_ptr(ptr);4.87 }4.89 -static inline void call_func1_r32disp8_exc( int preg, uint32_t disp8, int arg1, int pc )4.90 +static inline void CALL2_r32disp_r32_r32( int preg, uint32_t disp, int arg1, int arg2 )4.91 {4.92 - if( arg1 != REG_EAX ) {4.93 - MOVL_r32_r32( arg1, REG_EAX );4.94 + if( arg2 != REG_ARG2 ) {4.95 + MOVL_r32_r32( arg2, REG_ARG2 );4.96 }4.97 - MOVP_immptr_rptr(0,REG_EDX);4.98 - sh4_x86_add_backpatch(xlat_output, pc, -2);4.99 - CALL_r32disp(preg, disp8);4.100 + if( arg1 != REG_ARG1 ) {4.101 + MOVL_r32_r32( arg1, REG_ARG1 );4.102 + }4.103 + CALL_r32disp(preg, disp);4.104 }4.106 -static inline void call_func2( void *ptr, int arg1, int arg2 )4.107 -{4.108 - if( arg2 != REG_EDX ) {4.109 - MOVL_r32_r32( arg2, REG_EDX );4.110 - }4.111 - if( arg1 != REG_EAX ) {4.112 - MOVL_r32_r32( arg1, REG_EAX );4.113 - }4.114 - MOVP_immptr_rptr((uint32_t)ptr, REG_ECX);4.115 - CALL_r32(REG_ECX);4.116 -}4.117 -4.118 -static inline void call_func2_r32( int addr_reg, int arg1, int arg2 )4.119 -{4.120 - if( arg2 != REG_EDX ) {4.121 - MOVL_r32_r32( arg2, REG_EDX );4.122 - }4.123 - if( arg1 != REG_EAX ) {4.124 - MOVL_r32_r32( arg1, REG_EAX );4.125 - }4.126 - CALL_r32(addr_reg);4.127 -}4.128 -4.129 -static inline void call_func2_r32disp8( int preg, uint32_t disp8, int arg1, int arg2 )4.130 -{4.131 - if( arg2 != REG_EDX ) {4.132 - MOVL_r32_r32( arg2, REG_EDX );4.133 - }4.134 - if( arg1 != REG_EAX ) {4.135 - MOVL_r32_r32( arg1, REG_EAX );4.136 - }4.137 - CALL_r32disp(preg, disp8);4.138 -}4.139 -4.140 -static inline void call_func2_r32disp8_exc( int preg, uint32_t disp8, int arg1, int arg2, int pc )4.141 -{4.142 - if( arg2 != REG_EDX ) {4.143 - MOVL_r32_r32( arg2, REG_EDX );4.144 - }4.145 - if( arg1 != REG_EAX ) {4.146 - MOVL_r32_r32( arg1, REG_EAX );4.147 - }4.148 - MOVL_imm32_rspdisp(0,0);4.149 - sh4_x86_add_backpatch(xlat_output, pc, -2);4.150 - CALL_r32disp(preg, disp8);4.151 -}4.152 -4.153 -4.154 -4.155 -static inline void call_func1_exc( void *ptr, int arg1, int pc )4.156 -{4.157 - if( arg1 != REG_EAX ) {4.158 - MOVL_r32_r32( arg1, REG_EAX );4.159 - }4.160 - MOVP_immptr_rptr(0,REG_EDX);4.161 - sh4_x86_add_backpatch(xlat_output, pc, -2);4.162 - MOVP_immptr_rptr((uint32_t)ptr, REG_ECX);4.163 - CALL_r32(REG_ECX);4.164 -}4.165 -4.166 -static inline void call_func2_exc( void *ptr, int arg1, int arg2, int pc )4.167 -{4.168 - if( arg2 != REG_EDX ) {4.169 - MOVL_r32_r32( arg2, REG_EDX );4.170 - }4.171 - if( arg1 != REG_EAX ) {4.172 - MOVL_r32_r32( arg1, REG_EAX );4.173 - }4.174 - MOVL_imm32_rspdisp(0,0);4.175 - sh4_x86_add_backpatch(xlat_output, pc, -2);4.176 - MOVP_immptr_rptr((uint32_t)ptr, REG_ECX);4.177 - CALL_r32(REG_ECX);4.178 -}4.179 +#define CALL3_r32disp_r32_r32_r32(preg,disp,arg1,arg2,arg3) CALL2_r32disp_r32_r32(preg,disp,arg1,arg2)4.181 #else4.182 -static inline void call_func1( void *ptr, int arg1 )4.183 +static inline void CALL1_ptr( void *ptr, int arg1 )4.184 {4.185 SUBL_imms_r32( 12, REG_ESP );4.186 PUSH_r32(arg1);4.187 - MOVP_immptr_rptr((uint32_t)ptr, REG_ECX);4.188 - CALL_r32(REG_ECX);4.189 + CALL_ptr(ptr);4.190 ADDL_imms_r32( 16, REG_ESP );4.191 }4.193 -static inline void call_func2( void *ptr, int arg1, int arg2 )4.194 +static inline void CALL1_r32disp_r32( int preg, uint32_t disp, int arg1 )4.195 +{4.196 + SUBL_imms_r32( 12, REG_ESP );4.197 + PUSH_r32(arg1);4.198 + CALL_r32disp(preg, disp);4.199 + ADDL_imms_r32( 16, REG_ESP );4.200 +}4.201 +4.202 +static inline void CALL2_ptr_r32_r32( void *ptr, int arg1, int arg2 )4.203 {4.204 SUBL_imms_r32( 8, REG_ESP );4.205 PUSH_r32(arg2);4.206 PUSH_r32(arg1);4.207 - MOVP_immptr_rptr((uint32_t)ptr, REG_ECX);4.208 - CALL_r32(REG_ECX);4.209 + CALL_ptr(ptr);4.210 + ADDL_imms_r32( 16, REG_ESP );4.211 +}4.212 +4.213 +static inline void CALL2_r32disp_r32_r32( int preg, uint32_t disp, int arg1, int arg2 )4.214 +{4.215 + SUBL_imms_r32( 8, REG_ESP );4.216 + PUSH_r32(arg2);4.217 + PUSH_r32(arg1);4.218 + CALL_r32disp(preg, disp);4.219 + ADDL_imms_r32( 16, REG_ESP );4.220 +}4.221 +4.222 +static inline void CALL3_r32disp_r32_r32_r32( int preg, uint32_t disp, int arg1, int arg2, int arg3 )4.223 +{4.224 + SUBL_imms_r32( 8, REG_ESP );4.225 + PUSH_r32(arg2);4.226 + PUSH_r32(arg1);4.227 + MOVL_rspdisp_r32( 16, REG_EAX );4.228 + MOVL_r32_rspdisp( R_EAX, 8 );4.229 + CALL_r32disp(preg,disp);4.230 ADDL_imms_r32( 16, REG_ESP );4.231 }4.233 @@ -180,10 +139,10 @@4.234 * Allocates 8 bytes for local variables, which also has the convenient4.235 * side-effect of aligning the stack.4.236 */4.237 -void enter_block( )4.238 +static inline void enter_block( )4.239 {4.240 PUSH_r32(REG_EBP);4.241 - load_ptr( REG_EBP, ((uint8_t *)&sh4r) + 128 );4.242 + MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );4.243 SUBL_imms_r32( 8, REG_ESP );4.244 }4.246 @@ -193,234 +152,3 @@4.247 POP_r32(REG_EBP);4.248 RET();4.249 }4.250 -4.251 -/**4.252 - * Exit the block with sh4r.new_pc written with the target pc4.253 - */4.254 -void exit_block_pcset( sh4addr_t pc )4.255 -{4.256 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 54.257 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 64.258 - load_spreg( REG_EAX, R_PC );4.259 - if( sh4_x86.tlb_on ) {4.260 - call_func1(xlat_get_code_by_vma,REG_EAX);4.261 - } else {4.262 - call_func1(xlat_get_code,REG_EAX);4.263 - }4.264 - exit_block();4.265 -}4.266 -4.267 -/**4.268 - * Exit the block with sh4r.new_pc written with the target pc4.269 - */4.270 -void exit_block_newpcset( sh4addr_t pc )4.271 -{4.272 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 54.273 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 64.274 - load_spreg( REG_EAX, R_NEW_PC );4.275 - store_spreg( REG_EAX, R_PC );4.276 - if( sh4_x86.tlb_on ) {4.277 - call_func1(xlat_get_code_by_vma,REG_EAX);4.278 - } else {4.279 - call_func1(xlat_get_code,REG_EAX);4.280 - }4.281 - exit_block();4.282 -}4.283 -4.284 -4.285 -/**4.286 - * Exit the block to an absolute PC4.287 - */4.288 -void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )4.289 -{4.290 - load_imm32( REG_ECX, pc ); // 54.291 - store_spreg( REG_ECX, REG_OFFSET(pc) ); // 34.292 - if( IS_IN_ICACHE(pc) ) {4.293 - MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 54.294 - ANDL_imms_r32( 0xFFFFFFFC, REG_EAX ); // 34.295 - } else if( sh4_x86.tlb_on ) {4.296 - call_func1(xlat_get_code_by_vma,REG_ECX);4.297 - } else {4.298 - call_func1(xlat_get_code,REG_ECX);4.299 - }4.300 - load_imm32( REG_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 54.301 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 64.302 - exit_block();4.303 -}4.304 -4.305 -/**4.306 - * Exit the block to a relative PC4.307 - */4.308 -void exit_block_rel( sh4addr_t pc, sh4addr_t endpc )4.309 -{4.310 - load_imm32( REG_ECX, pc - sh4_x86.block_start_pc ); // 54.311 - ADDL_rbpdisp_r32( R_PC, REG_ECX );4.312 - store_spreg( REG_ECX, R_PC ); // 34.313 - if( IS_IN_ICACHE(pc) ) {4.314 - MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 54.315 - ANDL_imms_r32( 0xFFFFFFFC, REG_EAX ); // 34.316 - } else if( sh4_x86.tlb_on ) {4.317 - call_func1(xlat_get_code_by_vma,REG_ECX);4.318 - } else {4.319 - call_func1(xlat_get_code,REG_ECX);4.320 - }4.321 - load_imm32( REG_ECX, ((endpc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 54.322 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 64.323 - exit_block();4.324 -}4.325 -4.326 -/**4.327 - * Exit unconditionally with a general exception4.328 - */4.329 -void exit_block_exc( int code, sh4addr_t pc )4.330 -{4.331 - load_imm32( REG_ECX, pc - sh4_x86.block_start_pc ); // 54.332 - ADDL_r32_rbpdisp( REG_ECX, R_PC );4.333 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 54.334 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 64.335 - load_imm32( REG_EAX, code );4.336 - call_func1( sh4_raise_exception, REG_EAX );4.337 -4.338 - load_spreg( REG_EAX, R_PC );4.339 - if( sh4_x86.tlb_on ) {4.340 - call_func1(xlat_get_code_by_vma,REG_EAX);4.341 - } else {4.342 - call_func1(xlat_get_code,REG_EAX);4.343 - }4.344 -4.345 - exit_block();4.346 -}4.347 -4.348 -/**4.349 - * Write the block trailer (exception handling block)4.350 - */4.351 -void sh4_translate_end_block( sh4addr_t pc ) {4.352 - if( sh4_x86.branch_taken == FALSE ) {4.353 - // Didn't exit unconditionally already, so write the termination here4.354 - exit_block_rel( pc, pc );4.355 - }4.356 - if( sh4_x86.backpatch_posn != 0 ) {4.357 - unsigned int i;4.358 - // Raise exception4.359 - uint8_t *end_ptr = xlat_output;4.360 - MOVL_r32_r32( REG_EDX, REG_ECX );4.361 - ADDL_r32_r32( REG_EDX, REG_ECX );4.362 - ADDL_r32_rbpdisp( REG_ECX, R_PC );4.363 - MOVL_moffptr_eax( &sh4_cpu_period );4.364 - MULL_r32( REG_EDX );4.365 - ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );4.366 -4.367 - POP_r32(REG_EAX);4.368 - call_func1( sh4_raise_exception, REG_EAX );4.369 - load_spreg( REG_EAX, R_PC );4.370 - if( sh4_x86.tlb_on ) {4.371 - call_func1(xlat_get_code_by_vma,REG_EAX);4.372 - } else {4.373 - call_func1(xlat_get_code,REG_EAX);4.374 - }4.375 - exit_block();4.376 -4.377 - // Exception already raised - just cleanup4.378 - uint8_t *preexc_ptr = xlat_output;4.379 - MOVL_r32_r32( REG_EDX, REG_ECX );4.380 - ADDL_r32_r32( REG_EDX, REG_ECX );4.381 - ADDL_r32_rbpdisp( REG_ECX, R_SPC );4.382 - MOVL_moffptr_eax( &sh4_cpu_period );4.383 - MULL_r32( REG_EDX );4.384 - ADDL_r32_rbpdisp( REG_EAX, REG_OFFSET(slice_cycle) );4.385 - load_spreg( REG_EAX, R_PC );4.386 - if( sh4_x86.tlb_on ) {4.387 - call_func1(xlat_get_code_by_vma,REG_EAX);4.388 - } else {4.389 - call_func1(xlat_get_code,REG_EAX);4.390 - }4.391 - exit_block();4.392 -4.393 - for( i=0; i< sh4_x86.backpatch_posn; i++ ) {4.394 - uint32_t *fixup_addr = (uint32_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset];4.395 - if( sh4_x86.backpatch_list[i].exc_code < 0 ) {4.396 - if( sh4_x86.backpatch_list[i].exc_code == -2 ) {4.397 - *fixup_addr = (uint32_t)xlat_output;4.398 - } else {4.399 - *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;4.400 - }4.401 - load_imm32( REG_EDX, sh4_x86.backpatch_list[i].fixup_icount );4.402 - int rel = preexc_ptr - xlat_output;4.403 - JMP_prerel(rel);4.404 - } else {4.405 - *fixup_addr += xlat_output - (uint8_t *)&xlat_current_block->code[sh4_x86.backpatch_list[i].fixup_offset] - 4;4.406 - PUSH_imm32( sh4_x86.backpatch_list[i].exc_code );4.407 - load_imm32( REG_EDX, sh4_x86.backpatch_list[i].fixup_icount );4.408 - int rel = end_ptr - xlat_output;4.409 - JMP_prerel(rel);4.410 - }4.411 - }4.412 - }4.413 -}4.414 -4.415 -4.416 -/**4.417 - * The unwind methods only work if we compiled with DWARF2 frame information4.418 - * (ie -fexceptions), otherwise we have to use the direct frame scan.4.419 - */4.420 -#ifdef HAVE_EXCEPTIONS4.421 -#include <unwind.h>4.422 -4.423 -struct UnwindInfo {4.424 - uintptr_t block_start;4.425 - uintptr_t block_end;4.426 - void *pc;4.427 -};4.428 -4.429 -_Unwind_Reason_Code xlat_check_frame( struct _Unwind_Context *context, void *arg )4.430 -{4.431 - struct UnwindInfo *info = arg;4.432 - void *pc = (void *)_Unwind_GetIP(context);4.433 - if( ((uintptr_t)pc) >= info->block_start && ((uintptr_t)pc) < info->block_end ) {4.434 - info->pc = pc;4.435 - return _URC_NORMAL_STOP;4.436 - }4.437 -4.438 - return _URC_NO_REASON;4.439 -}4.440 -4.441 -void *xlat_get_native_pc( void *code, uint32_t code_size )4.442 -{4.443 - struct _Unwind_Exception exc;4.444 - struct UnwindInfo info;4.445 -4.446 - info.pc = NULL;4.447 - info.block_start = (uintptr_t)code;4.448 - info.block_end = info.block_start + code_size;4.449 - void *result = NULL;4.450 - _Unwind_Backtrace( xlat_check_frame, &info );4.451 - return info.pc;4.452 -}4.453 -#else4.454 -void *xlat_get_native_pc( void *code, uint32_t code_size )4.455 -{4.456 - void *result = NULL;4.457 - asm(4.458 - "mov %%ebp, %%eax\n\t"4.459 - "mov $0x8, %%ecx\n\t"4.460 - "mov %1, %%edx\n"4.461 - "frame_loop: test %%eax, %%eax\n\t"4.462 - "je frame_not_found\n\t"4.463 - "cmp (%%eax), %%edx\n\t"4.464 - "je frame_found\n\t"4.465 - "sub $0x1, %%ecx\n\t"4.466 - "je frame_not_found\n\t"4.467 - "movl (%%eax), %%eax\n\t"4.468 - "jmp frame_loop\n"4.469 - "frame_found: movl 0x4(%%eax), %0\n"4.470 - "frame_not_found:"4.471 - : "=r" (result)4.472 - : "r" (((uint8_t *)&sh4r) + 128 )4.473 - : "eax", "ecx", "edx" );4.474 - return result;4.475 -}4.476 -#endif4.477 -4.478 -#endif /* !lxdream_ia32mac.h */4.479 -4.480 -
5.1 --- a/src/xlat/x86/x86op.h Thu Mar 05 21:37:44 2009 +00005.2 +++ b/src/xlat/x86/x86op.h Thu Mar 05 21:42:35 2009 +00005.3 @@ -1,7 +1,7 @@5.4 /**5.5 * $Id$5.6 *5.7 - * x86/x86-64 Instruction generation macros5.8 + * x86/x86-64 Instruction generator5.9 *5.10 * Copyright (c) 2009 Nathan Keynes.5.11 *5.12 @@ -15,6 +15,10 @@5.13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the5.14 * GNU General Public License for more details.5.15 */5.16 +5.17 +#ifndef lxdream_x86op_H5.18 +#define lxdream_x86op_H5.19 +5.20 #include <stdint.h>5.21 #include <assert.h>5.23 @@ -130,6 +134,9 @@5.24 #define PREF_REXR 0x445.25 #define PREF_REXW 0x485.27 +/* PREF_REXW if required for pointer operations, otherwise 0 */5.28 +#define PREF_PTR ((sizeof(void *) == 8) ? PREF_REXW : 0)5.29 +5.30 extern unsigned char *xlat_output;5.32 #define OP(x) *xlat_output++ = (x)5.33 @@ -309,7 +316,7 @@5.34 #define x86_encode_r64_rm64(opcode,rr,rb) x86_encode_reg_rm(PREF_REXW,opcode,rr,rb)5.35 #define x86_encode_r32_mem32(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(0,opcode,rr,rb,rx,ss,disp32)5.36 #define x86_encode_r64_mem64(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,rx,ss,disp32)5.37 -#define x86_encode_rptr_memptr(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm( (sizeof(void *)==8) ? PREF_REXW : 0,opcode,rr,rb,rx,ss,disp32)5.38 +#define x86_encode_rptr_memptr(opcode,rr,rb,rx,ss,disp32) x86_encode_modrm(PREF_PTR,opcode,rr,rb,rx,ss,disp32)5.39 #define x86_encode_r32_mem32disp32(opcode,rr,rb,disp32) x86_encode_modrm(0,opcode,rr,rb,-1,0,disp32)5.40 #define x86_encode_r64_mem64disp64(opcode,rr,rb,disp32) x86_encode_modrm(PREF_REXW,opcode,rr,rb,-1,0,disp32)5.41 #define x86_encode_r32_ripdisp32(opcode,rr,disp32) x86_encode_modrm_rip(0,opcode,rr,disp32)5.42 @@ -328,6 +335,9 @@5.43 #define x86_encode_imms_rm64(opcode8,opcode32,reg,imm,rb) \5.44 if( IS_INT8(((int32_t)imm)) ) { x86_encode_r64_rm64(opcode8,reg,rb); OP((int8_t)imm); \5.45 } else { x86_encode_r64_rm64(opcode32,reg,rb); OP32(imm); }5.46 +#define x86_encode_imms_rmptr(opcode8,opcode32,reg,imm,rb) \5.47 + if( IS_INT8(((int32_t)imm)) ) { x86_encode_reg_rm( PREF_PTR, opcode8,reg,rb); OP((int8_t)imm); \5.48 + } else { x86_encode_reg_rm( PREF_PTR, opcode32,reg,rb); OP32(imm); }5.49 #define x86_encode_imms_rbpdisp32(opcode8,opcode32,reg,imm,disp) \5.50 if( IS_INT8(((int32_t)imm)) ) { x86_encode_r32_rbpdisp32(opcode8,reg,disp); OP((int8_t)imm); \5.51 } else { x86_encode_r32_rbpdisp32(opcode32,reg,disp); OP32(imm); }5.52 @@ -374,6 +384,7 @@5.53 #define ANDL_rbpdisp_r32(disp,r1) x86_encode_r32_rbpdisp32(0x23, r1, disp)5.54 #define ANDQ_r64_r64(r1,r2) x86_encode_r64_rm64(0x21, r1, r2)5.55 #define ANDQ_imms_r64(imm,r1) x86_encode_imms_rm64(0x83, 0x81, 4, imm, r1)5.56 +#define ANDP_imms_rptr(imm,r1) x86_encode_imms_rmptr(0x83, 0x81, 4, imm, r1)5.58 #define CLC() OP(0xF8)5.59 #define CLD() OP(0xFC)5.60 @@ -437,8 +448,9 @@5.61 #define MOVQ_r64_rspdisp(r1,disp) x86_encode_r64_rspdisp64(0x89, r1, disp)5.62 #define MOVQ_rbpdisp_r64(disp,r1) x86_encode_r64_rbpdisp64(0x8B, r1, disp)5.63 #define MOVQ_rspdisp_r64(disp,r1) x86_encode_r64_rspdisp64(0x8B, r1, disp)5.64 -#define MOVP_immptr_rptr(p,r1) x86_encode_opcodereg( (sizeof(void*)==8 ? PREF_REXW : 0), 0xB8, r1); OPPTR(p)5.65 +#define MOVP_immptr_rptr(p,r1) x86_encode_opcodereg( PREF_PTR, 0xB8, r1); OPPTR(p)5.66 #define MOVP_moffptr_rax(p) if( sizeof(void*)==8 ) { OP(PREF_REXW); } OP(0xA1); OPPTR(p)5.67 +#define MOVP_rptr_rptr(r1,r2) x86_encode_reg_rm(PREF_PTR, 0x89, r1, r2)5.68 #define MOVP_sib_rptr(ss,ii,bb,d,r1) x86_encode_rptr_memptr(0x8B, r1, bb, ii, ss, d)5.70 #define MOVSXL_r8_r32(r1,r2) x86_encode_r32_rm32(0x0FBE, r2, r1)5.71 @@ -766,3 +778,12 @@5.72 #define MOVSHDUP_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F16, r2, r1)5.73 #define MOVSLDUP_rbpdisp_xmm(dsp,r1) OP(0xF3); x86_encode_r32_rbpdisp32(0x0F12, r1, dsp)5.74 #define MOVSLDUP_xmm_xmm(r1,r2) OP(0xF3); x86_encode_r32_rm32(0x0F12, r2, r1)5.75 +5.76 +/************************ Import calling conventions *************************/5.77 +#if SIZEOF_VOID_P == 85.78 +#include "xlat/x86/amd64abi.h"5.79 +#else /* 32-bit system */5.80 +#include "xlat/x86/ia32abi.h"5.81 +#endif5.82 +5.83 +#endif /* !lxdream_x86op_H */
.