/home/travis/build/MoarVM/MoarVM/src/jit/x64/arch.c
Line | Count | Source (jump to first uncovered line) |
1 | | #include "moar.h" |
2 | | #include "jit/internal.h" |
3 | | |
4 | | #define MVM_JIT_PLATFORM_POSIX 1 |
5 | | #define MVM_JIT_PLATFORM_WIN32 2 |
6 | | |
7 | | #if MVM_JIT_PLATFORM == MVM_JIT_PLATFORM_POSIX |
8 | | |
9 | | static const MVMint8 arg_gpr[] = { |
10 | | MVM_JIT_REG(RDI), |
11 | | MVM_JIT_REG(RSI), |
12 | | MVM_JIT_REG(RDX), |
13 | | MVM_JIT_REG(RCX), |
14 | | MVM_JIT_REG(R8), |
15 | | MVM_JIT_REG(R9), |
16 | | }; |
17 | | |
18 | | static const MVMint8 arg_fpr[] = { |
19 | | MVM_JIT_REG(XMM0), |
20 | | MVM_JIT_REG(XMM1), |
21 | | MVM_JIT_REG(XMM2), |
22 | | MVM_JIT_REG(XMM3), |
23 | | MVM_JIT_REG(XMM4), |
24 | | MVM_JIT_REG(XMM5), |
25 | | MVM_JIT_REG(XMM6), |
26 | | MVM_JIT_REG(XMM7), |
27 | | }; |
28 | | |
29 | | |
30 | | void MVM_jit_arch_storage_for_arglist(MVMThreadContext *tc, MVMJitCompiler *compiler, |
31 | | MVMJitExprTree *tree, MVMint32 arglist_node, |
32 | 303k | MVMJitStorageRef *storage) { |
33 | 303k | MVMint32 narg = tree->nodes[arglist_node + 1]; |
34 | 303k | MVMint32 i, ngpr = 0, nfpr = 0, nstack = 0; |
35 | 1.41M | for (i = 0; i < narg; i++) { |
36 | 1.11M | MVMint32 carg_node = tree->nodes[arglist_node + 2 + i]; |
37 | 1.11M | MVMint32 carg_type = tree->nodes[carg_node + 2]; |
38 | 1.11M | /* posix stores numeric args in floating point registers, everything |
39 | 1.11M | * else in general purpose registers, until it doesn't fit anymore, in |
40 | 1.11M | * which case it stores them on the stack */ |
41 | 1.11M | if (carg_type == MVM_JIT_NUM && nfpr < sizeof(arg_fpr)) { |
42 | 0 | storage[i]._cls = MVM_JIT_STORAGE_FPR; |
43 | 0 | storage[i]._pos = arg_fpr[nfpr++]; |
44 | 1.11M | } else if (ngpr < sizeof(arg_gpr)) { |
45 | 1.08M | storage[i]._cls = MVM_JIT_STORAGE_GPR; |
46 | 1.08M | storage[i]._pos = arg_gpr[ngpr++]; |
47 | 28.3k | } else { |
48 | 28.3k | storage[i]._cls = MVM_JIT_STORAGE_STACK; |
49 | 28.3k | storage[i]._pos = 8 * nstack++; |
50 | 28.3k | } |
51 | 1.11M | } |
52 | 303k | } |
53 | | |
54 | | |
55 | | #elif MVM_JIT_PLATFORM == MVM_JIT_PLATFORM_WIN32 |
56 | | |
57 | | static const MVMint8 arg_gpr[] = { |
58 | | MVM_JIT_REG(RCX), |
59 | | MVM_JIT_REG(RDX), |
60 | | MVM_JIT_REG(R8), |
61 | | MVM_JIT_REG(R9), |
62 | | }; |
63 | | |
64 | | static const MVMint8 arg_fpr[] = { |
65 | | MVM_JIT_REG(XMM0), |
66 | | MVM_JIT_REG(XMM1), |
67 | | MVM_JIT_REG(XMM2), |
68 | | MVM_JIT_REG(XMM3), |
69 | | }; |
70 | | |
71 | | |
72 | | void MVM_jit_arch_storage_for_arglist(MVMThreadContext *tc, MVMJitCompiler *compiler, |
73 | | MVMJitExprTree *tree, MVMint32 arglist_node, |
74 | | MVMJitStorageRef *storage) { |
75 | | MVMint32 i, narg = tree->nodes[arglist_node + 1]; |
76 | | for (i = 0; i < MIN(narg, 4); i++) { |
77 | | MVMint32 carg_node = tree->nodes[arglist_node + 2 + i]; |
78 | | MVMint32 carg_type = tree->nodes[carg_node + 2]; |
79 | | if (carg_type == MVM_JIT_NUM) { |
80 | | storage[i]._cls = MVM_JIT_STORAGE_FPR; |
81 | | storage[i]._pos = arg_fpr[i]; |
82 | | } else { |
83 | | storage[i]._cls = MVM_JIT_STORAGE_GPR; |
84 | | storage[i]._pos = arg_gpr[i]; |
85 | | } |
86 | | } |
87 | | /* rest of arguments is passed on stack. first 4 quadwords (32 bytes) are |
88 | | * reserved for first 4 args, hence we start counting from 4 upwards. |
89 | | * See https://msdn.microsoft.com/en-us/library/ms235286.aspx */ |
90 | | for (; i < narg; i++) { |
91 | | storage[i]._cls = MVM_JIT_STORAGE_STACK; |
92 | | storage[i]._pos = i * 8; |
93 | | } |
94 | | |
95 | | } |
96 | | |
97 | | #else |
98 | | #error "Unknown platform " MVM_JIT_PLATFORM |
99 | | #endif |