~ppsspp/ppsspp/ppsspp_1.3.0

« back to all changes in this revision

Viewing changes to Common/ABI.cpp

  • Committer: Sérgio Benjamim
  • Date: 2017-01-02 00:12:05 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20170102001205-cxbta9za203nmjwm
1.3.0 source (from ppsspp_1.3.0-r160.p5.l1762.a165.t83~56~ubuntu16.04.1.tar.xz).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2003 Dolphin Project.
 
2
 
 
3
// This program is free software: you can redistribute it and/or modify
 
4
// it under the terms of the GNU General Public License as published by
 
5
// the Free Software Foundation, version 2.0 or later versions.
 
6
 
 
7
// This program is distributed in the hope that it will be useful,
 
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
// GNU General Public License 2.0 for more details.
 
11
 
 
12
// A copy of the GPL 2.0 should have been included with the program.
 
13
// If not, see http://www.gnu.org/licenses/
 
14
 
 
15
// Official SVN repository and contact information can be found at
 
16
// http://code.google.com/p/dolphin-emu/
 
17
 
 
18
#include "x64Emitter.h"
 
19
#include "ABI.h"
 
20
 
 
21
using namespace Gen;
 
22
 
 
23
// Shared code between Win64 and Unix64
 
24
 
 
25
// Sets up a __cdecl function.
 
26
void XEmitter::ABI_EmitPrologue(int maxCallParams)
 
27
{
 
28
#ifdef _M_IX86
 
29
        // Don't really need to do anything
 
30
#elif defined(_M_X64)
 
31
#if _WIN32
 
32
        int stacksize = ((maxCallParams + 1) & ~1) * 8 + 8;
 
33
        // Set up a stack frame so that we can call functions
 
34
        // TODO: use maxCallParams
 
35
    SUB(64, R(RSP), Imm8(stacksize));
 
36
#endif
 
37
#else
 
38
#error Arch not supported
 
39
#endif
 
40
}
 
41
 
 
42
void XEmitter::ABI_EmitEpilogue(int maxCallParams)
 
43
{
 
44
#ifdef _M_IX86
 
45
        RET();
 
46
#elif defined(_M_X64)
 
47
#ifdef _WIN32
 
48
        int stacksize = ((maxCallParams+1)&~1)*8 + 8;
 
49
        ADD(64, R(RSP), Imm8(stacksize));
 
50
#endif
 
51
        RET();
 
52
#else
 
53
#error Arch not supported
 
54
 
 
55
 
 
56
#endif
 
57
}
 
58
 
 
59
#ifdef _M_IX86 // All32
 
60
 
 
61
// Shared code between Win32 and Unix32
 
62
void XEmitter::ABI_CallFunction(const void *func) {
 
63
        ABI_AlignStack(0);
 
64
        CALL(func);
 
65
        ABI_RestoreStack(0);
 
66
}
 
67
 
 
68
void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) {
 
69
        ABI_AlignStack(1 * 2);
 
70
        PUSH(16, Imm16(param1));
 
71
        CALL(func);
 
72
        ABI_RestoreStack(1 * 2);
 
73
}
 
74
 
 
75
void XEmitter::ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2) {
 
76
        ABI_AlignStack(1 * 2 + 1 * 4);
 
77
        PUSH(16, Imm16(param2));
 
78
        PUSH(32, Imm32(param1));
 
79
        CALL(func);
 
80
        ABI_RestoreStack(1 * 2 + 1 * 4);
 
81
}
 
82
 
 
83
void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) {
 
84
        ABI_AlignStack(1 * 4);
 
85
        PUSH(32, Imm32(param1));
 
86
        CALL(func);
 
87
        ABI_RestoreStack(1 * 4);
 
88
}
 
89
 
 
90
void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) {
 
91
        ABI_AlignStack(2 * 4);
 
92
        PUSH(32, Imm32(param2));
 
93
        PUSH(32, Imm32(param1));
 
94
        CALL(func);
 
95
        ABI_RestoreStack(2 * 4);
 
96
}
 
97
 
 
98
void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3) {
 
99
        ABI_AlignStack(3 * 4);
 
100
        PUSH(32, Imm32(param3));
 
101
        PUSH(32, Imm32(param2));
 
102
        PUSH(32, Imm32(param1));
 
103
        CALL(func);
 
104
        ABI_RestoreStack(3 * 4);
 
105
}
 
