Search
lxdream.org :: lxdream :: r1292:799fdd4f704a
lxdream 0.9.1
released Jun 29
Download Now
changeset1292:799fdd4f704a
parent1291:8884bf45f010
child1293:36123decfb24
authornkeynes
dateFri Aug 24 08:53:50 2012 +1000 (8 years ago)
Move the generated prologue/epilogue code out into a common entry stub
(reduces space requirements) and pre-save all saved registers. Change
FASTCALL to use 3 regs instead of 2 since we can now keep everything in
regs.
src/lxdream.h
src/sh4/mmux86.c
src/sh4/sh4trans.c
src/sh4/sh4trans.h
src/sh4/sh4x86.in
src/xlat/x86/amd64abi.h
src/xlat/x86/ia32abi.h
1.1 --- a/src/lxdream.h Sat Aug 04 08:46:28 2012 +1000
1.2 +++ b/src/lxdream.h Fri Aug 24 08:53:50 2012 +1000
1.3 @@ -111,7 +111,7 @@
1.4
1.5
1.6 #ifdef HAVE_FASTCALL
1.7 -#define FASTCALL __attribute__((regparm(2)))
1.8 +#define FASTCALL __attribute__((regparm(3)))
1.9 #else
1.10 #define FASTCALL
1.11 #endif
2.1 --- a/src/sh4/mmux86.c Sat Aug 04 08:46:28 2012 +1000
2.2 +++ b/src/sh4/mmux86.c Fri Aug 24 08:53:50 2012 +1000
2.3 @@ -70,10 +70,10 @@
2.4 int rel = (*fn - xlat_output);
2.5 JMP_prerel( rel ); // 5
2.6 } else {
2.7 - MOVL_r32_r32( REG_ARG1, REG_ECX ); // 2
2.8 - SHRL_imm_r32( 12, REG_ECX ); // 3
2.9 - XLAT(addr_space, REG_ECX); // 14
2.10 - JMP_r32disp(REG_ECX, (((uintptr_t)out) - ((uintptr_t)&page->fn)) ); // 3
2.11 + MOVL_r32_r32( REG_ARG1, REG_CALLPTR ); // 2
2.12 + SHRL_imm_r32( 12, REG_CALLPTR ); // 3
2.13 + XLAT(addr_space, REG_CALLPTR); // 14
2.14 + JMP_r32disp(REG_CALLPTR, (((uintptr_t)out) - ((uintptr_t)&page->fn)) ); // 3
2.15 }
2.16 }
2.17
2.18 @@ -105,21 +105,21 @@
2.19
2.20 for( i=0; i<9; i++, out++ ) {
2.21 *out = xlat_output;
2.22 - MOVL_r32_r32( REG_ARG1, REG_ECX );
2.23 - SHRL_imm_r32( 10, REG_ECX );
2.24 - ANDL_imms_r32( 0x3, REG_ECX );
2.25 - XLAT( (uintptr_t)&entry->subpages[0], REG_ECX );
2.26 - JMP_r32disp(REG_ECX, (((uintptr_t)out) - ((uintptr_t)&entry->fn)) ); // 3
2.27 + MOVL_r32_r32( REG_ARG1, REG_CALLPTR );
2.28 + SHRL_imm_r32( 10, REG_CALLPTR );
2.29 + ANDL_imms_r32( 0x3, REG_CALLPTR );
2.30 + XLAT( (uintptr_t)&entry->subpages[0], REG_CALLPTR );
2.31 + JMP_r32disp(REG_CALLPTR, (((uintptr_t)out) - ((uintptr_t)&entry->fn)) ); // 3
2.32 }
2.33
2.34 out = (uint8_t **)&entry->user_fn;
2.35 for( i=0; i<9; i++, out++ ) {
2.36 *out = xlat_output;
2.37 - MOVL_r32_r32( REG_ARG1, REG_ECX );
2.38 - SHRL_imm_r32( 10, REG_ECX );
2.39 - ANDL_imms_r32( 0x3, REG_ECX );
2.40 - XLAT( (uintptr_t)&entry->user_subpages[0], REG_ECX );
2.41 - JMP_r32disp(REG_ECX, (((uintptr_t)out) - ((uintptr_t)&entry->user_fn)) ); // 3
2.42 + MOVL_r32_r32( REG_ARG1, REG_CALLPTR );
2.43 + SHRL_imm_r32( 10, REG_CALLPTR );
2.44 + ANDL_imms_r32( 0x3, REG_CALLPTR );
2.45 + XLAT( (uintptr_t)&entry->user_subpages[0], REG_CALLPTR );
2.46 + JMP_r32disp(REG_CALLPTR, (((uintptr_t)out) - ((uintptr_t)&entry->user_fn)) ); // 3
2.47 }
2.48
2.49 }
3.1 --- a/src/sh4/sh4trans.c Sat Aug 04 08:46:28 2012 +1000
3.2 +++ b/src/sh4/sh4trans.c Fri Aug 24 08:53:50 2012 +1000
3.3 @@ -63,7 +63,7 @@
3.4 } else {
3.5 code = sh4_translate_basic_block( sh4r.pc );
3.6 }
3.7 - code();
3.8 + sh4_translate_enter(code);
3.9 }
3.10 }
3.11
4.1 --- a/src/sh4/sh4trans.h Sat Aug 04 08:46:28 2012 +1000
4.2 +++ b/src/sh4/sh4trans.h Fri Aug 24 08:53:50 2012 +1000
4.3 @@ -67,6 +67,11 @@
4.4 void sh4_translate_add_recovery( uint32_t icount );
4.5
4.6 /**
4.7 + * Enter the VM at the given translated entry point
4.8 + */
4.9 +void FASTCALL (*sh4_translate_enter)(void *code);
4.10 +
4.11 +/**
4.12 * Initialize shadow execution mode
4.13 */
4.14 void sh4_shadow_init( void );
5.1 --- a/src/sh4/sh4x86.in Sat Aug 04 08:46:28 2012 +1000
5.2 +++ b/src/sh4/sh4x86.in Fri Aug 24 08:53:50 2012 +1000
5.3 @@ -115,6 +115,9 @@
5.4
5.5 static struct sh4_x86_state sh4_x86;
5.6
5.7 +static uint8_t sh4_entry_stub[128];
5.8 +void FASTCALL (*sh4_translate_enter)(void *code);
5.9 +
5.10 static uint32_t max_int = 0x7FFFFFFF;
5.11 static uint32_t min_int = 0x80000000;
5.12 static uint32_t save_fcw; /* save value for fpu control word */
5.13 @@ -143,16 +146,45 @@
5.14 sh4_x86.user_address_space = user;
5.15 }
5.16
5.17 +void sh4_translate_write_entry_stub(void)
5.18 +{
5.19 + mem_unprotect(sh4_entry_stub, sizeof(sh4_entry_stub));
5.20 + xlat_output = sh4_entry_stub;
5.21 + PUSH_r32(REG_EBP);
5.22 + MOVP_immptr_rptr( ((uint8_t *)&sh4r) + 128, REG_EBP );
5.23 + PUSH_r32(REG_EBX);
5.24 + PUSH_r32(REG_SAVE1);
5.25 + PUSH_r32(REG_SAVE2);
5.26 +#if SIZEOF_VOID_P == 8
5.27 + PUSH_r32(REG_SAVE3);
5.28 + PUSH_r32(REG_SAVE4);
5.29 + CALL_r32( REG_ARG1 );
5.30 + POP_r32(REG_SAVE4);
5.31 + POP_r32(REG_SAVE3);
5.32 +#else
5.33 + SUBL_imms_r32( 8, REG_ESP );
5.34 + CALL_r32( REG_ARG1 );
5.35 + ADDL_imms_r32( 8, REG_ESP );
5.36 +#endif
5.37 + POP_r32(REG_SAVE2);
5.38 + POP_r32(REG_SAVE1);
5.39 + POP_r32(REG_EBX);
5.40 + POP_r32(REG_EBP);
5.41 + RET();
5.42 + sh4_translate_enter = sh4_entry_stub;
5.43 +}
5.44 +
5.45 void sh4_translate_init(void)
5.46 {
5.47 sh4_x86.backpatch_list = malloc(DEFAULT_BACKPATCH_SIZE);
5.48 sh4_x86.backpatch_size = DEFAULT_BACKPATCH_SIZE / sizeof(struct backpatch_record);
5.49 sh4_x86.begin_callback = NULL;
5.50 sh4_x86.end_callback = NULL;
5.51 - sh4_translate_set_address_space( sh4_address_space, sh4_user_address_space );
5.52 sh4_x86.fastmem = TRUE;
5.53 sh4_x86.sse3_enabled = is_sse3_supported();
5.54 xlat_set_target_fns(&x86_target_fns);
5.55 + sh4_translate_set_address_space( sh4_address_space, sh4_user_address_space );
5.56 + sh4_translate_write_entry_stub();
5.57 }
5.58
5.59 void sh4_translate_set_callbacks( xlat_block_begin_callback_t begin, xlat_block_end_callback_t end )
5.60 @@ -344,16 +376,16 @@
5.61 #ifdef HAVE_FRAME_ADDRESS
5.62 static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
5.63 {
5.64 - decode_address(address_space(), addr_reg);
5.65 + decode_address(address_space(), addr_reg, REG_CALLPTR);
5.66 if( !sh4_x86.tlb_on && (sh4_x86.sh4_mode & SR_MD) ) {
5.67 - CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
5.68 + CALL1_r32disp_r32(REG_CALLPTR, offset, addr_reg);
5.69 } else {
5.70 if( addr_reg != REG_ARG1 ) {
5.71 MOVL_r32_r32( addr_reg, REG_ARG1 );
5.72 }
5.73 MOVP_immptr_rptr( 0, REG_ARG2 );
5.74 sh4_x86_add_backpatch( xlat_output, pc, -2 );
5.75 - CALL2_r32disp_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2);
5.76 + CALL2_r32disp_r32_r32(REG_CALLPTR, offset, REG_ARG1, REG_ARG2);
5.77 }
5.78 if( value_reg != REG_RESULT1 ) {
5.79 MOVL_r32_r32( REG_RESULT1, value_reg );
5.80 @@ -362,9 +394,9 @@
5.81
5.82 static void call_write_func(int addr_reg, int value_reg, int offset, int pc)
5.83 {
5.84 - decode_address(address_space(), addr_reg);
5.85 + decode_address(address_space(), addr_reg, REG_CALLPTR);
5.86 if( !sh4_x86.tlb_on && (sh4_x86.sh4_mode & SR_MD) ) {
5.87 - CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
5.88 + CALL2_r32disp_r32_r32(REG_CALLPTR, offset, addr_reg, value_reg);
5.89 } else {
5.90 if( value_reg != REG_ARG2 ) {
5.91 MOVL_r32_r32( value_reg, REG_ARG2 );
5.92 @@ -375,19 +407,19 @@
5.93 #if MAX_REG_ARG > 2
5.94 MOVP_immptr_rptr( 0, REG_ARG3 );
5.95 sh4_x86_add_backpatch( xlat_output, pc, -2 );
5.96 - CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, REG_ARG3);
5.97 + CALL3_r32disp_r32_r32_r32(REG_CALLPTR, offset, REG_ARG1, REG_ARG2, REG_ARG3);
5.98 #else
5.99 MOVL_imm32_rspdisp( 0, 0 );
5.100 sh4_x86_add_backpatch( xlat_output, pc, -2 );
5.101 - CALL3_r32disp_r32_r32_r32(REG_ECX, offset, REG_ARG1, REG_ARG2, 0);
5.102 + CALL3_r32disp_r32_r32_r32(REG_CALLPTR, offset, REG_ARG1, REG_ARG2, 0);
5.103 #endif
5.104 }
5.105 }
5.106 #else
5.107 static void call_read_func(int addr_reg, int value_reg, int offset, int pc)
5.108 {
5.109 - decode_address(address_space(), addr_reg);
5.110 - CALL1_r32disp_r32(REG_ECX, offset, addr_reg);
5.111 + decode_address(address_space(), addr_reg, REG_CALLPTR);
5.112 + CALL1_r32disp_r32(REG_CALLPTR, offset, addr_reg);
5.113 if( value_reg != REG_RESULT1 ) {
5.114 MOVL_r32_r32( REG_RESULT1, value_reg );
5.115 }
5.116 @@ -395,8 +427,8 @@
5.117
5.118 static void call_write_func(int addr_reg, int value_reg, int offset, int pc)
5.119 {
5.120 - decode_address(address_space(), addr_reg);
5.121 - CALL2_r32disp_r32_r32(REG_ECX, offset, addr_reg, value_reg);
5.122 + decode_address(address_space(), addr_reg, REG_CALLPTR);
5.123 + CALL2_r32disp_r32_r32(REG_CALLPTR, offset, addr_reg, value_reg);
5.124 }
5.125 #endif
5.126
5.127 @@ -430,7 +462,6 @@
5.128 sh4_x86.double_prec = sh4r.fpscr & FPSCR_PR;
5.129 sh4_x86.double_size = sh4r.fpscr & FPSCR_SZ;
5.130 sh4_x86.sh4_mode = sh4r.xlat_sh4_mode;
5.131 - emit_prologue();
5.132 if( sh4_x86.begin_callback ) {
5.133 CALL_ptr( sh4_x86.begin_callback );
5.134 }
5.135 @@ -486,7 +517,6 @@
5.136 CMPL_imms_r32disp( sh4_x86.sh4_mode, REG_EAX, XLAT_SH4_MODE_CODE_OFFSET );
5.137 }
5.138 JNE_label(wrongmode);
5.139 - LEAP_rptrdisp_rptr(REG_EAX, PROLOGUE_SIZE,REG_EAX);
5.140 if( sh4_x86.end_callback ) {
5.141 /* Note this does leave the stack out of alignment, but doesn't matter
5.142 * for what we're currently using it for.
5.143 @@ -518,7 +548,7 @@
5.144 }
5.145 uint8_t *backpatch = ((uint8_t *)__builtin_return_address(0)) - (CALL1_PTR_MIN_SIZE);
5.146 *backpatch = 0xE9;
5.147 - *(uint32_t *)(backpatch+1) = (uint32_t)(target-backpatch)+PROLOGUE_SIZE-5;
5.148 + *(uint32_t *)(backpatch+1) = (uint32_t)(target-backpatch)-5;
5.149 *(void **)(backpatch+5) = XLAT_BLOCK_FOR_CODE(target)->use_list;
5.150 XLAT_BLOCK_FOR_CODE(target)->use_list = backpatch;
5.151
5.152 @@ -586,7 +616,6 @@
5.153
5.154 static void exit_block()
5.155 {
5.156 - emit_epilogue();
5.157 if( sh4_x86.end_callback ) {
5.158 MOVP_immptr_rptr(sh4_x86.end_callback, REG_ECX);
5.159 JMP_rptr(REG_ECX);
5.160 @@ -674,7 +703,7 @@
5.161 * looping.
5.162 */
5.163 CMPL_r32_rbpdisp( REG_ECX, REG_OFFSET(event_pending) );
5.164 - uint32_t backdisp = ((uintptr_t)(sh4_x86.code - xlat_output)) + PROLOGUE_SIZE;
5.165 + uint32_t backdisp = ((uintptr_t)(sh4_x86.code - xlat_output));
5.166 JCC_cc_prerel(X86_COND_A, backdisp);
5.167 } else {
5.168 MOVL_imm32_r32( pc - sh4_x86.block_start_pc, REG_ARG1 );
5.169 @@ -855,9 +884,9 @@
5.170 COUNT_INST(I_ANDB);
5.171 load_reg( REG_EAX, 0 );
5.172 ADDL_rbpdisp_r32( R_GBR, REG_EAX );
5.173 - MOVL_r32_rspdisp(REG_EAX, 0);
5.174 + MOVL_r32_r32(REG_EAX, REG_SAVE1);
5.175 MEM_READ_BYTE_FOR_WRITE( REG_EAX, REG_EDX );
5.176 - MOVL_rspdisp_r32(0, REG_EAX);
5.177 + MOVL_r32_r32(REG_SAVE1, REG_EAX);
5.178 ANDL_imms_r32(imm, REG_EDX );
5.179 MEM_WRITE_BYTE( REG_EAX, REG_EDX );
5.180 sh4_x86.tstate = TSTATE_NONE;
5.181 @@ -1044,7 +1073,7 @@
5.182 load_reg( REG_EAX, Rm );
5.183 check_ralign32( REG_EAX );
5.184 MEM_READ_LONG( REG_EAX, REG_EAX );
5.185 - MOVL_r32_rspdisp(REG_EAX, 0);
5.186 + MOVL_r32_r32(REG_EAX, REG_SAVE1);
5.187 load_reg( REG_EAX, Rm );
5.188 LEAL_r32disp_r32( REG_EAX, 4, REG_EAX );
5.189 MEM_READ_LONG( REG_EAX, REG_EAX );
5.190 @@ -1053,7 +1082,7 @@
5.191 load_reg( REG_EAX, Rm );
5.192 check_ralign32( REG_EAX );
5.193 MEM_READ_LONG( REG_EAX, REG_EAX );
5.194 - MOVL_r32_rspdisp( REG_EAX, 0 );
5.195 + MOVL_r32_r32(REG_EAX, REG_SAVE1);
5.196 load_reg( REG_EAX, Rn );
5.197 check_ralign32( REG_EAX );
5.198 MEM_READ_LONG( REG_EAX, REG_EAX );
5.199 @@ -1061,7 +1090,7 @@
5.200 ADDL_imms_rbpdisp( 4, REG_OFFSET(r[Rm]) );
5.201 }
5.202
5.203 - IMULL_rspdisp( 0 );
5.204 + IMULL_r32( REG_SAVE1 );
5.205 ADDL_r32_rbpdisp( REG_EAX, R_MACL );
5.206 ADCL_r32_rbpdisp( REG_EDX, R_MACH );
5.207
5.208 @@ -1078,7 +1107,7 @@
5.209 load_reg( REG_EAX, Rm );
5.210 check_ralign16( REG_EAX );
5.211 MEM_READ_WORD( REG_EAX, REG_EAX );
5.212 - MOVL_r32_rspdisp( REG_EAX, 0 );
5.213 + MOVL_r32_r32( REG_EAX, REG_SAVE1 );
5.214 load_reg( REG_EAX, Rm );
5.215 LEAL_r32disp_r32( REG_EAX, 2, REG_EAX );
5.216 MEM_READ_WORD( REG_EAX, REG_EAX );
5.217 @@ -1089,14 +1118,14 @@
5.218 load_reg( REG_EAX, Rn );
5.219 check_ralign16( REG_EAX );
5.220 MEM_READ_WORD( REG_EAX, REG_EAX );
5.221 - MOVL_r32_rspdisp( REG_EAX, 0 );
5.222 + MOVL_r32_r32( REG_EAX, REG_SAVE1 );
5.223 load_reg( REG_EAX, Rm );
5.224 check_ralign16( REG_EAX );
5.225 MEM_READ_WORD( REG_EAX, REG_EAX );
5.226 ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rn]) );
5.227 ADDL_imms_rbpdisp( 2, REG_OFFSET(r[Rm]) );
5.228 }
5.229 - IMULL_rspdisp( 0 );
5.230 + IMULL_r32( REG_SAVE1 );
5.231 MOVL_rbpdisp_r32( R_S, REG_ECX );
5.232 TESTL_r32_r32( REG_ECX, REG_ECX );
5.233 JE_label( nosat );
5.234 @@ -1195,9 +1224,9 @@
5.235 COUNT_INST(I_ORB);
5.236 load_reg( REG_EAX, 0 );
5.237 ADDL_rbpdisp_r32( R_GBR, REG_EAX );
5.238 - MOVL_r32_rspdisp( REG_EAX, 0 );
5.239 + MOVL_r32_r32( REG_EAX, REG_SAVE1 );
5.240 MEM_READ_BYTE_FOR_WRITE( REG_EAX, REG_EDX );
5.241 - MOVL_rspdisp_r32( 0, REG_EAX );
5.242 + MOVL_r32_r32( REG_SAVE1, REG_EAX );
5.243 ORL_imms_r32(imm, REG_EDX );
5.244 MEM_WRITE_BYTE( REG_EAX, REG_EDX );
5.245 sh4_x86.tstate = TSTATE_NONE;
5.246 @@ -1413,12 +1442,12 @@
5.247 TAS.B @Rn {:
5.248 COUNT_INST(I_TASB);
5.249 load_reg( REG_EAX, Rn );
5.250 - MOVL_r32_rspdisp( REG_EAX, 0 );
5.251 + MOVL_r32_r32( REG_EAX, REG_SAVE1 );
5.252 MEM_READ_BYTE_FOR_WRITE( REG_EAX, REG_EDX );
5.253 TESTB_r8_r8( REG_DL, REG_DL );
5.254 SETE_t();
5.255 ORB_imms_r8( 0x80, REG_DL );
5.256 - MOVL_rspdisp_r32( 0, REG_EAX );
5.257 + MOVL_r32_r32( REG_SAVE1, REG_EAX );
5.258 MEM_WRITE_BYTE( REG_EAX, REG_EDX );
5.259 sh4_x86.tstate = TSTATE_NONE;
5.260 :}
5.261 @@ -1465,9 +1494,9 @@
5.262 COUNT_INST(I_XORB);
5.263 load_reg( REG_EAX, 0 );
5.264 ADDL_rbpdisp_r32( R_GBR, REG_EAX );
5.265 - MOVL_r32_rspdisp( REG_EAX, 0 );
5.266 + MOVL_r32_r32( REG_EAX, REG_SAVE1 );
5.267 MEM_READ_BYTE_FOR_WRITE(REG_EAX, REG_EDX);
5.268 - MOVL_rspdisp_r32( 0, REG_EAX );
5.269 + MOVL_r32_r32( REG_SAVE1, REG_EAX );
5.270 XORL_imms_r32( imm, REG_EDX );
5.271 MEM_WRITE_BYTE( REG_EAX, REG_EDX );
5.272 sh4_x86.tstate = TSTATE_NONE;
6.1 --- a/src/xlat/x86/amd64abi.h Sat Aug 04 08:46:28 2012 +1000
6.2 +++ b/src/xlat/x86/amd64abi.h Fri Aug 24 08:53:50 2012 +1000
6.3 @@ -22,13 +22,18 @@
6.4 #define REG_ARG3 REG_RDX
6.5 #define REG_RESULT1 REG_RAX
6.6 #define MAX_REG_ARG 3 /* There's more, but we don't use more than 3 here anyway */
6.7 +#define REG_SAVE1 REG_R12
6.8 +#define REG_SAVE2 REG_R13
6.9 +#define REG_SAVE3 REG_R14
6.10 +#define REG_SAVE4 REG_R15
6.11 +#define REG_CALLPTR REG_EBX
6.12
6.13 -static inline void decode_address( uintptr_t base, int addr_reg )
6.14 +static inline void decode_address( uintptr_t base, int addr_reg, int target_reg )
6.15 {
6.16 - MOVL_r32_r32( addr_reg, REG_ECX );
6.17 - SHRL_imm_r32( 12, REG_ECX );
6.18 + MOVL_r32_r32( addr_reg, target_reg );
6.19 + SHRL_imm_r32( 12, target_reg );
6.20 MOVP_immptr_rptr( base, REG_RDI );
6.21 - MOVP_sib_rptr( 3, REG_RCX, REG_RDI, 0, REG_RCX );
6.22 + MOVP_sib_rptr( 3, target_reg, REG_RDI, 0, target_reg );
6.23 }
6.24
6.25 /**
7.1 --- a/src/xlat/x86/ia32abi.h Sat Aug 04 08:46:28 2012 +1000
7.2 +++ b/src/xlat/x86/ia32abi.h Fri Aug 24 08:53:50 2012 +1000
7.3 @@ -23,14 +23,18 @@
7.4
7.5 #define REG_ARG1 REG_EAX
7.6 #define REG_ARG2 REG_EDX
7.7 +#define REG_ARG3 REG_ECX
7.8 #define REG_RESULT1 REG_EAX
7.9 -#define MAX_REG_ARG 2
7.10 +#define MAX_REG_ARG 3
7.11 +#define REG_SAVE1 REG_ESI
7.12 +#define REG_SAVE2 REG_EDI
7.13 +#define REG_CALLPTR REG_EBX
7.14
7.15 -static inline void decode_address( uintptr_t base, int addr_reg )
7.16 +static inline void decode_address( uintptr_t base, int addr_reg, int target_reg )
7.17 {
7.18 - MOVL_r32_r32( addr_reg, REG_ECX );
7.19 - SHRL_imm_r32( 12, REG_ECX );
7.20 - MOVP_sib_rptr( 2, REG_ECX, -1, base, REG_ECX );
7.21 + MOVL_r32_r32( addr_reg, target_reg );
7.22 + SHRL_imm_r32( 12, target_reg );
7.23 + MOVP_sib_rptr( 2, target_reg, -1, base, target_reg );
7.24 }
7.25
7.26 /**
7.27 @@ -84,7 +88,19 @@
7.28 CALL_r32disp(preg, disp);
7.29 }
7.30
7.31 -#define CALL3_r32disp_r32_r32_r32(preg,disp,arg1,arg2,arg3) CALL2_r32disp_r32_r32(preg,disp,arg1,arg2)
7.32 +static inline void CALL3_r32disp_r32_r32_r32( int preg, uint32_t disp, int arg1, int arg2, int arg3)
7.33 +{
7.34 + if( arg3 != REG_ARG3 ) {
7.35 + MOVL_r32_r32( arg3, REG_ARG3 );
7.36 + }
7.37 + if( arg2 != REG_ARG2 ) {
7.38 + MOVL_r32_r32( arg2, REG_ARG2 );
7.39 + }
7.40 + if( arg1 != REG_ARG1 ) {
7.41 + MOVL_r32_r32( arg1, REG_ARG1 );
7.42 + }
7.43 + CALL_r32disp(preg, disp);
7.44 +}
7.45
7.46 #else
7.47
.