Search
lxdream.org :: lxdream :: r995:eb9d43e8aa08
lxdream 0.9.1
released Jun 29
Download Now
changeset995:eb9d43e8aa08
parent994:a92d433f1be8
child996:2e8cf0a87243
authornkeynes
dateThu Mar 05 21:42:35 2009 +0000 (13 years ago)
Cleanup ABI headers - most of the content made consistent between versions, and moved into sh4x86.in proper
src/sh4/mmux86.c
src/sh4/sh4x86.in
src/xlat/x86/amd64abi.h
src/xlat/x86/ia32abi.h
src/xlat/x86/x86op.h
1.1 --- a/src/sh4/mmux86.c Thu Mar 05 21:37:44 2009 +0000
1.2 +++ b/src/sh4/mmux86.c Thu Mar 05 21:42:35 2009 +0000
1.3 @@ -25,8 +25,6 @@
1.4 #include "xlat/x86/x86op.h"
1.5
1.6 #if SIZEOF_VOID_P == 8
1.7 -#define ARG1 REG_RDI
1.8 -#define ARG2 REG_RSI
1.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 #else
1.16 -#define ARG1 REG_EAX
1.17 -#define ARG2 R_EDX
1.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 ); // 6
1.26 + ADDL_imms_r32( ppn-vpn, REG_ARG1 ); // 6
1.27 if( ent->mask >= 0xFFFFF000 ) {
1.28 // Maps to a single page, so jump directly there
1.29 int rel = (*fn - xlat_output);
1.30 JMP_prerel( rel ); // 5
1.31 } else {
1.32 - MOVL_r32_r32( ARG1, REG_ECX ); // 2
1.33 + MOVL_r32_r32( REG_ARG1, REG_ECX ); // 2
1.34 SHRL_imm_r32( 12, REG_ECX ); // 3
1.35 XLAT(addr_space, REG_ECX); // 14
1.36 JMP_r32disp(REG_ECX, (((uintptr_t)out) - ((uintptr_t)&page->fn)) ); // 3
1.37 @@ -96,7 +92,7 @@
1.38
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.47
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 +0000
2.2 +++ b/src/sh4/sh4x86.in Thu Mar 05 21:42:35 2009 +0000
2.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.6
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)+4
2.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)+4
2.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 0
2.50 +#define DELAY_PC 1
2.51 +#define DELAY_PC_PR 2
2.52
2.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.58
2.59 -#define DELAY_NONE 0
2.60 -#define DELAY_PC 1
2.61 -#define DELAY_PC_PR 2
2.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() and
2.66 @@ -145,14 +151,14 @@
2.67 }
2.68
2.69 #define TSTATE_NONE -1
2.70 -#define TSTATE_O 0
2.71 -#define TSTATE_C 2
2.72 -#define TSTATE_E 4
2.73 -#define TSTATE_NE 5
2.74 -#define TSTATE_G 0xF
2.75 -#define TSTATE_GE 0xD
2.76 -#define TSTATE_A 7
2.77 -#define TSTATE_AE 3
2.78 +#define TSTATE_O X86_COND_O
2.79 +#define TSTATE_C X86_COND_C
2.80 +#define TSTATE_E X86_COND_E
2.81 +#define TSTATE_NE X86_COND_NE
2.82 +#define TSTATE_G X86_COND_G
2.83 +#define TSTATE_GE X86_COND_GE
2.84 +#define TSTATE_A X86_COND_A
2.85 +#define TSTATE_AE X86_COND_AE
2.86
2.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.92
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.102
2.103 /**
2.104 * Load an FR register (single-precision floating point) into an integer x86
2.105 @@ -233,7 +234,7 @@
2.106 #define pop_xdr(frm) FSTPD_rbpdisp( REG_OFFSET(fr[1][(frm)&0x0E]) )
2.107
2.108 #ifdef ENABLE_SH4STATS
2.109 -#define COUNT_INST(id) load_imm32(REG_EAX,id); call_func1(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE
2.110 +#define COUNT_INST(id) MOVL_imm32_r32( id, REG_EAX ); CALL1_ptr_r32(sh4_stats_add, REG_EAX); sh4_x86.tstate = TSTATE_NONE
2.111 #else
2.112 #define COUNT_INST(id)
2.113 #endif
2.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.125
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, so
2.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_ADDRESS
2.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 -#else
2.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 > 2
2.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 +#else
2.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 +#endif
2.182 + }
2.183 +}
2.184 +#else
2.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 #endif
2.200
2.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.218
2.219 #define SLOTILLEGAL() exit_block_exc(EXC_SLOT_ILLEGAL, pc-2); sh4_x86.in_delay_slot = DELAY_NONE; return 2;
2.220
2.221 -/****** Import appropriate calling conventions ******/
2.222 -#if SIZEOF_VOID_P == 8
2.223 -#include "xlat/x86/amd64abi.h"
2.224 -#else /* 32-bit system */
2.225 -#include "xlat/x86/ia32abi.h"
2.226 -#endif
2.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.241
2.242 @@ -366,6 +405,102 @@
2.243 #define UNTRANSLATABLE(pc) !IS_IN_ICACHE(pc)
2.244
2.245 /**
2.246 + * Exit the block with sh4r.pc already written
2.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 pc
2.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 PC
2.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 PC
2.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 exception
2.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 we
2.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 ); // 5
2.350 + MOVL_imm32_r32( endpc - sh4_x86.block_start_pc, REG_ECX ); // 5
2.351 ADDL_r32_rbpdisp( REG_ECX, R_PC );
2.352
2.353 - load_imm32( REG_ECX, (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period ); // 5
2.354 + MOVL_imm32_r32( (((endpc - sh4_x86.block_start_pc)>>1)+1)*sh4_cpu_period, REG_ECX ); // 5
2.355 ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
2.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.360
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.374
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 here
2.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 exit
2.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 specially
2.426 * by translating both branch and delayed instruction as a single unit (as
2.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 DIV1
2.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); // tmp1
2.460 XORB_r8_r8( REG_DL, REG_AL ); // Q' = Q ^ tmp1
2.461 XORB_r8_r8( REG_AL, REG_CL ); // Q'' = Q' ^ M
2.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.496
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.514
2.515 ADDL_r32_rbpdisp( REG_EAX, R_MACL ); // 6
2.516 JNO_label( end ); // 2
2.517 - load_imm32( REG_EDX, 1 ); // 5
2.518 - store_spreg( REG_EDX, R_MACH ); // 6
2.519 + MOVL_imm32_r32( 1, REG_EDX ); // 5
2.520 + MOVL_r32_rbpdisp( REG_EDX, R_MACH ); // 6
2.521 JS_label( positive ); // 2
2.522 - load_imm32( REG_EAX, 0x80000000 );// 5
2.523 - store_spreg( REG_EAX, R_MACL ); // 6
2.524 + MOVL_imm32_r32( 0x80000000, REG_EAX );// 5
2.525 + MOVL_r32_rbpdisp( REG_EAX, R_MACL ); // 6
2.526 JMP_label(end2); // 2
2.527
2.528 JMP_TARGET(positive);
2.529 - load_imm32( REG_EAX, 0x7FFFFFFF );// 5
2.530 - store_spreg( REG_EAX, R_MACL ); // 6
2.531 + MOVL_imm32_r32( 0x7FFFFFFF, REG_EAX );// 5
2.532 + MOVL_r32_rbpdisp( REG_EAX, R_MACL ); // 6
2.533 JMP_label(end3); // 2
2.534
2.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 a
2.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.737
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 ); // 5
2.810 + MOVL_imm32_r32( pc+2 - sh4_x86.block_start_pc, REG_ECX ); // 5
2.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 ); // 5
2.849 - FILD_r32disp( REG_ECX, 0 ); // 2
2.850 - FCOMIP_st(1); // 2
2.851 - JAE_label( sat2 ); // 2
2.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); // 3
2.863 + FISTP_rbpdisp(R_FPUL);
2.864 FLDCW_r32disp( REG_EAX, 0 );
2.865 - JMP_label(end); // 2
2.866 + JMP_label(end);
2.867
2.868 JMP_TARGET(sat);
2.869 JMP_TARGET(sat2);
2.870 MOVL_r32disp_r32( REG_ECX, 0, REG_ECX ); // 2
2.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 information
2.1384 + * (ie -fexceptions), otherwise we have to use the direct frame scan.
2.1385 + */
2.1386 +#ifdef HAVE_EXCEPTIONS
2.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 +#else
2.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 +#endif
2.1443 +
3.1 --- a/src/xlat/x86/amd64abi.h Thu Mar 05 21:37:44 2009 +0000
3.2 +++ b/src/xlat/x86/amd64abi.h Thu Mar 05 21:42:35 2009 +0000
3.3 @@ -17,97 +17,93 @@
3.4 * GNU General Public License for more details.
3.5 */
3.6
3.7 -#ifndef lxdream_ia64abi_H
3.8 -#define lxdream_ia64abi_H 1
3.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_RDI
3.14 +#define REG_ARG2 REG_RSI
3.15 +#define REG_ARG3 REG_RDX
3.16 +#define REG_RESULT1 REG_RAX
3.17 +#define MAX_REG_ARG 3 /* There's more, but we don't use more than 3 here anyway */
3.18
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.30
3.31 /**
3.32 - * Note: clobbers EAX to make the indirect call - this isn't usually
3.33 - * a problem since the callee will usually clobber it anyway.
3.34 + * Note: clobbers ECX to make the indirect call - this isn't usually
3.35 + * a problem since the callee will generally clobber it anyway.
3.36 * Size: 12 bytes
3.37 */
3.38 -#define CALL_FUNC0_SIZE 12
3.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.47
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.58
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.71
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.85
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.101
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.119
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 save
3.140 * SI/DI as required
3.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 bytes
3.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.152
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 written
3.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 ); // 5
3.165 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
3.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 address
3.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 ); // 5
3.181 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
3.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 PC
3.195 - */
3.196 -void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )
3.197 -{
3.198 - load_imm32( REG_RCX, pc ); // 5
3.199 - store_spreg( REG_RCX, REG_OFFSET(pc) ); // 3
3.200 - if( IS_IN_ICACHE(pc) ) {
3.201 - MOVP_moffptr_rax( xlat_get_lut_entry(pc) );
3.202 - ANDQ_imms_r64( 0xFFFFFFFC, REG_RAX ); // 4
3.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 ); // 5
3.209 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
3.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 PC
3.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 ); // 5
3.222 - ADDL_rbpdisp_r32( R_PC, REG_ECX );
3.223 - store_spreg( REG_ECX, REG_OFFSET(pc) ); // 3
3.224 - if( IS_IN_ICACHE(pc) ) {
3.225 - MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
3.226 - ANDQ_imms_r64( 0xFFFFFFFC, REG_RAX ); // 4
3.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 ); // 5
3.233 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
3.234 - exit_block();
3.235 -}
3.236 -
3.237 -/**
3.238 - * Exit unconditionally with a general exception
3.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 ); // 5
3.243 - ADDL_r32_rbpdisp( REG_ECX, R_PC );
3.244 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
3.245 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
3.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 here
3.266 - exit_block_rel( pc, pc );
3.267 - }
3.268 - if( sh4_x86.backpatch_posn != 0 ) {
3.269 - unsigned int i;
3.270 - // Raise exception
3.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 cleanup
3.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 +0000
4.2 +++ b/src/xlat/x86/ia32abi.h Thu Mar 05 21:42:35 2009 +0000
4.3 @@ -5,6 +5,8 @@
4.4 * (eg prologue, epilogue, and calling conventions). Stack frame is
4.5 * aligned on 16-byte boundaries for the benefit of OS X (which
4.6 * requires it).
4.7 + *
4.8 + * Note: These should only be included from x86op.h
4.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.15
4.16 -#ifndef lxdream_ia32mac_H
4.17 -#define lxdream_ia32mac_H 1
4.18 -
4.19 -#define load_ptr( reg, ptr ) load_imm32( reg, (uint32_t)ptr );
4.20 +#define REG_ARG1 REG_EAX
4.21 +#define REG_ARG2 REG_EDX
4.22 +#define REG_RESULT1 REG_EAX
4.23 +#define MAX_REG_ARG 2
4.24
4.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.33
4.34 /**
4.35 - * Note: clobbers EAX to make the indirect call - this isn't usually
4.36 - * a problem since the callee will usually clobber it anyway.
4.37 + * Note: clobbers ECX to make the indirect call - this isn't usually
4.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.47
4.48 #ifdef HAVE_FASTCALL
4.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.61
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.73
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.88
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.105
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.180
4.181 #else
4.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.192
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.232
4.233 @@ -180,10 +139,10 @@
4.234 * Allocates 8 bytes for local variables, which also has the convenient
4.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.245
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 pc
4.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 ); // 5
4.257 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
4.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 pc
4.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 ); // 5
4.273 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
4.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 PC
4.287 - */
4.288 -void exit_block_abs( sh4addr_t pc, sh4addr_t endpc )
4.289 -{
4.290 - load_imm32( REG_ECX, pc ); // 5
4.291 - store_spreg( REG_ECX, REG_OFFSET(pc) ); // 3
4.292 - if( IS_IN_ICACHE(pc) ) {
4.293 - MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
4.294 - ANDL_imms_r32( 0xFFFFFFFC, REG_EAX ); // 3
4.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 ); // 5
4.301 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
4.302 - exit_block();
4.303 -}
4.304 -
4.305 -/**
4.306 - * Exit the block to a relative PC
4.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 ); // 5
4.311 - ADDL_rbpdisp_r32( R_PC, REG_ECX );
4.312 - store_spreg( REG_ECX, R_PC ); // 3
4.313 - if( IS_IN_ICACHE(pc) ) {
4.314 - MOVP_moffptr_rax( xlat_get_lut_entry(GET_ICACHE_PHYS(pc)) ); // 5
4.315 - ANDL_imms_r32( 0xFFFFFFFC, REG_EAX ); // 3
4.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 ); // 5
4.322 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
4.323 - exit_block();
4.324 -}
4.325 -
4.326 -/**
4.327 - * Exit unconditionally with a general exception
4.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 ); // 5
4.332 - ADDL_r32_rbpdisp( REG_ECX, R_PC );
4.333 - load_imm32( REG_ECX, ((pc - sh4_x86.block_start_pc)>>1)*sh4_cpu_period ); // 5
4.334 - ADDL_r32_rbpdisp( REG_ECX, REG_OFFSET(slice_cycle) ); // 6
4.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 here
4.354 - exit_block_rel( pc, pc );
4.355 - }
4.356 - if( sh4_x86.backpatch_posn != 0 ) {
4.357 - unsigned int i;
4.358 - // Raise exception
4.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 cleanup
4.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 information
4.418 - * (ie -fexceptions), otherwise we have to use the direct frame scan.
4.419 - */
4.420 -#ifdef HAVE_EXCEPTIONS
4.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 -#else
4.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 -#endif
4.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 +0000
5.2 +++ b/src/xlat/x86/x86op.h Thu Mar 05 21:42:35 2009 +0000
5.3 @@ -1,7 +1,7 @@
5.4 /**
5.5 * $Id$
5.6 *
5.7 - * x86/x86-64 Instruction generation macros
5.8 + * x86/x86-64 Instruction generator
5.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 the
5.14 * GNU General Public License for more details.
5.15 */
5.16 +
5.17 +#ifndef lxdream_x86op_H
5.18 +#define lxdream_x86op_H
5.19 +
5.20 #include <stdint.h>
5.21 #include <assert.h>
5.22
5.23 @@ -130,6 +134,9 @@
5.24 #define PREF_REXR 0x44
5.25 #define PREF_REXW 0x48
5.26
5.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.31
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.57
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.69
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 == 8
5.78 +#include "xlat/x86/amd64abi.h"
5.79 +#else /* 32-bit system */
5.80 +#include "xlat/x86/ia32abi.h"
5.81 +#endif
5.82 +
5.83 +#endif /* !lxdream_x86op_H */
.