106
 
 
107
void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) {
 
108
        ABI_AlignStack(3 * 4);
 
109
        PUSH(32, ImmPtr(param3));
 
110
        PUSH(32, Imm32(param2));
 
111
        PUSH(32, Imm32(param1));
 
112
        CALL(func);
 
113
        ABI_RestoreStack(3 * 4);
 
114
}
 
115
 
 
116
void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2,u32 param3, void *param4) {
 
117
        ABI_AlignStack(4 * 4);
 
118
        PUSH(32, ImmPtr(param4));
 
119
        PUSH(32, Imm32(param3));
 
120
        PUSH(32, Imm32(param2));
 
121
        PUSH(32, Imm32(param1));
 
122
        CALL(func);
 
123
        ABI_RestoreStack(4 * 4);
 
124
}
 
125
 
 
126
void XEmitter::ABI_CallFunctionP(const void *func, void *param1) {
 
127
        ABI_AlignStack(1 * 4);
 
128
        PUSH(32, ImmPtr(param1));
 
129
        CALL(func);
 
130
        ABI_RestoreStack(1 * 4);
 
131
}
 
132
 
 
133
void XEmitter::ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpArg &arg2) {
 
134
        ABI_AlignStack(2 * 4);
 
135
        PUSH(32, arg2);
 
136
        PUSH(32, ImmPtr(param1));
 
137
        CALL(func);
 
138
        ABI_RestoreStack(2 * 4);
 
139
}
 
140
 
 
141
void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::OpArg &arg2, const Gen::OpArg &arg3) {
 
142
        ABI_AlignStack(3 * 4);
 
143
        PUSH(32, arg3);
 
144
        PUSH(32, arg2);
 
145
        PUSH(32, ImmPtr(param1));
 
146
        CALL(func);
 
147
        ABI_RestoreStack(3 * 4);
 
148
}
 
149
 
 
150
void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) {
 
151
        ABI_AlignStack(3 * 4);
 
152
        PUSH(32, Imm32(param3));
 
153
        PUSH(32, ImmPtr(param2));
 
154
        PUSH(32, ImmPtr(param1));
 
155
        CALL(func);
 
156
        ABI_RestoreStack(3 * 4);
 
157
}
 
158
 
 
159
// Pass a register as a parameter.
 
160
void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) {
 
161
        ABI_AlignStack(1 * 4);
 
162
        PUSH(32, R(reg1));
 
163
        CALL(func);
 
164
        ABI_RestoreStack(1 * 4);
 
165
}
 
166
 
 
167
// Pass two registers as parameters.
 
168
void XEmitter::ABI_CallFunctionRR(const void *func, Gen::X64Reg reg1, Gen::X64Reg reg2)
 
169
{
 
170
        ABI_AlignStack(2 * 4);
 
171
        PUSH(32, R(reg2));
 
172
        PUSH(32, R(reg1));
 
173
        CALL(func);
 
174
        ABI_RestoreStack(2 * 4);
 
175
}
 
176
 
 
177
void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2)
 
178
{
 
179
        ABI_AlignStack(2 * 4);
 
180
        PUSH(32, Imm32(param2));
 
181
        PUSH(32, arg1);
 
182
        CALL(func);
 
183
        ABI_RestoreStack(2 * 4);
 
184
}
 
185
 
 
186
void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
 
187
{
 
188
        ABI_AlignStack(3 * 4);
 
189
        PUSH(32, Imm32(param3));
 
190
        PUSH(32, Imm32(param2));
 
191
        PUSH(32, arg1);
 
192
        CALL(func);
 
193
        ABI_RestoreStack(3 * 4);
 
194
}
 
195
 
 
196
void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1)
 
197
{
 
198
        ABI_AlignStack(1 * 4);
 
199
        PUSH(32, arg1);
 
200
        CALL(func);
 
201
        ABI_RestoreStack(1 * 4);
 
202
}
 
203
 
 
204
void XEmitter::ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2)
 
205
{
 
206
        ABI_AlignStack(2 * 4);
 
207
        PUSH(32, arg2);
 
208
        PUSH(32, arg1);
 
209
        CALL(func);
 
210
        ABI_RestoreStack(2 * 4);
 
211
}
 
