summaryrefslogtreecommitdiff
path: root/src/common/x64/abi.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/common/x64/abi.cpp127
1 files changed, 57 insertions, 70 deletions
diff --git a/src/common/x64/abi.cpp b/src/common/x64/abi.cpp
index 955eb86ce..504b9c940 100644
--- a/src/common/x64/abi.cpp
+++ b/src/common/x64/abi.cpp
@@ -22,7 +22,8 @@ using namespace Gen;
22 22
23// Shared code between Win64 and Unix64 23// Shared code between Win64 and Unix64
24 24
25void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size, size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp) { 25void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size,
26 size_t* shadowp, size_t* subtractionp, size_t* xmm_offsetp) {
26 size_t shadow = 0; 27 size_t shadow = 0;
27#if defined(_WIN32) 28#if defined(_WIN32)
28 shadow = 0x20; 29 shadow = 0x20;
@@ -49,17 +50,19 @@ void XEmitter::ABI_CalculateFrameSize(BitSet32 mask, size_t rsp_alignment, size_
49 *xmm_offsetp = subtraction - xmm_base_subtraction; 50 *xmm_offsetp = subtraction - xmm_base_subtraction;
50} 51}
51 52
52size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size) { 53size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment,
54 size_t needed_frame_size) {
53 size_t shadow, subtraction, xmm_offset; 55 size_t shadow, subtraction, xmm_offset;
54 ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, &xmm_offset); 56 ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction,
57 &xmm_offset);
55 58
56 for (int r : mask & ABI_ALL_GPRS) 59 for (int r : mask& ABI_ALL_GPRS)
57 PUSH((X64Reg)r); 60 PUSH((X64Reg)r);
58 61
59 if (subtraction) 62 if (subtraction)
60 SUB(64, R(RSP), subtraction >= 0x80 ? Imm32((u32)subtraction) : Imm8((u8)subtraction)); 63 SUB(64, R(RSP), subtraction >= 0x80 ? Imm32((u32)subtraction) : Imm8((u8)subtraction));
61 64
62 for (int x : mask & ABI_ALL_FPRS) { 65 for (int x : mask& ABI_ALL_FPRS) {
63 MOVAPD(MDisp(RSP, (int)xmm_offset), (X64Reg)(x - 16)); 66 MOVAPD(MDisp(RSP, (int)xmm_offset), (X64Reg)(x - 16));
64 xmm_offset += 16; 67 xmm_offset += 16;
65 } 68 }
@@ -67,12 +70,14 @@ size_t XEmitter::ABI_PushRegistersAndAdjustStack(BitSet32 mask, size_t rsp_align
67 return shadow; 70 return shadow;
68} 71}
69 72
70void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment, size_t needed_frame_size) { 73void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignment,
74 size_t needed_frame_size) {
71 size_t shadow, subtraction, xmm_offset; 75 size_t shadow, subtraction, xmm_offset;
72 ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction, &xmm_offset); 76 ABI_CalculateFrameSize(mask, rsp_alignment, needed_frame_size, &shadow, &subtraction,
77 &xmm_offset);
73 78
74 for (int x : mask & ABI_ALL_FPRS) { 79 for (int x : mask& ABI_ALL_FPRS) {
75 MOVAPD((X64Reg) (x - 16), MDisp(RSP, (int)xmm_offset)); 80 MOVAPD((X64Reg)(x - 16), MDisp(RSP, (int)xmm_offset));
76 xmm_offset += 16; 81 xmm_offset += 16;
77 } 82 }
78 83
@@ -86,10 +91,9 @@ void XEmitter::ABI_PopRegistersAndAdjustStack(BitSet32 mask, size_t rsp_alignmen
86} 91}
87 92
88// Common functions 93// Common functions
89void XEmitter::ABI_CallFunction(const void *func) { 94void XEmitter::ABI_CallFunction(const void* func) {
90 u64 distance = u64(func) - (u64(code) + 5); 95 u64 distance = u64(func) - (u64(code) + 5);
91 if (distance >= 0x0000000080000000ULL 96 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
92 && distance < 0xFFFFFFFF80000000ULL) {
93 // Far call 97 // Far call
94 MOV(64, R(RAX), ImmPtr(func)); 98 MOV(64, R(RAX), ImmPtr(func));
95 CALLptr(R(RAX)); 99 CALLptr(R(RAX));
@@ -98,11 +102,10 @@ void XEmitter::ABI_CallFunction(const void *func) {
98 } 102 }
99} 103}
100 104
101void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) { 105void XEmitter::ABI_CallFunctionC16(const void* func, u16 param1) {
102 MOV(32, R(ABI_PARAM1), Imm32((u32)param1)); 106 MOV(32, R(ABI_PARAM1), Imm32((u32)param1));
103 u64 distance = u64(func) - (u64(code) + 5); 107 u64 distance = u64(func) - (u64(code) + 5);
104 if (distance >= 0x0000000080000000ULL 108 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
105 && distance < 0xFFFFFFFF80000000ULL) {
106 // Far call 109 // Far call
107 MOV(64, R(RAX), ImmPtr(func)); 110 MOV(64, R(RAX), ImmPtr(func));
108 CALLptr(R(RAX)); 111 CALLptr(R(RAX));
@@ -111,25 +114,23 @@ void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) {
111 } 114 }
112} 115}
113 116
114void XEmitter::ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2) { 117void XEmitter::ABI_CallFunctionCC16(const void* func, u32 param1, u16 param2) {
115 MOV(32, R(ABI_PARAM1), Imm32(param1)); 118 MOV(32, R(ABI_PARAM1), Imm32(param1));
116 MOV(32, R(ABI_PARAM2), Imm32((u32)param2)); 119 MOV(32, R(ABI_PARAM2), Imm32((u32)param2));
117 u64 distance = u64(func) - (u64(code) + 5); 120 u64 distance = u64(func) - (u64(code) + 5);
118 if (distance >= 0x0000000080000000ULL 121 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
119 && distance < 0xFFFFFFFF80000000ULL) { 122 // Far call
120 // Far call 123 MOV(64, R(RAX), ImmPtr(func));
121 MOV(64, R(RAX), ImmPtr(func)); 124 CALLptr(R(RAX));
122 CALLptr(R(RAX));
123 } else { 125 } else {
124 CALL(func); 126 CALL(func);
125 } 127 }
126} 128}
127 129
128void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) { 130void XEmitter::ABI_CallFunctionC(const void* func, u32 param1) {
129 MOV(32, R(ABI_PARAM1), Imm32(param1)); 131 MOV(32, R(ABI_PARAM1), Imm32(param1));
130 u64 distance = u64(func) - (u64(code) + 5); 132 u64 distance = u64(func) - (u64(code) + 5);
131 if (distance >= 0x0000000080000000ULL 133 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
132 && distance < 0xFFFFFFFF80000000ULL) {
133 // Far call 134 // Far call
134 MOV(64, R(RAX), ImmPtr(func)); 135 MOV(64, R(RAX), ImmPtr(func));
135 CALLptr(R(RAX)); 136 CALLptr(R(RAX));
@@ -138,12 +139,11 @@ void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) {
138 } 139 }
139} 140}
140 141
141void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) { 142void XEmitter::ABI_CallFunctionCC(const void* func, u32 param1, u32 param2) {
142 MOV(32, R(ABI_PARAM1), Imm32(param1)); 143 MOV(32, R(ABI_PARAM1), Imm32(param1));
143 MOV(32, R(ABI_PARAM2), Imm32(param2)); 144 MOV(32, R(ABI_PARAM2), Imm32(param2));
144 u64 distance = u64(func) - (u64(code) + 5); 145 u64 distance = u64(func) - (u64(code) + 5);
145 if (distance >= 0x0000000080000000ULL 146 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
146 && distance < 0xFFFFFFFF80000000ULL) {
147 // Far call 147 // Far call
148 MOV(64, R(RAX), ImmPtr(func)); 148 MOV(64, R(RAX), ImmPtr(func));
149 CALLptr(R(RAX)); 149 CALLptr(R(RAX));
@@ -152,13 +152,12 @@ void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) {
152 } 152 }
153} 153}
154 154
155void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3) { 155void XEmitter::ABI_CallFunctionCCC(const void* func, u32 param1, u32 param2, u32 param3) {
156 MOV(32, R(ABI_PARAM1), Imm32(param1)); 156 MOV(32, R(ABI_PARAM1), Imm32(param1));
157 MOV(32, R(ABI_PARAM2), Imm32(param2)); 157 MOV(32, R(ABI_PARAM2), Imm32(param2));
158 MOV(32, R(ABI_PARAM3), Imm32(param3)); 158 MOV(32, R(ABI_PARAM3), Imm32(param3));
159 u64 distance = u64(func) - (u64(code) + 5); 159 u64 distance = u64(func) - (u64(code) + 5);
160 if (distance >= 0x0000000080000000ULL 160 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
161 && distance < 0xFFFFFFFF80000000ULL) {
162 // Far call 161 // Far call
163 MOV(64, R(RAX), ImmPtr(func)); 162 MOV(64, R(RAX), ImmPtr(func));
164 CALLptr(R(RAX)); 163 CALLptr(R(RAX));
@@ -167,13 +166,12 @@ void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32
167 } 166 }
168} 167}
169 168
170void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) { 169void XEmitter::ABI_CallFunctionCCP(const void* func, u32 param1, u32 param2, void* param3) {
171 MOV(32, R(ABI_PARAM1), Imm32(param1)); 170 MOV(32, R(ABI_PARAM1), Imm32(param1));
172 MOV(32, R(ABI_PARAM2), Imm32(param2)); 171 MOV(32, R(ABI_PARAM2), Imm32(param2));
173 MOV(64, R(ABI_PARAM3), ImmPtr(param3)); 172 MOV(64, R(ABI_PARAM3), ImmPtr(param3));
174 u64 distance = u64(func) - (u64(code) + 5); 173 u64 distance = u64(func) - (u64(code) + 5);
175 if (distance >= 0x0000000080000000ULL 174 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
176 && distance < 0xFFFFFFFF80000000ULL) {
177 // Far call 175 // Far call
178 MOV(64, R(RAX), ImmPtr(func)); 176 MOV(64, R(RAX), ImmPtr(func));
179 CALLptr(R(RAX)); 177 CALLptr(R(RAX));
@@ -182,14 +180,14 @@ void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, voi
182 } 180 }
183} 181}
184 182
185void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u32 param3, void *param4) { 183void XEmitter::ABI_CallFunctionCCCP(const void* func, u32 param1, u32 param2, u32 param3,
184 void* param4) {
186 MOV(32, R(ABI_PARAM1), Imm32(param1)); 185 MOV(32, R(ABI_PARAM1), Imm32(param1));
187 MOV(32, R(ABI_PARAM2), Imm32(param2)); 186 MOV(32, R(ABI_PARAM2), Imm32(param2));
188 MOV(32, R(ABI_PARAM3), Imm32(param3)); 187 MOV(32, R(ABI_PARAM3), Imm32(param3));
189 MOV(64, R(ABI_PARAM4), ImmPtr(param4)); 188 MOV(64, R(ABI_PARAM4), ImmPtr(param4));
190 u64 distance = u64(func) - (u64(code) + 5); 189 u64 distance = u64(func) - (u64(code) + 5);
191 if (distance >= 0x0000000080000000ULL 190 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
192 && distance < 0xFFFFFFFF80000000ULL) {
193 // Far call 191 // Far call
194 MOV(64, R(RAX), ImmPtr(func)); 192 MOV(64, R(RAX), ImmPtr(func));
195 CALLptr(R(RAX)); 193 CALLptr(R(RAX));
@@ -198,11 +196,10 @@ void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u3
198 } 196 }
199} 197}
200 198
201void XEmitter::ABI_CallFunctionP(const void *func, void *param1) { 199void XEmitter::ABI_CallFunctionP(const void* func, void* param1) {
202 MOV(64, R(ABI_PARAM1), ImmPtr(param1)); 200 MOV(64, R(ABI_PARAM1), ImmPtr(param1));
203 u64 distance = u64(func) - (u64(code) + 5); 201 u64 distance = u64(func) - (u64(code) + 5);
204 if (distance >= 0x0000000080000000ULL 202 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
205 && distance < 0xFFFFFFFF80000000ULL) {
206 // Far call 203 // Far call
207 MOV(64, R(RAX), ImmPtr(func)); 204 MOV(64, R(RAX), ImmPtr(func));
208 CALLptr(R(RAX)); 205 CALLptr(R(RAX));
@@ -211,13 +208,12 @@ void XEmitter::ABI_CallFunctionP(const void *func, void *param1) {
211 } 208 }
212} 209}
213 210
214void XEmitter::ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpArg &arg2) { 211void XEmitter::ABI_CallFunctionPA(const void* func, void* param1, const Gen::OpArg& arg2) {
215 MOV(64, R(ABI_PARAM1), ImmPtr(param1)); 212 MOV(64, R(ABI_PARAM1), ImmPtr(param1));
216 if (!arg2.IsSimpleReg(ABI_PARAM2)) 213 if (!arg2.IsSimpleReg(ABI_PARAM2))
217 MOV(32, R(ABI_PARAM2), arg2); 214 MOV(32, R(ABI_PARAM2), arg2);
218 u64 distance = u64(func) - (u64(code) + 5); 215 u64 distance = u64(func) - (u64(code) + 5);
219 if (distance >= 0x0000000080000000ULL 216 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
220 && distance < 0xFFFFFFFF80000000ULL) {
221 // Far call 217 // Far call
222 MOV(64, R(RAX), ImmPtr(func)); 218 MOV(64, R(RAX), ImmPtr(func));
223 CALLptr(R(RAX)); 219 CALLptr(R(RAX));
@@ -226,15 +222,15 @@ void XEmitter::ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpA
226 } 222 }
227} 223}
228 224
229void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::OpArg &arg2, const Gen::OpArg &arg3) { 225void XEmitter::ABI_CallFunctionPAA(const void* func, void* param1, const Gen::OpArg& arg2,
226 const Gen::OpArg& arg3) {
230 MOV(64, R(ABI_PARAM1), ImmPtr(param1)); 227 MOV(64, R(ABI_PARAM1), ImmPtr(param1));
231 if (!arg2.IsSimpleReg(ABI_PARAM2)) 228 if (!arg2.IsSimpleReg(ABI_PARAM2))
232 MOV(32, R(ABI_PARAM2), arg2); 229 MOV(32, R(ABI_PARAM2), arg2);
233 if (!arg3.IsSimpleReg(ABI_PARAM3)) 230 if (!arg3.IsSimpleReg(ABI_PARAM3))
234 MOV(32, R(ABI_PARAM3), arg3); 231 MOV(32, R(ABI_PARAM3), arg3);
235 u64 distance = u64(func) - (u64(code) + 5); 232 u64 distance = u64(func) - (u64(code) + 5);
236 if (distance >= 0x0000000080000000ULL 233 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
237 && distance < 0xFFFFFFFF80000000ULL) {
238 // Far call 234 // Far call
239 MOV(64, R(RAX), ImmPtr(func)); 235 MOV(64, R(RAX), ImmPtr(func));
240 CALLptr(R(RAX)); 236 CALLptr(R(RAX));
@@ -243,13 +239,12 @@ void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::Op
243 } 239 }
244} 240}
245 241
246void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) { 242void XEmitter::ABI_CallFunctionPPC(const void* func, void* param1, void* param2, u32 param3) {
247 MOV(64, R(ABI_PARAM1), ImmPtr(param1)); 243 MOV(64, R(ABI_PARAM1), ImmPtr(param1));
248 MOV(64, R(ABI_PARAM2), ImmPtr(param2)); 244 MOV(64, R(ABI_PARAM2), ImmPtr(param2));
249 MOV(32, R(ABI_PARAM3), Imm32(param3)); 245 MOV(32, R(ABI_PARAM3), Imm32(param3));
250 u64 distance = u64(func) - (u64(code) + 5); 246 u64 distance = u64(func) - (u64(code) + 5);
251 if (distance >= 0x0000000080000000ULL 247 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
252 && distance < 0xFFFFFFFF80000000ULL) {
253 // Far call 248 // Far call
254 MOV(64, R(RAX), ImmPtr(func)); 249 MOV(64, R(RAX), ImmPtr(func));
255 CALLptr(R(RAX)); 250 CALLptr(R(RAX));
@@ -259,12 +254,11 @@ void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2,
259} 254}
260 255
261// Pass a register as a parameter. 256// Pass a register as a parameter.
262void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) { 257void XEmitter::ABI_CallFunctionR(const void* func, X64Reg reg1) {
263 if (reg1 != ABI_PARAM1) 258 if (reg1 != ABI_PARAM1)
264 MOV(32, R(ABI_PARAM1), R(reg1)); 259 MOV(32, R(ABI_PARAM1), R(reg1));
265 u64 distance = u64(func) - (u64(code) + 5); 260 u64 distance = u64(func) - (u64(code) + 5);
266 if (distance >= 0x0000000080000000ULL 261 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
267 && distance < 0xFFFFFFFF80000000ULL) {
268 // Far call 262 // Far call
269 MOV(64, R(RAX), ImmPtr(func)); 263 MOV(64, R(RAX), ImmPtr(func));
270 CALLptr(R(RAX)); 264 CALLptr(R(RAX));
@@ -274,7 +268,7 @@ void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) {
274} 268}
275 269
276// Pass two registers as parameters. 270// Pass two registers as parameters.
277void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) { 271void XEmitter::ABI_CallFunctionRR(const void* func, X64Reg reg1, X64Reg reg2) {
278 if (reg2 != ABI_PARAM1) { 272 if (reg2 != ABI_PARAM1) {
279 if (reg1 != ABI_PARAM1) 273 if (reg1 != ABI_PARAM1)
280 MOV(64, R(ABI_PARAM1), R(reg1)); 274 MOV(64, R(ABI_PARAM1), R(reg1));
@@ -287,8 +281,7 @@ void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) {
287 MOV(64, R(ABI_PARAM1), R(reg1)); 281 MOV(64, R(ABI_PARAM1), R(reg1));
288 } 282 }
289 u64 distance = u64(func) - (u64(code) + 5); 283 u64 distance = u64(func) - (u64(code) + 5);
290 if (distance >= 0x0000000080000000ULL 284 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
291 && distance < 0xFFFFFFFF80000000ULL) {
292 // Far call 285 // Far call
293 MOV(64, R(RAX), ImmPtr(func)); 286 MOV(64, R(RAX), ImmPtr(func));
294 CALLptr(R(RAX)); 287 CALLptr(R(RAX));
@@ -297,14 +290,12 @@ void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) {
297 } 290 }
298} 291}
299 292
300void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2) 293void XEmitter::ABI_CallFunctionAC(const void* func, const Gen::OpArg& arg1, u32 param2) {
301{
302 if (!arg1.IsSimpleReg(ABI_PARAM1)) 294 if (!arg1.IsSimpleReg(ABI_PARAM1))
303 MOV(32, R(ABI_PARAM1), arg1); 295 MOV(32, R(ABI_PARAM1), arg1);
304 MOV(32, R(ABI_PARAM2), Imm32(param2)); 296 MOV(32, R(ABI_PARAM2), Imm32(param2));
305 u64 distance = u64(func) - (u64(code) + 5); 297 u64 distance = u64(func) - (u64(code) + 5);
306 if (distance >= 0x0000000080000000ULL 298 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
307 && distance < 0xFFFFFFFF80000000ULL) {
308 // Far call 299 // Far call
309 MOV(64, R(RAX), ImmPtr(func)); 300 MOV(64, R(RAX), ImmPtr(func));
310 CALLptr(R(RAX)); 301 CALLptr(R(RAX));
@@ -313,15 +304,14 @@ void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32
313 } 304 }
314} 305}
315 306
316void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3) 307void XEmitter::ABI_CallFunctionACC(const void* func, const Gen::OpArg& arg1, u32 param2,
317{ 308 u32 param3) {
318 if (!arg1.IsSimpleReg(ABI_PARAM1)) 309 if (!arg1.IsSimpleReg(ABI_PARAM1))
319 MOV(32, R(ABI_PARAM1), arg1); 310 MOV(32, R(ABI_PARAM1), arg1);
320 MOV(32, R(ABI_PARAM2), Imm32(param2)); 311 MOV(32, R(ABI_PARAM2), Imm32(param2));
321 MOV(64, R(ABI_PARAM3), Imm64(param3)); 312 MOV(64, R(ABI_PARAM3), Imm64(param3));
322 u64 distance = u64(func) - (u64(code) + 5); 313 u64 distance = u64(func) - (u64(code) + 5);
323 if (distance >= 0x0000000080000000ULL 314 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
324 && distance < 0xFFFFFFFF80000000ULL) {
325 // Far call 315 // Far call
326 MOV(64, R(RAX), ImmPtr(func)); 316 MOV(64, R(RAX), ImmPtr(func));
327 CALLptr(R(RAX)); 317 CALLptr(R(RAX));
@@ -330,13 +320,11 @@ void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32
330 } 320 }
331} 321}
332 322
333void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1) 323void XEmitter::ABI_CallFunctionA(const void* func, const Gen::OpArg& arg1) {
334{
335 if (!arg1.IsSimpleReg(ABI_PARAM1)) 324 if (!arg1.IsSimpleReg(ABI_PARAM1))
336 MOV(32, R(ABI_PARAM1), arg1); 325 MOV(32, R(ABI_PARAM1), arg1);
337 u64 distance = u64(func) - (u64(code) + 5); 326 u64 distance = u64(func) - (u64(code) + 5);
338 if (distance >= 0x0000000080000000ULL 327 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
339 && distance < 0xFFFFFFFF80000000ULL) {
340 // Far call 328 // Far call
341 MOV(64, R(RAX), ImmPtr(func)); 329 MOV(64, R(RAX), ImmPtr(func));
342 CALLptr(R(RAX)); 330 CALLptr(R(RAX));
@@ -345,15 +333,14 @@ void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1)
345 } 333 }
346} 334}
347 335
348void XEmitter::ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2) 336void XEmitter::ABI_CallFunctionAA(const void* func, const Gen::OpArg& arg1,
349{ 337 const Gen::OpArg& arg2) {
350 if (!arg1.IsSimpleReg(ABI_PARAM1)) 338 if (!arg1.IsSimpleReg(ABI_PARAM1))
351 MOV(32, R(ABI_PARAM1), arg1); 339 MOV(32, R(ABI_PARAM1), arg1);
352 if (!arg2.IsSimpleReg(ABI_PARAM2)) 340 if (!arg2.IsSimpleReg(ABI_PARAM2))
353 MOV(32, R(ABI_PARAM2), arg2); 341 MOV(32, R(ABI_PARAM2), arg2);
354 u64 distance = u64(func) - (u64(code) + 5); 342 u64 distance = u64(func) - (u64(code) + 5);
355 if (distance >= 0x0000000080000000ULL 343 if (distance >= 0x0000000080000000ULL && distance < 0xFFFFFFFF80000000ULL) {
356 && distance < 0xFFFFFFFF80000000ULL) {
357 // Far call 344 // Far call
358 MOV(64, R(RAX), ImmPtr(func)); 345 MOV(64, R(RAX), ImmPtr(func));
359 CALLptr(R(RAX)); 346 CALLptr(R(RAX));