212
 
 
213
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
 
214
        // Note: 4 * 4 = 16 bytes, so alignment is preserved.
 
215
        PUSH(EBP);
 
216
        PUSH(EBX);
 
217
        PUSH(ESI);
 
218
        PUSH(EDI);
 
219
}
 
220
 
 
221
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
 
222
        POP(EDI);
 
223
        POP(ESI);
 
224
        POP(EBX);
 
225
        POP(EBP);
 
226
}
 
227
 
 
228
unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize) {
 
229
        frameSize += 4; // reserve space for return address
 
230
        unsigned int alignedSize =
 
231
#ifdef __GNUC__
 
232
                (frameSize + 15) & -16;
 
233
#else
 
234
                (frameSize + 3) & -4;
 
235
#endif
 
236
        return alignedSize;
 
237
}
 
238
 
 
239
 
 
240
void XEmitter::ABI_AlignStack(unsigned int frameSize) {
 
241
// Mac OS X requires the stack to be 16-byte aligned before every call.
 
242
// Linux requires the stack to be 16-byte aligned before calls that put SSE
 
243
// vectors on the stack, but since we do not keep track of which calls do that,
 
244
// it is effectively every call as well.
 
245
// Windows binaries compiled with MSVC do not have such a restriction*, but I
 
246
// expect that GCC on Windows acts the same as GCC on Linux in this respect.
 
247
// It would be nice if someone could verify this.
 
248
// *However, the MSVC optimizing compiler assumes a 4-byte-aligned stack at times.
 
249
        unsigned int fillSize =
 
250
                ABI_GetAlignedFrameSize(frameSize) - (frameSize + 4);
 
251
        if (fillSize != 0) {
 
252
                SUB(32, R(ESP), Imm8(fillSize));
 
253
        }
 
254
}
 
255
 
 
256
void XEmitter::ABI_RestoreStack(unsigned int frameSize) {
 
257
        unsigned int alignedSize = ABI_GetAlignedFrameSize(frameSize);
 
258
        alignedSize -= 4; // return address is POPped at end of call
 
259
        if (alignedSize != 0) {
 
260
                ADD(32, R(ESP), Imm8(alignedSize));
 
261
        }
 
262
}
 
263
 
 
264
#else //64bit
 
265
 
 
266
// Common functions
 
267
void XEmitter::ABI_CallFunction(const void *func) {
 
268
        u64 distance = u64(func) - (u64(code) + 5);
 
269
        if (distance >= 0x0000000080000000ULL
 
270
         && distance <  0xFFFFFFFF80000000ULL) {
 
271
            // Far call
 
272
            MOV(64, R(RAX), ImmPtr(func));
 
273
            CALLptr(R(RAX));
 
274
        } else {
 
275
            CALL(func);
 
276
        }
 
277
}
 
278
 
 
279
void XEmitter::ABI_CallFunctionC16(const void *func, u16 param1) {
 
280
        MOV(32, R(ABI_PARAM1), Imm32((u32)param1));
 
281
        u64 distance = u64(func) - (u64(code) + 5);
 
282
        if (distance >= 0x0000000080000000ULL
 
283
         && distance <  0xFFFFFFFF80000000ULL) {
 
284
            // Far call
 
285
            MOV(64, R(RAX), ImmPtr(func));
 
286
            CALLptr(R(RAX));
 
287
        } else {
 
288
            CALL(func);
 
289
        }
 
290
}
 
291
 
 
292
void XEmitter::ABI_CallFunctionCC16(const void *func, u32 param1, u16 param2) {
 
293
        MOV(32, R(ABI_PARAM1), Imm32(param1));
 
294
        MOV(32, R(ABI_PARAM2), Imm32((u32)param2));
 
295
        u64 distance = u64(func) - (u64(code) + 5);
 
296
        if (distance >= 0x0000000080000000ULL
 
297
                && distance <  0xFFFFFFFF80000000ULL) {
 
298
                        // Far call
 
299
                        MOV(64, R(RAX), ImmPtr(func));
 
300
                        CALLptr(R(RAX));
 
301
        } else {
 
302
                CALL(func);
 
303
        }
 
304
}
 
305
 
 
306
void XEmitter::ABI_CallFunctionC(const void *func, u32 param1) {
 
307
        MOV(32, R(ABI_PARAM1), Imm32(param1));
 
308
        u64 distance = u64(func) - (u64(code) + 5);
 
309
        if (distance >= 0x0000000080000000ULL
 
310
         && distance <  0xFFFFFFFF80000000ULL) {
 
311
            // Far call
 
312
            MOV(64, R(RAX), ImmPtr(func));
 
313
            CALLptr(R(RAX));
 
314
        } else {
 
315
            CALL(func);
 
316
        }
 
317
}
 
318
 
 
319
void XEmitter::ABI_CallFunctionCC(const void *func, u32 param1, u32 param2) {
 
320
        MOV(32, R(ABI_PARAM1), Imm32(param1));
 
321
        MOV(32, R(ABI_PARAM2), Imm32(param2));
 
322
        u64 distance = u64(func) - (u64(code) + 5);
 
323
        if (distance >= 0x0000000080000000ULL
 
324
         && distance <  0xFFFFFFFF80000000ULL) {
 
325
            // Far call
 
326
            MOV(64, R(RAX), ImmPtr(func));
 
327
            CALLptr(R(RAX));
 
328
        } else {
 
329
            CALL(func);
 
330
        }
 
331
}
 
332
 
 
333
void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3) {
 
334
        MOV(32, R(ABI_PARAM1), Imm32(param1));
 
335
        MOV(32, R(ABI_PARAM2), Imm32(param2));
 
336
        MOV(32, R(ABI_PARAM3), Imm32(param3));
 
337
        u64 distance = u64(func) - (u64(code) + 5);
 
338
        if (distance >= 0x0000000080000000ULL
 
339
         && distance <  0xFFFFFFFF80000000ULL) {
 
340
            // Far call
 
341
            MOV(64, R(RAX), ImmPtr(func));
 
342
            CALLptr(R(RAX));
 
343
        } else {
 
344
            CALL(func);
 
345
        }
 
346
}
 
347
 
 
348
void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) {
 
349
        MOV(32, R(ABI_PARAM1), Imm32(param1));
 
350
        MOV(32, R(ABI_PARAM2), Imm32(param2));
 
351
        MOV(64, R(ABI_PARAM3), ImmPtr(param3));
 
352
        u64 distance = u64(func) - (u64(code) + 5);
 
353
        if (distance >= 0x0000000080000000ULL
 
354
         && distance <  0xFFFFFFFF80000000ULL) {
 
355
            // Far call
 
356
            MOV(64, R(RAX), ImmPtr(func));
 
357
            CALLptr(R(RAX));
 
358
        } else {
 
359
            CALL(func);
 
360
        }
 
361
}
 
362
 
 
363
void XEmitter::ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u32 param3, void *param4) {
 
364
        MOV(32, R(ABI_PARAM1), Imm32(param1));
 
365
        MOV(32, R(ABI_PARAM2), Imm32(param2));
 
366
        MOV(32, R(ABI_PARAM3), Imm32(param3));
 
367
        MOV(64, R(ABI_PARAM4), ImmPtr(param4));
 
368
        u64 distance = u64(func) - (u64(code) + 5);
 
369
        if (distance >= 0x0000000080000000ULL
 
370
         && distance <  0xFFFFFFFF80000000ULL) {
 
371
            // Far call
 
372
            MOV(64, R(RAX), ImmPtr(func));
 
373
            CALLptr(R(RAX));
 
374
        } else {
 
375
            CALL(func);
 
376
        }
 
377
}
 
378
 
 
379
void XEmitter::ABI_CallFunctionP(const void *func, void *param1) {
 
380
        MOV(64, R(ABI_PARAM1), ImmPtr(param1));
 
381
        u64 distance = u64(func) - (u64(code) + 5);
 
382
        if (distance >= 0x0000000080000000ULL
 
383
         && distance <  0xFFFFFFFF80000000ULL) {
 
384
            // Far call
 
385
            MOV(64, R(RAX), ImmPtr(func));
 
386
            CALLptr(R(RAX));
 
387
        } else {
 
388
            CALL(func);
 
389
        }
 
390
}
 
391
 
 
392
void XEmitter::ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpArg &arg2) {
 
393
        MOV(64, R(ABI_PARAM1), ImmPtr(param1));
 
394
        if (!arg2.IsSimpleReg(ABI_PARAM2))
 
395
                MOV(32, R(ABI_PARAM2), arg2);
 
396
        u64 distance = u64(func) - (u64(code) + 5);
 
397
        if (distance >= 0x0000000080000000ULL
 
398
         && distance <  0xFFFFFFFF80000000ULL) {
 
399
            // Far call
 
400
            MOV(64, R(RAX), ImmPtr(func));
 
401
            CALLptr(R(RAX));
 
402
        } else {
 
403
            CALL(func);
 
404
        }
 
405
}
 
406
 
 
407
void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::OpArg &arg2, const Gen::OpArg &arg3) {
 
408
        MOV(64, R(ABI_PARAM1), ImmPtr(param1));
 
409
        if (!arg2.IsSimpleReg(ABI_PARAM2))
 
410
                MOV(32, R(ABI_PARAM2), arg2);
 
411
        if (!arg3.IsSimpleReg(ABI_PARAM3))
 
412
                MOV(32, R(ABI_PARAM3), arg3);
 
413
        u64 distance = u64(func) - (u64(code) + 5);
 
414
        if (distance >= 0x0000000080000000ULL
 
415
         && distance <  0xFFFFFFFF80000000ULL) {
 
416
            // Far call
 
417
            MOV(64, R(RAX), ImmPtr(func));
 
418
            CALLptr(R(RAX));
 
419
        } else {
 
420
            CALL(func);
 
421
        }
 
422
}
 
423
 
 
424
void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) {
 
425
        MOV(64, R(ABI_PARAM1), ImmPtr(param1));
 
426
        MOV(64, R(ABI_PARAM2), ImmPtr(param2));
 
427
        MOV(32, R(ABI_PARAM3), Imm32(param3));
 
428
        u64 distance = u64(func) - (u64(code) + 5);
 
429
        if (distance >= 0x0000000080000000ULL
 
430
         && distance <  0xFFFFFFFF80000000ULL) {
 
431
            // Far call
 
432
            MOV(64, R(RAX), ImmPtr(func));
 
433
            CALLptr(R(RAX));
 
434
        } else {
 
435
            CALL(func);
 
436
        }
 
437
}
 
438
 
 
439
// Pass a register as a parameter.
 
440
void XEmitter::ABI_CallFunctionR(const void *func, X64Reg reg1) {
 
441
        if (reg1 != ABI_PARAM1)
 
442
                MOV(32, R(ABI_PARAM1), R(reg1));
 
443
        u64 distance = u64(func) - (u64(code) + 5);
 
444
        if (distance >= 0x0000000080000000ULL
 
445
         && distance <  0xFFFFFFFF80000000ULL) {
 
446
            // Far call
 
447
            MOV(64, R(RAX), ImmPtr(func));
 
448
            CALLptr(R(RAX));
 
449
        } else {
 
450
            CALL(func);
 
451
        }
 
452
}
 
453
 
 
454
// Pass two registers as parameters.
 
455
void XEmitter::ABI_CallFunctionRR(const void *func, X64Reg reg1, X64Reg reg2) {
 
456
        if (reg2 != ABI_PARAM1) {
 
457
                if (reg1 != ABI_PARAM1)
 
458
                        MOV(64, R(ABI_PARAM1), R(reg1));
 
459
                if (reg2 != ABI_PARAM2)
 
460
                        MOV(64, R(ABI_PARAM2), R(reg2));
 
461
        } else {
 
462
                if (reg2 != ABI_PARAM2)
 
463
                        MOV(64, R(ABI_PARAM2), R(reg2));
 
464
                if (reg1 != ABI_PARAM1)
 
465
                        MOV(64, R(ABI_PARAM1), R(reg1));
 
466
        }
 
467
        u64 distance = u64(func) - (u64(code) + 5);
 
468
        if (distance >= 0x0000000080000000ULL
 
469
         && distance <  0xFFFFFFFF80000000ULL) {
 
470
            // Far call
 
471
            MOV(64, R(RAX), ImmPtr(func));
 
472
            CALLptr(R(RAX));
 
473
        } else {
 
474
            CALL(func);
 
475
        }
 
476
}
 
477
 
 
478
void XEmitter::ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2)
 
479
{
 
480
        if (!arg1.IsSimpleReg(ABI_PARAM1))
 
481
                MOV(32, R(ABI_PARAM1), arg1);
 
482
        MOV(32, R(ABI_PARAM2), Imm32(param2));
 
483
        u64 distance = u64(func) - (u64(code) + 5);
 
484
        if (distance >= 0x0000000080000000ULL
 
485
         && distance <  0xFFFFFFFF80000000ULL) {
 
486
            // Far call
 
487
            MOV(64, R(RAX), ImmPtr(func));
 
488
            CALLptr(R(RAX));
 
489
        } else {
 
490
            CALL(func);
 
491
        }
 
492
}
 
493
 
 
494
void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3)
 
495
{
 
496
        if (!arg1.IsSimpleReg(ABI_PARAM1))
 
497
                MOV(32, R(ABI_PARAM1), arg1);
 
498
        MOV(32, R(ABI_PARAM2), Imm32(param2));
 
499
        MOV(64, R(ABI_PARAM3), Imm64(param3));
 
500
        u64 distance = u64(func) - (u64(code) + 5);
 
501
        if (distance >= 0x0000000080000000ULL
 
502
         && distance <  0xFFFFFFFF80000000ULL) {
 
503
            // Far call
 
504
            MOV(64, R(RAX), ImmPtr(func));
 
505
            CALLptr(R(RAX));
 
506
        } else {
 
507
            CALL(func);
 
508
        }
 
509
}
 
510
 
 
511
void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1)
 
512
{
 
513
        if (!arg1.IsSimpleReg(ABI_PARAM1))
 
514
                MOV(32, R(ABI_PARAM1), arg1);
 
515
        u64 distance = u64(func) - (u64(code) + 5);
 
516
        if (distance >= 0x0000000080000000ULL
 
517
         && distance <  0xFFFFFFFF80000000ULL) {
 
518
            // Far call
 
519
            MOV(64, R(RAX), ImmPtr(func));
 
520
            CALLptr(R(RAX));
 
521
        } else {
 
522
            CALL(func);
 
523
        }
 
524
}
 
525
 
 
526
void XEmitter::ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2)
 
527
{
 
528
        if (!arg1.IsSimpleReg(ABI_PARAM1))
 
529
                MOV(32, R(ABI_PARAM1), arg1);
 
530
        if (!arg2.IsSimpleReg(ABI_PARAM2))
 
531
                MOV(32, R(ABI_PARAM2), arg2);
 
532
        u64 distance = u64(func) - (u64(code) + 5);
 
533
        if (distance >= 0x0000000080000000ULL
 
534
         && distance <  0xFFFFFFFF80000000ULL) {
 
535
            // Far call
 
536
            MOV(64, R(RAX), ImmPtr(func));
 
537
            CALLptr(R(RAX));
 
538
        } else {
 
539
            CALL(func);
 
540
        }
 
541
}
 
542
 
 
543
unsigned int XEmitter::ABI_GetAlignedFrameSize(unsigned int frameSize) {
 
544
        return frameSize;
 
545
}
 
546
 
 
547
#ifdef _WIN32
 
548
 
 
549
// The Windows x64 ABI requires XMM6 - XMM15 to be callee saved.  10 regs.
 
550
// But, not saving XMM4 and XMM5 breaks things in VS 2010, even though they are volatile regs.
 
551
// Let's just save all 16.
 
552
const int XMM_STACK_SPACE = 16 * 16;
 
553
 
 
554
// Win64 Specific Code
 
555
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
 
556
        //we only want to do this once
 
557
        PUSH(RBX);
 
558
        PUSH(RSI);
 
559
        PUSH(RDI);
 
560
        PUSH(RBP);
 
561
        PUSH(R12);
 
562
        PUSH(R13);
 
563
        PUSH(R14);
 
564
        PUSH(R15);
 
565
        ABI_AlignStack(0);
 
566
 
 
567
        // Do this after aligning, because before it's offset by 8.
 
568
        SUB(64, R(RSP), Imm32(XMM_STACK_SPACE));
 
569
        for (int i = 0; i < 16; ++i)
 
570
                MOVAPS(MDisp(RSP, i * 16), (X64Reg)(XMM0 + i));
 
571
}
 
572
 
 
573
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
 
574
        for (int i = 0; i < 16; ++i)
 
575
                MOVAPS((X64Reg)(XMM0 + i), MDisp(RSP, i * 16));
 
576
        ADD(64, R(RSP), Imm32(XMM_STACK_SPACE));
 
577
 
 
578
        ABI_RestoreStack(0);
 
579
        POP(R15);
 
580
        POP(R14); 
 
581
        POP(R13); 
 
582
        POP(R12);
 
583
        POP(RBP);
 
584
        POP(RDI);
 
585
        POP(RSI); 
 
586
        POP(RBX); 
 
587
}
 
588
 
 
589
// Win64 Specific Code
 
590
void XEmitter::ABI_PushAllCallerSavedRegsAndAdjustStack() {
 
591
        PUSH(RCX);
 
592
        PUSH(RDX);
 
593
        PUSH(RSI); 
 
594
        PUSH(RDI);
 
595
        PUSH(R8);
 
596
        PUSH(R9);
 
597
        PUSH(R10);
 
598
        PUSH(R11);
 
599
        // TODO: Callers preserve XMM4-5 (XMM0-3 are args.)
 
600
        ABI_AlignStack(0);
 
601
}
 
602
 
 
603
void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
 
604
        ABI_RestoreStack(0);
 
605
        POP(R11);
 
606
        POP(R10);
 
607
        POP(R9);
 
608
        POP(R8);
 
609
        POP(RDI); 
 
610
        POP(RSI); 
 
611
        POP(RDX);
 
612
        POP(RCX);
 
613
}
 
614
 
 
615
void XEmitter::ABI_AlignStack(unsigned int /*frameSize*/) {
 
616
        SUB(64, R(RSP), Imm8(0x28));
 
617
}
 
618
 
 
619
void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) {
 
620
        ADD(64, R(RSP), Imm8(0x28));
 
621
}
 
622
 
 
623
#else
 
624
// Unix64 Specific Code
 
625
void XEmitter::ABI_PushAllCalleeSavedRegsAndAdjustStack() {
 
626
        PUSH(RBX); 
 
627
        PUSH(RBP);
 
628
        PUSH(R12); 
 
629
        PUSH(R13); 
 
630
        PUSH(R14); 
 
631
        PUSH(R15);
 
632
        PUSH(R15); //just to align stack. duped push/pop doesn't hurt.
 
633
        // TODO: XMM?
 
634
}
 
635
 
 
636
void XEmitter::ABI_PopAllCalleeSavedRegsAndAdjustStack() {
 
637
        POP(R15);
 
638
        POP(R15);
 
639
        POP(R14); 
 
640
        POP(R13); 
 
641
        POP(R12);
 
642
        POP(RBP);
 
643
        POP(RBX); 
 
644
}
 
645
 
 
646
void XEmitter::ABI_PushAllCallerSavedRegsAndAdjustStack() {
 
647
        PUSH(RCX);
 
648
        PUSH(RDX);
 
649
        PUSH(RSI); 
 
650
        PUSH(RDI);
 
651
        PUSH(R8);
 
652
        PUSH(R9);
 
653
        PUSH(R10);
 
654
        PUSH(R11);
 
655
        PUSH(R11);
 
656
}
 
657
 
 
658
void XEmitter::ABI_PopAllCallerSavedRegsAndAdjustStack() {
 
659
        POP(R11);
 
660
        POP(R11);
 
661
        POP(R10);
 
662
        POP(R9);
 
663
        POP(R8);
 
664
        POP(RDI); 
 
665
        POP(RSI); 
 
666
        POP(RDX);
 
667
        POP(RCX);
 
668
}
 
669
 
 
670
void XEmitter::ABI_AlignStack(unsigned int /*frameSize*/) {
 
671
        SUB(64, R(RSP), Imm8(0x08));
 
672
}
 
673
 
 
674
void XEmitter::ABI_RestoreStack(unsigned int /*frameSize*/) {
 
675
        ADD(64, R(RSP), Imm8(0x08));
 
676
}
 
677
 
 
678
#endif // WIN32
 
679
 
 
680
#endif // 32bit
 
681
 
 
682