/home/travis/build/MoarVM/MoarVM/src/jit/x64/emit.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | ** This file has been pre-processed with DynASM. |
3 | | ** http://luajit.org/dynasm.html |
4 | | ** DynASM version 1.3.0, DynASM x64 version 1.3.0 |
5 | | ** DO NOT EDIT! The original file is in "src/jit/x64/emit.dasc". |
6 | | */ |
7 | | |
8 | | #line 1 "src/jit/x64/emit.dasc" |
9 | | /* -*-C-*- */ |
10 | | #include "moar.h" |
11 | | #include "jit/internal.h" |
12 | | #include "dasm_x86.h" |
13 | | |
14 | | #ifdef _MSC_VER |
15 | | #pragma warning( disable : 4129 ) |
16 | | #endif |
17 | | |
18 | | /** |
19 | | * CONVENTIONS |
20 | | |
21 | | * Much of this file contains snippets of assembly code, which are concatenated |
22 | | * at runtime in order to form a single executable routine. It is essential for |
23 | | * the correctness of the result that each of the snippets behaves |
24 | | * nicely. Because you can't be expected to know what that is, it is documented |
25 | | * here. |
26 | | |
27 | | * REGISTERS: |
28 | | |
29 | | * Register and calling conventions differ between POSIX and windows |
30 | | * systems. The registers rax, rcx, rdx, r8, r9, r10 and r11 are caller-saved, |
31 | | * meaning that you are free to overwrrite them, and functions you may call are |
32 | | * free to do thesame. Hence you should save their values on stack, if you wish |
33 | | * to keep them after calling. In contrast, rbx, rsp, rbp, and r12-r15 are |
34 | | * callee-saved, meaning that their values before entering and after returning |
35 | | * from a function must be the same. POSIX also makes rdi and rsi caller-saved, |
36 | | * windows makes them callee-saved. For this reason we avoid using them. The |
37 | | * first 4 (windows) or 6 (POSIX) function call arguments are placed in |
38 | | * registers. These registers sets are not the same between windows and POSIX, |
39 | | * but they're always caller-saved. |
40 | | |
41 | | * To deal with the ambiguity, register names have been aliased. |
42 | | |
43 | | * + RV stands for 'return value', and is aliased to rax |
44 | | * + TMP1-6 are the 6 shared caller-saved registers |
45 | | * + ARG1-4 are (different) aliases for argument registers |
46 | | * + TC, CU, WORK are registers that hold interpreter variables; these are callee- |
47 | | * saved registers set up at entry and restored at exit |
48 | | * + TMP5 (r10) is also aliased as FUNCTION; it never conflicts with an argument |
49 | | * register, and neither does TMP6. |
50 | | * + The suffixes d, w, and b stand for the 4, 2, and 1 byte-width value of the |
51 | | * registers. |
52 | | |
53 | | * Note that the current convention for function calls is to load the function |
54 | | * pointer as a 64 bit value in a register from the machine code, and call on |
55 | | * that register. This is not ideal, but call doesn't natively take 64 bit |
56 | | * values, and it is neccesary to ensure that the function lives within 32 bits |
57 | | * distance from the function otherwise. Other methods are being considered. |
58 | | |
59 | | * LABELS: |
60 | | |
61 | | * Don't use dynamic labels in this code, unless they have been passed to you |
62 | | * from outside. Dynamic labels need to be allocated and not conflict, hence |
63 | | * just picking one is typically unsafe. Local labels are usually safe. |
64 | | |
65 | | * WRITE BARRIERS: |
66 | | |
67 | | * Use of write barriers is tricky, because they may involve a function call, and |
68 | | * that may or may not mean you have to store your temporaries on the stack. |
69 | | * Hence, a write barrier (MVM_ASSIGN_REF) is split into two parts: |
70 | | |
71 | | * + check_wb (root, value, label) |
72 | | * + hit_wb (root) |
73 | | |
74 | | * You should have the label parameter point somewhere after hit_wb, and save |
75 | | * and restore your temporaries around the hib_wb. |
76 | | **/ |
77 | | |
78 | | |
79 | | //|.arch x64 |
80 | | #if DASM_VERSION != 10300 |
81 | | #error "Version mismatch between DynASM and included encoding engine" |
82 | | #endif |
83 | | #line 72 "src/jit/x64/emit.dasc" |
84 | | //|.actionlist actions |
85 | | static const unsigned char actions[5296] = { |
86 | | 254,0,85,72,137,229,255,72,129,250,236,0,1,0,0,255,76,137,117,250,248,76, |
87 | | 137,109,250,240,72,137,93,250,232,255,73,137,250,254,73,137,250,245,77,139, |
88 | | 158,231,73,139,155,231,255,72,141,68,36,250,248,73,137,134,231,255,250,255, |
89 | | 226,255,246,10,255,73,199,134,231,0,0,0,0,255,76,139,117,250,248,76,139,109, |
90 | | 250,240,72,139,93,250,232,255,72,137,250,236,93,195,255,72,185,235,235,72, |
91 | | 137,139,231,255,72,199,131,231,235,255,73,139,141,231,72,139,137,231,72,137, |
92 | | 139,231,255,73,139,142,231,72,139,137,231,72,137,139,231,255,72,139,139,231, |
93 | | 72,139,137,231,255,72,139,137,231,73,139,150,231,72,139,146,231,72,133,201, |
94 | | 72,15,68,202,255,77,139,158,231,255,77,139,155,231,255,77,139,147,231,255, |
95 | | 77,139,146,231,255,77,133,210,15,133,242,247,255,76,137,250,247,76,137,222, |
96 | | 72,199,194,235,254,1,246,5,235,235,254,0,250,255,21,242,5,255,73,137,194, |
97 | | 246,1,255,76,137,147,231,255,76,139,155,231,77,139,155,231,255,76,139,147, |
98 | | 231,102,65,250,247,130,231,234,15,133,242,247,77,139,154,231,77,139,155,231, |
99 | | 65,129,187,231,237,15,133,242,247,77,139,154,231,76,137,250,247,72,139,179, |
100 | | 231,76,137,218,254,1,250,255,21,242,5,72,137,131,231,250,233,242,248,246, |
101 | | 1,76,137,250,247,72,190,235,235,254,1,250,255,21,242,5,246,2,255,76,137,250, |
102 | | 247,255,73,139,181,231,72,139,182,231,72,199,194,235,254,1,250,255,21,242, |
103 | | 5,72,133,192,15,132,242,247,72,139,0,72,137,131,231,250,233,242,248,246,1, |
104 | | 77,139,134,231,77,139,128,231,76,137,131,231,246,2,255,73,139,142,231,255, |
105 | | 72,139,145,231,76,139,131,231,76,137,130,231,255,102,250,247,129,231,234, |
106 | | 15,132,242,248,77,133,192,15,132,242,248,102,65,250,247,128,231,234,15,133, |
107 | | 242,248,72,137,206,76,137,250,247,254,1,72,139,139,231,72,139,145,231,72, |
108 | | 139,146,231,129,186,231,237,15,133,242,247,102,250,247,129,231,234,15,132, |
109 | | 242,248,246,1,76,137,250,247,72,190,235,235,254,1,250,255,21,242,5,246,2, |
110 | | 72,139,177,231,72,139,147,231,76,137,250,247,254,1,250,255,21,242,5,72,137, |
111 | | 131,231,255,73,139,142,231,72,139,137,231,72,139,137,231,72,137,139,231,255, |
112 | | 72,139,139,231,72,141,145,231,76,139,137,231,77,141,145,231,77,133,201,73, |
113 | | 15,69,210,255,76,139,2,77,133,192,255,15,133,242,249,255,77,139,134,231,77, |
114 | | 139,128,231,246,3,255,76,139,2,255,77,133,192,15,133,242,250,255,77,139,134, |
115 | | 231,77,139,128,231,77,139,128,231,255,102,250,247,129,231,234,15,132,242, |
116 | | 249,77,133,192,15,132,242,249,102,65,250,247,128,231,234,15,133,242,249,72, |
117 | | 137,85,216,76,137,69,208,72,139,179,231,76,137,250,247,254,1,250,255,21,242, |
118 | | 5,76,139,69,208,72,139,85,216,246,3,255,76,137,2,246,4,255,76,139,2,77,133, |
119 | | 192,15,133,242,250,255,76,137,250,247,73,139,182,231,72,139,182,231,72,139, |
120 | | 182,231,254,1,250,255,21,242,5,73,137,192,255,250,255,21,242,5,76,139,69, |
121 | | 208,72,139,85,216,246,3,76,137,2,255,76,137,131,231,255,72,139,139,231,72, |
122 | | 139,147,231,255,102,250,247,129,231,234,15,132,242,248,72,133,210,15,132, |
123 | | 242,248,102,250,247,130,231,234,15,133,242,248,255,250,255,21,242,5,72,139, |
124 | | 139,231,72,139,147,231,246,2,255,72,137,145,231,255,72,139,139,231,72,139, |
125 | | 145,231,72,137,147,231,255,72,139,139,231,72,139,147,231,72,139,137,231,72, |
126 | | 137,17,255,72,139,139,231,76,139,129,231,73,139,16,72,137,147,231,255,72, |
127 | | 139,139,231,72,139,147,231,76,141,129,231,73,131,184,231,0,15,132,242,247, |
128 | | 77,139,128,231,246,1,255,102,250,247,129,231,234,15,132,242,248,72,133,210, |
129 | | 15,132,242,248,102,250,247,130,231,234,15,133,242,248,72,137,85,216,76,137, |
130 | | 69,208,72,139,179,231,76,137,250,247,254,1,250,255,21,242,5,76,139,69,208, |
131 | | 72,139,85,216,246,2,255,73,137,144,231,255,72,139,139,231,72,137,139,231, |
132 | | 255,72,139,139,231,73,137,142,231,255,73,139,142,231,72,131,250,249,0,15, |
133 | | 132,242,248,73,139,150,231,72,131,250,250,0,15,132,242,247,77,139,134,231, |
134 | | 77,139,128,231,76,57,194,15,133,242,248,246,1,72,137,139,231,73,199,134,231, |
135 | | 235,250,233,242,249,246,2,73,139,142,231,72,139,137,231,72,137,139,231,246, |
136 | | 3,255,76,137,250,247,73,139,182,231,254,1,72,139,139,231,102,250,247,129, |
137 | | 231,234,15,133,242,247,72,139,145,231,72,139,146,231,129,186,231,237,15,132, |
138 | | 242,248,246,1,76,137,250,247,72,190,235,235,254,1,250,255,21,242,5,246,2, |
139 | | 72,137,139,231,255,73,139,142,231,72,139,137,231,72,133,201,15,132,242,247, |
140 | | 72,139,137,231,246,1,72,137,139,231,255,73,139,141,231,255,72,199,131,231, |
141 | | 0,0,0,0,255,72,139,139,231,72,133,201,15,148,210,72,15,182,210,72,137,147, |
142 | | 231,255,76,139,147,231,102,65,250,247,130,231,234,15,133,242,247,77,139,154, |
143 | | 231,77,139,155,231,65,129,187,231,237,15,133,242,247,76,137,250,247,73,139, |
144 | | 178,231,72,139,147,231,254,1,72,129,131,231,237,255,72,129,171,231,237,255, |
145 | | 72,129,139,231,237,255,72,129,163,231,237,255,72,129,179,231,237,255,72,139, |
146 | | 131,231,255,72,1,131,231,255,72,41,131,231,255,72,9,131,231,255,72,33,131, |
147 | | 231,255,72,49,131,231,255,72,129,192,237,255,72,129,250,232,237,255,72,129, |
148 | | 200,237,255,72,129,224,237,255,72,129,250,240,237,255,72,3,131,231,255,72, |
149 | | 43,131,231,255,72,11,131,231,255,72,35,131,231,255,72,51,131,231,255,72,15, |
150 | | 175,131,231,255,138,139,231,72,211,224,255,138,139,231,72,211,250,232,255, |
151 | | 72,49,192,72,139,139,231,72,57,193,15,140,242,249,72,250,255,192,76,139,131, |
152 | | 231,246,1,72,250,247,193,1,0,0,0,15,132,242,248,73,250,247,250,232,246,2, |
153 | | 77,15,175,192,72,209,250,233,15,133,242,1,246,3,72,137,131,231,255,72,139, |
154 | | 131,231,72,139,139,231,72,131,250,249,0,15,133,242,247,76,137,250,247,72, |
155 | | 190,235,235,254,1,250,255,21,242,5,246,1,255,15,156,214,72,131,250,248,0, |
156 | | 15,156,210,48,250,242,68,15,182,194,72,153,72,250,247,250,249,72,133,210, |
157 | | 15,149,209,65,32,200,255,76,41,192,72,137,131,231,255,250,255,21,242,5,246, |
158 | | 1,72,153,72,250,247,250,249,72,137,147,231,255,72,131,131,231,1,255,72,131, |
159 | | 171,231,1,255,72,139,139,231,72,250,247,209,72,137,139,231,255,72,139,139, |
160 | | 231,72,250,247,217,72,137,139,231,255,72,139,131,231,72,152,72,137,131,231, |
161 | | 255,72,139,139,231,255,102,137,202,72,137,147,231,255,250,242,15,16,131,231, |
162 | | 255,250,242,15,88,131,231,255,250,242,15,92,131,231,255,250,242,15,89,131, |
163 | | 231,255,250,242,15,94,131,231,255,250,242,15,17,131,231,255,250,242,72,15, |
164 | | 42,131,231,250,242,15,17,131,231,255,250,242,72,15,44,131,231,72,137,131, |
165 | | 231,255,72,199,193,1,0,0,0,72,193,225,63,72,139,147,231,72,49,202,72,137, |
166 | | 147,231,255,72,59,131,231,255,15,148,208,255,15,149,208,255,15,156,208,255, |
167 | | 15,158,208,255,15,159,208,255,15,157,208,255,72,15,182,192,72,137,131,231, |
168 | | 255,72,59,139,231,255,15,159,210,72,15,182,210,65,15,156,208,77,15,182,192, |
169 | | 76,41,194,72,137,147,231,255,72,199,194,1,0,0,0,255,72,199,194,250,255,250, |
170 | | 255,250,255,250,255,255,72,199,194,0,0,0,0,255,72,59,147,231,255,72,199,193, |
171 | | 0,0,0,0,255,72,199,193,1,0,0,0,255,250,242,15,16,131,231,102,15,46,131,231, |
172 | | 255,15,147,209,255,15,155,210,72,15,68,202,255,15,154,210,72,15,68,202,255, |
173 | | 15,151,209,255,72,15,182,201,72,137,139,231,255,250,242,15,16,131,231,250, |
174 | | 242,15,16,139,231,102,15,46,193,15,151,209,72,15,182,193,102,15,46,200,15, |
175 | | 151,209,72,15,182,201,72,41,200,72,137,131,231,255,72,199,199,235,72,139, |
176 | | 179,231,72,139,147,231,254,1,72,129,250,248,237,15,148,208,255,72,129,250, |
177 | | 248,237,15,149,208,255,72,139,139,231,72,133,201,15,132,242,247,72,139,137, |
178 | | 231,72,139,137,231,72,129,185,231,237,15,133,242,247,72,199,131,231,1,0,0, |
179 | | 0,250,233,242,248,246,1,72,199,131,231,0,0,0,0,246,2,255,72,139,139,231,72, |
180 | | 139,145,231,72,131,194,1,76,139,129,231,255,76,57,194,15,156,209,72,15,182, |
181 | | 201,72,137,139,231,255,72,139,139,231,72,139,145,231,72,133,210,15,149,210, |
182 | | 72,15,182,210,72,137,147,231,255,76,139,155,231,77,133,219,15,132,242,247, |
183 | | 76,137,250,247,73,139,179,231,76,139,150,231,77,139,146,231,65,250,255,210, |
184 | | 76,15,183,152,231,246,1,76,137,155,231,255,76,139,155,231,77,133,219,15,132, |
185 | | 242,247,73,139,179,231,76,139,150,231,77,139,146,231,76,137,250,247,65,250, |
186 | | 255,210,76,15,183,152,231,77,133,219,15,132,242,247,76,15,183,152,231,246, |
187 | | 1,76,137,155,231,255,76,139,147,231,77,133,210,15,132,242,247,76,137,250, |
188 | | 247,73,139,178,231,76,139,150,231,77,139,146,231,65,250,255,210,76,139,152, |
189 | | 231,73,131,250,251,1,15,133,242,247,76,139,152,231,76,137,155,231,250,233, |
190 | | 242,248,246,1,72,199,131,231,0,0,0,0,246,2,255,72,139,139,231,72,133,201, |
191 | | 15,149,210,77,139,134,231,77,139,128,231,76,57,193,65,15,149,208,68,32,194, |
192 | | 72,15,182,210,72,137,147,231,255,76,139,147,231,77,139,154,231,77,139,155, |
193 | | 231,65,129,187,231,237,15,132,242,247,76,137,250,247,72,190,235,235,254,1, |
194 | | 250,255,21,242,5,246,1,76,137,250,247,76,137,214,254,1,250,255,21,242,5,246, |
195 | | 1,76,137,250,247,72,139,179,231,76,137,210,254,1,72,139,139,231,72,133,201, |
196 | | 15,148,210,77,139,134,231,77,139,128,231,76,57,193,65,15,148,208,68,8,194, |
197 | | 72,15,182,210,72,137,147,231,255,76,137,250,247,72,199,198,235,254,1,250, |
198 | | 255,21,242,5,73,139,142,231,72,139,137,231,72,139,137,231,72,137,136,231, |
199 | | 102,199,128,231,234,65,139,142,231,137,136,231,72,137,131,231,255,76,139, |
200 | | 147,231,77,133,210,255,15,132,242,247,102,65,250,247,130,231,234,255,15,133, |
201 | | 242,247,77,139,154,231,77,139,155,231,77,133,219,255,15,132,242,247,76,137, |
202 | | 250,247,76,137,214,72,141,147,231,77,139,147,231,65,250,255,210,250,233,242, |
203 | | 248,246,1,255,76,137,147,231,246,2,255,72,139,139,231,72,133,201,15,132,242, |
204 | | 247,72,139,137,231,72,139,137,231,72,133,201,246,1,15,149,209,72,15,182,201, |
205 | | 72,137,139,231,255,73,139,142,231,72,139,137,231,72,139,137,231,72,139,147, |
206 | | 231,72,139,146,231,72,57,209,15,133,242,247,77,139,134,231,77,139,128,231, |
207 | | 77,139,128,231,76,137,131,231,250,233,242,248,246,1,255,76,137,250,247,72, |
208 | | 139,179,231,255,73,139,149,231,72,139,146,231,72,199,193,235,76,141,155,231, |
209 | | 77,137,216,254,1,72,139,139,231,72,133,201,15,132,242,247,102,250,247,129, |
210 | | 231,234,15,133,242,247,72,199,131,231,1,0,0,0,250,233,242,248,246,1,72,199, |
211 | | 131,231,0,0,0,0,246,2,255,72,139,139,231,72,139,137,231,72,199,194,1,0,0, |
212 | | 0,73,184,235,235,76,59,129,231,15,133,242,247,76,139,137,231,77,133,201,15, |
213 | | 133,242,247,76,33,202,246,1,72,137,147,231,255,73,139,142,231,72,137,139, |
214 | | 231,73,199,134,231,0,0,0,0,255,73,139,142,231,72,133,201,15,132,242,247,72, |
215 | | 139,137,231,72,137,139,231,250,233,242,248,246,1,73,139,142,231,72,139,137, |
216 | | 231,72,137,139,231,246,2,255,65,139,142,231,131,193,1,65,137,142,231,72,137, |
217 | | 139,231,255,65,139,142,231,131,250,233,1,65,137,142,231,72,137,139,231,255, |
218 | | 72,139,179,231,76,139,150,231,77,139,146,231,77,133,210,15,133,242,247,76, |
219 | | 137,250,247,72,190,235,235,254,1,250,255,21,242,5,246,1,76,137,250,247,72, |
220 | | 139,147,231,255,65,250,255,210,255,76,137,250,247,72,139,179,231,72,199,194, |
221 | | 235,254,1,250,255,21,242,5,72,133,192,15,132,242,247,72,139,0,246,1,72,137, |
222 | | 131,231,255,73,139,182,231,72,141,182,231,102,68,139,150,231,102,68,59,150, |
223 | | 231,15,132,242,247,76,137,250,247,254,1,72,139,139,231,72,133,201,15,133, |
224 | | 242,247,76,137,250,247,254,1,76,137,250,247,73,139,182,231,72,139,182,231, |
225 | | 72,199,194,235,254,1,76,137,250,247,73,139,182,231,72,139,182,231,72,139, |
226 | | 182,231,72,199,194,235,254,1,72,139,139,231,139,145,231,77,49,192,131,250, |
227 | | 250,0,15,142,242,247,77,139,134,231,77,139,128,231,77,139,4,208,77,139,128, |
228 | | 231,246,1,76,137,131,231,255,102,250,247,129,231,234,15,133,242,247,72,139, |
229 | | 145,231,72,139,146,231,129,186,231,237,15,132,242,248,246,1,255,76,137,250, |
230 | | 247,72,139,179,231,72,49,210,254,1,72,137,198,255,72,141,187,231,77,139,158, |
231 | | 231,73,137,187,231,255,65,198,131,231,233,255,73,139,190,231,72,139,63,73, |
232 | | 137,187,231,255,76,137,250,247,72,139,147,231,72,139,138,231,72,139,145,231, |
233 | | 72,139,137,231,76,139,150,231,77,139,146,231,65,250,255,210,255,250,255,21, |
234 | | 242,5,246,2,72,139,145,231,72,15,183,146,231,72,137,147,231,255,250,255,21, |
235 | | 242,5,246,2,72,139,145,231,102,68,139,130,231,102,139,146,231,102,68,57,194, |
236 | | 15,149,208,72,15,182,192,72,137,131,231,255,250,255,21,242,5,246,2,72,139, |
237 | | 177,231,76,137,250,247,254,1,77,139,134,231,255,72,139,139,231,102,250,247, |
238 | | 129,231,234,15,133,242,247,72,139,145,231,72,139,146,231,129,186,231,237, |
239 | | 15,133,242,247,72,139,145,231,72,137,147,231,250,233,242,248,246,1,76,137, |
240 | | 250,247,72,190,235,235,254,1,72,139,145,231,72,139,146,231,129,186,231,237, |
241 | | 15,132,242,247,255,250,255,21,242,5,246,1,72,139,147,231,72,137,145,231,255, |
242 | | 77,139,134,231,76,137,131,231,255,76,137,250,247,72,139,183,231,72,141,182, |
243 | | 231,72,199,194,235,254,1,76,137,250,247,72,139,183,231,72,141,182,231,254, |
244 | | 1,76,137,250,247,72,139,179,231,72,139,147,231,72,139,139,231,76,141,131, |
245 | | 231,76,139,150,231,77,139,146,231,77,139,146,231,65,250,255,210,255,76,137, |
246 | | 250,247,72,139,179,231,76,139,150,231,77,139,146,231,77,139,146,231,65,250, |
247 | | 255,210,72,137,131,231,255,76,137,250,247,72,139,179,231,72,139,147,231,76, |
248 | | 139,150,231,77,139,146,231,77,139,146,231,65,250,255,210,255,77,137,250,243, |
249 | | 255,77,137,250,235,255,77,139,158,231,77,141,155,231,255,77,139,158,231,77, |
250 | | 139,155,231,255,76,139,155,231,255,76,141,155,231,255,77,139,157,231,77,139, |
251 | | 155,231,255,73,199,195,235,255,73,187,235,235,255,76,139,155,231,77,141,155, |
252 | | 231,255,77,139,150,231,77,139,18,77,49,219,102,69,139,154,231,78,139,28,219, |
253 | | 255,76,141,29,243,255,77,139,158,231,77,139,155,231,77,139,155,231,255,77, |
254 | | 139,158,231,77,139,155,231,77,141,155,231,255,77,139,158,231,77,139,155,231, |
255 | | 77,139,155,231,77,139,155,231,255,76,139,157,231,255,76,137,223,255,76,137, |
256 | | 222,255,76,137,218,255,76,137,217,255,77,137,216,255,77,137,217,255,102,73, |
257 | | 15,110,195,255,102,73,15,110,203,255,102,73,15,110,211,255,102,73,15,110, |
258 | | 219,255,102,73,15,110,227,255,102,73,15,110,250,235,255,102,73,15,110,250, |
259 | | 243,255,102,73,15,110,250,251,255,68,136,156,251,36,231,255,102,68,137,156, |
260 | | 251,36,231,255,76,137,156,251,36,231,255,72,139,8,72,137,139,231,255,72,139, |
261 | | 139,231,72,137,8,255,73,139,142,231,72,139,9,72,49,210,102,139,145,231,72, |
262 | | 137,4,211,255,72,133,192,15,132,242,250,72,139,8,250,233,242,251,246,4,73, |
263 | | 139,142,231,72,139,137,231,246,5,72,137,139,231,255,72,137,133,231,255,73, |
264 | | 131,190,231,0,15,132,242,247,76,137,250,247,254,1,250,233,242,10,255,250, |
265 | | 233,243,255,72,139,131,231,72,133,192,15,133,243,255,72,139,131,231,72,133, |
266 | | 192,15,132,243,255,102,72,15,110,131,231,102,15,87,201,102,15,46,193,15,138, |
267 | | 243,15,133,243,255,102,72,15,110,131,231,102,15,87,201,102,15,46,193,15,138, |
268 | | 242,247,15,133,242,247,250,233,243,246,1,255,76,137,250,247,72,139,179,231, |
269 | | 254,1,250,255,21,242,5,72,133,192,255,72,139,139,231,72,133,201,15,132,242, |
270 | | 247,73,139,150,231,72,139,146,231,72,57,209,15,132,242,247,250,233,243,246, |
271 | | 1,255,72,139,139,231,72,133,201,15,132,242,247,131,185,231,0,15,132,242,247, |
272 | | 250,233,243,246,1,255,72,139,139,231,72,133,201,15,132,243,131,185,231,0, |
273 | | 15,132,243,246,1,255,76,137,250,247,72,139,179,231,72,139,147,231,255,73, |
274 | | 139,141,231,72,139,137,231,254,1,72,131,250,248,250,255,255,15,142,243,255, |
275 | | 15,140,243,255,15,141,243,255,15,143,243,255,73,139,150,231,72,139,146,231, |
276 | | 72,139,146,231,255,72,133,201,15,132,242,247,255,72,59,145,231,15,133,242, |
277 | | 247,255,102,250,247,129,231,234,255,102,250,247,129,231,234,15,133,242,247, |
278 | | 255,76,139,129,231,77,139,128,231,65,129,184,231,237,15,133,242,247,72,59, |
279 | | 145,231,15,133,242,247,255,72,57,202,15,133,242,247,255,72,57,202,15,132, |
280 | | 242,247,255,102,250,247,129,231,234,15,132,242,247,255,76,137,250,247,72, |
281 | | 199,198,235,72,199,194,235,254,1,250,233,242,10,246,2,255,73,139,150,231, |
282 | | 72,139,18,77,139,150,231,73,137,146,231,255,77,137,154,231,255,65,198,130, |
283 | | 231,233,255,73,199,130,231,235,255,72,141,147,231,73,137,146,231,255,76,139, |
284 | | 139,231,77,137,138,231,255,73,185,235,235,77,137,138,231,255,77,139,141,231, |
285 | | 77,139,137,231,77,137,138,231,255,76,137,250,247,72,139,179,231,76,137,218, |
286 | | 72,199,193,235,254,1,73,139,181,231,72,139,182,231,72,141,147,231,72,199, |
287 | | 193,235,77,139,134,231,77,139,128,231,77,139,128,231,77,139,141,231,77,139, |
288 | | 137,231,254,1,76,137,85,216,76,137,93,208,255,76,137,250,247,72,139,179,231, |
289 | | 72,141,85,208,76,137,209,73,199,192,0,0,0,0,254,1,76,139,93,208,76,139,85, |
290 | | 216,255,76,137,250,247,72,137,198,76,137,218,76,137,209,255,76,139,144,231, |
291 | | 77,139,146,231,65,250,255,210,255,72,139,139,231,72,131,250,249,0,15,140, |
292 | | 242,248,72,129,250,249,237,15,141,242,248,72,107,201,8,72,141,21,242,247, |
293 | | 72,1,202,250,255,226,248,7,246,1,255,247,250,233,243,248,7,255,205,3,255, |
294 | | 64,252,138,128,251,238,10,238,8,231,255,102,253,139,128,251,238,10,238,8, |
295 | | 231,255,72,252,139,128,251,238,10,238,8,231,255,64,252,136,128,251,238,10, |
296 | | 238,8,231,255,102,253,137,128,251,238,10,238,8,231,255,72,252,137,128,251, |
297 | | 238,10,238,8,231,255,72,252,137,192,238,14,238,12,255,144,255,72,252,141, |
298 | | 128,251,238,10,238,8,231,255,72,252,141,132,251,238,10,192,238,15,238,13, |
299 | | 231,255,72,252,184,238,0,235,235,255,72,252,199,192,238,12,235,255,253,138, |
300 | | 128,251,238,10,238,8,231,255,64,252,138,132,251,238,10,192,238,15,238,13, |
301 | | 231,255,102,253,139,132,251,238,10,192,238,15,238,13,231,255,72,252,139,132, |
302 | | 251,238,10,192,238,15,238,13,231,255,64,252,136,132,251,238,10,192,238,15, |
303 | | 238,13,231,255,102,253,137,132,251,238,10,192,238,15,238,13,231,255,72,252, |
304 | | 137,132,251,238,10,192,238,15,238,13,231,255,102,64,252,15,190,192,238,14, |
305 | | 238,12,255,253,15,191,192,238,14,238,12,255,72,252,15,190,192,238,14,238, |
306 | | 12,255,72,252,15,191,192,238,14,238,12,255,253,137,192,238,14,72,152,72,252, |
307 | | 137,192,238,12,255,102,64,252,15,182,192,238,14,238,12,255,253,15,183,192, |
308 | | 238,14,238,12,255,72,252,15,182,192,238,14,238,12,255,72,252,15,183,192,238, |
309 | | 14,238,12,255,253,137,192,238,14,238,12,255,72,252,137,192,238,14,255,72, |
310 | | 252,1,192,238,14,238,12,255,72,184,235,235,72,252,1,192,238,12,255,72,252, |
311 | | 129,192,238,12,237,255,72,252,184,238,0,235,235,72,252,1,192,238,14,238,12, |
312 | | 255,72,252,137,192,238,14,238,12,72,252,129,192,238,12,237,255,64,252,2,128, |
313 | | 251,238,10,238,8,231,255,102,253,3,128,251,238,10,238,8,231,255,72,252,3, |
314 | | 128,251,238,10,238,8,231,255,64,252,2,132,251,238,10,192,238,15,238,13,231, |
315 | | 255,102,253,3,132,251,238,10,192,238,15,238,13,231,255,72,252,3,132,251,238, |
316 | | 10,192,238,15,238,13,231,255,72,252,33,192,238,14,238,12,255,72,184,235,235, |
317 | | 72,252,33,192,238,12,255,72,252,129,224,238,12,237,255,72,252,184,238,0,235, |
318 | | 235,72,252,33,192,238,14,238,12,255,72,252,137,192,238,14,238,12,72,252,129, |
319 | | 224,238,12,237,255,64,252,34,128,251,238,10,238,8,231,255,102,253,35,128, |
320 | | 251,238,10,238,8,231,255,72,252,35,128,251,238,10,238,8,231,255,64,252,34, |
321 | | 132,251,238,10,192,238,15,238,13,231,255,102,253,35,132,251,238,10,192,238, |
322 | | 15,238,13,231,255,72,252,35,132,251,238,10,192,238,15,238,13,231,255,72,252, |
323 | | 9,192,238,14,238,12,255,72,252,49,192,238,14,238,12,255,72,252,250,247,208, |
324 | | 238,12,255,72,252,41,192,238,14,238,12,255,72,184,235,235,72,252,41,192,238, |
325 | | 12,255,72,252,129,250,232,238,12,237,255,72,184,235,235,72,252,137,192,238, |
326 | | 14,238,12,72,252,41,192,238,12,255,72,252,137,192,238,14,238,12,72,252,129, |
327 | | 250,232,238,12,237,255,64,252,42,128,251,238,10,238,8,231,255,102,253,43, |
328 | | 128,251,238,10,238,8,231,255,72,252,43,128,251,238,10,238,8,231,255,64,252, |
329 | | 42,132,251,238,10,192,238,15,238,13,231,255,102,253,43,132,251,238,10,192, |
330 | | 238,15,238,13,231,255,72,252,43,132,251,238,10,192,238,15,238,13,231,255, |
331 | | 64,252,132,192,238,14,238,12,255,102,253,133,192,238,14,238,12,255,72,252, |
332 | | 133,192,238,14,238,12,255,64,252,128,184,251,238,8,231,0,255,102,253,131, |
333 | | 184,251,238,8,231,0,255,72,252,131,184,251,238,8,231,0,255,64,252,128,188, |
334 | | 251,192,238,15,238,13,231,0,255,102,253,131,188,251,192,238,15,238,13,231, |
335 | | 0,255,72,252,131,188,251,192,238,15,238,13,231,0,255,64,252,250,246,192,238, |
336 | | 12,233,255,102,253,250,247,192,238,12,234,255,253,250,247,192,238,12,235, |
337 | | 255,72,252,250,247,192,238,12,235,255,72,184,235,235,72,252,133,192,238,12, |
338 | | 255,64,252,250,246,128,251,238,8,231,233,255,102,253,250,247,128,251,238, |
339 | | 8,231,234,255,253,250,247,128,251,238,8,231,235,255,72,252,250,247,128,251, |
340 | | 238,8,231,235,255,72,184,235,235,72,252,133,128,251,238,8,231,255,64,252, |
341 | | 56,192,238,14,238,12,255,102,253,57,192,238,14,238,12,255,72,252,57,192,238, |
342 | | 14,238,12,255,64,252,15,156,208,238,12,255,64,252,15,158,208,238,12,255,64, |
343 | | 252,15,148,208,238,12,255,64,252,15,149,208,238,12,255,64,252,15,157,208, |
344 | | 238,12,255,64,252,15,159,208,238,12,255,72,252,141,5,238,2,243,255,253,250, |
345 | | 255,208,238,12,255,253,250,255,144,251,238,8,231,255 |
346 | | }; |
347 | | |
348 | | #line 73 "src/jit/x64/emit.dasc" |
349 | | //|.section code, data |
350 | | #define DASM_SECTION_CODE 0 |
351 | | #define DASM_SECTION_DATA 1 |
352 | | #define DASM_MAXSECTION 2 |
353 | | #line 74 "src/jit/x64/emit.dasc" |
354 | | //|.globals MVM_JIT_LABEL_ |
355 | | enum { |
356 | | MVM_JIT_LABEL_exit, |
357 | | MVM_JIT_LABEL__MAX |
358 | | }; |
359 | | #line 75 "src/jit/x64/emit.dasc" |
360 | | |
361 | | #if MVM_JIT_LABEL__MAX > MVM_JIT_MAX_GLOBALS |
362 | | #error "Not enough space for labels" |
363 | | #endif |
364 | | |
365 | | /* type declarations */ |
366 | | //|.type REGISTER, MVMRegister |
367 | 67.1k | #define Dt1(_V) (int)(ptrdiff_t)&(((MVMRegister *)0)_V) |
368 | | #line 82 "src/jit/x64/emit.dasc" |
369 | | //|.type FRAME, MVMFrame |
370 | 245k | #define Dt2(_V) (int)(ptrdiff_t)&(((MVMFrame *)0)_V) |
371 | | #line 83 "src/jit/x64/emit.dasc" |
372 | | //|.type ARGCTX, MVMArgProcContext |
373 | 360 | #define Dt3(_V) (int)(ptrdiff_t)&(((MVMArgProcContext *)0)_V) |
374 | | #line 84 "src/jit/x64/emit.dasc" |
375 | | //|.type CALLSITEPTR, MVMCallsite* |
376 | 26.1k | #define Dt4(_V) (int)(ptrdiff_t)&(((MVMCallsite* *)0)_V) |
377 | | #line 85 "src/jit/x64/emit.dasc" |
378 | | //|.type CAPTURE, MVMCallCapture |
379 | 153 | #define Dt5(_V) (int)(ptrdiff_t)&(((MVMCallCapture *)0)_V) |
380 | | #line 86 "src/jit/x64/emit.dasc" |
381 | | //|.type CAPTUREBODY, MVMCallCaptureBody |
382 | | #define Dt6(_V) (int)(ptrdiff_t)&(((MVMCallCaptureBody *)0)_V) |
383 | | #line 87 "src/jit/x64/emit.dasc" |
384 | | //|.type ARGPROCCONTEXT, MVMArgProcContext |
385 | 78 | #define Dt7(_V) (int)(ptrdiff_t)&(((MVMArgProcContext *)0)_V) |
386 | | #line 88 "src/jit/x64/emit.dasc" |
387 | | //|.type STATICFRAME, MVMStaticFrame |
388 | | #define Dt8(_V) (int)(ptrdiff_t)&(((MVMStaticFrame *)0)_V) |
389 | | #line 89 "src/jit/x64/emit.dasc" |
390 | | //|.type P6OPAQUE, MVMP6opaque |
391 | 14.4k | #define Dt9(_V) (int)(ptrdiff_t)&(((MVMP6opaque *)0)_V) |
392 | | #line 90 "src/jit/x64/emit.dasc" |
393 | | //|.type P6OBODY, MVMP6opaqueBody |
394 | 6.62k | #define DtA(_V) (int)(ptrdiff_t)&(((MVMP6opaqueBody *)0)_V) |
395 | | #line 91 "src/jit/x64/emit.dasc" |
396 | | //|.type MVMITER, MVMIter |
397 | 0 | #define DtB(_V) (int)(ptrdiff_t)&(((MVMIter *)0)_V) |
398 | | #line 92 "src/jit/x64/emit.dasc" |
399 | | //|.type MVMINSTANCE, MVMInstance |
400 | 6.12k | #define DtC(_V) (int)(ptrdiff_t)&(((MVMInstance *)0)_V) |
401 | | #line 93 "src/jit/x64/emit.dasc" |
402 | | //|.type MVMACTIVEHANDLERS, MVMActiveHandler |
403 | 0 | #define DtD(_V) (int)(ptrdiff_t)&(((MVMActiveHandler *)0)_V) |
404 | | #line 94 "src/jit/x64/emit.dasc" |
405 | | //|.type OBJECT, MVMObject |
406 | 124k | #define DtE(_V) (int)(ptrdiff_t)&(((MVMObject *)0)_V) |
407 | | #line 95 "src/jit/x64/emit.dasc" |
408 | | //|.type STOOGE, MVMObjectStooge |
409 | 6.35k | #define DtF(_V) (int)(ptrdiff_t)&(((MVMObjectStooge *)0)_V) |
410 | | #line 96 "src/jit/x64/emit.dasc" |
411 | | //|.type VMARRAY, MVMArray |
412 | 0 | #define Dt10(_V) (int)(ptrdiff_t)&(((MVMArray *)0)_V) |
413 | | #line 97 "src/jit/x64/emit.dasc" |
414 | | //|.type COLLECTABLE, MVMCollectable |
415 | 18.2k | #define Dt11(_V) (int)(ptrdiff_t)&(((MVMCollectable *)0)_V) |
416 | | #line 98 "src/jit/x64/emit.dasc" |
417 | | //|.type STABLE, MVMSTable |
418 | 35.1k | #define Dt12(_V) (int)(ptrdiff_t)&(((MVMSTable *)0)_V) |
419 | | #line 99 "src/jit/x64/emit.dasc" |
420 | | //|.type REPR, MVMREPROps |
421 | 7.42k | #define Dt13(_V) (int)(ptrdiff_t)&(((MVMREPROps *)0)_V) |
422 | | #line 100 "src/jit/x64/emit.dasc" |
423 | | //|.type STRING, MVMString |
424 | 419 | #define Dt14(_V) (int)(ptrdiff_t)&(((MVMString *)0)_V) |
425 | | #line 101 "src/jit/x64/emit.dasc" |
426 | | //|.type OBJECTPTR, MVMObject* |
427 | 103k | #define Dt15(_V) (int)(ptrdiff_t)&(((MVMObject* *)0)_V) |
428 | | #line 102 "src/jit/x64/emit.dasc" |
429 | | //|.type CONTEXT, MVMContext |
430 | 0 | #define Dt16(_V) (int)(ptrdiff_t)&(((MVMContext *)0)_V) |
431 | | #line 103 "src/jit/x64/emit.dasc" |
432 | | //|.type CONTAINERSPEC, MVMContainerSpec |
433 | 8.28k | #define Dt17(_V) (int)(ptrdiff_t)&(((MVMContainerSpec *)0)_V) |
434 | | #line 104 "src/jit/x64/emit.dasc" |
435 | | //|.type STORAGESPEC, MVMStorageSpec |
436 | 78 | #define Dt18(_V) (int)(ptrdiff_t)&(((MVMStorageSpec *)0)_V) |
437 | | #line 105 "src/jit/x64/emit.dasc" |
438 | | //|.type HLLCONFIG, MVMHLLConfig; |
439 | 1.91k | #define Dt19(_V) (int)(ptrdiff_t)&(((MVMHLLConfig *)0)_V) |
440 | | #line 106 "src/jit/x64/emit.dasc" |
441 | | //|.type SCREF, MVMSerializationContext |
442 | | #define Dt1A(_V) (int)(ptrdiff_t)&(((MVMSerializationContext *)0)_V) |
443 | | #line 107 "src/jit/x64/emit.dasc" |
444 | | //|.type SCREFBODY, MVMSerializationContextBody |
445 | 5 | #define Dt1B(_V) (int)(ptrdiff_t)&(((MVMSerializationContextBody *)0)_V) |
446 | | #line 108 "src/jit/x64/emit.dasc" |
447 | | //|.type NFGSYNTH, MVMNFGSynthetic |
448 | | #define Dt1C(_V) (int)(ptrdiff_t)&(((MVMNFGSynthetic *)0)_V) |
449 | | #line 109 "src/jit/x64/emit.dasc" |
450 | | //|.type CODE, MVMCode |
451 | 7.57k | #define Dt1D(_V) (int)(ptrdiff_t)&(((MVMCode *)0)_V) |
452 | | #line 110 "src/jit/x64/emit.dasc" |
453 | | //|.type U8, MVMuint8 |
454 | | #define Dt1E(_V) (int)(ptrdiff_t)&(((MVMuint8 *)0)_V) |
455 | | #line 111 "src/jit/x64/emit.dasc" |
456 | | //|.type U16, MVMuint16 |
457 | 1 | #define Dt1F(_V) (int)(ptrdiff_t)&(((MVMuint16 *)0)_V) |
458 | | #line 112 "src/jit/x64/emit.dasc" |
459 | | //|.type U32, MVMuint32 |
460 | | #define Dt20(_V) (int)(ptrdiff_t)&(((MVMuint32 *)0)_V) |
461 | | #line 113 "src/jit/x64/emit.dasc" |
462 | | //|.type U64, MVMuint64 |
463 | | #define Dt21(_V) (int)(ptrdiff_t)&(((MVMuint64 *)0)_V) |
464 | | #line 114 "src/jit/x64/emit.dasc" |
465 | | |
466 | | |
467 | | /* Static allocation of relevant types to registers. I pick |
468 | | * callee-save registers for efficiency. It is likely we'll be calling |
469 | | * quite a C functions, and this saves us the trouble of storing |
470 | | * them. Moreover, C compilers preferentially do not use callee-saved |
471 | | * registers, and so in most cases, these won't be touched at all. */ |
472 | | //|.type TC, MVMThreadContext, r14 |
473 | 209k | #define Dt22(_V) (int)(ptrdiff_t)&(((MVMThreadContext *)0)_V) |
474 | | #line 122 "src/jit/x64/emit.dasc" |
475 | | /* Alternative base pointer. I'll be using this often, so picking rbx |
476 | | * here rather than the extended registers will lead to smaller |
477 | | * bytecode */ |
478 | | //|.type WORK, MVMRegister, rbx |
479 | 579k | #define Dt23(_V) (int)(ptrdiff_t)&(((MVMRegister *)0)_V) |
480 | | #line 126 "src/jit/x64/emit.dasc" |
481 | | //|.type CU, MVMCompUnit, r13 |
482 | 53.3k | #define Dt24(_V) (int)(ptrdiff_t)&(((MVMCompUnit *)0)_V) |
483 | | #line 127 "src/jit/x64/emit.dasc" |
484 | | |
485 | | |
486 | | |
487 | | |
488 | 11.1k | const MVMint32 MVM_jit_support(void) { |
489 | 11.1k | #ifdef __i386__ |
490 | | /* Usually, this file should only be compiled only on a amd64 |
491 | | platform; but when compiling 'fat' or 'universal' binaries, we |
492 | | may compile it for other platform. In this case we use the |
493 | | runtime check to disable the JIT */ |
494 | | return 0; |
495 | | #else |
496 | 11.1k | return 1; |
497 | 11.1k | #endif |
498 | 11.1k | } |
499 | | |
500 | 10.7k | const unsigned char * MVM_jit_actions(void) { |
501 | 10.7k | return actions; |
502 | 10.7k | } |
503 | | |
504 | | /* C Call argument registers */ |
505 | | //|.if WIN32 |
506 | | //|.define ARG1, rcx |
507 | | //|.define ARG2, rdx |
508 | | //|.define ARG3, r8 |
509 | | //|.define ARG4, r9 |
510 | | //|.define ARG5, [rsp+0x20] |
511 | | //|.define ARG6, [rsp+0x28] |
512 | | //|.else |
513 | | //|.define ARG1, rdi |
514 | | //|.define ARG2, rsi |
515 | | //|.define ARG3, rdx |
516 | | //|.define ARG4, rcx |
517 | | //|.define ARG5, r8 |
518 | | //|.define ARG6, r9 |
519 | | //|.endif |
520 | | |
521 | | /* C call argument registers for floating point */ |
522 | | //|.if WIN32 |
523 | | //|.define ARG1F, xmm0 |
524 | | //|.define ARG2F, xmm1 |
525 | | //|.define ARG3F, xmm2 |
526 | | //|.define ARG4F, xmm3 |
527 | | //|.else |
528 | | //|.define ARG1F, xmm0 |
529 | | //|.define ARG2F, xmm1 |
530 | | //|.define ARG3F, xmm2 |
531 | | //|.define ARG4F, xmm3 |
532 | | //|.define ARG5F, xmm4 |
533 | | //|.define ARG6F, xmm5 |
534 | | //|.define ARG7F, xmm6 |
535 | | //|.define ARG8F, xmm7 |
536 | | //|.endif |
537 | | |
538 | | /* Special register for the function to be invoked |
539 | | * (chosen because it isn't involved in argument passing |
540 | | * and volatile) */ |
541 | | //|.define FUNCTION, r10 |
542 | | /* all-purpose temporary registers */ |
543 | | //|.define TMP1, rcx |
544 | | //|.define TMP2, rdx |
545 | | //|.define TMP3, r8 |
546 | | //|.define TMP4, r9 |
547 | | //|.define TMP5, r10 |
548 | | //|.define TMP6, r11 |
549 | | /* same, but 32 bits wide */ |
550 | | //|.define TMP1d, ecx |
551 | | //|.define TMP2d, edx |
552 | | //|.define TMP3d, r8d |
553 | | //|.define TMP4d, r9d |
554 | | //|.define TMP5d, r10d |
555 | | //|.define TMP6d, r11d |
556 | | /* and 16 bits wide */ |
557 | | //|.define TMP1w, cx |
558 | | //|.define TMP2w, dx |
559 | | //|.define TMP3w, r8w |
560 | | //|.define TMP4w, r9w |
561 | | //|.define TMP5w, r10w |
562 | | //|.define TMP6w, r11w |
563 | | /* and 8 bits for good measure */ |
564 | | //|.define TMP1b, cl |
565 | | //|.define TMP2b, dl |
566 | | //|.define TMP3b, r8b |
567 | | //|.define TMP4b, r9b |
568 | | //|.define TMP5b, r10b |
569 | | //|.define TMP6b, r11b |
570 | | |
571 | | |
572 | | /* return value */ |
573 | | //|.define RV, rax |
574 | | //|.define RVd, eax |
575 | | //|.define RVF, xmm0 |
576 | | |
577 | | |
578 | | //|.macro callp, funcptr |
579 | | //|.data |
580 | | //|5: |
581 | | //|.dword (MVMuint32)((uintptr_t)(funcptr)), (MVMuint32)((uintptr_t)(funcptr) >> 32); |
582 | | //|.code |
583 | | //| call qword [<5]; |
584 | | //|.endmacro |
585 | | |
586 | | |
587 | | //|.macro check_wb, root, ref, lbl; |
588 | | //| test word COLLECTABLE:root->flags, MVM_CF_SECOND_GEN; |
589 | | //| jz lbl; |
590 | | //| test ref, ref; |
591 | | //| jz lbl; |
592 | | //| test word COLLECTABLE:ref->flags, MVM_CF_SECOND_GEN; |
593 | | //| jnz lbl; |
594 | | //|.endmacro; |
595 | | |
596 | | //|.macro hit_wb, obj |
597 | | //| mov ARG2, obj; |
598 | | //| mov ARG1, TC; |
599 | | //| callp &MVM_gc_write_barrier_hit; |
600 | | //|.endmacro |
601 | | |
602 | | //|.macro get_spesh_slot, reg, idx; |
603 | | //| mov reg, TC->cur_frame; |
604 | | //| mov reg, FRAME:reg->effective_spesh_slots; |
605 | | //| mov reg, OBJECTPTR:reg[idx]; |
606 | | //|.endmacro |
607 | | |
608 | | //|.macro get_vmnull, reg |
609 | | //| mov reg, TC->instance; |
610 | | //| mov reg, MVMINSTANCE:reg->VMNull; |
611 | | //|.endmacro |
612 | | |
613 | | //|.macro get_cur_op, reg |
614 | | //| mov reg, TC->interp_cur_op |
615 | | //| mov reg, [reg] |
616 | | //|.endmacro |
617 | | |
618 | | //|.macro get_string, reg, idx |
619 | | //|| MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, idx); |
620 | | //| mov reg, CU->body.strings; |
621 | | //| mov reg, OBJECTPTR:reg[idx]; |
622 | | //|.endmacro |
623 | | |
624 | | //|.macro test_type_object, reg |
625 | | //| test word OBJECT:reg->header.flags, MVM_CF_TYPE_OBJECT |
626 | | //|.endmacro |
627 | | |
628 | | //|.macro gc_sync_point |
629 | | //| cmp qword TC->gc_status, 0; |
630 | | //| je >1; |
631 | | //| mov ARG1, TC; |
632 | | //| callp &MVM_gc_enter_from_interrupt; |
633 | | //|1: |
634 | | //|.endmacro |
635 | | |
636 | | //|.macro throw_adhoc, msg |
637 | | //| mov ARG1, TC; |
638 | | //| mov64 ARG2, (uintptr_t)(msg); |
639 | | //| callp &MVM_exception_throw_adhoc; |
640 | | //|.endmacro |
641 | | |
642 | | //|.macro get_stable, out, in |
643 | | //| mov out, aword OBJECT:in->st; |
644 | | //|.endmacro |
645 | | |
646 | | //|.macro get_repr, out, in |
647 | | //| get_stable out, in; |
648 | | //| mov out, aword STABLE:out->REPR; |
649 | | //|.endmacro |
650 | | |
651 | | //|.macro cmp_repr_id, obj, tmp, id |
652 | | //| get_repr tmp, obj; |
653 | | //| cmp dword REPR:tmp->ID, id; |
654 | | //|.endmacro |
655 | | |
656 | | //|.define FRAME_NR, dword [rbp-0x20] |
657 | | |
658 | | /* A function prologue is always the same in x86 / x64, because |
659 | | * we do not provide variable arguments, instead arguments are provided |
660 | | * via a frame. All JIT entry points receive a prologue. */ |
661 | | |
662 | | void MVM_jit_emit_prologue(MVMThreadContext *tc, MVMJitCompiler *compiler, |
663 | 10.7k | MVMJitGraph *jg) { |
664 | 10.7k | //|.code |
665 | 10.7k | dasm_put(Dst, 0); |
666 | 10.7k | #line 308 "src/jit/x64/emit.dasc" |
667 | 10.7k | /* Setup stack */ |
668 | 10.7k | //| push rbp; |
669 | 10.7k | //| mov rbp, rsp; |
670 | 10.7k | dasm_put(Dst, 2); |
671 | 10.7k | #line 311 "src/jit/x64/emit.dasc" |
672 | 10.7k | /* allocate stack space: 0x100 bytes = 256 bytes |
673 | 10.7k | * |
674 | 10.7k | * layout: [ a: 0x20 | b: 0x40 | c: 0xa0 | d: 0x20 ] |
675 | 10.7k | * a: space for 4 callee-save registers |
676 | 10.7k | * b: small scratch space |
677 | 10.7k | * c: space for stack arguments to c calls |
678 | 10.7k | * d: reserve space for GPR registers to c calls (win64) or more space for |
679 | 10.7k | * stack arguments (posix) */ |
680 | 10.7k | //| sub rsp, 0x100; |
681 | 10.7k | dasm_put(Dst, 7); |
682 | 10.7k | #line 320 "src/jit/x64/emit.dasc" |
683 | 10.7k | /* save callee-save registers */ |
684 | 10.7k | //| mov [rbp-0x8], TC; |
685 | 10.7k | //| mov [rbp-0x10], CU; |
686 | 10.7k | //| mov [rbp-0x18], WORK; |
687 | 10.7k | dasm_put(Dst, 16); |
688 | 10.7k | #line 324 "src/jit/x64/emit.dasc" |
689 | 10.7k | /* setup special frame variables */ |
690 | 10.7k | //| mov TC, ARG1; |
691 | 10.7k | //| mov CU, ARG2; |
692 | 10.7k | //| mov TMP6, TC->cur_frame; |
693 | 10.7k | //| mov WORK, FRAME:TMP6->work; |
694 | 10.7k | dasm_put(Dst, 32, Dt22(->cur_frame), Dt2(->work)); |
695 | 10.7k | #line 329 "src/jit/x64/emit.dasc" |
696 | 10.7k | /* If in the future we call a function, the return address into the JIT |
697 | 10.7k | * frame will be stored in this position. */ |
698 | 10.7k | if (!jg->no_trampoline) { |
699 | 10.7k | //| lea rax, [rsp-0x8]; |
700 | 10.7k | //| mov aword TC->jit_return_address, rax; |
701 | 10.7k | dasm_put(Dst, 49, Dt22(->jit_return_address)); |
702 | 10.7k | #line 334 "src/jit/x64/emit.dasc" |
703 | 10.7k | } |
704 | 10.7k | /* ARG3 contains our 'entry label' */ |
705 | 10.7k | //| jmp ARG3 |
706 | 10.7k | dasm_put(Dst, 60); |
707 | 10.7k | #line 337 "src/jit/x64/emit.dasc" |
708 | 10.7k | } |
709 | | |
710 | | /* And a function epilogue is also always the same */ |
711 | 10.7k | void MVM_jit_emit_epilogue(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg) { |
712 | 10.7k | //| ->exit: |
713 | 10.7k | dasm_put(Dst, 64); |
714 | 10.7k | #line 342 "src/jit/x64/emit.dasc" |
715 | 10.7k | /* clear the return address, so that we know there's no longer a JIT frame |
716 | 10.7k | * on the stack */ |
717 | 10.7k | if (!jg->no_trampoline) { |
718 | 10.7k | //| mov aword TC->jit_return_address, 0; |
719 | 10.7k | dasm_put(Dst, 67, Dt22(->jit_return_address)); |
720 | 10.7k | #line 346 "src/jit/x64/emit.dasc" |
721 | 10.7k | } |
722 | 10.7k | /* restore callee-save registers */ |
723 | 10.7k | //| mov TC, [rbp-0x8]; |
724 | 10.7k | //| mov CU, [rbp-0x10]; |
725 | 10.7k | //| mov WORK, [rbp-0x18]; |
726 | 10.7k | dasm_put(Dst, 76); |
727 | 10.7k | #line 351 "src/jit/x64/emit.dasc" |
728 | 10.7k | /* Restore stack */ |
729 | 10.7k | //| mov rsp, rbp; |
730 | 10.7k | //| pop rbp; |
731 | 10.7k | //| ret; |
732 | 10.7k | dasm_put(Dst, 92); |
733 | 10.7k | #line 355 "src/jit/x64/emit.dasc" |
734 | 10.7k | } |
735 | | |
736 | | static MVMuint64 try_emit_gen2_ref(MVMThreadContext *tc, MVMJitCompiler *compiler, |
737 | 5.99k | MVMJitGraph *jg, MVMObject *obj, MVMint16 reg) { |
738 | 5.99k | if (!(obj->header.flags & MVM_CF_SECOND_GEN)) |
739 | 0 | return 0; |
740 | 5.99k | //| mov64 TMP1, (uintptr_t)obj; |
741 | 5.99k | //| mov WORK[reg], TMP1; |
742 | 5.99k | dasm_put(Dst, 99, (unsigned int)((uintptr_t)obj), (unsigned int)(((uintptr_t)obj)>>32), Dt23([reg])); |
743 | 5.99k | #line 363 "src/jit/x64/emit.dasc" |
744 | 5.99k | return 1; |
745 | 5.99k | } |
746 | | |
747 | 106k | static MVMint64 fits_in_32_bit(MVMint64 number) { |
748 | 106k | /* Used to determine if a 64 bit integer can be safely used as a |
749 | 106k | * 32 bit constant for immediate mode access */ |
750 | 106k | return (number >= INT32_MIN) && (number <= INT32_MAX); |
751 | 106k | } |
752 | | |
753 | | /* compile per instruction, can't really do any better yet */ |
754 | | void MVM_jit_emit_primitive(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
755 | 135k | MVMJitPrimitive * prim) { |
756 | 135k | MVMSpeshIns *ins = prim->ins; |
757 | 135k | MVMuint16 op = ins->info->opcode; |
758 | 135k | MVM_jit_log(tc, "emit opcode: <%s>\n", ins->info->name); |
759 | 135k | /* Quite a few of these opcodes are copies. Ultimately, I want to |
760 | 135k | * move copies to their own node (MVMJitCopy or such), and reduce |
761 | 135k | * the number of copies (and thereby increase the efficiency), but |
762 | 135k | * currently that isn't really feasible. */ |
763 | 135k | switch (op) { |
764 | 8.42k | case MVM_OP_const_i64_16: |
765 | 8.42k | case MVM_OP_const_i64_32: { |
766 | 8.42k | MVMint32 reg = ins->operands[0].reg.orig; |
767 | 8.42k | /* Upgrade to 64 bit */ |
768 | 8.42k | MVMint64 val = (op == MVM_OP_const_i64_16 ? (MVMint64)ins->operands[1].lit_i16 : |
769 | 1 | (MVMint64)ins->operands[1].lit_i32); |
770 | 8.42k | //| mov qword WORK[reg], val; |
771 | 8.42k | dasm_put(Dst, 108, Dt23([reg]), val); |
772 | 8.42k | #line 390 "src/jit/x64/emit.dasc" |
773 | 8.42k | break; |
774 | 8.42k | } |
775 | 0 | case MVM_OP_const_i64: { |
776 | 0 | MVMint32 reg = ins->operands[0].reg.orig; |
777 | 0 | MVMint64 val = ins->operands[1].lit_i64; |
778 | 0 | //| mov64 TMP1, val; |
779 | 0 | //| mov WORK[reg], TMP1; |
780 | 0 | dasm_put(Dst, 99, (unsigned int)(val), (unsigned int)((val)>>32), Dt23([reg])); |
781 | 0 | #line 397 "src/jit/x64/emit.dasc" |
782 | 0 | break; |
783 | 8.42k | } |
784 | 451 | case MVM_OP_const_n64: { |
785 | 451 | MVMint16 reg = ins->operands[0].reg.orig; |
786 | 451 | MVMint64 valbytes = ins->operands[1].lit_i64; |
787 | 451 | MVM_jit_log(tc, "store const %f\n", ins->operands[1].lit_n64); |
788 | 451 | //| mov64 TMP1, valbytes; |
789 | 451 | //| mov WORK[reg], TMP1; |
790 | 451 | dasm_put(Dst, 99, (unsigned int)(valbytes), (unsigned int)((valbytes)>>32), Dt23([reg])); |
791 | 451 | #line 405 "src/jit/x64/emit.dasc" |
792 | 451 | break; |
793 | 8.42k | } |
794 | 0 | case MVM_OP_inf: |
795 | 0 | case MVM_OP_neginf: |
796 | 0 | case MVM_OP_nan: { |
797 | 0 | MVMint16 reg = ins->operands[0].reg.orig; |
798 | 0 | MVMRegister tmp; |
799 | 0 | if (op == MVM_OP_nan) |
800 | 0 | tmp.n64 = MVM_num_nan(tc); |
801 | 0 | else if (op == MVM_OP_inf) |
802 | 0 | tmp.n64 = MVM_num_posinf(tc); |
803 | 0 | else if (op == MVM_OP_neginf) |
804 | 0 | tmp.n64 = MVM_num_neginf(tc); |
805 | 0 | //| mov64 TMP1, tmp.i64; |
806 | 0 | //| mov WORK[reg], TMP1; |
807 | 0 | dasm_put(Dst, 99, (unsigned int)(tmp.i64), (unsigned int)((tmp.i64)>>32), Dt23([reg])); |
808 | 0 | #line 420 "src/jit/x64/emit.dasc" |
809 | 0 | break; |
810 | 0 | } |
811 | 5.99k | case MVM_OP_const_s: { |
812 | 5.99k | MVMint16 reg = ins->operands[0].reg.orig; |
813 | 5.99k | MVMuint32 idx = ins->operands[1].lit_str_idx; |
814 | 5.99k | MVMStaticFrame *sf = jg->sg->sf; |
815 | 5.99k | MVMString * s = MVM_cu_string(tc, sf->body.cu, idx); |
816 | 5.99k | if (!try_emit_gen2_ref(tc, compiler, jg, (MVMObject*)s, reg)) { |
817 | 0 | //| get_string TMP1, idx; |
818 | 0 | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, idx); |
819 | 0 | #line 429 "src/jit/x64/emit.dasc" |
820 | 0 | //| mov WORK[reg], TMP1; |
821 | 0 | dasm_put(Dst, 114, Dt24(->body.strings), Dt15([idx]), Dt23([reg])); |
822 | 0 | #line 430 "src/jit/x64/emit.dasc" |
823 | 0 | } |
824 | 5.99k | break; |
825 | 0 | } |
826 | 219 | case MVM_OP_null: { |
827 | 219 | MVMint16 reg = ins->operands[0].reg.orig; |
828 | 219 | //| get_vmnull TMP1; |
829 | 219 | //| mov WORK[reg], TMP1; |
830 | 219 | dasm_put(Dst, 127, Dt22(->instance), DtC(->VMNull), Dt23([reg])); |
831 | 219 | #line 437 "src/jit/x64/emit.dasc" |
832 | 219 | break; |
833 | 0 | } |
834 | 337 | case MVM_OP_getwhat: |
835 | 337 | case MVM_OP_getwho: { |
836 | 337 | MVMint16 dst = ins->operands[0].reg.orig; |
837 | 337 | MVMint16 obj = ins->operands[1].reg.orig; |
838 | 337 | //| mov TMP1, WORK[obj]; |
839 | 337 | //| mov TMP1, OBJECT:TMP1->st; |
840 | 337 | dasm_put(Dst, 140, Dt23([obj]), DtE(->st)); |
841 | 337 | #line 445 "src/jit/x64/emit.dasc" |
842 | 337 | if (op == MVM_OP_getwho) { |
843 | 337 | //| mov TMP1, STABLE:TMP1->WHO; |
844 | 337 | //| get_vmnull TMP2; |
845 | 337 | //| test TMP1, TMP1; |
846 | 337 | //| cmovz TMP1, TMP2; |
847 | 337 | dasm_put(Dst, 149, Dt12(->WHO), Dt22(->instance), DtC(->VMNull)); |
848 | 337 | #line 450 "src/jit/x64/emit.dasc" |
849 | 0 | } else { |
850 | 0 | //| mov TMP1, STABLE:TMP1->WHAT; |
851 | 0 | dasm_put(Dst, 144, Dt12(->WHAT)); |
852 | 0 | #line 452 "src/jit/x64/emit.dasc" |
853 | 0 | } |
854 | 337 | //| mov WORK[dst], TMP1; |
855 | 337 | dasm_put(Dst, 103, Dt23([dst])); |
856 | 337 | #line 454 "src/jit/x64/emit.dasc" |
857 | 337 | break; |
858 | 337 | } |
859 | 9.91k | case MVM_OP_getlex: |
860 | 9.91k | case MVM_OP_sp_getlex_o: |
861 | 9.91k | case MVM_OP_sp_getlex_ins: { |
862 | 9.91k | MVMuint16 *lexical_types; |
863 | 9.91k | MVMStaticFrame * sf = jg->sg->sf; |
864 | 9.91k | MVMint16 dst = ins->operands[0].reg.orig; |
865 | 9.91k | MVMint16 idx = ins->operands[1].lex.idx; |
866 | 9.91k | MVMint16 out = ins->operands[1].lex.outers; |
867 | 9.91k | MVMint16 i; |
868 | 9.91k | //| mov TMP6, TC->cur_frame; |
869 | 9.91k | dasm_put(Dst, 169, Dt22(->cur_frame)); |
870 | 9.91k | #line 466 "src/jit/x64/emit.dasc" |
871 | 21.6k | for (i = 0; i < out; i++) { |
872 | 11.7k | /* I'm going to skip compiling the check whether the outer |
873 | 11.7k | * node really exists, because if the code has run N times |
874 | 11.7k | * correctly, then the outer frame must have existed then, |
875 | 11.7k | * and since this chain is static, it should still exist |
876 | 11.7k | * now. If it doesn't exist, that means we crash. |
877 | 11.7k | * |
878 | 11.7k | * NB: inlining /might/ make this all wrong! But, if that |
879 | 11.7k | * happens, the interpreter will panic even without JIT */ |
880 | 11.7k | //| mov TMP6, FRAME:TMP6->outer; |
881 | 11.7k | dasm_put(Dst, 174, Dt2(->outer)); |
882 | 11.7k | #line 476 "src/jit/x64/emit.dasc" |
883 | 11.7k | sf = sf->body.outer; |
884 | 11.7k | } |
885 | 9.91k | /* get array of lexicals */ |
886 | 9.91k | //| mov TMP5, FRAME:TMP6->env; |
887 | 9.91k | dasm_put(Dst, 179, Dt2(->env)); |
888 | 9.91k | #line 480 "src/jit/x64/emit.dasc" |
889 | 9.91k | /* read value */ |
890 | 9.91k | //| mov TMP5, REGISTER:TMP5[idx]; |
891 | 9.91k | dasm_put(Dst, 184, Dt1([idx])); |
892 | 9.91k | #line 482 "src/jit/x64/emit.dasc" |
893 | 9.91k | /* it seems that if at runtime, if the outer frame has been inlined, |
894 | 9.91k | * this /could/ be wrong. But if that is so, the interpreted instruction |
895 | 9.91k | * would also be wrong, because it'd refer to the wrong lexical. */ |
896 | 2.45k | lexical_types = (!out && jg->sg->lexical_types ? |
897 | 1.87k | jg->sg->lexical_types : |
898 | 8.04k | sf->body.lexical_types); |
899 | 9.91k | MVM_jit_log(tc, "Lexical type of register: %d\n", lexical_types[idx]); |
900 | 9.91k | if (lexical_types[idx] == MVM_reg_obj) { |
901 | 6.32k | MVM_jit_log(tc, "Emit lex vifivy check\n"); |
902 | 6.32k | /* if it is zero, check if we need to auto-vivify */ |
903 | 6.32k | //| test TMP5, TMP5; |
904 | 6.32k | //| jnz >1; |
905 | 6.32k | dasm_put(Dst, 189); |
906 | 6.32k | #line 494 "src/jit/x64/emit.dasc" |
907 | 6.32k | /* setup args */ |
908 | 6.32k | //| mov ARG1, TC; |
909 | 6.32k | //| mov ARG2, TMP6; |
910 | 6.32k | //| mov ARG3, idx; |
911 | 6.32k | //| callp &MVM_frame_vivify_lexical; |
912 | 6.32k | dasm_put(Dst, 197, idx); |
913 | 6.32k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_vivify_lexical)), (MVMuint32)((uintptr_t)(&MVM_frame_vivify_lexical) >> 32)); |
914 | 6.32k | dasm_put(Dst, 216); |
915 | 6.32k | #line 499 "src/jit/x64/emit.dasc" |
916 | 6.32k | /* use return value for the result */ |
917 | 6.32k | //| mov TMP5, RV; |
918 | 6.32k | //|1: |
919 | 6.32k | dasm_put(Dst, 222); |
920 | 6.32k | #line 502 "src/jit/x64/emit.dasc" |
921 | 6.32k | } |
922 | 9.91k | /* store the value */ |
923 | 9.91k | //| mov WORK[dst], TMP5; |
924 | 9.91k | dasm_put(Dst, 228, Dt23([dst])); |
925 | 9.91k | #line 505 "src/jit/x64/emit.dasc" |
926 | 9.91k | break; |
927 | 9.91k | } |
928 | 372 | case MVM_OP_sp_getlexvia_o: |
929 | 372 | case MVM_OP_sp_getlexvia_ins: { |
930 | 372 | MVMint16 dst = ins->operands[0].reg.orig; |
931 | 372 | MVMint16 idx = ins->operands[1].lit_ui16; |
932 | 372 | MVMint16 out = ins->operands[2].lit_ui16; |
933 | 372 | MVMint16 via = ins->operands[3].reg.orig; |
934 | 372 | MVMint16 i; |
935 | 372 | /* Resolve the frame. */ |
936 | 372 | //| mov TMP6, WORK[via]; |
937 | 372 | //| mov TMP6, CODE:TMP6->body.outer; |
938 | 372 | dasm_put(Dst, 233, Dt23([via]), Dt1D(->body.outer)); |
939 | 372 | #line 517 "src/jit/x64/emit.dasc" |
940 | 600 | for (i = 1; i < out; i++) /* From 1 as we are already at outer */ |
941 | 372 | //| mov TMP6, FRAME:TMP6->outer; |
942 | 228 | dasm_put(Dst, 174, Dt2(->outer)); |
943 | 372 | #line 519 "src/jit/x64/emit.dasc" |
944 | 372 | /* get array of lexicals */ |
945 | 372 | //| mov TMP5, FRAME:TMP6->env; |
946 | 372 | dasm_put(Dst, 179, Dt2(->env)); |
947 | 372 | #line 521 "src/jit/x64/emit.dasc" |
948 | 372 | /* read value */ |
949 | 372 | //| mov TMP5, REGISTER:TMP5[idx]; |
950 | 372 | dasm_put(Dst, 184, Dt1([idx])); |
951 | 372 | #line 523 "src/jit/x64/emit.dasc" |
952 | 372 | if (op == MVM_OP_sp_getlexvia_o) { |
953 | 255 | MVM_jit_log(tc, "Emit lex vifivy check for via code-ref lookup\n"); |
954 | 255 | /* if it is zero, check if we need to auto-vivify */ |
955 | 255 | //| test TMP5, TMP5; |
956 | 255 | //| jnz >1; |
957 | 255 | dasm_put(Dst, 189); |
958 | 255 | #line 528 "src/jit/x64/emit.dasc" |
959 | 255 | /* setup args */ |
960 | 255 | //| mov ARG1, TC; |
961 | 255 | //| mov ARG2, TMP6; |
962 | 255 | //| mov ARG3, idx; |
963 | 255 | //| callp &MVM_frame_vivify_lexical; |
964 | 255 | dasm_put(Dst, 197, idx); |
965 | 255 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_vivify_lexical)), (MVMuint32)((uintptr_t)(&MVM_frame_vivify_lexical) >> 32)); |
966 | 255 | dasm_put(Dst, 216); |
967 | 255 | #line 533 "src/jit/x64/emit.dasc" |
968 | 255 | /* use return value for the result */ |
969 | 255 | //| mov TMP5, RV; |
970 | 255 | //|1: |
971 | 255 | dasm_put(Dst, 222); |
972 | 255 | #line 536 "src/jit/x64/emit.dasc" |
973 | 255 | } |
974 | 372 | /* store the value */ |
975 | 372 | //| mov WORK[dst], TMP5; |
976 | 372 | dasm_put(Dst, 228, Dt23([dst])); |
977 | 372 | #line 539 "src/jit/x64/emit.dasc" |
978 | 372 | break; |
979 | 372 | } |
980 | 0 | case MVM_OP_getlexreldyn: { |
981 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
982 | 0 | MVMint16 ctx = ins->operands[1].reg.orig; |
983 | 0 | MVMint16 name = ins->operands[2].reg.orig; |
984 | 0 | //| mov TMP5, aword WORK[ctx]; |
985 | 0 | //| test_type_object TMP5; |
986 | 0 | //| jnz >1; |
987 | 0 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_MVMContext; |
988 | 0 | //| jne >1; |
989 | 0 | //| mov TMP6, CONTEXT:TMP5->body.context; |
990 | 0 | //| mov ARG1, TC; |
991 | 0 | //| mov ARG2, aword WORK[name]; |
992 | 0 | //| mov ARG3, TMP6; |
993 | 0 | //| callp &MVM_frame_getdynlex; |
994 | 0 | dasm_put(Dst, 242, Dt23([ctx]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMContext, Dt16(->body.context), Dt23([name])); |
995 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_getdynlex)), (MVMuint32)((uintptr_t)(&MVM_frame_getdynlex) >> 32)); |
996 | 0 | #line 555 "src/jit/x64/emit.dasc" |
997 | 0 | //| mov WORK[dst], RV; |
998 | 0 | //| jmp >2; |
999 | 0 | //|1: |
1000 | 0 | //| throw_adhoc "getlexreldyn needs a context"; |
1001 | 0 | dasm_put(Dst, 291, Dt23([dst]), (unsigned int)((uintptr_t)("getlexreldyn needs a context")), (unsigned int)(((uintptr_t)("getlexreldyn needs a context"))>>32)); |
1002 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1003 | 0 | #line 559 "src/jit/x64/emit.dasc" |
1004 | 0 | //|2: |
1005 | 0 | dasm_put(Dst, 316); |
1006 | 0 | #line 560 "src/jit/x64/emit.dasc" |
1007 | 0 | break; |
1008 | 372 | } |
1009 | 139 | case MVM_OP_getlex_no: |
1010 | 139 | case MVM_OP_sp_getlex_no: { |
1011 | 139 | MVMint16 dst = ins->operands[0].reg.orig; |
1012 | 139 | MVMuint32 idx = ins->operands[1].lit_str_idx; |
1013 | 139 | //| mov ARG1, TC; |
1014 | 139 | //| get_string ARG2, idx; |
1015 | 139 | dasm_put(Dst, 324); |
1016 | 139 | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, idx); |
1017 | 139 | #line 568 "src/jit/x64/emit.dasc" |
1018 | 139 | //| mov ARG3, MVM_reg_obj; |
1019 | 139 | //| callp &MVM_frame_find_lexical_by_name; |
1020 | 139 | dasm_put(Dst, 329, Dt24(->body.strings), Dt15([idx]), MVM_reg_obj); |
1021 | 139 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_find_lexical_by_name)), (MVMuint32)((uintptr_t)(&MVM_frame_find_lexical_by_name) >> 32)); |
1022 | 139 | #line 570 "src/jit/x64/emit.dasc" |
1023 | 139 | //| test RV, RV; |
1024 | 139 | //| jz >1; |
1025 | 139 | //| mov RV, [RV]; |
1026 | 139 | //| mov WORK[dst], RV; |
1027 | 139 | //| jmp >2; |
1028 | 139 | //|1: |
1029 | 139 | //| get_vmnull TMP3; |
1030 | 139 | //| mov WORK[dst], TMP3; |
1031 | 139 | //|2: |
1032 | 139 | dasm_put(Dst, 343, Dt23([dst]), Dt22(->instance), DtC(->VMNull), Dt23([dst])); |
1033 | 139 | #line 579 "src/jit/x64/emit.dasc" |
1034 | 139 | break; |
1035 | 139 | } |
1036 | 2.09k | case MVM_OP_bindlex: { |
1037 | 2.09k | MVMuint16 *lexical_types; |
1038 | 2.09k | MVMStaticFrame *sf = jg->sg->sf; |
1039 | 2.09k | MVMint16 idx = ins->operands[0].lex.idx; |
1040 | 2.09k | MVMint16 out = ins->operands[0].lex.outers; |
1041 | 2.09k | MVMint16 src = ins->operands[1].reg.orig; |
1042 | 2.09k | MVMint16 i; |
1043 | 2.09k | //| mov TMP1, TC->cur_frame; |
1044 | 2.09k | dasm_put(Dst, 383, Dt22(->cur_frame)); |
1045 | 2.09k | #line 589 "src/jit/x64/emit.dasc" |
1046 | 2.18k | for (i = 0; i < out; i++) { |
1047 | 82 | //| mov TMP1, FRAME:TMP1->outer; |
1048 | 82 | dasm_put(Dst, 144, Dt2(->outer)); |
1049 | 82 | #line 591 "src/jit/x64/emit.dasc" |
1050 | 82 | sf = sf->body.outer; |
1051 | 82 | } |
1052 | 2.02k | lexical_types = (!out && jg->sg->lexical_types ? |
1053 | 1.55k | jg->sg->lexical_types : |
1054 | 547 | sf->body.lexical_types); |
1055 | 2.09k | //| mov TMP2, FRAME:TMP1->env; |
1056 | 2.09k | //| mov TMP3, WORK[src]; |
1057 | 2.09k | //| mov REGISTER:TMP2[idx], TMP3; |
1058 | 2.09k | dasm_put(Dst, 388, Dt2(->env), Dt23([src]), Dt1([idx])); |
1059 | 2.09k | #line 599 "src/jit/x64/emit.dasc" |
1060 | 2.09k | if (lexical_types[idx] == MVM_reg_obj || |
1061 | 2.08k | lexical_types[idx] == MVM_reg_str) { |
1062 | 2.08k | //| check_wb TMP1, TMP3, >2; |
1063 | 2.08k | //| hit_wb TMP1; |
1064 | 2.08k | dasm_put(Dst, 401, Dt11(->flags), MVM_CF_SECOND_GEN, Dt11(->flags), MVM_CF_SECOND_GEN); |
1065 | 2.08k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit)), (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit) >> 32)); |
1066 | 2.08k | #line 603 "src/jit/x64/emit.dasc" |
1067 | 2.08k | //|2: |
1068 | 2.08k | dasm_put(Dst, 316); |
1069 | 2.08k | #line 604 "src/jit/x64/emit.dasc" |
1070 | 2.08k | } |
1071 | 2.09k | break; |
1072 | 139 | } |
1073 | 0 | case MVM_OP_lexprimspec: { |
1074 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1075 | 0 | MVMint16 ctx = ins->operands[1].reg.orig; |
1076 | 0 | MVMint16 name = ins->operands[2].reg.orig; |
1077 | 0 | //| mov TMP1, WORK[ctx]; |
1078 | 0 | //| cmp_repr_id, TMP1, TMP2, MVM_REPR_ID_MVMContext; |
1079 | 0 | //| jne >1; |
1080 | 0 | //| test_type_object TMP1; |
1081 | 0 | //| jz >2; |
1082 | 0 | //|1: |
1083 | 0 | //| throw_adhoc "lexprimspec needs a context"; |
1084 | 0 | dasm_put(Dst, 438, Dt23([ctx]), DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMContext, DtE(->header.flags), MVM_CF_TYPE_OBJECT, (unsigned int)((uintptr_t)("lexprimspec needs a context")), (unsigned int)(((uintptr_t)("lexprimspec needs a context"))>>32)); |
1085 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1086 | 0 | #line 618 "src/jit/x64/emit.dasc" |
1087 | 0 | //|2: |
1088 | 0 | //| mov ARG2, CONTEXT:TMP1->body.context; |
1089 | 0 | //| mov ARG3, WORK[name]; |
1090 | 0 | //| mov ARG1, TC; |
1091 | 0 | //| callp &MVM_frame_lexical_primspec; |
1092 | 0 | dasm_put(Dst, 480, Dt16(->body.context), Dt23([name])); |
1093 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_lexical_primspec)), (MVMuint32)((uintptr_t)(&MVM_frame_lexical_primspec) >> 32)); |
1094 | 0 | #line 623 "src/jit/x64/emit.dasc" |
1095 | 0 | //| mov WORK[dst], RV; |
1096 | 0 | dasm_put(Dst, 501, Dt23([dst])); |
1097 | 0 | #line 624 "src/jit/x64/emit.dasc" |
1098 | 0 | break; |
1099 | 139 | } |
1100 | 0 | case MVM_OP_getarg_o: |
1101 | 0 | case MVM_OP_getarg_n: |
1102 | 0 | case MVM_OP_getarg_s: |
1103 | 0 | case MVM_OP_getarg_i: { |
1104 | 0 | MVMint32 reg = ins->operands[0].reg.orig; |
1105 | 0 | MVMuint16 idx = ins->operands[1].callsite_idx; |
1106 | 0 | //| mov TMP1, TC->cur_frame; |
1107 | 0 | //| mov TMP1, FRAME:TMP1->args; |
1108 | 0 | //| mov TMP1, REGISTER:TMP1[idx]; |
1109 | 0 | //| mov WORK[reg], TMP1; |
1110 | 0 | dasm_put(Dst, 511, Dt22(->cur_frame), Dt2(->args), Dt1([idx]), Dt23([reg])); |
1111 | 0 | #line 636 "src/jit/x64/emit.dasc" |
1112 | 0 | break; |
1113 | 0 | } |
1114 | 256 | case MVM_OP_sp_getarg_o: |
1115 | 256 | case MVM_OP_sp_getarg_n: |
1116 | 256 | case MVM_OP_sp_getarg_s: |
1117 | 256 | case MVM_OP_sp_getarg_i: { |
1118 | 256 | MVMint32 reg = ins->operands[0].reg.orig; |
1119 | 256 | MVMuint16 idx = ins->operands[1].callsite_idx; |
1120 | 256 | //| mov TMP1, TC->cur_frame; |
1121 | 256 | //| mov TMP1, FRAME:TMP1->params.args; |
1122 | 256 | //| mov TMP1, REGISTER:TMP1[idx]; |
1123 | 256 | //| mov WORK[reg], TMP1; |
1124 | 256 | dasm_put(Dst, 511, Dt22(->cur_frame), Dt2(->params.args), Dt1([idx]), Dt23([reg])); |
1125 | 256 | #line 648 "src/jit/x64/emit.dasc" |
1126 | 256 | break; |
1127 | 256 | } |
1128 | 11.0k | case MVM_OP_sp_p6oget_i: |
1129 | 11.0k | case MVM_OP_sp_p6oget_n: |
1130 | 11.0k | case MVM_OP_sp_p6oget_s: |
1131 | 11.0k | case MVM_OP_sp_p6oget_o: |
1132 | 11.0k | case MVM_OP_sp_p6ogetvc_o: |
1133 | 11.0k | case MVM_OP_sp_p6ogetvt_o: { |
1134 | 11.0k | MVMint16 dst = ins->operands[0].reg.orig; |
1135 | 11.0k | MVMint16 obj = ins->operands[1].reg.orig; |
1136 | 11.0k | MVMint16 offset = ins->operands[2].lit_i16; |
1137 | 11.0k | MVMint16 body = offsetof(MVMP6opaque, body); |
1138 | 11.0k | /* load address and object */ |
1139 | 11.0k | //| mov TMP1, WORK[obj]; |
1140 | 11.0k | //| lea TMP2, [TMP1 + (offset + body)]; |
1141 | 11.0k | //| mov TMP4, P6OPAQUE:TMP1->body.replaced; |
1142 | 11.0k | //| lea TMP5, [TMP4 + offset]; |
1143 | 11.0k | //| test TMP4, TMP4; |
1144 | 11.0k | //| cmovnz TMP2, TMP5; |
1145 | 11.0k | dasm_put(Dst, 528, Dt23([obj]), (offset + body), Dt9(->body.replaced), offset); |
1146 | 11.0k | #line 667 "src/jit/x64/emit.dasc" |
1147 | 11.0k | /* TMP2 now contains address of item */ |
1148 | 11.0k | if (op == MVM_OP_sp_p6oget_o) { |
1149 | 137 | //| mov TMP3, [TMP2]; |
1150 | 137 | //| test TMP3, TMP3; |
1151 | 137 | dasm_put(Dst, 552); |
1152 | 137 | #line 671 "src/jit/x64/emit.dasc" |
1153 | 137 | /* Check if object doesn't point to NULL */ |
1154 | 137 | //| jnz >3; |
1155 | 137 | dasm_put(Dst, 559); |
1156 | 137 | #line 673 "src/jit/x64/emit.dasc" |
1157 | 137 | /* Otherwise load VMNull */ |
1158 | 137 | //| get_vmnull TMP3; |
1159 | 137 | //|3: |
1160 | 137 | dasm_put(Dst, 564, Dt22(->instance), DtC(->VMNull)); |
1161 | 137 | #line 676 "src/jit/x64/emit.dasc" |
1162 | 10.9k | } else if (op == MVM_OP_sp_p6ogetvt_o) { |
1163 | 5.67k | /* vivify as type object */ |
1164 | 5.67k | MVMint16 spesh_idx = ins->operands[3].lit_i16; |
1165 | 5.67k | //| mov TMP3, [TMP2]; |
1166 | 5.67k | dasm_put(Dst, 575); |
1167 | 5.67k | #line 680 "src/jit/x64/emit.dasc" |
1168 | 5.67k | /* check for null */ |
1169 | 5.67k | //| test TMP3, TMP3; |
1170 | 5.67k | //| jnz >4; |
1171 | 5.67k | dasm_put(Dst, 579); |
1172 | 5.67k | #line 683 "src/jit/x64/emit.dasc" |
1173 | 5.67k | /* if null, vivify as type object from spesh slot */ |
1174 | 5.67k | //| get_spesh_slot TMP3, spesh_idx; |
1175 | 5.67k | dasm_put(Dst, 587, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([spesh_idx])); |
1176 | 5.67k | #line 685 "src/jit/x64/emit.dasc" |
1177 | 5.67k | /* need to hit write barrier? */ |
1178 | 5.67k | //| check_wb TMP1, TMP3, >3; |
1179 | 5.67k | //| mov qword [rbp-0x28], TMP2; // address |
1180 | 5.67k | //| mov qword [rbp-0x30], TMP3; // value |
1181 | 5.67k | //| hit_wb WORK[obj]; // write barrier for header |
1182 | 5.67k | dasm_put(Dst, 600, Dt11(->flags), MVM_CF_SECOND_GEN, Dt11(->flags), MVM_CF_SECOND_GEN, Dt23([obj])); |
1183 | 5.67k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit)), (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit) >> 32)); |
1184 | 5.67k | #line 690 "src/jit/x64/emit.dasc" |
1185 | 5.67k | //| mov TMP3, qword [rbp-0x30]; |
1186 | 5.67k | //| mov TMP2, qword [rbp-0x28]; |
1187 | 5.67k | //|3: |
1188 | 5.67k | dasm_put(Dst, 646); |
1189 | 5.67k | #line 693 "src/jit/x64/emit.dasc" |
1190 | 5.67k | /* store vivified type value in memory location */ |
1191 | 5.67k | //| mov qword [TMP2], TMP3; |
1192 | 5.67k | //|4: |
1193 | 5.67k | dasm_put(Dst, 662); |
1194 | 5.67k | #line 696 "src/jit/x64/emit.dasc" |
1195 | 5.28k | } else if (op == MVM_OP_sp_p6ogetvc_o) { |
1196 | 0 | MVMint16 spesh_idx = ins->operands[3].lit_i16; |
1197 | 0 | //| mov TMP3, [TMP2]; |
1198 | 0 | //| test TMP3, TMP3; |
1199 | 0 | //| jnz >4; |
1200 | 0 | dasm_put(Dst, 668); |
1201 | 0 | #line 701 "src/jit/x64/emit.dasc" |
1202 | 0 | /* vivify as clone */ |
1203 | 0 | //| mov ARG1, TC; |
1204 | 0 | //| get_spesh_slot ARG2, spesh_idx; |
1205 | 0 | //| callp &MVM_repr_clone; |
1206 | 0 | dasm_put(Dst, 679, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([spesh_idx])); |
1207 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_repr_clone)), (MVMuint32)((uintptr_t)(&MVM_repr_clone) >> 32)); |
1208 | 0 | #line 705 "src/jit/x64/emit.dasc" |
1209 | 0 | //| mov TMP3, RV; |
1210 | 0 | dasm_put(Dst, 697); |
1211 | 0 | #line 706 "src/jit/x64/emit.dasc" |
1212 | 0 | /* reload object and address */ |
1213 | 0 | //| mov TMP1, WORK[obj]; |
1214 | 0 | //| lea TMP2, [TMP1 + (offset + body)]; |
1215 | 0 | //| mov TMP4, P6OPAQUE:TMP1->body.replaced; |
1216 | 0 | //| lea TMP5, [TMP4 + offset]; |
1217 | 0 | //| test TMP4, TMP4; |
1218 | 0 | //| cmovnz TMP2, TMP5; |
1219 | 0 | dasm_put(Dst, 528, Dt23([obj]), (offset + body), Dt9(->body.replaced), offset); |
1220 | 0 | #line 713 "src/jit/x64/emit.dasc" |
1221 | 0 | /* assign with write barrier */ |
1222 | 0 | //| check_wb TMP1, TMP3, >3; |
1223 | 0 | //| mov qword [rbp-0x28], TMP2; // address |
1224 | 0 | //| mov qword [rbp-0x30], TMP3; // value |
1225 | 0 | //| hit_wb WORK[obj]; // write barrier for header |
1226 | 0 | dasm_put(Dst, 600, Dt11(->flags), MVM_CF_SECOND_GEN, Dt11(->flags), MVM_CF_SECOND_GEN, Dt23([obj])); |
1227 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit)), (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit) >> 32)); |
1228 | 0 | #line 718 "src/jit/x64/emit.dasc" |
1229 | 0 | //| mov TMP3, qword [rbp-0x30]; |
1230 | 0 | //| mov TMP2, qword [rbp-0x28]; |
1231 | 0 | //|3: |
1232 | 0 | //| mov qword [TMP2], TMP3; |
1233 | 0 | dasm_put(Dst, 706); |
1234 | 0 | #line 722 "src/jit/x64/emit.dasc" |
1235 | 0 | /* done */ |
1236 | 0 | //|4: |
1237 | 0 | dasm_put(Dst, 665); |
1238 | 0 | #line 724 "src/jit/x64/emit.dasc" |
1239 | 5.28k | } else { |
1240 | 5.28k | /* the regular case */ |
1241 | 5.28k | //| mov TMP3, [TMP2]; |
1242 | 5.28k | dasm_put(Dst, 575); |
1243 | 5.28k | #line 727 "src/jit/x64/emit.dasc" |
1244 | 5.28k | } |
1245 | 11.0k | /* store in local register */ |
1246 | 11.0k | //| mov WORK[dst], TMP3; |
1247 | 11.0k | dasm_put(Dst, 725, Dt23([dst])); |
1248 | 11.0k | #line 730 "src/jit/x64/emit.dasc" |
1249 | 11.0k | break; |
1250 | 11.0k | } |
1251 | 0 | case MVM_OP_sp_bind_i64: |
1252 | 0 | case MVM_OP_sp_bind_n: |
1253 | 0 | case MVM_OP_sp_bind_s: |
1254 | 0 | case MVM_OP_sp_bind_o: { |
1255 | 0 | MVMint16 obj = ins->operands[0].reg.orig; |
1256 | 0 | MVMint16 offset = ins->operands[1].lit_i16; |
1257 | 0 | MVMint16 val = ins->operands[2].reg.orig; |
1258 | 0 | //| mov TMP1, WORK[obj]; // object |
1259 | 0 | //| mov TMP2, WORK[val]; // value |
1260 | 0 | dasm_put(Dst, 730, Dt23([obj]), Dt23([val])); |
1261 | 0 | #line 741 "src/jit/x64/emit.dasc" |
1262 | 0 | if (op == MVM_OP_sp_bind_o || op == MVM_OP_sp_bind_s) { |
1263 | 0 | /* check if we should hit write barrier */ |
1264 | 0 | //| check_wb TMP1, TMP2, >2; |
1265 | 0 | dasm_put(Dst, 739, Dt11(->flags), MVM_CF_SECOND_GEN, Dt11(->flags), MVM_CF_SECOND_GEN); |
1266 | 0 | #line 744 "src/jit/x64/emit.dasc" |
1267 | 0 | /* note: it is uneccesary to store pointers, because they |
1268 | 0 | can just be loaded from memory */ |
1269 | 0 | //| hit_wb WORK[obj]; |
1270 | 0 | dasm_put(Dst, 636, Dt23([obj])); |
1271 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit)), (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit) >> 32)); |
1272 | 0 | #line 747 "src/jit/x64/emit.dasc" |
1273 | 0 | //| mov TMP1, aword WORK[obj]; // reload object |
1274 | 0 | //| mov TMP2, aword WORK[val]; // reload value |
1275 | 0 | //|2: // done |
1276 | 0 | dasm_put(Dst, 767, Dt23([obj]), Dt23([val])); |
1277 | 0 | #line 750 "src/jit/x64/emit.dasc" |
1278 | 0 | } |
1279 | 0 | //| mov qword [TMP1+offset], TMP2; // store value into body |
1280 | 0 | dasm_put(Dst, 783, offset); |
1281 | 0 | #line 752 "src/jit/x64/emit.dasc" |
1282 | 0 | break; |
1283 | 0 | } |
1284 | 0 | case MVM_OP_sp_get_i64: |
1285 | 0 | case MVM_OP_sp_get_n: |
1286 | 0 | case MVM_OP_sp_get_s: |
1287 | 0 | case MVM_OP_sp_get_o: { |
1288 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1289 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
1290 | 0 | MVMint16 offset = ins->operands[2].lit_i16; |
1291 | 0 | //| mov TMP1, WORK[obj]; // object |
1292 | 0 | //| mov TMP2, qword [TMP1+offset]; // get value from body |
1293 | 0 | //| mov WORK[dst], TMP2; |
1294 | 0 | dasm_put(Dst, 788, Dt23([obj]), offset, Dt23([dst])); |
1295 | 0 | #line 764 "src/jit/x64/emit.dasc" |
1296 | 0 | break; |
1297 | 0 | } |
1298 | 0 | case MVM_OP_sp_deref_bind_i64: |
1299 | 0 | case MVM_OP_sp_deref_bind_n: { |
1300 | 0 | MVMint16 obj = ins->operands[0].reg.orig; |
1301 | 0 | MVMint16 val = ins->operands[1].reg.orig; |
1302 | 0 | MVMint16 offset = ins->operands[2].lit_i16; |
1303 | 0 | //| mov TMP1, WORK[obj]; // object |
1304 | 0 | //| mov TMP2, WORK[val]; // value |
1305 | 0 | //| mov TMP1, qword [TMP1+offset]; // find address of target |
1306 | 0 | //| mov qword [TMP1], TMP2; |
1307 | 0 | dasm_put(Dst, 801, Dt23([obj]), Dt23([val]), offset); |
1308 | 0 | #line 775 "src/jit/x64/emit.dasc" |
1309 | 0 | break; |
1310 | 0 | } |
1311 | 0 | case MVM_OP_sp_deref_get_i64: |
1312 | 0 | case MVM_OP_sp_deref_get_n: { |
1313 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1314 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
1315 | 0 | MVMint16 offset = ins->operands[2].lit_i16; |
1316 | 0 | //| mov TMP1, WORK[obj]; // object |
1317 | 0 | //| mov TMP3, qword [TMP1+offset]; // get value pointer from body |
1318 | 0 | //| mov TMP2, qword [TMP3]; // deref the pointer |
1319 | 0 | //| mov WORK[dst], TMP2; |
1320 | 0 | dasm_put(Dst, 817, Dt23([obj]), offset, Dt23([dst])); |
1321 | 0 | #line 786 "src/jit/x64/emit.dasc" |
1322 | 0 | break; |
1323 | 0 | } |
1324 | 3.31k | case MVM_OP_sp_p6obind_i: |
1325 | 3.31k | case MVM_OP_sp_p6obind_n: |
1326 | 3.31k | case MVM_OP_sp_p6obind_s: |
1327 | 3.31k | case MVM_OP_sp_p6obind_o: { |
1328 | 3.31k | MVMint16 obj = ins->operands[0].reg.orig; |
1329 | 3.31k | MVMint16 offset = ins->operands[1].lit_i16; |
1330 | 3.31k | MVMint16 val = ins->operands[2].reg.orig; |
1331 | 3.31k | //| mov TMP1, WORK[obj]; // object |
1332 | 3.31k | //| mov TMP2, WORK[val]; // value |
1333 | 3.31k | //| lea TMP3, P6OPAQUE:TMP1->body; // body |
1334 | 3.31k | //| cmp qword P6OBODY:TMP3->replaced, 0; |
1335 | 3.31k | //| je >1; |
1336 | 3.31k | //| mov TMP3, P6OBODY:TMP3->replaced; // replaced object body |
1337 | 3.31k | //|1: |
1338 | 3.31k | dasm_put(Dst, 833, Dt23([obj]), Dt23([val]), Dt9(->body), DtA(->replaced), DtA(->replaced)); |
1339 | 3.31k | #line 802 "src/jit/x64/emit.dasc" |
1340 | 3.31k | if (op == MVM_OP_sp_p6obind_o || op == MVM_OP_sp_p6obind_s) { |
1341 | 1.35k | /* check if we should hit write barrier */ |
1342 | 1.35k | //| check_wb TMP1, TMP2, >2; |
1343 | 1.35k | //| mov qword [rbp-0x28], TMP2; // store value |
1344 | 1.35k | //| mov qword [rbp-0x30], TMP3; // store body pointer |
1345 | 1.35k | //| hit_wb WORK[obj]; |
1346 | 1.35k | dasm_put(Dst, 861, Dt11(->flags), MVM_CF_SECOND_GEN, Dt11(->flags), MVM_CF_SECOND_GEN, Dt23([obj])); |
1347 | 1.35k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit)), (MVMuint32)((uintptr_t)(&MVM_gc_write_barrier_hit) >> 32)); |
1348 | 1.35k | #line 808 "src/jit/x64/emit.dasc" |
1349 | 1.35k | //| mov TMP3, qword [rbp-0x30]; // restore body pointer |
1350 | 1.35k | //| mov TMP2, qword [rbp-0x28]; // restore value |
1351 | 1.35k | //|2: // done |
1352 | 1.35k | dasm_put(Dst, 906); |
1353 | 1.35k | #line 811 "src/jit/x64/emit.dasc" |
1354 | 1.35k | } |
1355 | 3.31k | //| mov [TMP3+offset], TMP2; // store value into body |
1356 | 3.31k | dasm_put(Dst, 922, offset); |
1357 | 3.31k | #line 813 "src/jit/x64/emit.dasc" |
1358 | 3.31k | break; |
1359 | 3.31k | } |
1360 | 34.4k | case MVM_OP_getwhere: |
1361 | 34.4k | case MVM_OP_set: { |
1362 | 34.4k | MVMint32 reg1 = ins->operands[0].reg.orig; |
1363 | 34.4k | MVMint32 reg2 = ins->operands[1].reg.orig; |
1364 | 34.4k | //| mov TMP1, WORK[reg2]; |
1365 | 34.4k | //| mov WORK[reg1], TMP1; |
1366 | 34.4k | dasm_put(Dst, 927, Dt23([reg2]), Dt23([reg1])); |
1367 | 34.4k | #line 821 "src/jit/x64/emit.dasc" |
1368 | 34.4k | break; |
1369 | 34.4k | } |
1370 | 8.98k | case MVM_OP_sp_getspeshslot: { |
1371 | 8.98k | MVMint16 dst = ins->operands[0].reg.orig; |
1372 | 8.98k | MVMint16 spesh_idx = ins->operands[1].lit_i16; |
1373 | 8.98k | //| get_spesh_slot TMP1, spesh_idx; |
1374 | 8.98k | //| mov WORK[dst], TMP1; |
1375 | 8.98k | dasm_put(Dst, 511, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([spesh_idx]), Dt23([dst])); |
1376 | 8.98k | #line 828 "src/jit/x64/emit.dasc" |
1377 | 8.98k | break; |
1378 | 34.4k | } |
1379 | 0 | case MVM_OP_setdispatcher: { |
1380 | 0 | MVMint16 src = ins->operands[0].reg.orig; |
1381 | 0 | //| mov TMP1, aword WORK[src]; |
1382 | 0 | //| mov aword TC->cur_dispatcher, TMP1; |
1383 | 0 | dasm_put(Dst, 936, Dt23([src]), Dt22(->cur_dispatcher)); |
1384 | 0 | #line 834 "src/jit/x64/emit.dasc" |
1385 | 0 | break; |
1386 | 34.4k | } |
1387 | 0 | case MVM_OP_takedispatcher: { |
1388 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1389 | 0 | //| mov TMP1, aword TC->cur_dispatcher; |
1390 | 0 | //| cmp TMP1, 0; |
1391 | 0 | //| je >2; |
1392 | 0 | //| mov TMP2, aword TC->cur_dispatcher_for; |
1393 | 0 | //| cmp TMP2, 0; |
1394 | 0 | //| je >1; |
1395 | 0 | //| mov TMP3, TC->cur_frame; |
1396 | 0 | //| mov TMP3, FRAME:TMP3->code_ref; |
1397 | 0 | //| cmp TMP2, TMP3; |
1398 | 0 | //| jne >2; |
1399 | 0 | //|1: |
1400 | 0 | //| mov aword WORK[dst], TMP1; |
1401 | 0 | //| mov aword TC->cur_dispatcher, NULL; |
1402 | 0 | //| jmp >3; |
1403 | 0 | //|2: |
1404 | 0 | //| get_vmnull TMP1; |
1405 | 0 | //| mov aword WORK[dst], TMP1; |
1406 | 0 | //|3: |
1407 | 0 | dasm_put(Dst, 945, Dt22(->cur_dispatcher), Dt22(->cur_dispatcher_for), Dt22(->cur_frame), Dt2(->code_ref), Dt23([dst]), Dt22(->cur_dispatcher), NULL, Dt22(->instance), DtC(->VMNull), Dt23([dst])); |
1408 | 0 | #line 856 "src/jit/x64/emit.dasc" |
1409 | 0 | break; |
1410 | 34.4k | } |
1411 | 0 | case MVM_OP_ctx: { |
1412 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1413 | 0 | //| mov ARG1, TC; |
1414 | 0 | //| mov ARG2, TC->cur_frame; |
1415 | 0 | //| callp &MVM_frame_context_wrapper; |
1416 | 0 | dasm_put(Dst, 1018, Dt22(->cur_frame)); |
1417 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_context_wrapper)), (MVMuint32)((uintptr_t)(&MVM_frame_context_wrapper) >> 32)); |
1418 | 0 | #line 863 "src/jit/x64/emit.dasc" |
1419 | 0 | //| mov WORK[dst], RV; |
1420 | 0 | dasm_put(Dst, 501, Dt23([dst])); |
1421 | 0 | #line 864 "src/jit/x64/emit.dasc" |
1422 | 0 | break; |
1423 | 34.4k | } |
1424 | 0 | case MVM_OP_ctxlexpad: { |
1425 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1426 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1427 | 0 | //| mov TMP1, WORK[src]; |
1428 | 0 | //| test_type_object TMP1; |
1429 | 0 | //| jnz >1; |
1430 | 0 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMContext; |
1431 | 0 | //| je >2; |
1432 | 0 | //|1: |
1433 | 0 | //| throw_adhoc "ctxlexpad needs an MVMContext"; |
1434 | 0 | dasm_put(Dst, 1028, Dt23([src]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMContext, (unsigned int)((uintptr_t)("ctxlexpad needs an MVMContext")), (unsigned int)(((uintptr_t)("ctxlexpad needs an MVMContext"))>>32)); |
1435 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1436 | 0 | #line 876 "src/jit/x64/emit.dasc" |
1437 | 0 | //|2: |
1438 | 0 | //| mov WORK[dst], TMP1; |
1439 | 0 | dasm_put(Dst, 1070, Dt23([dst])); |
1440 | 0 | #line 878 "src/jit/x64/emit.dasc" |
1441 | 0 | break; |
1442 | 34.4k | } |
1443 | 0 | case MVM_OP_curcode: { |
1444 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1445 | 0 | //| mov TMP1, TC->cur_frame; |
1446 | 0 | //| mov TMP1, aword FRAME:TMP1->code_ref; |
1447 | 0 | //| mov aword WORK[dst], TMP1; |
1448 | 0 | dasm_put(Dst, 127, Dt22(->cur_frame), Dt2(->code_ref), Dt23([dst])); |
1449 | 0 | #line 885 "src/jit/x64/emit.dasc" |
1450 | 0 | break; |
1451 | 34.4k | } |
1452 | 0 | case MVM_OP_getcode: { |
1453 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1454 | 0 | MVMuint16 idx = ins->operands[1].coderef_idx; |
1455 | 0 | //| mov TMP1, aword CU->body.coderefs; |
1456 | 0 | //| mov TMP1, aword OBJECTPTR:TMP1[idx]; |
1457 | 0 | //| mov aword WORK[dst], TMP1; |
1458 | 0 | dasm_put(Dst, 114, Dt24(->body.coderefs), Dt15([idx]), Dt23([dst])); |
1459 | 0 | #line 893 "src/jit/x64/emit.dasc" |
1460 | 0 | break; |
1461 | 34.4k | } |
1462 | 0 | case MVM_OP_callercode: { |
1463 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1464 | 0 | //| mov TMP1, TC->cur_frame; |
1465 | 0 | //| mov TMP1, aword FRAME:TMP1->caller; |
1466 | 0 | //| test TMP1, TMP1; |
1467 | 0 | //| jz >1; |
1468 | 0 | //| mov TMP1, aword FRAME:TMP1->code_ref; |
1469 | 0 | //|1: |
1470 | 0 | //| mov aword WORK[dst], TMP1; |
1471 | 0 | dasm_put(Dst, 1082, Dt22(->cur_frame), Dt2(->caller), Dt2(->code_ref), Dt23([dst])); |
1472 | 0 | #line 904 "src/jit/x64/emit.dasc" |
1473 | 0 | break; |
1474 | 34.4k | } |
1475 | 1.91k | case MVM_OP_hllboxtype_n: |
1476 | 1.91k | case MVM_OP_hllboxtype_s: |
1477 | 1.91k | case MVM_OP_hllboxtype_i: { |
1478 | 1.91k | MVMint16 dst = ins->operands[0].reg.orig; |
1479 | 1.91k | //| mov TMP1, CU->body.hll_config; |
1480 | 1.91k | dasm_put(Dst, 1108, Dt24(->body.hll_config)); |
1481 | 1.91k | #line 911 "src/jit/x64/emit.dasc" |
1482 | 1.91k | if (op == MVM_OP_hllboxtype_n) { |
1483 | 274 | //| mov TMP1, aword HLLCONFIG:TMP1->num_box_type; |
1484 | 274 | dasm_put(Dst, 144, Dt19(->num_box_type)); |
1485 | 274 | #line 913 "src/jit/x64/emit.dasc" |
1486 | 1.64k | } else if (op == MVM_OP_hllboxtype_s) { |
1487 | 92 | //| mov TMP1, aword HLLCONFIG:TMP1->str_box_type; |
1488 | 92 | dasm_put(Dst, 144, Dt19(->str_box_type)); |
1489 | 92 | #line 915 "src/jit/x64/emit.dasc" |
1490 | 1.55k | } else { |
1491 | 1.55k | //| mov TMP1, aword HLLCONFIG:TMP1->int_box_type; |
1492 | 1.55k | dasm_put(Dst, 144, Dt19(->int_box_type)); |
1493 | 1.55k | #line 917 "src/jit/x64/emit.dasc" |
1494 | 1.55k | } |
1495 | 1.91k | //| mov aword WORK[dst], TMP1; |
1496 | 1.91k | dasm_put(Dst, 103, Dt23([dst])); |
1497 | 1.91k | #line 919 "src/jit/x64/emit.dasc" |
1498 | 1.91k | break; |
1499 | 1.91k | } |
1500 | 0 | case MVM_OP_null_s: { |
1501 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1502 | 0 | //| mov qword WORK[dst], 0; |
1503 | 0 | dasm_put(Dst, 1113, Dt23([dst])); |
1504 | 0 | #line 924 "src/jit/x64/emit.dasc" |
1505 | 0 | break; |
1506 | 1.91k | } |
1507 | 463 | case MVM_OP_isnull_s: { |
1508 | 463 | MVMint16 dst = ins->operands[0].reg.orig; |
1509 | 463 | MVMint16 src = ins->operands[1].reg.orig; |
1510 | 463 | //| mov TMP1, WORK[src]; |
1511 | 463 | //| test TMP1, TMP1; |
1512 | 463 | //| setz TMP2b; |
1513 | 463 | //| movzx TMP2, TMP2b; |
1514 | 463 | //| mov qword WORK[dst], TMP2; |
1515 | 463 | dasm_put(Dst, 1122, Dt23([src]), Dt23([dst])); |
1516 | 463 | #line 934 "src/jit/x64/emit.dasc" |
1517 | 463 | break; |
1518 | 1.91k | } |
1519 | 75 | case MVM_OP_captureposarg: { |
1520 | 75 | MVMint16 dst = ins->operands[0].reg.orig; |
1521 | 75 | MVMint16 src = ins->operands[1].reg.orig; |
1522 | 75 | MVMint16 pos = ins->operands[2].reg.orig; |
1523 | 75 | //| mov TMP5, qword WORK[src]; |
1524 | 75 | //| test_type_object TMP5; |
1525 | 75 | //| jnz >1; |
1526 | 75 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_MVMCallCapture; |
1527 | 75 | //| jne >1; |
1528 | 75 | //| mov ARG1, TC; |
1529 | 75 | //| mov ARG2, aword CAPTURE:TMP5->body.apc; |
1530 | 75 | //| mov ARG3, WORK[pos]; |
1531 | 75 | //| callp &MVM_args_get_required_pos_obj; |
1532 | 75 | dasm_put(Dst, 1141, Dt23([src]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture, Dt5(->body.apc), Dt23([pos])); |
1533 | 75 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_get_required_pos_obj)), (MVMuint32)((uintptr_t)(&MVM_args_get_required_pos_obj) >> 32)); |
1534 | 75 | #line 949 "src/jit/x64/emit.dasc" |
1535 | 75 | //| mov WORK[dst], RV; |
1536 | 75 | //| jmp >2; |
1537 | 75 | //|1: |
1538 | 75 | //| throw_adhoc "captureposarg needs a MVMCallCapture"; |
1539 | 75 | dasm_put(Dst, 291, Dt23([dst]), (unsigned int)((uintptr_t)("captureposarg needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("captureposarg needs a MVMCallCapture"))>>32)); |
1540 | 75 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1541 | 75 | #line 953 "src/jit/x64/emit.dasc" |
1542 | 75 | //|2: |
1543 | 75 | dasm_put(Dst, 316); |
1544 | 75 | #line 954 "src/jit/x64/emit.dasc" |
1545 | 75 | break; |
1546 | 1.91k | } |
1547 | 0 | case MVM_OP_captureposarg_i: { |
1548 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1549 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1550 | 0 | MVMint16 pos = ins->operands[2].reg.orig; |
1551 | 0 | //| mov TMP5, qword WORK[src]; |
1552 | 0 | //| test_type_object TMP5; |
1553 | 0 | //| jnz >1; |
1554 | 0 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_MVMCallCapture; |
1555 | 0 | //| jne >1; |
1556 | 0 | //| mov ARG1, TC; |
1557 | 0 | //| mov ARG2, aword CAPTURE:TMP5->body.apc; |
1558 | 0 | //| mov ARG3, qword WORK[pos]; |
1559 | 0 | //| callp &MVM_args_get_required_pos_int; |
1560 | 0 | dasm_put(Dst, 1141, Dt23([src]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture, Dt5(->body.apc), Dt23([pos])); |
1561 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_get_required_pos_int)), (MVMuint32)((uintptr_t)(&MVM_args_get_required_pos_int) >> 32)); |
1562 | 0 | #line 969 "src/jit/x64/emit.dasc" |
1563 | 0 | //| mov WORK[dst], RV; |
1564 | 0 | //| jmp >2; |
1565 | 0 | //|1: |
1566 | 0 | //| throw_adhoc "captureposarg_i needs a MVMCallCapture"; |
1567 | 0 | dasm_put(Dst, 291, Dt23([dst]), (unsigned int)((uintptr_t)("captureposarg_i needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("captureposarg_i needs a MVMCallCapture"))>>32)); |
1568 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1569 | 0 | #line 973 "src/jit/x64/emit.dasc" |
1570 | 0 | //|2: |
1571 | 0 | dasm_put(Dst, 316); |
1572 | 0 | #line 974 "src/jit/x64/emit.dasc" |
1573 | 0 | break; |
1574 | 1.91k | } |
1575 | 0 | case MVM_OP_captureposarg_n: { |
1576 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1577 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1578 | 0 | MVMint16 pos = ins->operands[2].reg.orig; |
1579 | 0 | //| mov TMP5, qword WORK[src]; |
1580 | 0 | //| test_type_object TMP5; |
1581 | 0 | //| jnz >1; |
1582 | 0 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_MVMCallCapture; |
1583 | 0 | //| jne >1; |
1584 | 0 | //| mov ARG1, TC; |
1585 | 0 | //| mov ARG2, aword CAPTURE:TMP5->body.apc; |
1586 | 0 | //| mov ARG3, qword WORK[pos]; |
1587 | 0 | //| callp &MVM_args_get_pos_num; |
1588 | 0 | dasm_put(Dst, 1141, Dt23([src]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture, Dt5(->body.apc), Dt23([pos])); |
1589 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_get_pos_num)), (MVMuint32)((uintptr_t)(&MVM_args_get_pos_num) >> 32)); |
1590 | 0 | #line 989 "src/jit/x64/emit.dasc" |
1591 | 0 | //| mov WORK[dst], RV; |
1592 | 0 | //| jmp >2; |
1593 | 0 | //|1: |
1594 | 0 | //| throw_adhoc "captureposarg_n needs a MVMCallCapture"; |
1595 | 0 | dasm_put(Dst, 291, Dt23([dst]), (unsigned int)((uintptr_t)("captureposarg_n needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("captureposarg_n needs a MVMCallCapture"))>>32)); |
1596 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1597 | 0 | #line 993 "src/jit/x64/emit.dasc" |
1598 | 0 | //|2: |
1599 | 0 | dasm_put(Dst, 316); |
1600 | 0 | #line 994 "src/jit/x64/emit.dasc" |
1601 | 0 | break; |
1602 | 1.91k | } |
1603 | 0 | case MVM_OP_captureposarg_s: { |
1604 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1605 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1606 | 0 | MVMint16 pos = ins->operands[2].reg.orig; |
1607 | 0 | //| mov TMP5, qword WORK[src]; |
1608 | 0 | //| test_type_object TMP5; |
1609 | 0 | //| jnz >1; |
1610 | 0 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_MVMCallCapture; |
1611 | 0 | //| jne >1; |
1612 | 0 | //| mov ARG1, TC; |
1613 | 0 | //| mov ARG2, aword CAPTURE:TMP5->body.apc; |
1614 | 0 | //| mov ARG3, aword WORK[pos]; |
1615 | 0 | //| callp MVM_args_get_required_pos_str; |
1616 | 0 | dasm_put(Dst, 1141, Dt23([src]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture, Dt5(->body.apc), Dt23([pos])); |
1617 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(MVM_args_get_required_pos_str)), (MVMuint32)((uintptr_t)(MVM_args_get_required_pos_str) >> 32)); |
1618 | 0 | #line 1009 "src/jit/x64/emit.dasc" |
1619 | 0 | //| mov WORK[dst], RV; |
1620 | 0 | //| jmp >2; |
1621 | 0 | //|1: |
1622 | 0 | //| throw_adhoc "captureposarg_s needs a MVMCallCapture"; |
1623 | 0 | dasm_put(Dst, 291, Dt23([dst]), (unsigned int)((uintptr_t)("captureposarg_s needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("captureposarg_s needs a MVMCallCapture"))>>32)); |
1624 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1625 | 0 | #line 1013 "src/jit/x64/emit.dasc" |
1626 | 0 | //|2: |
1627 | 0 | dasm_put(Dst, 316); |
1628 | 0 | #line 1014 "src/jit/x64/emit.dasc" |
1629 | 0 | break; |
1630 | 1.91k | } |
1631 | 1.83k | case MVM_OP_add_i: |
1632 | 1.83k | case MVM_OP_sub_i: |
1633 | 1.83k | case MVM_OP_bor_i: |
1634 | 1.83k | case MVM_OP_band_i: |
1635 | 1.83k | case MVM_OP_bxor_i: { |
1636 | 1.83k | MVMint32 reg_a = ins->operands[0].reg.orig; |
1637 | 1.83k | MVMint32 reg_b = ins->operands[1].reg.orig; |
1638 | 1.83k | MVMint32 reg_c = ins->operands[2].reg.orig; |
1639 | 1.83k | |
1640 | 1.83k | MVMSpeshFacts *operand_facts = MVM_spesh_get_facts(tc, jg->sg, ins->operands[2]); |
1641 | 1.83k | |
1642 | 1.83k | if (reg_a == reg_b) { |
1643 | 123 | if (operand_facts->flags & MVM_SPESH_FACT_KNOWN_VALUE && |
1644 | 1 | fits_in_32_bit(operand_facts->value.i)) { |
1645 | 1 | MVMint64 value = operand_facts->value.i; |
1646 | 1 | MVM_jit_log(tc, "accumulator for %s stayed in memory and " |
1647 | 1 | " constant value %"PRId64" used\n", ins->info->name, value); |
1648 | 1 | switch(ins->info->opcode) { |
1649 | 0 | case MVM_OP_add_i: |
1650 | 0 | //| add qword WORK[reg_a], qword value; |
1651 | 0 | dasm_put(Dst, 1187, Dt23([reg_a]), value); |
1652 | 0 | #line 1036 "src/jit/x64/emit.dasc" |
1653 | 0 | break; |
1654 | 1 | case MVM_OP_sub_i: |
1655 | 1 | //| sub qword WORK[reg_a], qword value; |
1656 | 1 | dasm_put(Dst, 1193, Dt23([reg_a]), value); |
1657 | 1 | #line 1039 "src/jit/x64/emit.dasc" |
1658 | 1 | break; |
1659 | 0 | case MVM_OP_bor_i: |
1660 | 0 | //| or qword WORK[reg_a], qword value; |
1661 | 0 | dasm_put(Dst, 1199, Dt23([reg_a]), value); |
1662 | 0 | #line 1042 "src/jit/x64/emit.dasc" |
1663 | 0 | break; |
1664 | 0 | case MVM_OP_band_i: |
1665 | 0 | //| and qword WORK[reg_a], qword value; |
1666 | 0 | dasm_put(Dst, 1205, Dt23([reg_a]), value); |
1667 | 0 | #line 1045 "src/jit/x64/emit.dasc" |
1668 | 0 | break; |
1669 | 0 | case MVM_OP_bxor_i: |
1670 | 0 | //| xor qword WORK[reg_a], qword value; |
1671 | 0 | dasm_put(Dst, 1211, Dt23([reg_a]), value); |
1672 | 0 | #line 1048 "src/jit/x64/emit.dasc" |
1673 | 0 | break; |
1674 | 1 | } |
1675 | 122 | } else { |
1676 | 122 | MVM_jit_log(tc, "accumulator for %s stayed in memory\n", ins->info->name); |
1677 | 122 | //| mov rax, WORK[reg_c]; |
1678 | 122 | dasm_put(Dst, 1217, Dt23([reg_c])); |
1679 | 122 | #line 1053 "src/jit/x64/emit.dasc" |
1680 | 122 | switch(ins->info->opcode) { |
1681 | 122 | case MVM_OP_add_i: |
1682 | 122 | //| add WORK[reg_a], rax; |
1683 | 122 | dasm_put(Dst, 1222, Dt23([reg_a])); |
1684 | 122 | #line 1056 "src/jit/x64/emit.dasc" |
1685 | 122 | break; |
1686 | 0 | case MVM_OP_sub_i: |
1687 | 0 | //| sub WORK[reg_a], rax; |
1688 | 0 | dasm_put(Dst, 1227, Dt23([reg_a])); |
1689 | 0 | #line 1059 "src/jit/x64/emit.dasc" |
1690 | 0 | break; |
1691 | 0 | case MVM_OP_bor_i: |
1692 | 0 | //| or WORK[reg_a], rax; |
1693 | 0 | dasm_put(Dst, 1232, Dt23([reg_a])); |
1694 | 0 | #line 1062 "src/jit/x64/emit.dasc" |
1695 | 0 | break; |
1696 | 0 | case MVM_OP_band_i: |
1697 | 0 | //| and WORK[reg_a], rax; |
1698 | 0 | dasm_put(Dst, 1237, Dt23([reg_a])); |
1699 | 0 | #line 1065 "src/jit/x64/emit.dasc" |
1700 | 0 | break; |
1701 | 0 | case MVM_OP_bxor_i: |
1702 | 0 | //| xor WORK[reg_a], rax; |
1703 | 0 | dasm_put(Dst, 1242, Dt23([reg_a])); |
1704 | 0 | #line 1068 "src/jit/x64/emit.dasc" |
1705 | 0 | break; |
1706 | 122 | } |
1707 | 122 | } |
1708 | 1.71k | } else { |
1709 | 1.71k | if (operand_facts->flags & MVM_SPESH_FACT_KNOWN_VALUE && |
1710 | 1.17k | fits_in_32_bit(operand_facts->value.i)) { |
1711 | 1.17k | MVMint64 value = operand_facts->value.i; |
1712 | 1.17k | MVM_jit_log(tc, "constant value %"PRId64" used for %s\n", |
1713 | 1.17k | value, ins->info->name); |
1714 | 1.17k | //| mov rax, WORK[reg_b]; |
1715 | 1.17k | dasm_put(Dst, 1217, Dt23([reg_b])); |
1716 | 1.17k | #line 1078 "src/jit/x64/emit.dasc" |
1717 | 1.17k | switch(ins->info->opcode) { |
1718 | 652 | case MVM_OP_add_i: |
1719 | 652 | //| add rax, qword value; |
1720 | 652 | dasm_put(Dst, 1247, value); |
1721 | 652 | #line 1081 "src/jit/x64/emit.dasc" |
1722 | 652 | break; |
1723 | 510 | case MVM_OP_sub_i: |
1724 | 510 | //| sub rax, qword value; |
1725 | 510 | dasm_put(Dst, 1252, value); |
1726 | 510 | #line 1084 "src/jit/x64/emit.dasc" |
1727 | 510 | break; |
1728 | 0 | case MVM_OP_bor_i: |
1729 | 0 | //| or rax, qword value; |
1730 | 0 | dasm_put(Dst, 1258, value); |
1731 | 0 | #line 1087 "src/jit/x64/emit.dasc" |
1732 | 0 | break; |
1733 | 8 | case MVM_OP_band_i: |
1734 | 8 | //| and rax, qword value; |
1735 | 8 | dasm_put(Dst, 1263, value); |
1736 | 8 | #line 1090 "src/jit/x64/emit.dasc" |
1737 | 8 | break; |
1738 | 0 | case MVM_OP_bxor_i: |
1739 | 0 | //| xor rax, qword value; |
1740 | 0 | dasm_put(Dst, 1268, value); |
1741 | 0 | #line 1093 "src/jit/x64/emit.dasc" |
1742 | 0 | break; |
1743 | 1.17k | } |
1744 | 1.17k | //| mov WORK[reg_a], rax; |
1745 | 1.17k | dasm_put(Dst, 506, Dt23([reg_a])); |
1746 | 1.17k | #line 1096 "src/jit/x64/emit.dasc" |
1747 | 544 | } else { |
1748 | 544 | //| mov rax, WORK[reg_b]; |
1749 | 544 | dasm_put(Dst, 1217, Dt23([reg_b])); |
1750 | 544 | #line 1098 "src/jit/x64/emit.dasc" |
1751 | 544 | switch(ins->info->opcode) { |
1752 | 0 | case MVM_OP_add_i: |
1753 | 0 | //| add rax, WORK[reg_c]; |
1754 | 0 | dasm_put(Dst, 1274, Dt23([reg_c])); |
1755 | 0 | #line 1101 "src/jit/x64/emit.dasc" |
1756 | 0 | break; |
1757 | 317 | case MVM_OP_sub_i: |
1758 | 317 | //| sub rax, WORK[reg_c]; |
1759 | 317 | dasm_put(Dst, 1279, Dt23([reg_c])); |
1760 | 317 | #line 1104 "src/jit/x64/emit.dasc" |
1761 | 317 | break; |
1762 | 40 | case MVM_OP_bor_i: |
1763 | 40 | //| or rax, WORK[reg_c]; |
1764 | 40 | dasm_put(Dst, 1284, Dt23([reg_c])); |
1765 | 40 | #line 1107 "src/jit/x64/emit.dasc" |
1766 | 40 | break; |
1767 | 187 | case MVM_OP_band_i: |
1768 | 187 | //| and rax, WORK[reg_c]; |
1769 | 187 | dasm_put(Dst, 1289, Dt23([reg_c])); |
1770 | 187 | #line 1110 "src/jit/x64/emit.dasc" |
1771 | 187 | break; |
1772 | 0 | case MVM_OP_bxor_i: |
1773 | 0 | //| xor rax, WORK[reg_c]; |
1774 | 0 | dasm_put(Dst, 1294, Dt23([reg_c])); |
1775 | 0 | #line 1113 "src/jit/x64/emit.dasc" |
1776 | 0 | break; |
1777 | 544 | } |
1778 | 544 | //| mov WORK[reg_a], rax; |
1779 | 544 | dasm_put(Dst, 506, Dt23([reg_a])); |
1780 | 544 | #line 1116 "src/jit/x64/emit.dasc" |
1781 | 544 | } |
1782 | 1.71k | } |
1783 | 1.83k | break; |
1784 | 1.83k | } |
1785 | 22 | case MVM_OP_mul_i: |
1786 | 22 | case MVM_OP_blshift_i: |
1787 | 22 | case MVM_OP_brshift_i: { |
1788 | 22 | MVMint32 reg_a = ins->operands[0].reg.orig; |
1789 | 22 | MVMint32 reg_b = ins->operands[1].reg.orig; |
1790 | 22 | MVMint32 reg_c = ins->operands[2].reg.orig; |
1791 | 22 | //| mov rax, WORK[reg_b]; |
1792 | 22 | dasm_put(Dst, 1217, Dt23([reg_b])); |
1793 | 22 | #line 1127 "src/jit/x64/emit.dasc" |
1794 | 22 | switch(ins->info->opcode) { |
1795 | 22 | case MVM_OP_mul_i: |
1796 | 22 | //| imul rax, WORK[reg_c]; |
1797 | 22 | dasm_put(Dst, 1299, Dt23([reg_c])); |
1798 | 22 | #line 1130 "src/jit/x64/emit.dasc" |
1799 | 22 | break; |
1800 | 0 | case MVM_OP_blshift_i: |
1801 | 0 | //| mov cl, byte WORK[reg_c]; |
1802 | 0 | //| shl rax, cl; |
1803 | 0 | dasm_put(Dst, 1305, Dt23([reg_c])); |
1804 | 0 | #line 1134 "src/jit/x64/emit.dasc" |
1805 | 0 | break; |
1806 | 0 | case MVM_OP_brshift_i: |
1807 | 0 | //| mov cl, byte WORK[reg_c]; |
1808 | 0 | //| shr rax, cl; |
1809 | 0 | dasm_put(Dst, 1312, Dt23([reg_c])); |
1810 | 0 | #line 1138 "src/jit/x64/emit.dasc" |
1811 | 0 | break; |
1812 | 22 | } |
1813 | 22 | //| mov WORK[reg_a], rax; |
1814 | 22 | dasm_put(Dst, 506, Dt23([reg_a])); |
1815 | 22 | #line 1141 "src/jit/x64/emit.dasc" |
1816 | 22 | break; |
1817 | 22 | } |
1818 | 0 | case MVM_OP_pow_i: { |
1819 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1820 | 0 | MVMint16 base = ins->operands[1].reg.orig; |
1821 | 0 | MVMint16 exp = ins->operands[2].reg.orig; |
1822 | 0 | //| xor rax, rax; |
1823 | 0 | //| mov rcx, WORK[exp]; |
1824 | 0 | //| cmp rcx, rax; |
1825 | 0 | //| jl >3; |
1826 | 0 | //| inc rax; |
1827 | 0 | //| mov r8, WORK[base]; |
1828 | 0 | //|1: |
1829 | 0 | //| test rcx, 1; |
1830 | 0 | //| jz >2; |
1831 | 0 | //| imul r8; |
1832 | 0 | //|2: |
1833 | 0 | //| imul r8, r8; |
1834 | 0 | //| shr rcx, 1; |
1835 | 0 | //| jnz <1; |
1836 | 0 | //|3: |
1837 | 0 | //| mov WORK[dst], rax; |
1838 | 0 | dasm_put(Dst, 1320, Dt23([exp]), Dt23([base]), Dt23([dst])); |
1839 | 0 | #line 1163 "src/jit/x64/emit.dasc" |
1840 | 0 | break; |
1841 | 22 | } |
1842 | 58 | case MVM_OP_div_i: { |
1843 | 58 | MVMint16 dst = ins->operands[0].reg.orig; |
1844 | 58 | MVMint16 a = ins->operands[1].reg.orig; |
1845 | 58 | MVMint16 b = ins->operands[2].reg.orig; |
1846 | 58 | //| mov rax, WORK[a]; |
1847 | 58 | //| mov rcx, WORK[b]; |
1848 | 58 | //| cmp rcx, 0; |
1849 | 58 | //| jnz >1; |
1850 | 58 | //| throw_adhoc "Division by zero"; |
1851 | 58 | dasm_put(Dst, 1382, Dt23([a]), Dt23([b]), (unsigned int)((uintptr_t)("Division by zero")), (unsigned int)(((uintptr_t)("Division by zero"))>>32)); |
1852 | 58 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1853 | 58 | #line 1174 "src/jit/x64/emit.dasc" |
1854 | 58 | //|1: |
1855 | 58 | dasm_put(Dst, 1409); |
1856 | 58 | #line 1175 "src/jit/x64/emit.dasc" |
1857 | 58 | /* either num < 0, or denom < 0, but not both */ |
1858 | 58 | //| setl dh; |
1859 | 58 | //| cmp rax, 0; |
1860 | 58 | //| setl dl; |
1861 | 58 | //| xor dl, dh; |
1862 | 58 | //| movzx r8d, dl; |
1863 | 58 | //| cqo; |
1864 | 58 | //| idiv rcx; |
1865 | 58 | //| test rdx, rdx; |
1866 | 58 | //| setnz cl; |
1867 | 58 | //| and r8b, cl; |
1868 | 58 | dasm_put(Dst, 1417); |
1869 | 58 | #line 1186 "src/jit/x64/emit.dasc" |
1870 | 58 | /* r8 = bias = (modulo != 0) & ((num < 0) ^ (denom < 0)) */ |
1871 | 58 | //| sub rax, r8; |
1872 | 58 | //| mov WORK[dst], rax; |
1873 | 58 | dasm_put(Dst, 1452, Dt23([dst])); |
1874 | 58 | #line 1189 "src/jit/x64/emit.dasc" |
1875 | 58 | break; |
1876 | 22 | } |
1877 | 179 | case MVM_OP_mod_i: { |
1878 | 179 | MVMint16 dst = ins->operands[0].reg.orig; |
1879 | 179 | MVMint16 a = ins->operands[1].reg.orig; |
1880 | 179 | MVMint16 b = ins->operands[2].reg.orig; |
1881 | 179 | //| mov rax, WORK[a]; |
1882 | 179 | //| mov rcx, WORK[b]; |
1883 | 179 | //| cmp rcx, 0; |
1884 | 179 | //| jnz >1; |
1885 | 179 | //| throw_adhoc "Division by zero"; |
1886 | 179 | dasm_put(Dst, 1382, Dt23([a]), Dt23([b]), (unsigned int)((uintptr_t)("Division by zero")), (unsigned int)(((uintptr_t)("Division by zero"))>>32)); |
1887 | 179 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
1888 | 179 | #line 1200 "src/jit/x64/emit.dasc" |
1889 | 179 | //|1: |
1890 | 179 | //| cqo; |
1891 | 179 | //| idiv rcx; |
1892 | 179 | //| mov WORK[dst], rdx; |
1893 | 179 | dasm_put(Dst, 1460, Dt23([dst])); |
1894 | 179 | #line 1204 "src/jit/x64/emit.dasc" |
1895 | 179 | break; |
1896 | 22 | } |
1897 | 0 | case MVM_OP_inc_i: { |
1898 | 0 | MVMint32 reg = ins->operands[0].reg.orig; |
1899 | 0 | //| add qword WORK[reg], 1; |
1900 | 0 | dasm_put(Dst, 1479, Dt23([reg])); |
1901 | 0 | #line 1209 "src/jit/x64/emit.dasc" |
1902 | 0 | break; |
1903 | 22 | } |
1904 | 152 | case MVM_OP_dec_i: { |
1905 | 152 | MVMint32 reg = ins->operands[0].reg.orig; |
1906 | 152 | //| sub qword WORK[reg], 1; |
1907 | 152 | dasm_put(Dst, 1485, Dt23([reg])); |
1908 | 152 | #line 1214 "src/jit/x64/emit.dasc" |
1909 | 152 | break; |
1910 | 22 | } |
1911 | 0 | case MVM_OP_bnot_i: { |
1912 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1913 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1914 | 0 | //| mov TMP1, WORK[src]; |
1915 | 0 | //| not TMP1; |
1916 | 0 | //| mov WORK[dst], TMP1; |
1917 | 0 | dasm_put(Dst, 1491, Dt23([src]), Dt23([dst])); |
1918 | 0 | #line 1222 "src/jit/x64/emit.dasc" |
1919 | 0 | break; |
1920 | 22 | } |
1921 | 0 | case MVM_OP_neg_i: { |
1922 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1923 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1924 | 0 | //| mov TMP1, WORK[src]; |
1925 | 0 | //| neg TMP1; |
1926 | 0 | //| mov WORK[dst], TMP1; |
1927 | 0 | dasm_put(Dst, 1504, Dt23([src]), Dt23([dst])); |
1928 | 0 | #line 1230 "src/jit/x64/emit.dasc" |
1929 | 0 | break; |
1930 | 22 | } |
1931 | 0 | case MVM_OP_extend_i32: { |
1932 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1933 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1934 | 0 | //| mov RV, WORK[src]; |
1935 | 0 | //| cdqe |
1936 | 0 | //| mov WORK[dst], RV; |
1937 | 0 | dasm_put(Dst, 1517, Dt23([src]), Dt23([dst])); |
1938 | 0 | #line 1238 "src/jit/x64/emit.dasc" |
1939 | 0 | break; |
1940 | 22 | } |
1941 | 0 | case MVM_OP_trunc_i16: { |
1942 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1943 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1944 | 0 | //| mov TMP1, WORK[src]; |
1945 | 0 | dasm_put(Dst, 1528, Dt23([src])); |
1946 | 0 | #line 1244 "src/jit/x64/emit.dasc" |
1947 | 0 | /* x86-64 auto-truncates the upper 48 bits when using registers in 16 |
1948 | 0 | * bit mode */ |
1949 | 0 | //| mov TMP2w, TMP1w; |
1950 | 0 | //| mov WORK[dst], TMP2; |
1951 | 0 | dasm_put(Dst, 1533, Dt23([dst])); |
1952 | 0 | #line 1248 "src/jit/x64/emit.dasc" |
1953 | 0 | break; |
1954 | 22 | } |
1955 | 0 | case MVM_OP_trunc_i32: { |
1956 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
1957 | 0 | MVMint16 src = ins->operands[1].reg.orig; |
1958 | 0 | //| mov TMP1, WORK[src]; |
1959 | 0 | dasm_put(Dst, 1528, Dt23([src])); |
1960 | 0 | #line 1254 "src/jit/x64/emit.dasc" |
1961 | 0 | /* x86-64 auto-truncates the upper 32 bits when using registers in 32 |
1962 | 0 | * bit mode */ |
1963 | 0 | //| mov TMP2d, TMP1d; |
1964 | 0 | //| mov WORK[dst], TMP2; |
1965 | 0 | dasm_put(Dst, 1534, Dt23([dst])); |
1966 | 0 | #line 1258 "src/jit/x64/emit.dasc" |
1967 | 0 | break; |
1968 | 22 | } |
1969 | 456 | case MVM_OP_add_n: |
1970 | 456 | case MVM_OP_sub_n: |
1971 | 456 | case MVM_OP_mul_n: |
1972 | 456 | case MVM_OP_div_n: { |
1973 | 456 | MVMint16 reg_a = ins->operands[0].reg.orig; |
1974 | 456 | MVMint16 reg_b = ins->operands[1].reg.orig; |
1975 | 456 | MVMint16 reg_c = ins->operands[2].reg.orig; |
1976 | 456 | /* Copying data to xmm (floating point) registers requires |
1977 | 456 | * a special move instruction */ |
1978 | 456 | //| movsd xmm0, qword WORK[reg_b]; |
1979 | 456 | dasm_put(Dst, 1541, Dt23([reg_b])); |
1980 | 456 | #line 1270 "src/jit/x64/emit.dasc" |
1981 | 456 | switch(ins->info->opcode) { |
1982 | 133 | case MVM_OP_add_n: |
1983 | 133 | //| addsd xmm0, qword WORK[reg_c]; |
1984 | 133 | dasm_put(Dst, 1548, Dt23([reg_c])); |
1985 | 133 | #line 1273 "src/jit/x64/emit.dasc" |
1986 | 133 | break; |
1987 | 135 | case MVM_OP_sub_n: |
1988 | 135 | //| subsd xmm0, qword WORK[reg_c]; |
1989 | 135 | dasm_put(Dst, 1555, Dt23([reg_c])); |
1990 | 135 | #line 1276 "src/jit/x64/emit.dasc" |
1991 | 135 | break; |
1992 | 1 | case MVM_OP_mul_n: |
1993 | 1 | //| mulsd xmm0, qword WORK[reg_c]; |
1994 | 1 | dasm_put(Dst, 1562, Dt23([reg_c])); |
1995 | 1 | #line 1279 "src/jit/x64/emit.dasc" |
1996 | 1 | break; |
1997 | 187 | case MVM_OP_div_n: |
1998 | 187 | //| divsd xmm0, qword WORK[reg_c]; |
1999 | 187 | dasm_put(Dst, 1569, Dt23([reg_c])); |
2000 | 187 | #line 1282 "src/jit/x64/emit.dasc" |
2001 | 187 | break; |
2002 | 456 | } |
2003 | 456 | //| movsd qword WORK[reg_a], xmm0; |
2004 | 456 | dasm_put(Dst, 1576, Dt23([reg_a])); |
2005 | 456 | #line 1285 "src/jit/x64/emit.dasc" |
2006 | 456 | break; |
2007 | 456 | } |
2008 | 2.94k | case MVM_OP_coerce_in: { |
2009 | 2.94k | MVMint16 dst = ins->operands[0].reg.orig; |
2010 | 2.94k | MVMint16 src = ins->operands[1].reg.orig; |
2011 | 2.94k | /* convert simple integer to double precision */ |
2012 | 2.94k | //| cvtsi2sd xmm0, qword WORK[src]; |
2013 | 2.94k | //| movsd qword WORK[dst], xmm0; |
2014 | 2.94k | dasm_put(Dst, 1583, Dt23([src]), Dt23([dst])); |
2015 | 2.94k | #line 1293 "src/jit/x64/emit.dasc" |
2016 | 2.94k | break; |
2017 | 456 | } |
2018 | 4.77k | case MVM_OP_coerce_ni: { |
2019 | 4.77k | MVMint16 dst = ins->operands[0].reg.orig; |
2020 | 4.77k | MVMint16 src = ins->operands[1].reg.orig; |
2021 | 4.77k | /* convert double precision to simple intege */ |
2022 | 4.77k | //| cvttsd2si rax, qword WORK[src]; |
2023 | 4.77k | //| mov WORK[dst], rax; |
2024 | 4.77k | dasm_put(Dst, 1597, Dt23([src]), Dt23([dst])); |
2025 | 4.77k | #line 1301 "src/jit/x64/emit.dasc" |
2026 | 4.77k | break; |
2027 | 456 | } |
2028 | 8 | case MVM_OP_neg_n: { |
2029 | 8 | /* Negation is xor-ing the highest byte. Pretty simple right */ |
2030 | 8 | MVMint16 dst = ins->operands[0].reg.orig; |
2031 | 8 | MVMint16 src = ins->operands[1].reg.orig; |
2032 | 8 | //| mov TMP1, 1; |
2033 | 8 | //| sal TMP1, 63; |
2034 | 8 | //| mov TMP2, qword WORK[src]; |
2035 | 8 | //| xor TMP2, TMP1; |
2036 | 8 | //| mov qword WORK[dst], TMP2; |
2037 | 8 | dasm_put(Dst, 1609, Dt23([src]), Dt23([dst])); |
2038 | 8 | #line 1312 "src/jit/x64/emit.dasc" |
2039 | 8 | break; |
2040 | 456 | } |
2041 | 5.53k | case MVM_OP_eq_i: |
2042 | 5.53k | case MVM_OP_eqaddr: |
2043 | 5.53k | case MVM_OP_ne_i: |
2044 | 5.53k | case MVM_OP_lt_i: |
2045 | 5.53k | case MVM_OP_le_i: |
2046 | 5.53k | case MVM_OP_gt_i: |
2047 | 5.53k | case MVM_OP_ge_i: { |
2048 | 5.53k | MVMint32 reg_a = ins->operands[0].reg.orig; |
2049 | 5.53k | MVMint32 reg_b = ins->operands[1].reg.orig; |
2050 | 5.53k | MVMint32 reg_c = ins->operands[2].reg.orig; |
2051 | 5.53k | //| mov rax, WORK[reg_b]; |
2052 | 5.53k | dasm_put(Dst, 1217, Dt23([reg_b])); |
2053 | 5.53k | #line 1325 "src/jit/x64/emit.dasc" |
2054 | 5.53k | /* comparison result in the setting bits in the rflags register */ |
2055 | 5.53k | //| cmp rax, WORK[reg_c]; |
2056 | 5.53k | dasm_put(Dst, 1632, Dt23([reg_c])); |
2057 | 5.53k | #line 1327 "src/jit/x64/emit.dasc" |
2058 | 5.53k | /* copy the right comparison bit to the lower byte of the rax |
2059 | 5.53k | register */ |
2060 | 5.53k | switch(ins->info->opcode) { |
2061 | 1.63k | case MVM_OP_eqaddr: |
2062 | 1.63k | case MVM_OP_eq_i: |
2063 | 1.63k | //| sete al; |
2064 | 1.63k | dasm_put(Dst, 1637); |
2065 | 1.63k | #line 1333 "src/jit/x64/emit.dasc" |
2066 | 1.63k | break; |
2067 | 65 | case MVM_OP_ne_i: |
2068 | 65 | //| setne al; |
2069 | 65 | dasm_put(Dst, 1641); |
2070 | 65 | #line 1336 "src/jit/x64/emit.dasc" |
2071 | 65 | break; |
2072 | 2.76k | case MVM_OP_lt_i: |
2073 | 2.76k | //| setl al; |
2074 | 2.76k | dasm_put(Dst, 1645); |
2075 | 2.76k | #line 1339 "src/jit/x64/emit.dasc" |
2076 | 2.76k | break; |
2077 | 11 | case MVM_OP_le_i: |
2078 | 11 | //| setle al; |
2079 | 11 | dasm_put(Dst, 1649); |
2080 | 11 | #line 1342 "src/jit/x64/emit.dasc" |
2081 | 11 | break; |
2082 | 629 | case MVM_OP_gt_i: |
2083 | 629 | //| setg al; |
2084 | 629 | dasm_put(Dst, 1653); |
2085 | 629 | #line 1345 "src/jit/x64/emit.dasc" |
2086 | 629 | break; |
2087 | 435 | case MVM_OP_ge_i: |
2088 | 435 | //| setge al; |
2089 | 435 | dasm_put(Dst, 1657); |
2090 | 435 | #line 1348 "src/jit/x64/emit.dasc" |
2091 | 435 | break; |
2092 | 5.53k | } |
2093 | 5.53k | /* zero extend al (lower byte) to rax (whole register) */ |
2094 | 5.53k | //| movzx rax, al; |
2095 | 5.53k | //| mov WORK[reg_a], rax; |
2096 | 5.53k | dasm_put(Dst, 1661, Dt23([reg_a])); |
2097 | 5.53k | #line 1353 "src/jit/x64/emit.dasc" |
2098 | 5.53k | break; |
2099 | 5.53k | } |
2100 | 0 | case MVM_OP_cmp_i : { |
2101 | 0 | MVMint32 reg_a = ins->operands[0].reg.orig; |
2102 | 0 | MVMint32 reg_b = ins->operands[1].reg.orig; |
2103 | 0 | MVMint32 reg_c = ins->operands[2].reg.orig; |
2104 | 0 | //| mov TMP1, WORK[reg_b]; |
2105 | 0 | dasm_put(Dst, 1528, Dt23([reg_b])); |
2106 | 0 | #line 1360 "src/jit/x64/emit.dasc" |
2107 | 0 | /* comparison result in the setting bits in the rflags register */ |
2108 | 0 | //| cmp TMP1, WORK[reg_c]; |
2109 | 0 | dasm_put(Dst, 1670, Dt23([reg_c])); |
2110 | 0 | #line 1362 "src/jit/x64/emit.dasc" |
2111 | 0 | /* copy the right comparison bit to the lower byte of the rax |
2112 | 0 | register */ |
2113 | 0 | //| setg TMP2b; |
2114 | 0 | //| movzx TMP2, TMP2b; |
2115 | 0 | //| setl TMP3b; |
2116 | 0 | //| movzx TMP3, TMP3b; |
2117 | 0 | //| sub TMP2, TMP3; |
2118 | 0 | //| mov WORK[reg_a], TMP2; |
2119 | 0 | dasm_put(Dst, 1675, Dt23([reg_a])); |
2120 | 0 | #line 1370 "src/jit/x64/emit.dasc" |
2121 | 0 | break; |
2122 | 5.53k | } |
2123 | 0 | case MVM_OP_gt_s: |
2124 | 0 | case MVM_OP_ge_s: |
2125 | 0 | case MVM_OP_lt_s: |
2126 | 0 | case MVM_OP_le_s: { |
2127 | 0 | /* src/jit/graph.c already put a call to the MVM_string_compare |
2128 | 0 | function into the graph, so here we just have to deal with the |
2129 | 0 | returned integers. */ |
2130 | 0 | MVMint32 reg = ins->operands[0].reg.orig; |
2131 | 0 | switch(ins->info->opcode) { |
2132 | 0 | case MVM_OP_gt_s: |
2133 | 0 | //| mov TMP2, 1; |
2134 | 0 | dasm_put(Dst, 1698); |
2135 | 0 | #line 1383 "src/jit/x64/emit.dasc" |
2136 | 0 | break; |
2137 | 0 | case MVM_OP_lt_s: |
2138 | 0 | //| mov TMP2, -1; |
2139 | 0 | dasm_put(Dst, 1706); |
2140 | 0 | #line 1386 "src/jit/x64/emit.dasc" |
2141 | 0 | break; |
2142 | 0 | case MVM_OP_ge_s: case MVM_OP_le_s: |
2143 | 0 | //| mov TMP2, 0; |
2144 | 0 | dasm_put(Dst, 1718); |
2145 | 0 | #line 1389 "src/jit/x64/emit.dasc" |
2146 | 0 | break; |
2147 | 0 | } |
2148 | 0 | //| cmp TMP2, WORK[reg]; |
2149 | 0 | dasm_put(Dst, 1726, Dt23([reg])); |
2150 | 0 | #line 1392 "src/jit/x64/emit.dasc" |
2151 | 0 | /* Mind the reversedness of the constant and the value as compared to |
2152 | 0 | * interp.c */ |
2153 | 0 | switch(ins->info->opcode) { |
2154 | 0 | case MVM_OP_gt_s: |
2155 | 0 | //| sete al; |
2156 | 0 | dasm_put(Dst, 1637); |
2157 | 0 | #line 1397 "src/jit/x64/emit.dasc" |
2158 | 0 | break; |
2159 | 0 | case MVM_OP_ge_s: |
2160 | 0 | //| setle al; |
2161 | 0 | dasm_put(Dst, 1649); |
2162 | 0 | #line 1400 "src/jit/x64/emit.dasc" |
2163 | 0 | break; |
2164 | 0 | case MVM_OP_lt_s: |
2165 | 0 | //| sete al; |
2166 | 0 | dasm_put(Dst, 1637); |
2167 | 0 | #line 1403 "src/jit/x64/emit.dasc" |
2168 | 0 | break; |
2169 | 0 | case MVM_OP_le_s: |
2170 | 0 | //| setge al; |
2171 | 0 | dasm_put(Dst, 1657); |
2172 | 0 | #line 1406 "src/jit/x64/emit.dasc" |
2173 | 0 | break; |
2174 | 0 | } |
2175 | 0 | //| movzx rax, al; |
2176 | 0 | //| mov WORK[reg], rax; |
2177 | 0 | dasm_put(Dst, 1661, Dt23([reg])); |
2178 | 0 | #line 1410 "src/jit/x64/emit.dasc" |
2179 | 0 | break; |
2180 | 0 | } |
2181 | 442 | case MVM_OP_not_i: { |
2182 | 442 | MVMint16 dst = ins->operands[0].reg.orig; |
2183 | 442 | MVMint16 src = ins->operands[1].reg.orig; |
2184 | 442 | //| mov TMP1, WORK[src]; |
2185 | 442 | //| test TMP1, TMP1; |
2186 | 442 | //| setz TMP2b; |
2187 | 442 | //| movzx TMP2, TMP2b; |
2188 | 442 | //| mov WORK[dst], TMP2; |
2189 | 442 | dasm_put(Dst, 1122, Dt23([src]), Dt23([dst])); |
2190 | 442 | #line 1420 "src/jit/x64/emit.dasc" |
2191 | 442 | break; |
2192 | 0 | } |
2193 | 3.87k | case MVM_OP_eq_n: |
2194 | 3.87k | case MVM_OP_ne_n: |
2195 | 3.87k | case MVM_OP_le_n: |
2196 | 3.87k | case MVM_OP_lt_n: |
2197 | 3.87k | case MVM_OP_ge_n: |
2198 | 3.87k | case MVM_OP_gt_n: { |
2199 | 3.87k | MVMint16 dst = ins->operands[0].reg.orig; |
2200 | 3.87k | MVMint16 a = ins->operands[1].reg.orig; |
2201 | 3.87k | MVMint16 b = ins->operands[2].reg.orig; |
2202 | 3.87k | if (op == MVM_OP_eq_n) { |
2203 | 2.13k | //| mov TMP1, 0; |
2204 | 2.13k | dasm_put(Dst, 1731); |
2205 | 2.13k | #line 1433 "src/jit/x64/emit.dasc" |
2206 | 1.73k | } else if (op == MVM_OP_ne_n) { |
2207 | 311 | //| mov TMP1, 1; |
2208 | 311 | dasm_put(Dst, 1739); |
2209 | 311 | #line 1435 "src/jit/x64/emit.dasc" |
2210 | 311 | } |
2211 | 3.87k | if (op == MVM_OP_lt_n || op == MVM_OP_le_n) { |
2212 | 468 | //| movsd xmm0, qword WORK[b]; |
2213 | 468 | //| ucomisd xmm0, qword WORK[a]; |
2214 | 468 | dasm_put(Dst, 1747, Dt23([b]), Dt23([a])); |
2215 | 468 | #line 1439 "src/jit/x64/emit.dasc" |
2216 | 3.40k | } else { |
2217 | 3.40k | //| movsd xmm0, qword WORK[a]; |
2218 | 3.40k | //| ucomisd xmm0, qword WORK[b]; |
2219 | 3.40k | dasm_put(Dst, 1747, Dt23([a]), Dt23([b])); |
2220 | 3.40k | #line 1442 "src/jit/x64/emit.dasc" |
2221 | 3.40k | } |
2222 | 3.87k | |
2223 | 3.87k | if (op == MVM_OP_le_n || op == MVM_OP_ge_n) { |
2224 | 640 | //| setae TMP1b; |
2225 | 640 | dasm_put(Dst, 1759); |
2226 | 640 | #line 1446 "src/jit/x64/emit.dasc" |
2227 | 3.23k | } else if (op == MVM_OP_eq_n) { |
2228 | 2.13k | //| setnp TMP2b; // zero if either is NaN, 1 otherwise |
2229 | 2.13k | //| cmove TMP1, TMP2; // if equal, overwrite 0 with 1 |
2230 | 2.13k | dasm_put(Dst, 1763); |
2231 | 2.13k | #line 1449 "src/jit/x64/emit.dasc" |
2232 | 1.09k | } else if (op == MVM_OP_ne_n) { |
2233 | 311 | //| setp TMP2b; // 1 if either is NaN (in which case they can't be equal) |
2234 | 311 | //| cmove TMP1, TMP2; // if equal, overwrite 1 with IsNan(a) | IsNaN(b) |
2235 | 311 | dasm_put(Dst, 1771); |
2236 | 311 | #line 1452 "src/jit/x64/emit.dasc" |
2237 | 787 | } else { |
2238 | 787 | //| seta TMP1b; |
2239 | 787 | dasm_put(Dst, 1779); |
2240 | 787 | #line 1454 "src/jit/x64/emit.dasc" |
2241 | 787 | } |
2242 | 3.87k | //| movzx TMP1, TMP1b; |
2243 | 3.87k | //| mov WORK[dst], TMP1; |
2244 | 3.87k | dasm_put(Dst, 1783, Dt23([dst])); |
2245 | 3.87k | #line 1457 "src/jit/x64/emit.dasc" |
2246 | 3.87k | break; |
2247 | 3.87k | } |
2248 | 0 | case MVM_OP_cmp_n: { |
2249 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2250 | 0 | MVMint16 a = ins->operands[1].reg.orig; |
2251 | 0 | MVMint16 b = ins->operands[2].reg.orig; |
2252 | 0 | //| movsd xmm0, qword WORK[a]; |
2253 | 0 | //| movsd xmm1, qword WORK[b]; |
2254 | 0 | //| ucomisd xmm0, xmm1 |
2255 | 0 | //| seta TMP1b; |
2256 | 0 | //| movzx rax, TMP1b; |
2257 | 0 | //| ucomisd xmm1, xmm0 |
2258 | 0 | //| seta TMP1b; |
2259 | 0 | //| movzx TMP1, TMP1b; |
2260 | 0 | //| sub rax, TMP1; |
2261 | 0 | //| mov WORK[dst], rax; |
2262 | 0 | dasm_put(Dst, 1792, Dt23([a]), Dt23([b]), Dt23([dst])); |
2263 | 0 | #line 1473 "src/jit/x64/emit.dasc" |
2264 | 0 | break; |
2265 | 3.87k | } |
2266 | 0 | case MVM_OP_eq_I: |
2267 | 0 | case MVM_OP_ne_I: |
2268 | 0 | case MVM_OP_lt_I: |
2269 | 0 | case MVM_OP_le_I: |
2270 | 0 | case MVM_OP_gt_I: |
2271 | 0 | case MVM_OP_ge_I: { |
2272 | 0 | MVMint32 reg_a = ins->operands[0].reg.orig; |
2273 | 0 | MVMint32 reg_b = ins->operands[1].reg.orig; |
2274 | 0 | MVMint32 reg_c = ins->operands[2].reg.orig; |
2275 | 0 | /* Call the bigint comparison function. */ |
2276 | 0 | //| mov ARG1, tc; |
2277 | 0 | //| mov ARG2, WORK[reg_b]; |
2278 | 0 | //| mov ARG3, WORK[reg_c]; |
2279 | 0 | //| callp &MVM_bigint_cmp; |
2280 | 0 | dasm_put(Dst, 1834, tc, Dt23([reg_b]), Dt23([reg_c])); |
2281 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_bigint_cmp)), (MVMuint32)((uintptr_t)(&MVM_bigint_cmp) >> 32)); |
2282 | 0 | dasm_put(Dst, 216); |
2283 | 0 | #line 1489 "src/jit/x64/emit.dasc" |
2284 | 0 | /* Handle result by opcode. */ |
2285 | 0 | switch(ins->info->opcode) { |
2286 | 0 | case MVM_OP_eq_I: |
2287 | 0 | //| cmp RV, MP_EQ |
2288 | 0 | //| sete al; |
2289 | 0 | dasm_put(Dst, 1848, MP_EQ); |
2290 | 0 | #line 1494 "src/jit/x64/emit.dasc" |
2291 | 0 | break; |
2292 | 0 | case MVM_OP_ne_I: |
2293 | 0 | //| cmp RV, MP_EQ |
2294 | 0 | //| setne al; |
2295 | 0 | dasm_put(Dst, 1857, MP_EQ); |
2296 | 0 | #line 1498 "src/jit/x64/emit.dasc" |
2297 | 0 | break; |
2298 | 0 | case MVM_OP_lt_I: |
2299 | 0 | //| cmp RV, MP_LT |
2300 | 0 | //| sete al; |
2301 | 0 | dasm_put(Dst, 1848, MP_LT); |
2302 | 0 | #line 1502 "src/jit/x64/emit.dasc" |
2303 | 0 | break; |
2304 | 0 | case MVM_OP_le_I: |
2305 | 0 | //| cmp RV, MP_GT |
2306 | 0 | //| setne al; |
2307 | 0 | dasm_put(Dst, 1857, MP_GT); |
2308 | 0 | #line 1506 "src/jit/x64/emit.dasc" |
2309 | 0 | break; |
2310 | 0 | case MVM_OP_gt_I: |
2311 | 0 | //| cmp RV, MP_GT |
2312 | 0 | //| sete al; |
2313 | 0 | dasm_put(Dst, 1848, MP_GT); |
2314 | 0 | #line 1510 "src/jit/x64/emit.dasc" |
2315 | 0 | break; |
2316 | 0 | case MVM_OP_ge_I: |
2317 | 0 | //| cmp RV, MP_LT |
2318 | 0 | //| setne al; |
2319 | 0 | dasm_put(Dst, 1857, MP_LT); |
2320 | 0 | #line 1514 "src/jit/x64/emit.dasc" |
2321 | 0 | break; |
2322 | 0 | } |
2323 | 0 | /* zero extend al (lower byte) to rax (whole register) */ |
2324 | 0 | //| movzx rax, al; |
2325 | 0 | //| mov WORK[reg_a], rax; |
2326 | 0 | dasm_put(Dst, 1661, Dt23([reg_a])); |
2327 | 0 | #line 1519 "src/jit/x64/emit.dasc" |
2328 | 0 | break; |
2329 | 0 | } |
2330 | 18 | case MVM_OP_isint: |
2331 | 18 | case MVM_OP_isnum: |
2332 | 18 | case MVM_OP_isstr: |
2333 | 18 | case MVM_OP_islist: |
2334 | 18 | case MVM_OP_ishash: { |
2335 | 18 | MVMint16 dst = ins->operands[0].reg.orig; |
2336 | 18 | MVMint16 obj = ins->operands[1].reg.orig; |
2337 | 18 | MVMint32 reprid = op == MVM_OP_isint ? MVM_REPR_ID_P6int : |
2338 | 18 | op == MVM_OP_isnum ? MVM_REPR_ID_P6num : |
2339 | 18 | op == MVM_OP_isstr ? MVM_REPR_ID_P6str : |
2340 | 4 | op == MVM_OP_islist ? MVM_REPR_ID_VMArray : |
2341 | 4 | /* op == MVM_OP_ishash */ MVM_REPR_ID_MVMHash; |
2342 | 18 | //| mov TMP1, aword WORK[obj]; |
2343 | 18 | //| test TMP1, TMP1; |
2344 | 18 | //| jz >1; |
2345 | 18 | //| mov TMP1, OBJECT:TMP1->st; |
2346 | 18 | //| mov TMP1, STABLE:TMP1->REPR; |
2347 | 18 | //| cmp qword REPR:TMP1->ID, reprid; |
2348 | 18 | //| jne >1; |
2349 | 18 | //| mov qword WORK[dst], 1; |
2350 | 18 | //| jmp >2; |
2351 | 18 | //|1: |
2352 | 18 | //| mov qword WORK[dst], 0; |
2353 | 18 | //|2: |
2354 | 18 | dasm_put(Dst, 1866, Dt23([obj]), DtE(->st), Dt12(->REPR), Dt13(->ID), reprid, Dt23([dst]), Dt23([dst])); |
2355 | 18 | #line 1545 "src/jit/x64/emit.dasc" |
2356 | 18 | break; |
2357 | 18 | } |
2358 | 0 | case MVM_OP_sp_boolify_iter_arr: { |
2359 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2360 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
2361 | 0 | //| mov TMP1, aword WORK[obj]; |
2362 | 0 | //| mov TMP2, MVMITER:TMP1->body.array_state.index; |
2363 | 0 | //| add TMP2, 1; |
2364 | 0 | //| mov TMP3, MVMITER:TMP1->body.array_state.limit; |
2365 | 0 | dasm_put(Dst, 1919, Dt23([obj]), DtB(->body.array_state.index), DtB(->body.array_state.limit)); |
2366 | 0 | #line 1554 "src/jit/x64/emit.dasc" |
2367 | 0 | /* index - limit will give a carry flag when index < limit */ |
2368 | 0 | //| cmp TMP2, TMP3; |
2369 | 0 | //| setl TMP1b; |
2370 | 0 | //| movzx TMP1, TMP1b; |
2371 | 0 | //| mov aword WORK[dst], TMP1; |
2372 | 0 | dasm_put(Dst, 1936, Dt23([dst])); |
2373 | 0 | #line 1559 "src/jit/x64/emit.dasc" |
2374 | 0 | break; |
2375 | 18 | } |
2376 | 0 | case MVM_OP_sp_boolify_iter_hash: { |
2377 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2378 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
2379 | 0 | //| mov TMP1, aword WORK[obj]; |
2380 | 0 | //| mov TMP2, MVMITER:TMP1->body.hash_state.next; |
2381 | 0 | //| test TMP2, TMP2; |
2382 | 0 | //| setnz TMP2b; |
2383 | 0 | //| movzx TMP2, TMP2b; |
2384 | 0 | //| mov aword WORK[dst], TMP2; |
2385 | 0 | dasm_put(Dst, 1951, Dt23([obj]), DtB(->body.hash_state.next), Dt23([dst])); |
2386 | 0 | #line 1570 "src/jit/x64/emit.dasc" |
2387 | 0 | break; |
2388 | 18 | } |
2389 | 0 | case MVM_OP_objprimspec: { |
2390 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2391 | 0 | MVMint16 type = ins->operands[1].reg.orig; |
2392 | 0 | //| mov TMP6, aword WORK[type]; |
2393 | 0 | //| test TMP6, TMP6; |
2394 | 0 | //| jz >1; |
2395 | 0 | //| mov ARG1, TC; |
2396 | 0 | //| mov ARG2, OBJECT:TMP6->st; |
2397 | 0 | //| mov FUNCTION, STABLE:ARG2->REPR; |
2398 | 0 | //| mov FUNCTION, REPR:FUNCTION->get_storage_spec; |
2399 | 0 | //| call FUNCTION; |
2400 | 0 | //| movzx TMP6, word STORAGESPEC:RV->boxed_primitive; |
2401 | 0 | //|1: |
2402 | 0 | //| mov aword WORK[dst], TMP6; |
2403 | 0 | dasm_put(Dst, 1974, Dt23([type]), DtE(->st), Dt12(->REPR), Dt13(->get_storage_spec), Dt18(->boxed_primitive), Dt23([dst])); |
2404 | 0 | #line 1586 "src/jit/x64/emit.dasc" |
2405 | 0 | break; |
2406 | 18 | } |
2407 | 26 | case MVM_OP_objprimbits: { |
2408 | 26 | MVMint16 dst = ins->operands[0].reg.orig; |
2409 | 26 | MVMint16 type = ins->operands[1].reg.orig; |
2410 | 26 | //| mov TMP6, aword WORK[type]; |
2411 | 26 | //| test TMP6, TMP6; |
2412 | 26 | //| jz >1; |
2413 | 26 | //| mov ARG2, OBJECT:TMP6->st; |
2414 | 26 | //| mov FUNCTION, STABLE:ARG2->REPR; |
2415 | 26 | //| mov FUNCTION, REPR:FUNCTION->get_storage_spec; |
2416 | 26 | //| mov ARG1, TC; |
2417 | 26 | //| call FUNCTION; |
2418 | 26 | //| movzx TMP6, word STORAGESPEC:RV->boxed_primitive; |
2419 | 26 | //| test TMP6, TMP6; |
2420 | 26 | //| jz >1; |
2421 | 26 | //| movzx TMP6, word STORAGESPEC:RV->bits; |
2422 | 26 | //|1: |
2423 | 26 | //| mov aword WORK[dst], TMP6; |
2424 | 26 | dasm_put(Dst, 2017, Dt23([type]), DtE(->st), Dt12(->REPR), Dt13(->get_storage_spec), Dt18(->boxed_primitive), Dt18(->bits), Dt23([dst])); |
2425 | 26 | #line 1605 "src/jit/x64/emit.dasc" |
2426 | 26 | break; |
2427 | 18 | } |
2428 | 13 | case MVM_OP_objprimunsigned: { |
2429 | 13 | MVMint16 dst = ins->operands[0].reg.orig; |
2430 | 13 | MVMint16 type = ins->operands[1].reg.orig; |
2431 | 13 | //| mov TMP5, aword WORK[type]; |
2432 | 13 | //| test TMP5, TMP5; |
2433 | 13 | //| jz >1; |
2434 | 13 | //| mov ARG1, TC; |
2435 | 13 | //| mov ARG2, OBJECT:TMP5->st; |
2436 | 13 | //| mov FUNCTION, STABLE:ARG2->REPR; |
2437 | 13 | //| mov FUNCTION, REPR:FUNCTION->get_storage_spec; |
2438 | 13 | //| call FUNCTION; |
2439 | 13 | //| mov TMP6, STORAGESPEC:RV->boxed_primitive; |
2440 | 13 | //| cmp TMP6, 1; |
2441 | 13 | //| jne >1; |
2442 | 13 | //| mov TMP6, STORAGESPEC:RV->is_unsigned; |
2443 | 13 | //| mov WORK[dst], TMP6; |
2444 | 13 | //| jmp >2; |
2445 | 13 | //|1: |
2446 | 13 | //| mov aword WORK[dst], 0; |
2447 | 13 | //|2: |
2448 | 13 | dasm_put(Dst, 2072, Dt23([type]), DtE(->st), Dt12(->REPR), Dt13(->get_storage_spec), Dt18(->boxed_primitive), Dt18(->is_unsigned), Dt23([dst]), Dt23([dst])); |
2449 | 13 | #line 1627 "src/jit/x64/emit.dasc" |
2450 | 13 | break; |
2451 | 18 | } |
2452 | 664 | case MVM_OP_isnonnull: { |
2453 | 664 | MVMint16 dst = ins->operands[0].reg.orig; |
2454 | 664 | MVMint16 obj = ins->operands[1].reg.orig; |
2455 | 664 | //| mov TMP1, WORK[obj]; |
2456 | 664 | //| test TMP1, TMP1; |
2457 | 664 | //| setnz TMP2b; |
2458 | 664 | //| get_vmnull TMP3; |
2459 | 664 | //| cmp TMP1, TMP3; |
2460 | 664 | //| setne TMP3b; |
2461 | 664 | //| and TMP2b, TMP3b; |
2462 | 664 | //| movzx TMP2, TMP2b; |
2463 | 664 | //| mov WORK[dst], TMP2; |
2464 | 664 | dasm_put(Dst, 2141, Dt23([obj]), Dt22(->instance), DtC(->VMNull), Dt23([dst])); |
2465 | 664 | #line 1641 "src/jit/x64/emit.dasc" |
2466 | 664 | break; |
2467 | 18 | } |
2468 | 13 | case MVM_OP_scgethandle: { |
2469 | 13 | MVMint16 dst = ins->operands[0].reg.orig; |
2470 | 13 | MVMint16 sc = ins->operands[1].reg.orig; |
2471 | 13 | //| mov TMP5, aword WORK[sc]; |
2472 | 13 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_SCRef; |
2473 | 13 | //| je >1; |
2474 | 13 | //| throw_adhoc "Must provide an SCRef operand to scgethandle" |
2475 | 13 | dasm_put(Dst, 2178, Dt23([sc]), DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_SCRef, (unsigned int)((uintptr_t)("Must provide an SCRef operand to scgethandle")), (unsigned int)(((uintptr_t)("Must provide an SCRef operand to scgethandle"))>>32)); |
2476 | 13 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2477 | 13 | #line 1650 "src/jit/x64/emit.dasc" |
2478 | 13 | //|1: |
2479 | 13 | //| mov ARG1, TC; |
2480 | 13 | //| mov ARG2, SCREF:TMP5; |
2481 | 13 | //| callp &MVM_sc_get_handle; |
2482 | 13 | dasm_put(Dst, 2209); |
2483 | 13 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_sc_get_handle)), (MVMuint32)((uintptr_t)(&MVM_sc_get_handle) >> 32)); |
2484 | 13 | #line 1654 "src/jit/x64/emit.dasc" |
2485 | 13 | //| mov WORK[dst], RV; |
2486 | 13 | dasm_put(Dst, 501, Dt23([dst])); |
2487 | 13 | #line 1655 "src/jit/x64/emit.dasc" |
2488 | 13 | break; |
2489 | 18 | } |
2490 | 0 | case MVM_OP_scobjcount: { |
2491 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2492 | 0 | MVMint16 sc = ins->operands[1].reg.orig; |
2493 | 0 | //| mov TMP5, aword WORK[dst]; |
2494 | 0 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_SCRef; |
2495 | 0 | //| je >1; |
2496 | 0 | //| throw_adhoc "Must provide an SCRef operand to scobjcount" |
2497 | 0 | dasm_put(Dst, 2178, Dt23([dst]), DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_SCRef, (unsigned int)((uintptr_t)("Must provide an SCRef operand to scobjcount")), (unsigned int)(((uintptr_t)("Must provide an SCRef operand to scobjcount"))>>32)); |
2498 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2499 | 0 | #line 1664 "src/jit/x64/emit.dasc" |
2500 | 0 | //|1: |
2501 | 0 | //| mov ARG1, TC; |
2502 | 0 | //| mov ARG2, SCREF:TMP5; |
2503 | 0 | //| callp &MVM_sc_get_object_count; |
2504 | 0 | dasm_put(Dst, 2209); |
2505 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_sc_get_object_count)), (MVMuint32)((uintptr_t)(&MVM_sc_get_object_count) >> 32)); |
2506 | 0 | #line 1668 "src/jit/x64/emit.dasc" |
2507 | 0 | //| mov WORK[dst], RV; |
2508 | 0 | dasm_put(Dst, 501, Dt23([dst])); |
2509 | 0 | #line 1669 "src/jit/x64/emit.dasc" |
2510 | 0 | break; |
2511 | 18 | } |
2512 | 0 | case MVM_OP_setobjsc: { |
2513 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2514 | 0 | MVMint16 sc = ins->operands[1].reg.orig; |
2515 | 0 | //| mov TMP5, WORK[sc]; |
2516 | 0 | //| cmp_repr_id TMP5, TMP6, MVM_REPR_ID_SCRef; |
2517 | 0 | //| je >1; |
2518 | 0 | //| throw_adhoc "Must provide an SCRef operand to setobjsc" |
2519 | 0 | dasm_put(Dst, 2178, Dt23([sc]), DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_SCRef, (unsigned int)((uintptr_t)("Must provide an SCRef operand to setobjsc")), (unsigned int)(((uintptr_t)("Must provide an SCRef operand to setobjsc"))>>32)); |
2520 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2521 | 0 | #line 1678 "src/jit/x64/emit.dasc" |
2522 | 0 | //|1: |
2523 | 0 | //| mov ARG1, TC; |
2524 | 0 | //| mov ARG2, aword WORK[dst]; |
2525 | 0 | //| mov ARG3, SCREF:TMP5; |
2526 | 0 | //| callp &MVM_sc_set_obj_sc; |
2527 | 0 | dasm_put(Dst, 2225, Dt23([dst])); |
2528 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_sc_set_obj_sc)), (MVMuint32)((uintptr_t)(&MVM_sc_set_obj_sc) >> 32)); |
2529 | 0 | dasm_put(Dst, 216); |
2530 | 0 | #line 1683 "src/jit/x64/emit.dasc" |
2531 | 0 | break; |
2532 | 18 | } |
2533 | 521 | case MVM_OP_isnull: { |
2534 | 521 | MVMint16 dst = ins->operands[0].reg.orig; |
2535 | 521 | MVMint16 obj = ins->operands[1].reg.orig; |
2536 | 521 | //| mov TMP1, WORK[obj]; |
2537 | 521 | //| test TMP1, TMP1; |
2538 | 521 | //| setz TMP2b; |
2539 | 521 | //| get_vmnull TMP3; |
2540 | 521 | //| cmp TMP1, TMP3; |
2541 | 521 | //| sete TMP3b; |
2542 | 521 | //| or TMP2b, TMP3b; |
2543 | 521 | //| movzx TMP2, TMP2b; |
2544 | 521 | //| mov WORK[dst], TMP2; |
2545 | 521 | dasm_put(Dst, 2245, Dt23([obj]), Dt22(->instance), DtC(->VMNull), Dt23([dst])); |
2546 | 521 | #line 1697 "src/jit/x64/emit.dasc" |
2547 | 521 | break; |
2548 | 18 | } |
2549 | 728 | case MVM_OP_sp_fastcreate: { |
2550 | 728 | MVMint16 dst = ins->operands[0].reg.orig; |
2551 | 728 | MVMuint16 size = ins->operands[1].lit_i16; |
2552 | 728 | MVMint16 spesh_idx = ins->operands[2].lit_i16; |
2553 | 728 | //| mov ARG1, TC; |
2554 | 728 | //| mov ARG2, size; |
2555 | 728 | //| callp &MVM_gc_allocate_zeroed; |
2556 | 728 | dasm_put(Dst, 2282, size); |
2557 | 728 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_allocate_zeroed)), (MVMuint32)((uintptr_t)(&MVM_gc_allocate_zeroed) >> 32)); |
2558 | 728 | #line 1706 "src/jit/x64/emit.dasc" |
2559 | 728 | //| get_spesh_slot TMP1, spesh_idx; |
2560 | 728 | //| mov aword OBJECT:RV->st, TMP1; // st is 64 bit (pointer) |
2561 | 728 | //| mov word OBJECT:RV->header.size, size; // object size is 16 bit |
2562 | 728 | //| mov TMP1d, dword TC->thread_id; // thread id is 32 bit |
2563 | 728 | //| mov dword OBJECT:RV->header.owner, TMP1d; // does this even work? |
2564 | 728 | //| mov aword WORK[dst], RV; // store in local register |
2565 | 728 | dasm_put(Dst, 2292, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([spesh_idx]), DtE(->st), DtE(->header.size), size, Dt22(->thread_id), DtE(->header.owner), Dt23([dst])); |
2566 | 728 | #line 1712 "src/jit/x64/emit.dasc" |
2567 | 728 | break; |
2568 | 18 | } |
2569 | 8.28k | case MVM_OP_decont: |
2570 | 8.28k | case MVM_OP_sp_decont: { |
2571 | 8.28k | MVMint16 dst = ins->operands[0].reg.orig; |
2572 | 8.28k | MVMint16 src = ins->operands[1].reg.orig; |
2573 | 8.28k | //| mov TMP5, WORK[src]; |
2574 | 8.28k | //| test TMP5, TMP5; |
2575 | 8.28k | dasm_put(Dst, 2330, Dt23([src])); |
2576 | 8.28k | #line 1720 "src/jit/x64/emit.dasc" |
2577 | 8.28k | // obj is null |
2578 | 8.28k | //| jz >1; |
2579 | 8.28k | //| test_type_object TMP5; |
2580 | 8.28k | dasm_put(Dst, 2338, DtE(->header.flags), MVM_CF_TYPE_OBJECT); |
2581 | 8.28k | #line 1723 "src/jit/x64/emit.dasc" |
2582 | 8.28k | // object is type object (not concrete) |
2583 | 8.28k | //| jnz >1; |
2584 | 8.28k | //| mov TMP6, OBJECT:TMP5->st; |
2585 | 8.28k | //| mov TMP6, STABLE:TMP6->container_spec; |
2586 | 8.28k | //| test TMP6, TMP6; |
2587 | 8.28k | dasm_put(Dst, 2350, DtE(->st), Dt12(->container_spec)); |
2588 | 8.28k | #line 1728 "src/jit/x64/emit.dasc" |
2589 | 8.28k | // container spec is zero |
2590 | 8.28k | //| jz >1; |
2591 | 8.28k | //| mov ARG1, TC; |
2592 | 8.28k | //| mov ARG2, TMP5; // object |
2593 | 8.28k | //| lea ARG3, WORK[dst]; // destination register |
2594 | 8.28k | //| mov FUNCTION, CONTAINERSPEC:TMP6->fetch; // get function pointer |
2595 | 8.28k | //| call FUNCTION; |
2596 | 8.28k | //| jmp >2; |
2597 | 8.28k | //|1: |
2598 | 8.28k | dasm_put(Dst, 2366, Dt23([dst]), Dt17(->fetch)); |
2599 | 8.28k | #line 1737 "src/jit/x64/emit.dasc" |
2600 | 8.28k | // otherwise just move the object into the register |
2601 | 8.28k | //| mov WORK[dst], TMP5; |
2602 | 8.28k | //|2: |
2603 | 8.28k | dasm_put(Dst, 2396, Dt23([dst])); |
2604 | 8.28k | #line 1740 "src/jit/x64/emit.dasc" |
2605 | 8.28k | break; |
2606 | 8.28k | } |
2607 | 0 | case MVM_OP_iscont: { |
2608 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2609 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
2610 | 0 | //| mov TMP1, aword WORK[obj]; |
2611 | 0 | //| test TMP1, TMP1; |
2612 | 0 | //| jz >1; |
2613 | 0 | //| mov TMP1, OBJECT:TMP1->st; |
2614 | 0 | //| mov TMP1, STABLE:TMP1->container_spec; |
2615 | 0 | //| test TMP1, TMP1; |
2616 | 0 | //|1: |
2617 | 0 | //| setnz TMP1b; |
2618 | 0 | //| movzx TMP1, TMP1b; |
2619 | 0 | //| mov qword WORK[dst], TMP1; |
2620 | 0 | dasm_put(Dst, 2403, Dt23([obj]), DtE(->st), Dt12(->container_spec), Dt23([dst])); |
2621 | 0 | #line 1755 "src/jit/x64/emit.dasc" |
2622 | 0 | break; |
2623 | 8.28k | } |
2624 | 13.4k | case MVM_OP_sp_findmeth: { |
2625 | 13.4k | MVMint16 dst = ins->operands[0].reg.orig; |
2626 | 13.4k | MVMint16 obj = ins->operands[1].reg.orig; |
2627 | 13.4k | MVMint32 str_idx = ins->operands[2].lit_str_idx; |
2628 | 13.4k | MVMuint16 ss_idx = ins->operands[3].lit_i16; |
2629 | 13.4k | //| get_spesh_slot TMP1, ss_idx; |
2630 | 13.4k | //| mov TMP2, WORK[obj]; |
2631 | 13.4k | //| mov TMP2, OBJECT:TMP2->st; |
2632 | 13.4k | //| cmp TMP1, TMP2; |
2633 | 13.4k | //| jne >1; |
2634 | 13.4k | //| get_spesh_slot TMP3, ss_idx + 1; |
2635 | 13.4k | //| mov WORK[dst], TMP3; |
2636 | 13.4k | //| jmp >2; |
2637 | 13.4k | //|1: |
2638 | 13.4k | dasm_put(Dst, 2439, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([ss_idx]), Dt23([obj]), DtE(->st), Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([ss_idx + 1]), Dt23([dst])); |
2639 | 13.4k | #line 1771 "src/jit/x64/emit.dasc" |
2640 | 13.4k | /* call find_method_spesh */ |
2641 | 13.4k | //| mov ARG1, TC; |
2642 | 13.4k | //| mov ARG2, WORK[obj]; |
2643 | 13.4k | //| get_string ARG3, str_idx; |
2644 | 13.4k | dasm_put(Dst, 2489, Dt23([obj])); |
2645 | 13.4k | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, str_idx); |
2646 | 13.4k | #line 1775 "src/jit/x64/emit.dasc" |
2647 | 13.4k | //| mov ARG4, ss_idx; |
2648 | 13.4k | //| lea TMP6, WORK[dst]; |
2649 | 13.4k | //| mov ARG5, TMP6; |
2650 | 13.4k | //| callp &MVM_6model_find_method_spesh; |
2651 | 13.4k | dasm_put(Dst, 2498, Dt24(->body.strings), Dt15([str_idx]), ss_idx, Dt23([dst])); |
2652 | 13.4k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_6model_find_method_spesh)), (MVMuint32)((uintptr_t)(&MVM_6model_find_method_spesh) >> 32)); |
2653 | 13.4k | #line 1779 "src/jit/x64/emit.dasc" |
2654 | 13.4k | //|2: |
2655 | 13.4k | dasm_put(Dst, 316); |
2656 | 13.4k | #line 1780 "src/jit/x64/emit.dasc" |
2657 | 13.4k | break; |
2658 | 8.28k | } |
2659 | 548 | case MVM_OP_isconcrete: { |
2660 | 548 | MVMint16 dst = ins->operands[0].reg.orig; |
2661 | 548 | MVMint16 obj = ins->operands[1].reg.orig; |
2662 | 548 | //| mov TMP1, WORK[obj]; |
2663 | 548 | //| test TMP1, TMP1; |
2664 | 548 | //| jz >1; |
2665 | 548 | //| test_type_object TMP1; |
2666 | 548 | //| jnz >1; |
2667 | 548 | //| mov qword WORK[dst], 1; |
2668 | 548 | //| jmp >2; |
2669 | 548 | //|1: |
2670 | 548 | //| mov qword WORK[dst], 0; |
2671 | 548 | //|2: |
2672 | 548 | dasm_put(Dst, 2519, Dt23([obj]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, Dt23([dst]), Dt23([dst])); |
2673 | 548 | #line 1795 "src/jit/x64/emit.dasc" |
2674 | 548 | break; |
2675 | 8.28k | } |
2676 | 22 | case MVM_OP_isinvokable: { |
2677 | 22 | MVMint16 dst = ins->operands[0].reg.orig; |
2678 | 22 | MVMint16 src = ins->operands[1].reg.orig; |
2679 | 22 | //| mov TMP1, aword WORK[src]; |
2680 | 22 | //| mov TMP1, OBJECT:TMP1->st; |
2681 | 22 | //| mov TMP2, 1; |
2682 | 22 | //| mov64 TMP3, ((uintptr_t)(MVM_6model_invoke_default)); |
2683 | 22 | //| cmp TMP3, STABLE:TMP1->invoke; |
2684 | 22 | //| jne >1; |
2685 | 22 | //| mov TMP4, STABLE:TMP1->invocation_spec; |
2686 | 22 | //| test TMP4, TMP4; |
2687 | 22 | //| jnz >1; |
2688 | 22 | //| and TMP2, TMP4; |
2689 | 22 | //|1: |
2690 | 22 | //| mov aword WORK[dst], TMP2; |
2691 | 22 | dasm_put(Dst, 2565, Dt23([src]), DtE(->st), (unsigned int)(((uintptr_t)(MVM_6model_invoke_default))), (unsigned int)((((uintptr_t)(MVM_6model_invoke_default)))>>32), Dt12(->invoke), Dt12(->invocation_spec), Dt23([dst])); |
2692 | 22 | #line 1812 "src/jit/x64/emit.dasc" |
2693 | 22 | break; |
2694 | 8.28k | } |
2695 | 12 | case MVM_OP_takehandlerresult: { |
2696 | 12 | MVMint16 dst = ins->operands[0].reg.orig; |
2697 | 12 | //| mov TMP1, aword TC->last_handler_result; |
2698 | 12 | //| mov aword WORK[dst], TMP1; |
2699 | 12 | //| mov aword TC->last_handler_result, 0; |
2700 | 12 | dasm_put(Dst, 2613, Dt22(->last_handler_result), Dt23([dst]), Dt22(->last_handler_result)); |
2701 | 12 | #line 1819 "src/jit/x64/emit.dasc" |
2702 | 12 | break; |
2703 | 8.28k | } |
2704 | 0 | case MVM_OP_exception: { |
2705 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2706 | 0 | //| mov TMP1, TC->active_handlers; |
2707 | 0 | //| test TMP1, TMP1; |
2708 | 0 | //| jz >1; |
2709 | 0 | //| mov TMP1, MVMACTIVEHANDLERS:TMP1->ex_obj; |
2710 | 0 | //| mov WORK[dst], TMP1; |
2711 | 0 | //| jmp >2; |
2712 | 0 | //|1: |
2713 | 0 | //| get_vmnull TMP1; |
2714 | 0 | //| mov WORK[dst], TMP1; |
2715 | 0 | //|2: |
2716 | 0 | dasm_put(Dst, 2630, Dt22(->active_handlers), DtD(->ex_obj), Dt23([dst]), Dt22(->instance), DtC(->VMNull), Dt23([dst])); |
2717 | 0 | #line 1833 "src/jit/x64/emit.dasc" |
2718 | 0 | break; |
2719 | 8.28k | } |
2720 | 778 | case MVM_OP_scwbdisable: { |
2721 | 778 | MVMint16 dst = ins->operands[0].reg.orig; |
2722 | 778 | //| mov TMP1d, dword TC->sc_wb_disable_depth; |
2723 | 778 | //| add TMP1d, 1; |
2724 | 778 | //| mov dword TC->sc_wb_disable_depth, TMP1d; |
2725 | 778 | //| mov qword WORK[dst], TMP1; |
2726 | 778 | dasm_put(Dst, 2670, Dt22(->sc_wb_disable_depth), Dt22(->sc_wb_disable_depth), Dt23([dst])); |
2727 | 778 | #line 1841 "src/jit/x64/emit.dasc" |
2728 | 778 | break; |
2729 | 8.28k | } |
2730 | 777 | case MVM_OP_scwbenable: { |
2731 | 777 | MVMint16 dst = ins->operands[0].reg.orig; |
2732 | 777 | //| mov TMP1d, dword TC->sc_wb_disable_depth; // should do zero-extension |
2733 | 777 | //| sub TMP1d, 1; |
2734 | 777 | //| mov dword TC->sc_wb_disable_depth, TMP1d; |
2735 | 777 | //| mov qword WORK[dst], TMP1; |
2736 | 777 | dasm_put(Dst, 2686, Dt22(->sc_wb_disable_depth), Dt22(->sc_wb_disable_depth), Dt23([dst])); |
2737 | 777 | #line 1849 "src/jit/x64/emit.dasc" |
2738 | 777 | break; |
2739 | 8.28k | } |
2740 | 0 | case MVM_OP_assign: |
2741 | 0 | case MVM_OP_assignunchecked: { |
2742 | 0 | MVMint16 cont = ins->operands[0].reg.orig; |
2743 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
2744 | 0 | //| mov ARG2, aword WORK[cont]; |
2745 | 0 | //| mov FUNCTION, OBJECT:ARG2->st; |
2746 | 0 | //| mov FUNCTION, STABLE:FUNCTION->container_spec; |
2747 | 0 | //| test FUNCTION, FUNCTION; |
2748 | 0 | //| jnz >1; |
2749 | 0 | //| throw_adhoc "Cannot assign to an immutable value"; |
2750 | 0 | dasm_put(Dst, 2703, Dt23([cont]), DtE(->st), Dt12(->container_spec), (unsigned int)((uintptr_t)("Cannot assign to an immutable value")), (unsigned int)(((uintptr_t)("Cannot assign to an immutable value"))>>32)); |
2751 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2752 | 0 | #line 1861 "src/jit/x64/emit.dasc" |
2753 | 0 | //|1: |
2754 | 0 | //| mov ARG1, TC; |
2755 | 0 | //| mov ARG3, aword WORK[obj]; |
2756 | 0 | dasm_put(Dst, 2732, Dt23([obj])); |
2757 | 0 | #line 1864 "src/jit/x64/emit.dasc" |
2758 | 0 | if (op == MVM_OP_assign) { |
2759 | 0 | //| mov FUNCTION, CONTAINERSPEC:FUNCTION->store; |
2760 | 0 | dasm_put(Dst, 184, Dt17(->store)); |
2761 | 0 | #line 1866 "src/jit/x64/emit.dasc" |
2762 | 0 | } else { |
2763 | 0 | //| mov FUNCTION, CONTAINERSPEC:FUNCTION->store_unchecked; |
2764 | 0 | dasm_put(Dst, 184, Dt17(->store_unchecked)); |
2765 | 0 | #line 1868 "src/jit/x64/emit.dasc" |
2766 | 0 | } |
2767 | 0 | //| call FUNCTION; |
2768 | 0 | dasm_put(Dst, 2748); |
2769 | 0 | #line 1870 "src/jit/x64/emit.dasc" |
2770 | 0 | break; |
2771 | 0 | } |
2772 | 267 | case MVM_OP_getlexstatic_o: |
2773 | 267 | case MVM_OP_getlexperinvtype_o: { |
2774 | 267 | MVMint16 dst = ins->operands[0].reg.orig; |
2775 | 267 | MVMint16 name = ins->operands[1].reg.orig; |
2776 | 267 | //| mov ARG1, TC; |
2777 | 267 | //| mov ARG2, aword WORK[name]; |
2778 | 267 | //| mov ARG3, MVM_reg_obj; |
2779 | 267 | //| callp &MVM_frame_find_lexical_by_name; |
2780 | 267 | dasm_put(Dst, 2753, Dt23([name]), MVM_reg_obj); |
2781 | 267 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_find_lexical_by_name)), (MVMuint32)((uintptr_t)(&MVM_frame_find_lexical_by_name) >> 32)); |
2782 | 267 | #line 1880 "src/jit/x64/emit.dasc" |
2783 | 267 | //| test RV, RV; |
2784 | 267 | //| jz >1; |
2785 | 267 | //| mov RV, [RV]; |
2786 | 267 | //|1: |
2787 | 267 | //| mov WORK[dst], RV; |
2788 | 267 | dasm_put(Dst, 2767, Dt23([dst])); |
2789 | 267 | #line 1885 "src/jit/x64/emit.dasc" |
2790 | 267 | break; |
2791 | 267 | } |
2792 | 180 | case MVM_OP_paramnamesused: |
2793 | 180 | //| mov ARG2, TC->cur_frame; |
2794 | 180 | //| lea ARG2, FRAME:ARG2->params; |
2795 | 180 | //| mov TMP5w, word ARGCTX:ARG2->num_pos; |
2796 | 180 | //| cmp TMP5w, word ARGCTX:ARG2->arg_count; |
2797 | 180 | //| je >1; |
2798 | 180 | //| mov ARG1, TC; |
2799 | 180 | //| callp &MVM_args_assert_nameds_used; |
2800 | 180 | dasm_put(Dst, 2789, Dt22(->cur_frame), Dt2(->params), Dt3(->num_pos), Dt3(->arg_count)); |
2801 | 180 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_assert_nameds_used)), (MVMuint32)((uintptr_t)(&MVM_args_assert_nameds_used) >> 32)); |
2802 | 180 | #line 1895 "src/jit/x64/emit.dasc" |
2803 | 180 | //|1: |
2804 | 180 | dasm_put(Dst, 1409); |
2805 | 180 | #line 1896 "src/jit/x64/emit.dasc" |
2806 | 180 | break; |
2807 | 0 | case MVM_OP_assertparamcheck: { |
2808 | 0 | MVMint16 ok = ins->operands[0].reg.orig; |
2809 | 0 | //| mov TMP1, qword WORK[ok]; |
2810 | 0 | //| test TMP1, TMP1; |
2811 | 0 | //| jnz >1; |
2812 | 0 | //| mov ARG1, TC; |
2813 | 0 | //| callp &MVM_args_bind_failed; |
2814 | 0 | dasm_put(Dst, 2817, Dt23([ok])); |
2815 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_bind_failed)), (MVMuint32)((uintptr_t)(&MVM_args_bind_failed) >> 32)); |
2816 | 0 | #line 1904 "src/jit/x64/emit.dasc" |
2817 | 0 | //|1: |
2818 | 0 | dasm_put(Dst, 1409); |
2819 | 0 | #line 1905 "src/jit/x64/emit.dasc" |
2820 | 0 | break; |
2821 | 267 | } |
2822 | 0 | case MVM_OP_prof_enterspesh: |
2823 | 0 | //| mov ARG1, TC; |
2824 | 0 | //| mov ARG2, TC->cur_frame; |
2825 | 0 | //| mov ARG2, aword FRAME:ARG2->static_info; |
2826 | 0 | //| mov ARG3, aword MVM_PROFILE_ENTER_JIT; |
2827 | 0 | //| callp &MVM_profile_log_enter; |
2828 | 0 | dasm_put(Dst, 2834, Dt22(->cur_frame), Dt2(->static_info), MVM_PROFILE_ENTER_JIT); |
2829 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_profile_log_enter)), (MVMuint32)((uintptr_t)(&MVM_profile_log_enter) >> 32)); |
2830 | 0 | dasm_put(Dst, 216); |
2831 | 0 | #line 1913 "src/jit/x64/emit.dasc" |
2832 | 0 | break; |
2833 | 0 | case MVM_OP_prof_enterinline: { |
2834 | 0 | MVMint16 spesh_idx = ins->operands[0].lit_i16; |
2835 | 0 | //| mov ARG1, TC; |
2836 | 0 | //| get_spesh_slot ARG2, spesh_idx; |
2837 | 0 | //| mov ARG3, aword MVM_PROFILE_ENTER_JIT_INLINE; |
2838 | 0 | //| callp &MVM_profile_log_enter; |
2839 | 0 | dasm_put(Dst, 2852, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([spesh_idx]), MVM_PROFILE_ENTER_JIT_INLINE); |
2840 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_profile_log_enter)), (MVMuint32)((uintptr_t)(&MVM_profile_log_enter) >> 32)); |
2841 | 0 | dasm_put(Dst, 216); |
2842 | 0 | #line 1920 "src/jit/x64/emit.dasc" |
2843 | 0 | break; |
2844 | 267 | } |
2845 | 5 | case MVM_OP_getobjsc: { |
2846 | 5 | MVMint16 dst = ins->operands[0].reg.orig; |
2847 | 5 | MVMint16 obj = ins->operands[1].reg.orig; |
2848 | 5 | //| mov TMP1, aword WORK[obj]; |
2849 | 5 | //| mov TMP2d, dword COLLECTABLE:TMP1->sc_forward_u.sc.sc_idx; |
2850 | 5 | //| xor TMP3, TMP3; |
2851 | 5 | //| cmp TMP2d, 0; |
2852 | 5 | //| jle >1; |
2853 | 5 | //| mov TMP3, aword TC->instance; |
2854 | 5 | //| mov TMP3, aword MVMINSTANCE:TMP3->all_scs; |
2855 | 5 | //| mov TMP3, aword [TMP3 + TMP2d * 8]; |
2856 | 5 | //| mov TMP3, SCREFBODY:TMP3->sc; |
2857 | 5 | //|1: |
2858 | 5 | //| mov aword WORK[dst], TMP3; |
2859 | 5 | dasm_put(Dst, 2874, Dt23([obj]), Dt11(->sc_forward_u.sc.sc_idx), Dt22(->instance), DtC(->all_scs), Dt1B(->sc), Dt23([dst])); |
2860 | 5 | #line 1936 "src/jit/x64/emit.dasc" |
2861 | 5 | break; |
2862 | 267 | } |
2863 | 0 | case MVM_OP_invokewithcapture: { |
2864 | 0 | MVMint16 dest = ins->operands[0].reg.orig; |
2865 | 0 | MVMint16 code = ins->operands[1].reg.orig; |
2866 | 0 | MVMint16 capture = ins->operands[2].reg.orig; |
2867 | 0 | //| mov TMP1, aword WORK[capture]; |
2868 | 0 | dasm_put(Dst, 1528, Dt23([capture])); |
2869 | 0 | #line 1943 "src/jit/x64/emit.dasc" |
2870 | 0 | /* if (IS_CONCRETE(capture) && REPR(capture)->ID == MVM_REPR_ID_MVMCallCapture) */ |
2871 | 0 | //| test_type_object TMP1; |
2872 | 0 | //| jnz >1; |
2873 | 0 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCallCapture; |
2874 | 0 | //| je >2; |
2875 | 0 | //|1: |
2876 | 0 | dasm_put(Dst, 2915, DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture); |
2877 | 0 | #line 1949 "src/jit/x64/emit.dasc" |
2878 | 0 | /* else throw */ |
2879 | 0 | //| throw_adhoc "invokewithcapture needs a MVMCallCapture"; |
2880 | 0 | dasm_put(Dst, 306, (unsigned int)((uintptr_t)("invokewithcapture needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("invokewithcapture needs a MVMCallCapture"))>>32)); |
2881 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2882 | 0 | #line 1951 "src/jit/x64/emit.dasc" |
2883 | 0 | //|2: |
2884 | 0 | dasm_put(Dst, 316); |
2885 | 0 | #line 1952 "src/jit/x64/emit.dasc" |
2886 | 0 | /* code = MVM_frame_find_invokee(tc, code, NULL) */ |
2887 | 0 | //| mov ARG1, TC; |
2888 | 0 | //| mov ARG2, WORK[code]; |
2889 | 0 | //| xor ARG3, ARG3; |
2890 | 0 | //| callp &MVM_frame_find_invokee; |
2891 | 0 | dasm_put(Dst, 2944, Dt23([code])); |
2892 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_find_invokee)), (MVMuint32)((uintptr_t)(&MVM_frame_find_invokee) >> 32)); |
2893 | 0 | dasm_put(Dst, 216); |
2894 | 0 | #line 1957 "src/jit/x64/emit.dasc" |
2895 | 0 |
|
2896 | 0 | //| mov ARG2, RV; // ARG2 = code |
2897 | 0 | dasm_put(Dst, 2957); |
2898 | 0 | #line 1959 "src/jit/x64/emit.dasc" |
2899 | 0 | /* tc->cur_frame->return_value = &GET_REG(cur_op, 2) */ |
2900 | 0 | //| lea ARG1, WORK[dest]; // ARG1 is used as scratch space |
2901 | 0 | //| mov TMP6, aword TC->cur_frame; |
2902 | 0 | //| mov aword FRAME:TMP6->return_value, ARG1; |
2903 | 0 | dasm_put(Dst, 2961, Dt23([dest]), Dt22(->cur_frame), Dt2(->return_value)); |
2904 | 0 | #line 1963 "src/jit/x64/emit.dasc" |
2905 | 0 | /* tc->cur_frame->return_type = MVM_RETURN_OBJ */ |
2906 | 0 | //| mov byte FRAME:TMP6->return_type, MVM_RETURN_OBJ; |
2907 | 0 | dasm_put(Dst, 2974, Dt2(->return_type), MVM_RETURN_OBJ); |
2908 | 0 | #line 1965 "src/jit/x64/emit.dasc" |
2909 | 0 | /* tc->cur_frame->return_address = cur_op */ |
2910 | 0 | //| get_cur_op ARG1; |
2911 | 0 | //| mov aword FRAME:TMP6->return_address, ARG1; |
2912 | 0 | dasm_put(Dst, 2980, Dt22(->interp_cur_op), Dt2(->return_address)); |
2913 | 0 | #line 1968 "src/jit/x64/emit.dasc" |
2914 | 0 | /* STABLE(code)->invoke(tc, code, capture->body.apc->effective_callsite, |
2915 | 0 | capture->body.apc->arg) */ |
2916 | 0 | //| mov ARG1, TC; |
2917 | 0 | //| mov ARG3, WORK[capture]; |
2918 | 0 | //| mov ARG4, aword CAPTURE:ARG3->body.apc; |
2919 | 0 | //| mov ARG3, aword ARGCTX:ARG4->callsite; |
2920 | 0 | //| mov ARG4, aword ARGCTX:ARG4->args; |
2921 | 0 | //| mov FUNCTION, OBJECT:ARG2->st; |
2922 | 0 | //| mov FUNCTION, STABLE:FUNCTION->invoke; |
2923 | 0 | //| call FUNCTION; |
2924 | 0 | dasm_put(Dst, 2992, Dt23([capture]), Dt5(->body.apc), Dt3(->callsite), Dt3(->args), DtE(->st), Dt12(->invoke)); |
2925 | 0 | #line 1978 "src/jit/x64/emit.dasc" |
2926 | 0 | /* jumping out is handled by invokish */ |
2927 | 0 | break; |
2928 | 267 | } |
2929 | 78 | case MVM_OP_captureposelems: { |
2930 | 78 | MVMint16 dest = ins->operands[0].reg.orig; |
2931 | 78 | MVMint16 capture = ins->operands[1].reg.orig; |
2932 | 78 | //| mov TMP1, aword WORK[capture]; |
2933 | 78 | dasm_put(Dst, 1528, Dt23([capture])); |
2934 | 78 | #line 1985 "src/jit/x64/emit.dasc" |
2935 | 78 | /* if (IS_CONCRETE(capture) && REPR(capture)->ID == MVM_REPR_ID_MVMCallCapture) */ |
2936 | 78 | //| test_type_object TMP1; |
2937 | 78 | //| jnz >1; |
2938 | 78 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCallCapture; |
2939 | 78 | //| je >2; |
2940 | 78 | //|1: |
2941 | 78 | dasm_put(Dst, 2915, DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture); |
2942 | 78 | #line 1991 "src/jit/x64/emit.dasc" |
2943 | 78 | /* else throw */ |
2944 | 78 | //| throw_adhoc "captureposelems needs a concrete MVMCallCapture"; |
2945 | 78 | dasm_put(Dst, 306, (unsigned int)((uintptr_t)("captureposelems needs a concrete MVMCallCapture")), (unsigned int)(((uintptr_t)("captureposelems needs a concrete MVMCallCapture"))>>32)); |
2946 | 78 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2947 | 78 | #line 1993 "src/jit/x64/emit.dasc" |
2948 | 78 | //|2: |
2949 | 78 | //| mov TMP2, aword CAPTURE:TMP1->body.apc; |
2950 | 78 | //| movzx TMP2, word ARGPROCCONTEXT:TMP2->num_pos; |
2951 | 78 | //| mov WORK[dest], TMP2; |
2952 | 78 | dasm_put(Dst, 3025, Dt5(->body.apc), Dt7(->num_pos), Dt23([dest])); |
2953 | 78 | #line 1997 "src/jit/x64/emit.dasc" |
2954 | 78 | break; |
2955 | 267 | } |
2956 | 0 | case MVM_OP_captureexistsnamed: { |
2957 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
2958 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
2959 | 0 | MVMint16 name = ins->operands[2].reg.orig; |
2960 | 0 | //| mov TMP1, WORK[obj]; |
2961 | 0 | //| test_type_object TMP1; |
2962 | 0 | //| jnz >1; |
2963 | 0 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCallCapture; |
2964 | 0 | //| je >2; |
2965 | 0 | //|1: |
2966 | 0 | //| throw_adhoc "captureexistsnamed needs a MVMCallCapture"; |
2967 | 0 | dasm_put(Dst, 1028, Dt23([obj]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture, (unsigned int)((uintptr_t)("captureexistsnamed needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("captureexistsnamed needs a MVMCallCapture"))>>32)); |
2968 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
2969 | 0 | #line 2010 "src/jit/x64/emit.dasc" |
2970 | 0 | //|2: |
2971 | 0 | //| mov ARG2, CAPTURE:TMP1->body.apc; |
2972 | 0 | //| mov ARG3, WORK[name]; |
2973 | 0 | //| mov ARG1, TC; |
2974 | 0 | //| callp MVM_args_has_named; |
2975 | 0 | dasm_put(Dst, 480, Dt5(->body.apc), Dt23([name])); |
2976 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(MVM_args_has_named)), (MVMuint32)((uintptr_t)(MVM_args_has_named) >> 32)); |
2977 | 0 | #line 2015 "src/jit/x64/emit.dasc" |
2978 | 0 | //| mov WORK[dst], RV; |
2979 | 0 | dasm_put(Dst, 501, Dt23([dst])); |
2980 | 0 | #line 2016 "src/jit/x64/emit.dasc" |
2981 | 0 | break; |
2982 | 267 | } |
2983 | 0 | case MVM_OP_capturehasnameds: { |
2984 | 0 | MVMint16 dest = ins->operands[0].reg.orig; |
2985 | 0 | MVMint16 capture = ins->operands[1].reg.orig; |
2986 | 0 | //| mov TMP1, aword WORK[capture]; |
2987 | 0 | dasm_put(Dst, 1528, Dt23([capture])); |
2988 | 0 | #line 2022 "src/jit/x64/emit.dasc" |
2989 | 0 | /* if (IS_CONCRETE(capture) && REPR(capture)->ID == MVM_REPR_ID_MVMCallCapture) */ |
2990 | 0 | //| test_type_object TMP1; |
2991 | 0 | //| jnz >1; |
2992 | 0 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCallCapture; |
2993 | 0 | //| je >2; |
2994 | 0 | //|1: |
2995 | 0 | dasm_put(Dst, 2915, DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture); |
2996 | 0 | #line 2028 "src/jit/x64/emit.dasc" |
2997 | 0 | /* else throw */ |
2998 | 0 | //| throw_adhoc "capturehasnameds needs a concrete MVMCallCapture"; |
2999 | 0 | dasm_put(Dst, 306, (unsigned int)((uintptr_t)("capturehasnameds needs a concrete MVMCallCapture")), (unsigned int)(((uintptr_t)("capturehasnameds needs a concrete MVMCallCapture"))>>32)); |
3000 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
3001 | 0 | #line 2030 "src/jit/x64/emit.dasc" |
3002 | 0 | //|2: |
3003 | 0 | //| mov TMP2, CAPTURE:TMP1->body.apc; |
3004 | 0 | //| mov TMP3w, word ARGPROCCONTEXT:TMP2->num_pos; |
3005 | 0 | //| mov TMP2w, word ARGPROCCONTEXT:TMP2->arg_count; |
3006 | 0 | //| cmp TMP2w, TMP3w; |
3007 | 0 | //| setne al; |
3008 | 0 | //| movzx rax, al; |
3009 | 0 | //| mov WORK[dest], rax; |
3010 | 0 | dasm_put(Dst, 3046, Dt5(->body.apc), Dt7(->num_pos), Dt7(->arg_count), Dt23([dest])); |
3011 | 0 | #line 2038 "src/jit/x64/emit.dasc" |
3012 | 0 | break; |
3013 | 267 | } |
3014 | 0 | case MVM_OP_capturenamedshash: { |
3015 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
3016 | 0 | MVMint16 obj = ins->operands[1].reg.orig; |
3017 | 0 | //| mov TMP1, WORK[obj]; |
3018 | 0 | //| test_type_object TMP1; |
3019 | 0 | //| jnz >1; |
3020 | 0 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCallCapture; |
3021 | 0 | //| je >2; |
3022 | 0 | //|1: |
3023 | 0 | //| throw_adhoc "capturenamedshash needs a MVMCallCapture"; |
3024 | 0 | dasm_put(Dst, 1028, Dt23([obj]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCallCapture, (unsigned int)((uintptr_t)("capturenamedshash needs a MVMCallCapture")), (unsigned int)(((uintptr_t)("capturenamedshash needs a MVMCallCapture"))>>32)); |
3025 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
3026 | 0 | #line 2050 "src/jit/x64/emit.dasc" |
3027 | 0 | //|2: |
3028 | 0 | //| mov ARG2, CAPTURE:TMP1->body.apc; |
3029 | 0 | //| mov ARG1, TC; |
3030 | 0 | //| callp MVM_args_slurpy_named; |
3031 | 0 | dasm_put(Dst, 3082, Dt5(->body.apc)); |
3032 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(MVM_args_slurpy_named)), (MVMuint32)((uintptr_t)(MVM_args_slurpy_named) >> 32)); |
3033 | 0 | #line 2054 "src/jit/x64/emit.dasc" |
3034 | 0 | //| mov WORK[dst], RV; |
3035 | 0 | dasm_put(Dst, 501, Dt23([dst])); |
3036 | 0 | #line 2055 "src/jit/x64/emit.dasc" |
3037 | 0 | break; |
3038 | 267 | } |
3039 | 0 | case MVM_OP_getstdin: |
3040 | 0 | case MVM_OP_getstdout: |
3041 | 0 | case MVM_OP_getstderr: { |
3042 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
3043 | 0 | //| mov TMP3, aword TC->instance; |
3044 | 0 | dasm_put(Dst, 3099, Dt22(->instance)); |
3045 | 0 | #line 2062 "src/jit/x64/emit.dasc" |
3046 | 0 | if (ins->info->opcode == MVM_OP_getstdin) { |
3047 | 0 | //| mov TMP3, aword MVMINSTANCE:TMP3->stdin_handle; |
3048 | 0 | dasm_put(Dst, 595, DtC(->stdin_handle)); |
3049 | 0 | #line 2064 "src/jit/x64/emit.dasc" |
3050 | 0 | } else if (ins->info->opcode == MVM_OP_getstdout) { |
3051 | 0 | //| mov TMP3, aword MVMINSTANCE:TMP3->stdout_handle; |
3052 | 0 | dasm_put(Dst, 595, DtC(->stdout_handle)); |
3053 | 0 | #line 2066 "src/jit/x64/emit.dasc" |
3054 | 0 | } else if (ins->info->opcode == MVM_OP_getstderr) { |
3055 | 0 | //| mov TMP3, aword MVMINSTANCE:TMP3->stderr_handle; |
3056 | 0 | dasm_put(Dst, 595, DtC(->stderr_handle)); |
3057 | 0 | #line 2068 "src/jit/x64/emit.dasc" |
3058 | 0 | } |
3059 | 0 | //| mov aword WORK[dst], TMP3; |
3060 | 0 | dasm_put(Dst, 725, Dt23([dst])); |
3061 | 0 | #line 2070 "src/jit/x64/emit.dasc" |
3062 | 0 | break; |
3063 | 0 | } |
3064 | 386 | case MVM_OP_ordat: |
3065 | 386 | case MVM_OP_ordfirst: { |
3066 | 386 | MVMint16 dst = ins->operands[0].reg.orig; |
3067 | 386 | MVMint16 str = ins->operands[1].reg.orig; |
3068 | 386 | //| mov ARG1, TC; |
3069 | 386 | //| mov ARG2, aword WORK[str]; |
3070 | 386 | dasm_put(Dst, 2489, Dt23([str])); |
3071 | 386 | #line 2078 "src/jit/x64/emit.dasc" |
3072 | 386 | if (op == MVM_OP_ordat) { |
3073 | 2 | MVMint16 idx = ins->operands[2].reg.orig; |
3074 | 2 | //| mov ARG3, qword WORK[idx]; |
3075 | 2 | dasm_put(Dst, 734, Dt23([idx])); |
3076 | 2 | #line 2081 "src/jit/x64/emit.dasc" |
3077 | 384 | } else { |
3078 | 384 | //| mov ARG3, 0; |
3079 | 384 | dasm_put(Dst, 1718); |
3080 | 384 | #line 2083 "src/jit/x64/emit.dasc" |
3081 | 384 | } |
3082 | 386 | //| callp &MVM_string_ord_at; |
3083 | 386 | dasm_put(Dst, 208); |
3084 | 386 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_string_ord_at)), (MVMuint32)((uintptr_t)(&MVM_string_ord_at) >> 32)); |
3085 | 386 | #line 2085 "src/jit/x64/emit.dasc" |
3086 | 386 | //| mov qword WORK[dst], RV; |
3087 | 386 | dasm_put(Dst, 501, Dt23([dst])); |
3088 | 386 | #line 2086 "src/jit/x64/emit.dasc" |
3089 | 386 | break; |
3090 | 386 | } |
3091 | 6 | case MVM_OP_getcodename: { |
3092 | 6 | MVMint16 obj = ins->operands[0].reg.orig; |
3093 | 6 | MVMint16 code = ins->operands[1].reg.orig; |
3094 | 6 | //| mov TMP1, aword WORK[code]; |
3095 | 6 | //| test_type_object TMP1; |
3096 | 6 | //| jnz >1; |
3097 | 6 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCode; |
3098 | 6 | //| jne >1; |
3099 | 6 | //| mov TMP2, CODE:TMP1->body.name; |
3100 | 6 | //| mov WORK[obj], TMP2; |
3101 | 6 | //| jmp >2; |
3102 | 6 | //|1: |
3103 | 6 | //| throw_adhoc "getcodename requires a concrete object"; |
3104 | 6 | dasm_put(Dst, 3104, Dt23([code]), DtE(->header.flags), MVM_CF_TYPE_OBJECT, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCode, Dt1D(->body.name), Dt23([obj]), (unsigned int)((uintptr_t)("getcodename requires a concrete object")), (unsigned int)(((uintptr_t)("getcodename requires a concrete object"))>>32)); |
3105 | 6 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
3106 | 6 | #line 2101 "src/jit/x64/emit.dasc" |
3107 | 6 | //|2: |
3108 | 6 | dasm_put(Dst, 316); |
3109 | 6 | #line 2102 "src/jit/x64/emit.dasc" |
3110 | 6 | break; |
3111 | 386 | } |
3112 | 0 | case MVM_OP_setcodeobj: { |
3113 | 0 | MVMint16 obj = ins->operands[0].reg.orig; |
3114 | 0 | MVMint16 code = ins->operands[1].reg.orig; |
3115 | 0 | //| mov TMP1, aword WORK[obj]; |
3116 | 0 | dasm_put(Dst, 1528, Dt23([obj])); |
3117 | 0 | #line 2108 "src/jit/x64/emit.dasc" |
3118 | 0 | /* if (REPR(obj)->ID == MVM_REPR_ID_MVMCode) */ |
3119 | 0 | //| cmp_repr_id TMP1, TMP2, MVM_REPR_ID_MVMCode; |
3120 | 0 | //| je >1; |
3121 | 0 | dasm_put(Dst, 3158, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCode); |
3122 | 0 | #line 2111 "src/jit/x64/emit.dasc" |
3123 | 0 | /* else throw */ |
3124 | 0 | //| throw_adhoc "setcodeobj needs a code ref"; |
3125 | 0 | dasm_put(Dst, 306, (unsigned int)((uintptr_t)("setcodeobj needs a code ref")), (unsigned int)(((uintptr_t)("setcodeobj needs a code ref"))>>32)); |
3126 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc)), (MVMuint32)((uintptr_t)(&MVM_exception_throw_adhoc) >> 32)); |
3127 | 0 | #line 2113 "src/jit/x64/emit.dasc" |
3128 | 0 | //|1: |
3129 | 0 | //| mov TMP2, aword WORK[code]; |
3130 | 0 | //| mov aword CODE:TMP1->body.code_object, TMP2; |
3131 | 0 | dasm_put(Dst, 3175, Dt23([code]), Dt1D(->body.code_object)); |
3132 | 0 | #line 2116 "src/jit/x64/emit.dasc" |
3133 | 0 | break; |
3134 | 386 | } |
3135 | 0 | case MVM_OP_lastexpayload: { |
3136 | 0 | MVMint16 dst = ins->operands[0].reg.orig; |
3137 | 0 | //| mov TMP3, aword TC->last_payload; |
3138 | 0 | //| mov aword WORK[dst], TMP3; |
3139 | 0 | dasm_put(Dst, 3191, Dt22(->last_payload), Dt23([dst])); |
3140 | 0 | #line 2122 "src/jit/x64/emit.dasc" |
3141 | 0 | break; |
3142 | 386 | } |
3143 | 135 | case MVM_OP_param_sp: { |
3144 | 135 | MVMuint16 dst = ins->operands[0].reg.orig; |
3145 | 135 | MVMuint16 off = ins->operands[1].lit_ui16; |
3146 | 135 | //| mov ARG1, TC |
3147 | 135 | //| mov ARG2, TC:ARG1->cur_frame |
3148 | 135 | //| lea ARG2, FRAME:ARG2->params |
3149 | 135 | //| mov ARG3, off |
3150 | 135 | //| callp &MVM_args_slurpy_positional; |
3151 | 135 | dasm_put(Dst, 3200, Dt22(->cur_frame), Dt2(->params), off); |
3152 | 135 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_slurpy_positional)), (MVMuint32)((uintptr_t)(&MVM_args_slurpy_positional) >> 32)); |
3153 | 135 | #line 2132 "src/jit/x64/emit.dasc" |
3154 | 135 | //| mov qword WORK[dst], RV; |
3155 | 135 | dasm_put(Dst, 501, Dt23([dst])); |
3156 | 135 | #line 2133 "src/jit/x64/emit.dasc" |
3157 | 135 | break; |
3158 | 386 | } |
3159 | 32 | case MVM_OP_param_sn: { |
3160 | 32 | MVMuint16 dst = ins->operands[0].reg.orig; |
3161 | 32 | //| mov ARG1, TC |
3162 | 32 | //| mov ARG2, TC:ARG1->cur_frame |
3163 | 32 | //| lea ARG2, FRAME:ARG2->params |
3164 | 32 | //| callp &MVM_args_slurpy_named; |
3165 | 32 | dasm_put(Dst, 3218, Dt22(->cur_frame), Dt2(->params)); |
3166 | 32 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_args_slurpy_named)), (MVMuint32)((uintptr_t)(&MVM_args_slurpy_named) >> 32)); |
3167 | 32 | #line 2141 "src/jit/x64/emit.dasc" |
3168 | 32 | //| mov qword WORK[dst], RV; |
3169 | 32 | dasm_put(Dst, 501, Dt23([dst])); |
3170 | 32 | #line 2142 "src/jit/x64/emit.dasc" |
3171 | 32 | break; |
3172 | 386 | } |
3173 | 0 | case MVM_OP_sp_cas_o: { |
3174 | 0 | MVMint16 target = ins->operands[1].reg.orig; |
3175 | 0 | MVMint16 expected = ins->operands[2].reg.orig; |
3176 | 0 | MVMint16 value = ins->operands[3].reg.orig; |
3177 | 0 | MVMint16 result = ins->operands[0].reg.orig; |
3178 | 0 | //| mov ARG1, TC; |
3179 | 0 | //| mov ARG2, aword WORK[target]; |
3180 | 0 | //| mov ARG3, aword WORK[expected]; |
3181 | 0 | //| mov ARG4, aword WORK[value]; |
3182 | 0 | //|.if WIN32; |
3183 | 0 | //| lea TMP6, WORK[result] |
3184 | 0 | //| mov ARG5, TMP6 |
3185 | 0 | //|.else; |
3186 | 0 | //| lea ARG5, WORK[result] |
3187 | 0 | //|.endif |
3188 | 0 | //| mov FUNCTION, OBJECT:ARG2->st; |
3189 | 0 | //| mov FUNCTION, STABLE:FUNCTION->container_spec; |
3190 | 0 | //| mov FUNCTION, CONTAINERSPEC:FUNCTION->cas; |
3191 | 0 | //| call FUNCTION; |
3192 | 0 | dasm_put(Dst, 3232, Dt23([target]), Dt23([expected]), Dt23([value]), Dt23([result]), DtE(->st), Dt12(->container_spec), Dt17(->cas)); |
3193 | 0 | #line 2163 "src/jit/x64/emit.dasc" |
3194 | 0 | break; |
3195 | 386 | } |
3196 | 0 | case MVM_OP_sp_atomicload_o: { |
3197 | 0 | MVMint16 target = ins->operands[1].reg.orig; |
3198 | 0 | MVMint16 result = ins->operands[0].reg.orig; |
3199 | 0 | //| mov ARG1, TC; |
3200 | 0 | //| mov ARG2, aword WORK[target]; |
3201 | 0 | //| mov FUNCTION, OBJECT:ARG2->st; |
3202 | 0 | //| mov FUNCTION, STABLE:FUNCTION->container_spec; |
3203 | 0 | //| mov FUNCTION, CONTAINERSPEC:FUNCTION->atomic_load; |
3204 | 0 | //| call FUNCTION; |
3205 | 0 | //| mov WORK[result], RV |
3206 | 0 | dasm_put(Dst, 3269, Dt23([target]), DtE(->st), Dt12(->container_spec), Dt17(->atomic_load), Dt23([result])); |
3207 | 0 | #line 2175 "src/jit/x64/emit.dasc" |
3208 | 0 | break; |
3209 | 386 | } |
3210 | 0 | case MVM_OP_sp_atomicstore_o: { |
3211 | 0 | MVMint16 target = ins->operands[0].reg.orig; |
3212 | 0 | MVMint16 value = ins->operands[1].reg.orig; |
3213 | 0 | //| mov ARG1, TC; |
3214 | 0 | //| mov ARG2, aword WORK[target]; |
3215 | 0 | //| mov ARG3, aword WORK[value]; |
3216 | 0 | //| mov FUNCTION, OBJECT:ARG2->st; |
3217 | 0 | //| mov FUNCTION, STABLE:FUNCTION->container_spec; |
3218 | 0 | //| mov FUNCTION, CONTAINERSPEC:FUNCTION->atomic_store; |
3219 | 0 | //| call FUNCTION; |
3220 | 0 | dasm_put(Dst, 3298, Dt23([target]), Dt23([value]), DtE(->st), Dt12(->container_spec), Dt17(->atomic_store)); |
3221 | 0 | #line 2187 "src/jit/x64/emit.dasc" |
3222 | 0 | break; |
3223 | 386 | } |
3224 | 0 | default: |
3225 | 0 | MVM_panic(1, "Can't JIT opcode <%s>", ins->info->name); |
3226 | 135k | } |
3227 | 135k | } |
3228 | | |
3229 | | |
3230 | | |
3231 | | /* Call argument decoder */ |
3232 | | static void load_call_arg(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3233 | 240k | MVMJitCallArg arg) { |
3234 | 240k | switch(arg.type) { |
3235 | 77.8k | case MVM_JIT_INTERP_VAR: |
3236 | 77.8k | switch (arg.v.ivar) { |
3237 | 67.2k | case MVM_JIT_INTERP_TC: |
3238 | 67.2k | //| mov TMP6, TC; |
3239 | 67.2k | dasm_put(Dst, 3327); |
3240 | 67.2k | #line 2204 "src/jit/x64/emit.dasc" |
3241 | 67.2k | break; |
3242 | 10.2k | case MVM_JIT_INTERP_CU: |
3243 | 10.2k | //| mov TMP6, CU; |
3244 | 10.2k | dasm_put(Dst, 3332); |
3245 | 10.2k | #line 2207 "src/jit/x64/emit.dasc" |
3246 | 10.2k | break; |
3247 | 0 | case MVM_JIT_INTERP_FRAME: |
3248 | 0 | //| mov TMP6, TC->cur_frame; |
3249 | 0 | dasm_put(Dst, 169, Dt22(->cur_frame)); |
3250 | 0 | #line 2210 "src/jit/x64/emit.dasc" |
3251 | 0 | break; |
3252 | 108 | case MVM_JIT_INTERP_PARAMS: |
3253 | 108 | //| mov TMP6, TC->cur_frame; |
3254 | 108 | //| lea TMP6, FRAME:TMP6->params; |
3255 | 108 | dasm_put(Dst, 3337, Dt22(->cur_frame), Dt2(->params)); |
3256 | 108 | #line 2214 "src/jit/x64/emit.dasc" |
3257 | 108 | break; |
3258 | 302 | case MVM_JIT_INTERP_CALLER: |
3259 | 302 | //| mov TMP6, TC->cur_frame; |
3260 | 302 | //| mov TMP6, aword FRAME:TMP6->caller; |
3261 | 302 | dasm_put(Dst, 3346, Dt22(->cur_frame), Dt2(->caller)); |
3262 | 302 | #line 2218 "src/jit/x64/emit.dasc" |
3263 | 302 | break; |
3264 | 77.8k | } |
3265 | 77.8k | break; |
3266 | 84.8k | case MVM_JIT_REG_VAL: |
3267 | 84.8k | //| mov TMP6, qword WORK[arg.v.reg]; |
3268 | 84.8k | dasm_put(Dst, 3355, Dt23([arg.v.reg])); |
3269 | 84.8k | #line 2223 "src/jit/x64/emit.dasc" |
3270 | 84.8k | break; |
3271 | 452 | case MVM_JIT_REG_VAL_F: |
3272 | 452 | //| mov TMP6, qword WORK[arg.v.reg]; |
3273 | 452 | dasm_put(Dst, 3355, Dt23([arg.v.reg])); |
3274 | 452 | #line 2226 "src/jit/x64/emit.dasc" |
3275 | 452 | break; |
3276 | 9.63k | case MVM_JIT_REG_ADDR: |
3277 | 9.63k | //| lea TMP6, WORK[arg.v.reg]; |
3278 | 9.63k | dasm_put(Dst, 3360, Dt23([arg.v.reg])); |
3279 | 9.63k | #line 2229 "src/jit/x64/emit.dasc" |
3280 | 9.63k | break; |
3281 | 8.25k | case MVM_JIT_STR_IDX: |
3282 | 8.25k | //| get_string TMP6, arg.v.lit_i64; |
3283 | 8.25k | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, arg.v.lit_i64); |
3284 | 8.25k | dasm_put(Dst, 3365, Dt24(->body.strings), Dt15([arg.v.lit_i64])); |
3285 | 8.25k | #line 2232 "src/jit/x64/emit.dasc" |
3286 | 8.25k | break; |
3287 | 46.4k | case MVM_JIT_LITERAL: |
3288 | 46.4k | //| mov TMP6, arg.v.lit_i64; |
3289 | 46.4k | dasm_put(Dst, 3374, arg.v.lit_i64); |
3290 | 46.4k | #line 2235 "src/jit/x64/emit.dasc" |
3291 | 46.4k | break; |
3292 | 8 | case MVM_JIT_LITERAL_64: |
3293 | 8 | case MVM_JIT_LITERAL_PTR: |
3294 | 8 | case MVM_JIT_LITERAL_F: |
3295 | 8 | //| mov64 TMP6, arg.v.lit_i64; |
3296 | 8 | dasm_put(Dst, 3379, (unsigned int)(arg.v.lit_i64), (unsigned int)((arg.v.lit_i64)>>32)); |
3297 | 8 | #line 2240 "src/jit/x64/emit.dasc" |
3298 | 8 | break; |
3299 | 6.35k | case MVM_JIT_REG_STABLE: |
3300 | 6.35k | //| mov TMP6, qword WORK[arg.v.reg]; |
3301 | 6.35k | //| mov TMP6, OBJECT:TMP6->st; |
3302 | 6.35k | dasm_put(Dst, 233, Dt23([arg.v.reg]), DtE(->st)); |
3303 | 6.35k | #line 2244 "src/jit/x64/emit.dasc" |
3304 | 6.35k | break; |
3305 | 6.35k | case MVM_JIT_REG_OBJBODY: |
3306 | 6.35k | //| mov TMP6, qword WORK[arg.v.reg]; |
3307 | 6.35k | //| lea TMP6, STOOGE:TMP6->data; |
3308 | 6.35k | dasm_put(Dst, 3384, Dt23([arg.v.reg]), DtF(->data)); |
3309 | 6.35k | #line 2248 "src/jit/x64/emit.dasc" |
3310 | 6.35k | break; |
3311 | 1 | case MVM_JIT_REG_DYNIDX: |
3312 | 1 | //| get_cur_op TMP5; |
3313 | 1 | //| xor TMP6, TMP6; |
3314 | 1 | //| mov TMP6w, U16:TMP5[arg.v.reg]; |
3315 | 1 | //| mov TMP6, qword [WORK + TMP6*8]; |
3316 | 1 | dasm_put(Dst, 3393, Dt22(->interp_cur_op), Dt1F([arg.v.reg])); |
3317 | 1 | #line 2254 "src/jit/x64/emit.dasc" |
3318 | 1 | break; |
3319 | 0 | case MVM_JIT_DATA_LABEL: |
3320 | 0 | //| lea TMP6, [=>(arg.v.lit_i64)]; |
3321 | 0 | dasm_put(Dst, 3413, (arg.v.lit_i64)); |
3322 | 0 | #line 2257 "src/jit/x64/emit.dasc" |
3323 | 0 | break; |
3324 | 2 | case MVM_JIT_ARG_I64: |
3325 | 2 | //| mov TMP6, TC->cur_frame; |
3326 | 2 | //| mov TMP6, FRAME:TMP6->args; |
3327 | 2 | //| mov TMP6, qword REGISTER:TMP6[arg.v.lit_i64]; |
3328 | 2 | dasm_put(Dst, 3418, Dt22(->cur_frame), Dt2(->args), Dt1([arg.v.lit_i64])); |
3329 | 2 | #line 2262 "src/jit/x64/emit.dasc" |
3330 | 2 | break; |
3331 | 0 | case MVM_JIT_ARG_I64_RW: |
3332 | 0 | //| mov TMP6, TC->cur_frame; |
3333 | 0 | //| mov TMP6, FRAME:TMP6->args; |
3334 | 0 | //| lea TMP6, qword REGISTER:TMP6[arg.v.lit_i64]; |
3335 | 0 | dasm_put(Dst, 3431, Dt22(->cur_frame), Dt2(->args), Dt1([arg.v.lit_i64])); |
3336 | 0 | #line 2267 "src/jit/x64/emit.dasc" |
3337 | 0 | break; |
3338 | 1 | case MVM_JIT_ARG_PTR: |
3339 | 1 | //| mov TMP6, TC->cur_frame; |
3340 | 1 | //| mov TMP6, FRAME:TMP6->args; |
3341 | 1 | //| mov TMP6, qword REGISTER:TMP6[arg.v.lit_i64]; |
3342 | 1 | //| mov TMP6, aword STOOGE:TMP6->data; |
3343 | 1 | dasm_put(Dst, 3444, Dt22(->cur_frame), Dt2(->args), Dt1([arg.v.lit_i64]), DtF(->data)); |
3344 | 1 | #line 2273 "src/jit/x64/emit.dasc" |
3345 | 1 | break; |
3346 | 0 | case MVM_JIT_ARG_VMARRAY: |
3347 | 0 | //| mov TMP6, TC->cur_frame; |
3348 | 0 | //| mov TMP6, FRAME:TMP6->args; |
3349 | 0 | //| mov TMP6, qword REGISTER:TMP6[arg.v.lit_i64]; |
3350 | 0 | //| mov TMP6, aword VMARRAY:TMP6->body.slots; |
3351 | 0 | dasm_put(Dst, 3444, Dt22(->cur_frame), Dt2(->args), Dt1([arg.v.lit_i64]), Dt10(->body.slots)); |
3352 | 0 | #line 2279 "src/jit/x64/emit.dasc" |
3353 | 0 | break; |
3354 | 0 | case MVM_JIT_PARAM_I64: |
3355 | 0 | //| mov TMP6, qword WORK[arg.v.lit_i64]; |
3356 | 0 | dasm_put(Dst, 3355, Dt23([arg.v.lit_i64])); |
3357 | 0 | #line 2282 "src/jit/x64/emit.dasc" |
3358 | 0 | break; |
3359 | 0 | case MVM_JIT_PARAM_I64_RW: |
3360 | 0 | //| lea TMP6, qword WORK[arg.v.lit_i64]; |
3361 | 0 | dasm_put(Dst, 3360, Dt23([arg.v.lit_i64])); |
3362 | 0 | #line 2285 "src/jit/x64/emit.dasc" |
3363 | 0 | break; |
3364 | 0 | case MVM_JIT_PARAM_PTR: |
3365 | 0 | //| mov TMP6, aword WORK[arg.v.lit_i64]; |
3366 | 0 | //| mov TMP6, aword STOOGE:TMP6->data; |
3367 | 0 | dasm_put(Dst, 233, Dt23([arg.v.lit_i64]), DtF(->data)); |
3368 | 0 | #line 2289 "src/jit/x64/emit.dasc" |
3369 | 0 | break; |
3370 | 0 | case MVM_JIT_PARAM_VMARRAY: |
3371 | 0 | //| mov TMP6, aword WORK[arg.v.lit_i64]; |
3372 | 0 | //| mov TMP6, aword VMARRAY:TMP6->body.slots; |
3373 | 0 | dasm_put(Dst, 233, Dt23([arg.v.lit_i64]), Dt10(->body.slots)); |
3374 | 0 | #line 2293 "src/jit/x64/emit.dasc" |
3375 | 0 | break; |
3376 | 148 | case MVM_JIT_SPESH_SLOT_VALUE: |
3377 | 148 | //| get_spesh_slot TMP6, arg.v.lit_i64; |
3378 | 148 | dasm_put(Dst, 3418, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([arg.v.lit_i64])); |
3379 | 148 | #line 2296 "src/jit/x64/emit.dasc" |
3380 | 148 | break; |
3381 | 4 | case MVM_JIT_STACK_VALUE: |
3382 | 4 | //| mov TMP6, [rbp-(0x28+arg.v.lit_i64*8)]; |
3383 | 4 | dasm_put(Dst, 3461, -(0x28+arg.v.lit_i64*8)); |
3384 | 4 | #line 2299 "src/jit/x64/emit.dasc" |
3385 | 4 | break; |
3386 | 0 | default: |
3387 | 0 | MVM_oops(tc, "JIT: Unknown JIT argument type %d", arg.type); |
3388 | 240k | } |
3389 | 240k | } |
3390 | | |
3391 | | static void emit_gpr_arg(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3392 | 231k | MVMint32 i) { |
3393 | 231k | switch (i) { |
3394 | 67.2k | case 0: |
3395 | 67.2k | //| mov ARG1, TMP6; |
3396 | 67.2k | dasm_put(Dst, 3466); |
3397 | 67.2k | #line 2310 "src/jit/x64/emit.dasc" |
3398 | 67.2k | break; |
3399 | 62.7k | case 1: |
3400 | 62.7k | //| mov ARG2, TMP6; |
3401 | 62.7k | dasm_put(Dst, 3470); |
3402 | 62.7k | #line 2313 "src/jit/x64/emit.dasc" |
3403 | 62.7k | break; |
3404 | 45.8k | case 2: |
3405 | 45.8k | //| mov ARG3, TMP6; |
3406 | 45.8k | dasm_put(Dst, 3474); |
3407 | 45.8k | #line 2316 "src/jit/x64/emit.dasc" |
3408 | 45.8k | break; |
3409 | 31.3k | case 3: |
3410 | 31.3k | //| mov ARG4, TMP6; |
3411 | 31.3k | dasm_put(Dst, 3478); |
3412 | 31.3k | #line 2319 "src/jit/x64/emit.dasc" |
3413 | 31.3k | break; |
3414 | 67.2k | //|.if POSIX |
3415 | 15.8k | case 4: |
3416 | 15.8k | //| mov ARG5, TMP6; |
3417 | 15.8k | dasm_put(Dst, 3482); |
3418 | 15.8k | break; |
3419 | 67.2k | #line 2324 "src/jit/x64/emit.dasc" |
3420 | 8.59k | case 5: |
3421 | 8.59k | //| mov ARG6, TMP6; |
3422 | 8.59k | dasm_put(Dst, 3486); |
3423 | 8.59k | break; |
3424 | 67.2k | #line 2327 "src/jit/x64/emit.dasc" |
3425 | 67.2k | //|.endif |
3426 | 0 | default: |
3427 | 0 | MVM_oops(tc, "JIT: can't store %d arguments in GPR", i); |
3428 | 231k | } |
3429 | 231k | } |
3430 | | |
3431 | | static void emit_sse_arg(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3432 | 452 | MVMint32 i) { |
3433 | 452 | switch (i) { |
3434 | 452 | case 0: |
3435 | 452 | //| movd ARG1F, TMP6; |
3436 | 452 | dasm_put(Dst, 3490); |
3437 | 452 | #line 2338 "src/jit/x64/emit.dasc" |
3438 | 452 | break; |
3439 | 0 | case 1: |
3440 | 0 | //| movd ARG2F, TMP6; |
3441 | 0 | dasm_put(Dst, 3496); |
3442 | 0 | #line 2341 "src/jit/x64/emit.dasc" |
3443 | 0 | break; |
3444 | 0 | case 2: |
3445 | 0 | //| movd ARG3F, TMP6; |
3446 | 0 | dasm_put(Dst, 3502); |
3447 | 0 | #line 2344 "src/jit/x64/emit.dasc" |
3448 | 0 | break; |
3449 | 0 | case 3: |
3450 | 0 | //| movd ARG4F, TMP6; |
3451 | 0 | dasm_put(Dst, 3508); |
3452 | 0 | #line 2347 "src/jit/x64/emit.dasc" |
3453 | 0 | break; |
3454 | 452 | //|.if POSIX |
3455 | 0 | case 4: |
3456 | 0 | //| movd ARG5F, TMP6; |
3457 | 0 | dasm_put(Dst, 3514); |
3458 | 0 | break; |
3459 | 452 | #line 2352 "src/jit/x64/emit.dasc" |
3460 | 0 | case 5: |
3461 | 0 | //| movd ARG6F, TMP6; |
3462 | 0 | dasm_put(Dst, 3520); |
3463 | 0 | break; |
3464 | 452 | #line 2355 "src/jit/x64/emit.dasc" |
3465 | 0 | case 6: |
3466 | 0 | //| movd ARG7F, TMP6; |
3467 | 0 | dasm_put(Dst, 3527); |
3468 | 0 | break; |
3469 | 452 | #line 2358 "src/jit/x64/emit.dasc" |
3470 | 0 | case 7: |
3471 | 0 | //| movd ARG8F, TMP6; |
3472 | 0 | dasm_put(Dst, 3534); |
3473 | 0 | break; |
3474 | 452 | #line 2361 "src/jit/x64/emit.dasc" |
3475 | 452 | //|.endif |
3476 | 0 | default: |
3477 | 0 | MVM_oops(tc, "JIT: can't put %d arguments in SSE", i); |
3478 | 452 | } |
3479 | 452 | } |
3480 | | |
3481 | | static void emit_stack_arg(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3482 | 8.19k | MVMint32 arg_size, MVMint32 pos) { |
3483 | 8.19k | /* basically, stack arguments are passed in right-to-left order |
3484 | 8.19k | on both POSIX and W64 backends, it seems. Thus the most logical |
3485 | 8.19k | thing to do is to count from the stack top upwards. */ |
3486 | 8.19k | if (pos + arg_size > 160) { |
3487 | 0 | MVM_oops(tc, "JIT: trying to pass arguments " |
3488 | 0 | " in local space (stack top offset:" |
3489 | 0 | " %d, size: %d)", pos, arg_size); |
3490 | 0 | } |
3491 | 8.19k | switch(arg_size) { |
3492 | 0 | case 1: |
3493 | 0 | //| mov byte [rsp+pos], TMP6b; |
3494 | 0 | dasm_put(Dst, 3541, pos); |
3495 | 0 | #line 2380 "src/jit/x64/emit.dasc" |
3496 | 0 | break; |
3497 | 0 | case 2: |
3498 | 0 | //| mov word [rsp+pos], TMP6w; |
3499 | 0 | dasm_put(Dst, 3548, pos); |
3500 | 0 | #line 2383 "src/jit/x64/emit.dasc" |
3501 | 0 | break; |
3502 | 0 | case 4: |
3503 | 0 | //| mov dword [rsp+pos], TMP6d; |
3504 | 0 | dasm_put(Dst, 3549, pos); |
3505 | 0 | #line 2386 "src/jit/x64/emit.dasc" |
3506 | 0 | break; |
3507 | 8.19k | case 8: |
3508 | 8.19k | //| mov qword [rsp+pos], TMP6; |
3509 | 8.19k | dasm_put(Dst, 3556, pos); |
3510 | 8.19k | #line 2389 "src/jit/x64/emit.dasc" |
3511 | 8.19k | break; |
3512 | 0 | default: |
3513 | 0 | MVM_oops(tc, "JIT: can't pass arguments size %d bytes", |
3514 | 0 | arg_size); |
3515 | 8.19k | } |
3516 | 8.19k | } |
3517 | | |
3518 | | static void emit_posix_callargs(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3519 | 67.2k | MVMJitCallArg args[], MVMint32 num_args) { |
3520 | 67.2k | MVMint32 num_gpr = 0, num_fpr = 0, num_stack = 0, i; |
3521 | 67.2k | MVMJitCallArg in_gpr[6], in_fpr[8], *on_stack = NULL; |
3522 | 67.2k | if (num_args > 6) |
3523 | 6.43k | on_stack = MVM_malloc(sizeof(MVMJitCallArg) * (num_args - 6)); |
3524 | 67.2k | /* divide in gpr, fpr, stack values */ |
3525 | 307k | for (i = 0; i < num_args; i++) { |
3526 | 240k | switch (args[i].type) { |
3527 | 239k | case MVM_JIT_INTERP_VAR: |
3528 | 239k | case MVM_JIT_REG_VAL: |
3529 | 239k | case MVM_JIT_REG_ADDR: |
3530 | 239k | case MVM_JIT_REG_OBJBODY: |
3531 | 239k | case MVM_JIT_REG_STABLE: |
3532 | 239k | case MVM_JIT_REG_DYNIDX: |
3533 | 239k | case MVM_JIT_STR_IDX: |
3534 | 239k | case MVM_JIT_LITERAL: |
3535 | 239k | case MVM_JIT_LITERAL_64: |
3536 | 239k | case MVM_JIT_LITERAL_PTR: |
3537 | 239k | case MVM_JIT_DATA_LABEL: |
3538 | 239k | case MVM_JIT_ARG_I64: |
3539 | 239k | case MVM_JIT_ARG_I64_RW: |
3540 | 239k | case MVM_JIT_ARG_PTR: |
3541 | 239k | case MVM_JIT_ARG_VMARRAY: |
3542 | 239k | case MVM_JIT_PARAM_I64: |
3543 | 239k | case MVM_JIT_PARAM_I64_RW: |
3544 | 239k | case MVM_JIT_PARAM_PTR: |
3545 | 239k | case MVM_JIT_PARAM_VMARRAY: |
3546 | 239k | case MVM_JIT_SPESH_SLOT_VALUE: |
3547 | 239k | case MVM_JIT_STACK_VALUE: |
3548 | 239k | if (num_gpr < 6) { |
3549 | 231k | in_gpr[num_gpr++] = args[i]; |
3550 | 8.19k | } else { |
3551 | 8.19k | on_stack[num_stack++] = args[i]; |
3552 | 8.19k | } |
3553 | 239k | break; |
3554 | 452 | case MVM_JIT_REG_VAL_F: |
3555 | 452 | case MVM_JIT_LITERAL_F: |
3556 | 452 | if (num_fpr < 8) { |
3557 | 452 | in_fpr[num_fpr++] = args[i]; |
3558 | 0 | } else { |
3559 | 0 | on_stack[num_stack++] = args[i]; |
3560 | 0 | } |
3561 | 452 | break; |
3562 | 0 | default: |
3563 | 0 | MVM_oops(tc, "JIT: Unknown JIT argument type %d for emit_posix_callargs", args[i].type); |
3564 | 240k | } |
3565 | 240k | } |
3566 | 298k | for (i = 0; i < num_gpr; i++) { |
3567 | 231k | load_call_arg(tc, compiler, jg, in_gpr[i]); |
3568 | 231k | emit_gpr_arg(tc, compiler, jg, i); |
3569 | 231k | } |
3570 | 67.6k | for (i = 0; i < num_fpr; i++) { |
3571 | 452 | load_call_arg(tc, compiler, jg, in_fpr[i]); |
3572 | 452 | emit_sse_arg(tc, compiler, jg, i); |
3573 | 452 | } |
3574 | 67.2k | /* push right-to-left */ |
3575 | 75.4k | for (i = 0; i < num_stack; i++) { |
3576 | 8.19k | load_call_arg(tc, compiler, jg, on_stack[i]); |
3577 | 8.19k | // I'm not sure this is correct, btw |
3578 | 8.19k | emit_stack_arg(tc, compiler, jg, 8, i*8); |
3579 | 8.19k | } |
3580 | 67.2k | if (on_stack) |
3581 | 6.43k | MVM_free(on_stack); |
3582 | 67.2k | } |
3583 | | |
3584 | | static void emit_win64_callargs(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3585 | 0 | MVMJitCallArg args[], MVMint32 num_args) { |
3586 | 0 | MVMint32 i; |
3587 | 0 | MVMint32 num_reg_args = (num_args > 4 ? 4 : num_args); |
3588 | 0 | for (i = 0; i < num_reg_args; i++) { |
3589 | 0 | load_call_arg(tc, compiler, jg, args[i]); |
3590 | 0 | if (args[i].type == MVM_JIT_REG_VAL_F || |
3591 | 0 | args[i].type == MVM_JIT_LITERAL_F) { |
3592 | 0 | emit_sse_arg(tc, compiler, jg, i); |
3593 | 0 | } else { |
3594 | 0 | emit_gpr_arg(tc, compiler, jg, i); |
3595 | 0 | } |
3596 | 0 | } |
3597 | 0 | for (; i < num_args; i++) { |
3598 | 0 | load_call_arg(tc, compiler, jg, args[i]); |
3599 | 0 | emit_stack_arg(tc, compiler, jg, 8, i * 8); |
3600 | 0 | } |
3601 | 0 | } |
3602 | | |
3603 | | void MVM_jit_emit_call_c(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3604 | 67.2k | MVMJitCallC * call_spec) { |
3605 | 67.2k | |
3606 | 67.2k | MVM_jit_log(tc, "emit c call <%d args>\n", call_spec->num_args); |
3607 | 67.2k | if (call_spec->has_vargs) { |
3608 | 0 | MVM_oops(tc, "JIT can't handle varargs yet"); |
3609 | 0 | } |
3610 | 67.2k | //|.if WIN32; |
3611 | 67.2k | #line 2490 "src/jit/x64/emit.dasc" |
3612 | 67.2k | //|.else; |
3613 | 67.2k | emit_posix_callargs(tc, compiler, jg, call_spec->args, call_spec->num_args); |
3614 | 67.2k | //|.endif |
3615 | 67.2k | /* Emit the call. I think we should be able to do something smarter than |
3616 | 67.2k | * store the constant into the bytecode, like a data segment. But I'm |
3617 | 67.2k | * not sure. */ |
3618 | 67.2k | //| callp call_spec->func_ptr; |
3619 | 67.2k | dasm_put(Dst, 208); |
3620 | 67.2k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(call_spec->func_ptr)), (MVMuint32)((uintptr_t)(call_spec->func_ptr) >> 32)); |
3621 | 67.2k | dasm_put(Dst, 216); |
3622 | 67.2k | #line 2497 "src/jit/x64/emit.dasc" |
3623 | 67.2k | /* right, now determine what to do with the return value */ |
3624 | 67.2k | switch(call_spec->rv_mode) { |
3625 | 36.9k | case MVM_JIT_RV_VOID: |
3626 | 36.9k | break; |
3627 | 30.3k | case MVM_JIT_RV_INT: |
3628 | 30.3k | case MVM_JIT_RV_PTR: |
3629 | 30.3k | //| mov WORK[call_spec->rv_idx], RV; |
3630 | 30.3k | dasm_put(Dst, 506, Dt23([call_spec->rv_idx])); |
3631 | 30.3k | #line 2504 "src/jit/x64/emit.dasc" |
3632 | 30.3k | break; |
3633 | 6 | case MVM_JIT_RV_NUM: |
3634 | 6 | //| movsd qword WORK[call_spec->rv_idx], RVF; |
3635 | 6 | dasm_put(Dst, 1576, Dt23([call_spec->rv_idx])); |
3636 | 6 | #line 2507 "src/jit/x64/emit.dasc" |
3637 | 6 | break; |
3638 | 0 | case MVM_JIT_RV_DEREF: |
3639 | 0 | //| mov TMP1, [RV]; |
3640 | 0 | //| mov WORK[call_spec->rv_idx], TMP1; |
3641 | 0 | dasm_put(Dst, 3563, Dt23([call_spec->rv_idx])); |
3642 | 0 | #line 2511 "src/jit/x64/emit.dasc" |
3643 | 0 | break; |
3644 | 0 | case MVM_JIT_RV_ADDR: |
3645 | 0 | /* store local at address */ |
3646 | 0 | //| mov TMP1, WORK[call_spec->rv_idx]; |
3647 | 0 | //| mov [RV], TMP1; |
3648 | 0 | dasm_put(Dst, 3571, Dt23([call_spec->rv_idx])); |
3649 | 0 | #line 2516 "src/jit/x64/emit.dasc" |
3650 | 0 | break; |
3651 | 1 | case MVM_JIT_RV_DYNIDX: |
3652 | 1 | /* store in register relative to cur_op */ |
3653 | 1 | //| get_cur_op TMP1; |
3654 | 1 | //| xor TMP2, TMP2; |
3655 | 1 | //| mov TMP2w, word [TMP1 + call_spec->rv_idx*2]; |
3656 | 1 | //| mov aword [WORK + TMP2*8], RV; |
3657 | 1 | dasm_put(Dst, 3579, Dt22(->interp_cur_op), call_spec->rv_idx*2); |
3658 | 1 | #line 2523 "src/jit/x64/emit.dasc" |
3659 | 1 | break; |
3660 | 0 | case MVM_JIT_RV_DEREF_OR_VMNULL: |
3661 | 0 | //| test RV, RV; |
3662 | 0 | //| jz >4; |
3663 | 0 | //| mov TMP1, [RV]; |
3664 | 0 | //| jmp >5; |
3665 | 0 | //|4: |
3666 | 0 | //| get_vmnull TMP1; |
3667 | 0 | //|5: |
3668 | 0 | //| mov WORK[call_spec->rv_idx], TMP1; |
3669 | 0 | dasm_put(Dst, 3598, Dt22(->instance), DtC(->VMNull), Dt23([call_spec->rv_idx])); |
3670 | 0 | #line 2533 "src/jit/x64/emit.dasc" |
3671 | 0 | break; |
3672 | 5 | case MVM_JIT_RV_TO_STACK: |
3673 | 5 | //| mov [rbp-(0x28+call_spec->rv_idx*8)], RV; |
3674 | 5 | dasm_put(Dst, 3629, -(0x28+call_spec->rv_idx*8)); |
3675 | 5 | #line 2536 "src/jit/x64/emit.dasc" |
3676 | 5 | break; |
3677 | 67.2k | } |
3678 | 67.2k | } |
3679 | | |
3680 | | void MVM_jit_emit_block_branch(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3681 | 22.9k | MVMJitBranch * branch) { |
3682 | 22.9k | MVMSpeshIns *ins = branch->ins; |
3683 | 22.9k | MVMint32 name = branch->dest; |
3684 | 22.9k | /* move gc sync point to the front so as to not have |
3685 | 22.9k | * awkward dispatching issues */ |
3686 | 22.9k | //| gc_sync_point; |
3687 | 22.9k | dasm_put(Dst, 3634, Dt22(->gc_status)); |
3688 | 22.9k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_gc_enter_from_interrupt)), (MVMuint32)((uintptr_t)(&MVM_gc_enter_from_interrupt) >> 32)); |
3689 | 22.9k | dasm_put(Dst, 1409); |
3690 | 22.9k | #line 2547 "src/jit/x64/emit.dasc" |
3691 | 22.9k | if (ins == NULL || ins->info->opcode == MVM_OP_goto) { |
3692 | 5.61k | MVM_jit_log(tc, "emit jump to label %d\n", name); |
3693 | 5.61k | if (name == MVM_JIT_BRANCH_EXIT) { |
3694 | 0 | //| jmp ->exit |
3695 | 0 | dasm_put(Dst, 3649); |
3696 | 0 | #line 2551 "src/jit/x64/emit.dasc" |
3697 | 5.61k | } else { |
3698 | 5.61k | //| jmp =>(name) |
3699 | 5.61k | dasm_put(Dst, 3654, (name)); |
3700 | 5.61k | #line 2553 "src/jit/x64/emit.dasc" |
3701 | 5.61k | } |
3702 | 17.2k | } else { |
3703 | 17.2k | MVMint16 val = ins->operands[0].reg.orig; |
3704 | 17.2k | MVM_jit_log(tc, "emit branch <%s> to label %d\n", |
3705 | 17.2k | ins->info->name, name); |
3706 | 17.2k | switch(ins->info->opcode) { |
3707 | 4.04k | case MVM_OP_if_i: |
3708 | 4.04k | //| mov rax, WORK[val]; |
3709 | 4.04k | //| test rax, rax; |
3710 | 4.04k | //| jnz =>(name); // jump to dynamic label |
3711 | 4.04k | dasm_put(Dst, 3658, Dt23([val]), (name)); |
3712 | 4.04k | #line 2563 "src/jit/x64/emit.dasc" |
3713 | 4.04k | break; |
3714 | 8.25k | case MVM_OP_unless_i: |
3715 | 8.25k | //| mov rax, WORK[val]; |
3716 | 8.25k | //| test rax, rax; |
3717 | 8.25k | //| jz =>(name); |
3718 | 8.25k | dasm_put(Dst, 3669, Dt23([val]), (name)); |
3719 | 8.25k | #line 2568 "src/jit/x64/emit.dasc" |
3720 | 8.25k | break; |
3721 | 22 | case MVM_OP_if_n: |
3722 | 22 | //| movd xmm0, qword WORK[val]; |
3723 | 22 | //| xorpd xmm1, xmm1; // make it zero |
3724 | 22 | //| ucomisd xmm0, xmm1; |
3725 | 22 | //| jp =>(name); // is NaN? |
3726 | 22 | //| jne =>(name); // not equal to zero? we're golden |
3727 | 22 | dasm_put(Dst, 3680, Dt23([val]), (name), (name)); |
3728 | 22 | #line 2575 "src/jit/x64/emit.dasc" |
3729 | 22 | break; |
3730 | 56 | case MVM_OP_unless_n: |
3731 | 56 | //| movd xmm0, qword WORK[val]; |
3732 | 56 | //| xorpd xmm1, xmm1; // make it zero |
3733 | 56 | //| ucomisd xmm0, xmm1; |
3734 | 56 | //| jp >1; // is NaN |
3735 | 56 | //| jne >1; // is not zero |
3736 | 56 | //| jmp =>(name); // it is zero yay! |
3737 | 56 | //|1: |
3738 | 56 | dasm_put(Dst, 3701, Dt23([val]), (name)); |
3739 | 56 | #line 2584 "src/jit/x64/emit.dasc" |
3740 | 56 | break; |
3741 | 0 | case MVM_OP_if_s0: |
3742 | 0 | case MVM_OP_unless_s0: |
3743 | 0 | //| mov ARG1, TC; |
3744 | 0 | //| mov ARG2, WORK[val]; |
3745 | 0 | //| callp &MVM_coerce_istrue_s; |
3746 | 0 | dasm_put(Dst, 3729, Dt23([val])); |
3747 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_coerce_istrue_s)), (MVMuint32)((uintptr_t)(&MVM_coerce_istrue_s) >> 32)); |
3748 | 0 | #line 2590 "src/jit/x64/emit.dasc" |
3749 | 0 | //| test RV, RV; |
3750 | 0 | dasm_put(Dst, 3739); |
3751 | 0 | #line 2591 "src/jit/x64/emit.dasc" |
3752 | 0 | if (ins->info->opcode == MVM_OP_unless_s0) |
3753 | 0 | //| jz =>(name); |
3754 | 0 | dasm_put(Dst, 3676, (name)); |
3755 | 0 | #line 2593 "src/jit/x64/emit.dasc" |
3756 | 0 | else |
3757 | 0 | //| jnz =>(name); |
3758 | 0 | dasm_put(Dst, 3665, (name)); |
3759 | 0 | #line 2595 "src/jit/x64/emit.dasc" |
3760 | 0 | break; |
3761 | 4.10k | case MVM_OP_ifnonnull: |
3762 | 4.10k | //| mov TMP1, WORK[val]; |
3763 | 4.10k | //| test TMP1, TMP1; |
3764 | 4.10k | //| jz >1; |
3765 | 4.10k | //| get_vmnull TMP2; |
3766 | 4.10k | //| cmp TMP1, TMP2; |
3767 | 4.10k | //| je >1; |
3768 | 4.10k | //| jmp =>(name); |
3769 | 4.10k | //|1: |
3770 | 4.10k | dasm_put(Dst, 3748, Dt23([val]), Dt22(->instance), DtC(->VMNull), (name)); |
3771 | 4.10k | #line 2605 "src/jit/x64/emit.dasc" |
3772 | 4.10k | break; |
3773 | 153 | case MVM_OP_if_s: |
3774 | 153 | //| mov TMP1, WORK[val]; |
3775 | 153 | //| test TMP1, TMP1; |
3776 | 153 | //| jz >1; |
3777 | 153 | //| cmp dword STRING:TMP1->body.num_graphs, 0; |
3778 | 153 | //| je >1; |
3779 | 153 | //| jmp =>(name); |
3780 | 153 | //|1: |
3781 | 153 | dasm_put(Dst, 3780, Dt23([val]), Dt14(->body.num_graphs), (name)); |
3782 | 153 | #line 2614 "src/jit/x64/emit.dasc" |
3783 | 153 | break; |
3784 | 266 | case MVM_OP_unless_s: |
3785 | 266 | //| mov TMP1, WORK[val]; |
3786 | 266 | //| test TMP1, TMP1; |
3787 | 266 | //| jz =>(name); |
3788 | 266 | //| cmp dword STRING:TMP1->body.num_graphs, 0; |
3789 | 266 | //| je =>(name); |
3790 | 266 | //|1: |
3791 | 266 | dasm_put(Dst, 3805, Dt23([val]), (name), Dt14(->body.num_graphs), (name)); |
3792 | 266 | #line 2622 "src/jit/x64/emit.dasc" |
3793 | 266 | break; |
3794 | 395 | case MVM_OP_indexat: |
3795 | 395 | case MVM_OP_indexnat: { |
3796 | 395 | MVMint16 offset = ins->operands[1].reg.orig; |
3797 | 395 | MVMuint32 str_idx = ins->operands[2].lit_str_idx; |
3798 | 395 | //| mov ARG1, TC; |
3799 | 395 | //| mov ARG2, WORK[val]; |
3800 | 395 | //| mov ARG3, WORK[offset]; |
3801 | 395 | //| get_string ARG4, str_idx; |
3802 | 395 | dasm_put(Dst, 3825, Dt23([val]), Dt23([offset])); |
3803 | 395 | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, str_idx); |
3804 | 395 | #line 2631 "src/jit/x64/emit.dasc" |
3805 | 395 | //| callp &MVM_string_char_at_in_string; |
3806 | 395 | dasm_put(Dst, 3838, Dt24(->body.strings), Dt15([str_idx])); |
3807 | 395 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_string_char_at_in_string)), (MVMuint32)((uintptr_t)(&MVM_string_char_at_in_string) >> 32)); |
3808 | 395 | dasm_put(Dst, 216); |
3809 | 395 | #line 2632 "src/jit/x64/emit.dasc" |
3810 | 395 | /* This subtlety is due to the value being overloaded to |
3811 | 395 | * -2 if it is out of bounds. Note that -1 is passed as a |
3812 | 395 | * 32 bit integer, but this magically works in a 64 bit |
3813 | 395 | * comparison because 32 bit values are sign-extended */ |
3814 | 395 | //| cmp RV, -1; |
3815 | 395 | dasm_put(Dst, 3848); |
3816 | 395 | #line 2637 "src/jit/x64/emit.dasc" |
3817 | 395 | if (ins->info->opcode == MVM_OP_indexat) |
3818 | 395 | //| jle =>(name); |
3819 | 387 | dasm_put(Dst, 3855, (name)); |
3820 | 395 | #line 2639 "src/jit/x64/emit.dasc" |
3821 | 8 | else { |
3822 | 8 | |
3823 | 8 | //| jne =>(name); |
3824 | 8 | dasm_put(Dst, 3665, (name)); |
3825 | 8 | #line 2642 "src/jit/x64/emit.dasc" |
3826 | 8 | } |
3827 | 395 | break; |
3828 | 395 | } |
3829 | 0 | default: |
3830 | 0 | MVM_panic(1, "JIT: Can't handle conditional <%s>", ins->info->name); |
3831 | 17.2k | } |
3832 | 17.2k | } |
3833 | 22.9k | } |
3834 | | |
3835 | | void MVM_jit_emit_label(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3836 | 723k | MVMint32 label) { |
3837 | 723k | MVM_jit_log(tc, "Emitting label %d\n", label); |
3838 | 723k | //| =>(label): |
3839 | 723k | dasm_put(Dst, 195, (label)); |
3840 | 723k | #line 2655 "src/jit/x64/emit.dasc" |
3841 | 723k | } |
3842 | | |
3843 | 155k | void MVM_jit_emit_branch(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMint32 label) { |
3844 | 155k | //| jmp =>(label); |
3845 | 155k | dasm_put(Dst, 3654, (label)); |
3846 | 155k | #line 2659 "src/jit/x64/emit.dasc" |
3847 | 155k | } |
3848 | | |
3849 | | void MVM_jit_emit_conditional_branch(MVMThreadContext *tc, MVMJitCompiler *compiler, |
3850 | 392k | MVMint32 cond, MVMint32 label) { |
3851 | 392k | switch (cond) { |
3852 | 0 | case MVM_JIT_LT: |
3853 | 0 | //| jl =>(label); |
3854 | 0 | dasm_put(Dst, 3859, (label)); |
3855 | 0 | #line 2666 "src/jit/x64/emit.dasc" |
3856 | 0 | break; |
3857 | 0 | case MVM_JIT_LE: |
3858 | 0 | //| jle =>(label); |
3859 | 0 | dasm_put(Dst, 3855, (label)); |
3860 | 0 | #line 2669 "src/jit/x64/emit.dasc" |
3861 | 0 | break; |
3862 | 18.3k | case MVM_JIT_EQ: |
3863 | 18.3k | //| je =>(label); |
3864 | 18.3k | dasm_put(Dst, 3676, (label)); |
3865 | 18.3k | #line 2672 "src/jit/x64/emit.dasc" |
3866 | 18.3k | break; |
3867 | 634 | case MVM_JIT_NE: |
3868 | 634 | //| jne =>(label); |
3869 | 634 | dasm_put(Dst, 3665, (label)); |
3870 | 634 | #line 2675 "src/jit/x64/emit.dasc" |
3871 | 634 | break; |
3872 | 0 | case MVM_JIT_GE: |
3873 | 0 | //| jge =>(label); |
3874 | 0 | dasm_put(Dst, 3863, (label)); |
3875 | 0 | #line 2678 "src/jit/x64/emit.dasc" |
3876 | 0 | break; |
3877 | 0 | case MVM_JIT_GT: |
3878 | 0 | //| jg =>(label); |
3879 | 0 | dasm_put(Dst, 3867, (label)); |
3880 | 0 | #line 2681 "src/jit/x64/emit.dasc" |
3881 | 0 | break; |
3882 | 90.6k | case MVM_JIT_NZ: |
3883 | 90.6k | //| jnz =>(label); |
3884 | 90.6k | dasm_put(Dst, 3665, (label)); |
3885 | 90.6k | #line 2684 "src/jit/x64/emit.dasc" |
3886 | 90.6k | break; |
3887 | 282k | case MVM_JIT_ZR: |
3888 | 282k | //| jz =>(label); |
3889 | 282k | dasm_put(Dst, 3676, (label)); |
3890 | 282k | #line 2687 "src/jit/x64/emit.dasc" |
3891 | 282k | break; |
3892 | 0 | default: |
3893 | 0 | MVM_oops(tc, "this condition cannot be compiled with conditional_branch"); |
3894 | 392k | } |
3895 | 392k | } |
3896 | | |
3897 | | void MVM_jit_emit_guard(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
3898 | 36.2k | MVMJitGuard *guard) { |
3899 | 36.2k | MVMint16 op = guard->ins->info->opcode; |
3900 | 36.2k | MVMint16 obj = guard->ins->operands[0].reg.orig; |
3901 | 36.2k | MVM_jit_log(tc, "emit guard <%s>\n", guard->ins->info->name); |
3902 | 36.2k | /* load object and spesh slot value, except for those that don't need it */ |
3903 | 36.2k | //| mov TMP1, WORK[obj]; |
3904 | 36.2k | dasm_put(Dst, 1528, Dt23([obj])); |
3905 | 36.2k | #line 2700 "src/jit/x64/emit.dasc" |
3906 | 36.2k | if (op != MVM_OP_sp_guardjustconc && op != MVM_OP_sp_guardjusttype) { |
3907 | 36.2k | MVMint16 spesh_idx = guard->ins->operands[1].lit_i16; |
3908 | 36.2k | //| get_spesh_slot TMP2, spesh_idx; |
3909 | 36.2k | dasm_put(Dst, 3871, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([spesh_idx])); |
3910 | 36.2k | #line 2703 "src/jit/x64/emit.dasc" |
3911 | 36.2k | } |
3912 | 36.2k | if (op == MVM_OP_sp_guard) { |
3913 | 4 | /* object in question should just match the type, so it shouldn't |
3914 | 4 | * be zero, and the STABLE should be equal to the value in the spesh |
3915 | 4 | * slot */ |
3916 | 4 | /* check for null */ |
3917 | 4 | //| test TMP1, TMP1; |
3918 | 4 | //| jz >1; |
3919 | 4 | dasm_put(Dst, 3884); |
3920 | 4 | #line 2711 "src/jit/x64/emit.dasc" |
3921 | 4 | /* get stable and compare */ |
3922 | 4 | //| cmp TMP2, OBJECT:TMP1->st; |
3923 | 4 | //| jne >1; |
3924 | 4 | dasm_put(Dst, 3892, DtE(->st)); |
3925 | 4 | #line 2714 "src/jit/x64/emit.dasc" |
3926 | 4 | /* we're good, no need to deopt */ |
3927 | 36.2k | } else if (op == MVM_OP_sp_guardtype) { |
3928 | 2.59k | /* object in question should be a type object, so it shouldn't |
3929 | 2.59k | * be zero, should not be concrete, and the STABLE should be |
3930 | 2.59k | * equal to the value in the spesh slot */ |
3931 | 2.59k | /* check for null */ |
3932 | 2.59k | //| test TMP1, TMP1; |
3933 | 2.59k | //| jz >1; |
3934 | 2.59k | dasm_put(Dst, 3884); |
3935 | 2.59k | #line 2722 "src/jit/x64/emit.dasc" |
3936 | 2.59k | /* check if type object (not concrete) */ |
3937 | 2.59k | //| test_type_object TMP1; |
3938 | 2.59k | dasm_put(Dst, 3901, DtE(->header.flags), MVM_CF_TYPE_OBJECT); |
3939 | 2.59k | #line 2724 "src/jit/x64/emit.dasc" |
3940 | 2.59k | /* if zero, this is a concrete object, and we should deopt */ |
3941 | 2.59k | //| jz >1; |
3942 | 2.59k | dasm_put(Dst, 3170); |
3943 | 2.59k | #line 2726 "src/jit/x64/emit.dasc" |
3944 | 2.59k | /* get stable and compare */ |
3945 | 2.59k | //| cmp TMP2, OBJECT:TMP1->st; |
3946 | 2.59k | //| jne >1; |
3947 | 2.59k | dasm_put(Dst, 3892, DtE(->st)); |
3948 | 2.59k | #line 2729 "src/jit/x64/emit.dasc" |
3949 | 2.59k | /* we're good, no need to deopt */ |
3950 | 33.6k | } else if (op == MVM_OP_sp_guardconc) { |
3951 | 26.4k | /* object should be a non-null concrete (non-type) object */ |
3952 | 26.4k | //| test TMP1, TMP1; |
3953 | 26.4k | //| jz >1; |
3954 | 26.4k | dasm_put(Dst, 3884); |
3955 | 26.4k | #line 2734 "src/jit/x64/emit.dasc" |
3956 | 26.4k | /* shouldn't be type object */ |
3957 | 26.4k | //| test_type_object TMP1; |
3958 | 26.4k | //| jnz >1; |
3959 | 26.4k | dasm_put(Dst, 3908, DtE(->header.flags), MVM_CF_TYPE_OBJECT); |
3960 | 26.4k | #line 2737 "src/jit/x64/emit.dasc" |
3961 | 26.4k | /* should have our stable */ |
3962 | 26.4k | //| cmp TMP2, OBJECT:TMP1->st; |
3963 | 26.4k | //| jne >1; |
3964 | 26.4k | dasm_put(Dst, 3892, DtE(->st)); |
3965 | 26.4k | #line 2740 "src/jit/x64/emit.dasc" |
3966 | 7.20k | } else if (op == MVM_OP_sp_guardsf) { |
3967 | 7.19k | /* Should be an MVMCode */ |
3968 | 7.19k | //| cmp_repr_id TMP1, TMP3, MVM_REPR_ID_MVMCode; |
3969 | 7.19k | //| jne >1; |
3970 | 7.19k | //| cmp TMP2, CODE:TMP1->body.sf; |
3971 | 7.19k | //| jne >1; |
3972 | 7.19k | dasm_put(Dst, 3919, DtE(->st), Dt12(->REPR), Dt13(->ID), MVM_REPR_ID_MVMCode, Dt1D(->body.sf)); |
3973 | 7.19k | #line 2746 "src/jit/x64/emit.dasc" |
3974 | 9 | } else if (op == MVM_OP_sp_guardobj) { |
3975 | 2 | /* object should match that from the spesh slot */ |
3976 | 2 | //| cmp TMP2, TMP1; |
3977 | 2 | //| jne >1; |
3978 | 2 | dasm_put(Dst, 3945); |
3979 | 2 | #line 2750 "src/jit/x64/emit.dasc" |
3980 | 7 | } else if (op == MVM_OP_sp_guardnotobj) { |
3981 | 1 | /* object should not match that from the spesh slot */ |
3982 | 1 | //| cmp TMP2, TMP1; |
3983 | 1 | //| je >1; |
3984 | 1 | dasm_put(Dst, 3953); |
3985 | 1 | #line 2754 "src/jit/x64/emit.dasc" |
3986 | 6 | } else if (op == MVM_OP_sp_guardjustconc) { |
3987 | 2 | /* object should be a non-null concrete (non-type) object; |
3988 | 2 | * exact type doesn't matter */ |
3989 | 2 | //| test TMP1, TMP1; |
3990 | 2 | //| jz >1; |
3991 | 2 | dasm_put(Dst, 3884); |
3992 | 2 | #line 2759 "src/jit/x64/emit.dasc" |
3993 | 2 | /* shouldn't be type object */ |
3994 | 2 | //| test_type_object TMP1; |
3995 | 2 | //| jnz >1; |
3996 | 2 | dasm_put(Dst, 3908, DtE(->header.flags), MVM_CF_TYPE_OBJECT); |
3997 | 2 | #line 2762 "src/jit/x64/emit.dasc" |
3998 | 4 | } else if (op == MVM_OP_sp_guardjusttype) { |
3999 | 4 | /* object in question should be a type object, so it shouldn't |
4000 | 4 | * be zero, and should not be concrete */ |
4001 | 4 | /* check for null */ |
4002 | 4 | //| test TMP1, TMP1; |
4003 | 4 | //| jz >1; |
4004 | 4 | dasm_put(Dst, 3884); |
4005 | 4 | #line 2768 "src/jit/x64/emit.dasc" |
4006 | 4 | /* should be type object */ |
4007 | 4 | //| test_type_object TMP1; |
4008 | 4 | //| jz >1; |
4009 | 4 | dasm_put(Dst, 3961, DtE(->header.flags), MVM_CF_TYPE_OBJECT); |
4010 | 4 | #line 2771 "src/jit/x64/emit.dasc" |
4011 | 4 | } |
4012 | 36.2k | /* if we're here, we didn't jump to deopt, so skip it */ |
4013 | 36.2k | //| jmp >2; |
4014 | 36.2k | //|1: |
4015 | 36.2k | dasm_put(Dst, 2389); |
4016 | 36.2k | #line 2775 "src/jit/x64/emit.dasc" |
4017 | 36.2k | /* emit deopt */ |
4018 | 36.2k | //| mov ARG1, TC; |
4019 | 36.2k | //| mov ARG2, guard->deopt_offset; |
4020 | 36.2k | //| mov ARG3, guard->deopt_target; |
4021 | 36.2k | //| callp &MVM_spesh_deopt_one_direct; |
4022 | 36.2k | dasm_put(Dst, 3972, guard->deopt_offset, guard->deopt_target); |
4023 | 36.2k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_spesh_deopt_one_direct)), (MVMuint32)((uintptr_t)(&MVM_spesh_deopt_one_direct) >> 32)); |
4024 | 36.2k | dasm_put(Dst, 216); |
4025 | 36.2k | #line 2780 "src/jit/x64/emit.dasc" |
4026 | 36.2k | /* jump out */ |
4027 | 36.2k | //| jmp ->exit; |
4028 | 36.2k | //|2: |
4029 | 36.2k | dasm_put(Dst, 3986); |
4030 | 36.2k | #line 2783 "src/jit/x64/emit.dasc" |
4031 | 36.2k | } |
4032 | | |
4033 | 26.1k | void MVM_jit_emit_invoke(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, MVMJitInvoke *invoke) { |
4034 | 26.1k | MVMint16 i; |
4035 | 26.1k | MVMuint16 callsite_idx = invoke->callsite_idx; |
4036 | 26.1k | MVM_jit_log(tc, "Emit invoke (%d args)\n", invoke->arg_count); |
4037 | 26.1k | |
4038 | 26.1k | /* The return address for the interpreter */ |
4039 | 26.1k | //| get_cur_op TMP2; |
4040 | 26.1k | //| mov TMP5, TC->cur_frame; |
4041 | 26.1k | //| mov aword FRAME:TMP5->return_address, TMP2; |
4042 | 26.1k | dasm_put(Dst, 3993, Dt22(->interp_cur_op), Dt22(->cur_frame), Dt2(->return_address)); |
4043 | 26.1k | #line 2794 "src/jit/x64/emit.dasc" |
4044 | 26.1k | |
4045 | 26.1k | /* Unless it's a resolve op (in which case we delay a lot of this)... */ |
4046 | 26.1k | if (!invoke->is_resolve) { |
4047 | 26.1k | /* Store callsite in tmp6, which we use at the end of invoke */ |
4048 | 26.1k | //| mov TMP6, CU->body.callsites; |
4049 | 26.1k | //| mov TMP6, CALLSITEPTR:TMP6[callsite_idx]; |
4050 | 26.1k | dasm_put(Dst, 3365, Dt24(->body.callsites), Dt4([callsite_idx])); |
4051 | 26.1k | #line 2800 "src/jit/x64/emit.dasc" |
4052 | 26.1k | |
4053 | 26.1k | /* Store callsite in the frame. I use TMP5 as it never conflicts |
4054 | 26.1k | * with argument passing (like TMP6, but unlike other TMP regs) */ |
4055 | 26.1k | //| mov FRAME:TMP5->cur_args_callsite, TMP6; |
4056 | 26.1k | dasm_put(Dst, 4009, Dt2(->cur_args_callsite)); |
4057 | 26.1k | #line 2804 "src/jit/x64/emit.dasc" |
4058 | 26.1k | |
4059 | 26.1k | /* Setup the frame for returning to our current position */ |
4060 | 26.1k | if (sizeof(MVMReturnType) == 1) { |
4061 | 26.1k | //| mov byte FRAME:TMP5->return_type, invoke->return_type; |
4062 | 26.1k | dasm_put(Dst, 4014, Dt2(->return_type), invoke->return_type); |
4063 | 26.1k | #line 2808 "src/jit/x64/emit.dasc" |
4064 | 0 | } else { |
4065 | 0 | MVM_panic(1, "JIT: MVMReturnType has unexpected size"); |
4066 | 0 | } |
4067 | 26.1k | |
4068 | 26.1k | /* The register for our return value */ |
4069 | 26.1k | if (invoke->return_type == MVM_RETURN_VOID) { |
4070 | 531 | //| mov aword FRAME:TMP5->return_value, NULL; |
4071 | 531 | dasm_put(Dst, 4020, Dt2(->return_value), NULL); |
4072 | 531 | #line 2815 "src/jit/x64/emit.dasc" |
4073 | 25.5k | } else { |
4074 | 25.5k | //| lea TMP2, WORK[invoke->return_register]; |
4075 | 25.5k | //| mov aword FRAME:TMP5->return_value, TMP2; |
4076 | 25.5k | dasm_put(Dst, 4026, Dt23([invoke->return_register]), Dt2(->return_value)); |
4077 | 25.5k | #line 2818 "src/jit/x64/emit.dasc" |
4078 | 25.5k | } |
4079 | 26.1k | } |
4080 | 26.1k | |
4081 | 26.1k | /* Install invoke args */ |
4082 | 26.1k | //| mov TMP5, FRAME:TMP5->args; |
4083 | 26.1k | dasm_put(Dst, 184, Dt2(->args)); |
4084 | 26.1k | #line 2823 "src/jit/x64/emit.dasc" |
4085 | 80.6k | for (i = 0; i < invoke->arg_count; i++) { |
4086 | 54.5k | MVMSpeshIns *ins = invoke->arg_ins[i]; |
4087 | 54.5k | switch (ins->info->opcode) { |
4088 | 51.4k | case MVM_OP_arg_i: |
4089 | 51.4k | case MVM_OP_arg_s: |
4090 | 51.4k | case MVM_OP_arg_n: |
4091 | 51.4k | case MVM_OP_arg_o: { |
4092 | 51.4k | MVMint16 dst = ins->operands[0].lit_i16; |
4093 | 51.4k | MVMint16 src = ins->operands[1].reg.orig; |
4094 | 51.4k | //| mov TMP4, WORK[src]; |
4095 | 51.4k | //| mov REGISTER:TMP5[dst], TMP4; |
4096 | 51.4k | dasm_put(Dst, 4035, Dt23([src]), Dt1([dst])); |
4097 | 51.4k | #line 2834 "src/jit/x64/emit.dasc" |
4098 | 51.4k | break; |
4099 | 51.4k | } |
4100 | 0 | case MVM_OP_argconst_n: |
4101 | 0 | case MVM_OP_argconst_i: { |
4102 | 0 | MVMint16 dst = ins->operands[0].lit_i16; |
4103 | 0 | MVMint64 val = ins->operands[1].lit_i64; |
4104 | 0 | //| mov64 TMP4, val; |
4105 | 0 | //| mov REGISTER:TMP5[dst], TMP4; |
4106 | 0 | dasm_put(Dst, 4044, (unsigned int)(val), (unsigned int)((val)>>32), Dt1([dst])); |
4107 | 0 | #line 2842 "src/jit/x64/emit.dasc" |
4108 | 0 | break; |
4109 | 0 | } |
4110 | 3.10k | case MVM_OP_argconst_s: { |
4111 | 3.10k | MVMint16 dst = ins->operands[0].lit_i16; |
4112 | 3.10k | MVMint32 idx = ins->operands[1].lit_str_idx; |
4113 | 3.10k | //| get_string TMP4, idx; |
4114 | 3.10k | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, idx); |
4115 | 3.10k | #line 2848 "src/jit/x64/emit.dasc" |
4116 | 3.10k | //| mov REGISTER:TMP5[dst], TMP4; |
4117 | 3.10k | dasm_put(Dst, 4053, Dt24(->body.strings), Dt15([idx]), Dt1([dst])); |
4118 | 3.10k | #line 2849 "src/jit/x64/emit.dasc" |
4119 | 3.10k | break; |
4120 | 0 | } |
4121 | 0 | default: |
4122 | 0 | MVM_panic(1, "JIT invoke: Can't add arg <%s>", |
4123 | 0 | ins->info->name); |
4124 | 54.5k | } |
4125 | 54.5k | } |
4126 | 26.1k | |
4127 | 26.1k | if (invoke->is_fast) { |
4128 | 7.03k | /* call MVM_frame_invoke_code */ |
4129 | 7.03k | //| mov ARG1, TC; |
4130 | 7.03k | //| mov ARG2, WORK[invoke->code_register_or_name]; |
4131 | 7.03k | //| mov ARG3, TMP6; // this is the callsite object |
4132 | 7.03k | //| mov ARG4, invoke->spesh_cand_or_sf_slot; |
4133 | 7.03k | //| callp &MVM_frame_invoke_code; |
4134 | 7.03k | dasm_put(Dst, 4066, Dt23([invoke->code_register_or_name]), invoke->spesh_cand_or_sf_slot); |
4135 | 7.03k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_invoke_code)), (MVMuint32)((uintptr_t)(&MVM_frame_invoke_code) >> 32)); |
4136 | 7.03k | dasm_put(Dst, 216); |
4137 | 7.03k | #line 2864 "src/jit/x64/emit.dasc" |
4138 | 19.0k | } else if (invoke->is_resolve) { |
4139 | 0 | /* call MVM_spesh_plugin_resolve_jit, which will trampoline out of |
4140 | 0 | * the JIT-compiled code if need be */ |
4141 | 0 | //| mov ARG1, TC; |
4142 | 0 | //| get_string ARG2, invoke->code_register_or_name; |
4143 | 0 | dasm_put(Dst, 324); |
4144 | 0 | MVM_cu_ensure_string_decoded(tc, jg->sg->sf->body.cu, invoke->code_register_or_name); |
4145 | 0 | #line 2869 "src/jit/x64/emit.dasc" |
4146 | 0 | //| lea ARG3, WORK[invoke->return_register]; |
4147 | 0 | //| mov ARG4, invoke->resolve_offset; |
4148 | 0 | //|.if WIN32 |
4149 | 0 | //| get_spesh_slot rax, invoke->spesh_cand_or_sf_slot; |
4150 | 0 | //| mov ARG5, rax; |
4151 | 0 | //| mov rax, CU->body.callsites; |
4152 | 0 | //| mov rax, CALLSITEPTR:rax[callsite_idx]; |
4153 | 0 | //| mov ARG6, rax; |
4154 | 0 | //|.else |
4155 | 0 | //| get_spesh_slot ARG5, invoke->spesh_cand_or_sf_slot; |
4156 | 0 | //| mov ARG6, CU->body.callsites; |
4157 | 0 | //| mov ARG6, CALLSITEPTR:ARG6[callsite_idx]; |
4158 | 0 | //|.endif |
4159 | 0 | //| callp &MVM_spesh_plugin_resolve_jit; |
4160 | 0 | dasm_put(Dst, 4083, Dt24(->body.strings), Dt15([invoke->code_register_or_name]), Dt23([invoke->return_register]), invoke->resolve_offset, Dt22(->cur_frame), Dt2(->effective_spesh_slots), Dt15([invoke->spesh_cand_or_sf_slot]), Dt24(->body.callsites), Dt4([callsite_idx])); |
4161 | 0 | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_spesh_plugin_resolve_jit)), (MVMuint32)((uintptr_t)(&MVM_spesh_plugin_resolve_jit) >> 32)); |
4162 | 0 | dasm_put(Dst, 216); |
4163 | 0 | #line 2883 "src/jit/x64/emit.dasc" |
4164 | 19.0k | } else { |
4165 | 19.0k | /* first, save callsite and args */ |
4166 | 19.0k | //| mov qword [rbp-0x28], TMP5; // args |
4167 | 19.0k | //| mov qword [rbp-0x30], TMP6; // callsite |
4168 | 19.0k | dasm_put(Dst, 4121); |
4169 | 19.0k | #line 2887 "src/jit/x64/emit.dasc" |
4170 | 19.0k | /* setup call MVM_frame_multi_ok(tc, code, &cur_callsite, args); */ |
4171 | 19.0k | //| mov ARG1, TC; |
4172 | 19.0k | //| mov ARG2, WORK[invoke->code_register_or_name]; // code object |
4173 | 19.0k | //| lea ARG3, [rbp-0x30]; // &cur_callsite |
4174 | 19.0k | //| mov ARG4, TMP5; // args |
4175 | 19.0k | //| mov ARG5, 0; // NULL to &was_multi |
4176 | 19.0k | //| callp &MVM_frame_find_invokee_multi_ok; |
4177 | 19.0k | dasm_put(Dst, 4130, Dt23([invoke->code_register_or_name])); |
4178 | 19.0k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(&MVM_frame_find_invokee_multi_ok)), (MVMuint32)((uintptr_t)(&MVM_frame_find_invokee_multi_ok) >> 32)); |
4179 | 19.0k | dasm_put(Dst, 216); |
4180 | 19.0k | #line 2894 "src/jit/x64/emit.dasc" |
4181 | 19.0k | /* restore callsite, args, RV now holds code object */ |
4182 | 19.0k | //| mov TMP6, [rbp-0x30]; // callsite |
4183 | 19.0k | //| mov TMP5, [rbp-0x28]; // args |
4184 | 19.0k | dasm_put(Dst, 4154); |
4185 | 19.0k | #line 2897 "src/jit/x64/emit.dasc" |
4186 | 19.0k | /* setup args for call to invoke(tc, code, cur_callsite, args) */ |
4187 | 19.0k | //| mov ARG1, TC; |
4188 | 19.0k | //| mov ARG2, RV; // code object |
4189 | 19.0k | //| mov ARG3, TMP6; // callsite |
4190 | 19.0k | //| mov ARG4, TMP5; // args |
4191 | 19.0k | dasm_put(Dst, 4163); |
4192 | 19.0k | #line 2902 "src/jit/x64/emit.dasc" |
4193 | 19.0k | /* get the actual function */ |
4194 | 19.0k | //| mov FUNCTION, OBJECT:RV->st; |
4195 | 19.0k | //| mov FUNCTION, STABLE:FUNCTION->invoke; |
4196 | 19.0k | //| call FUNCTION; |
4197 | 19.0k | dasm_put(Dst, 4177, DtE(->st), Dt12(->invoke)); |
4198 | 19.0k | #line 2906 "src/jit/x64/emit.dasc" |
4199 | 19.0k | } |
4200 | 26.1k | } |
4201 | | |
4202 | | void MVM_jit_emit_jumplist(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitGraph *jg, |
4203 | 713 | MVMJitJumpList *jumplist) { |
4204 | 713 | MVMint32 i; |
4205 | 713 | MVM_jit_log(tc, "Emit jumplist (%"PRId64" labels)\n", jumplist->num_labels); |
4206 | 713 | //| mov TMP1, WORK[jumplist->reg]; |
4207 | 713 | //| cmp TMP1, 0; |
4208 | 713 | //| jl >2; |
4209 | 713 | //| cmp TMP1, jumplist->num_labels; |
4210 | 713 | //| jge >2; |
4211 | 713 | //| imul TMP1, 0x8; // 8 bytes per goto |
4212 | 713 | //| lea TMP2, [>1]; |
4213 | 713 | //| add TMP2, TMP1; |
4214 | 713 | //| jmp TMP2; |
4215 | 713 | //|.align 8; |
4216 | 713 | //|1: |
4217 | 713 | dasm_put(Dst, 4190, Dt23([jumplist->reg]), jumplist->num_labels); |
4218 | 713 | #line 2924 "src/jit/x64/emit.dasc" |
4219 | 6.68k | for (i = 0; i < jumplist->num_labels; i++) { |
4220 | 5.97k | //|=>(jumplist->in_labels[i]): |
4221 | 5.97k | //| jmp =>(jumplist->out_labels[i]); |
4222 | 5.97k | //|.align 8; |
4223 | 5.97k | dasm_put(Dst, 4232, (jumplist->in_labels[i]), (jumplist->out_labels[i])); |
4224 | 5.97k | #line 2928 "src/jit/x64/emit.dasc" |
4225 | 5.97k | } |
4226 | 713 | //|2: |
4227 | 713 | dasm_put(Dst, 321); |
4228 | 713 | #line 2930 "src/jit/x64/emit.dasc" |
4229 | 713 | } |
4230 | | |
4231 | | void MVM_jit_emit_control(MVMThreadContext *tc, MVMJitCompiler *compiler, |
4232 | 0 | MVMJitControl *ctrl, MVMJitTile *tile) { |
4233 | 0 | MVMJitControlType type = (tile != NULL ? tile->args[0] : ctrl->type); |
4234 | 0 | if (type == MVM_JIT_CONTROL_BREAKPOINT) { |
4235 | 0 | /* Debug breakpoint */ |
4236 | 0 | //| int 3; |
4237 | 0 | dasm_put(Dst, 4239); |
4238 | 0 | #line 2938 "src/jit/x64/emit.dasc" |
4239 | 0 | } else { |
4240 | 0 | MVM_panic(1, "Unknown control code: <%s>", ctrl->ins->info->name); |
4241 | 0 | } |
4242 | 0 | } |
4243 | | |
4244 | | |
4245 | | void MVM_jit_emit_load(MVMThreadContext *tc, MVMJitCompiler *compiler, |
4246 | | MVMint32 reg_cls, MVMint8 reg_dst, |
4247 | 470k | MVMint32 mem_cls, MVMint32 mem_src, MVMint32 size) { |
4248 | 470k | MVMint8 mem_base; |
4249 | 470k | if (mem_cls == MVM_JIT_STORAGE_LOCAL) { |
4250 | 470k | mem_base = MVM_JIT_REG(RBX); |
4251 | 0 | } else if (mem_cls == MVM_JIT_STORAGE_STACK) { |
4252 | 0 | mem_base = MVM_JIT_REG(RSP); |
4253 | 0 | } else { |
4254 | 0 | MVM_panic(1, "Cannot refer to this memory class: %d", mem_cls); |
4255 | 0 | } |
4256 | 470k | if (reg_cls == MVM_JIT_STORAGE_GPR) { |
4257 | 470k | switch(size) { |
4258 | 0 | case 1: |
4259 | 0 | //| mov Rb(reg_dst), byte [Rq(mem_base)+mem_src]; |
4260 | 0 | dasm_put(Dst, 4242, (reg_dst), (mem_base), mem_src); |
4261 | 0 | #line 2959 "src/jit/x64/emit.dasc" |
4262 | 0 | break; |
4263 | 0 | case 2: |
4264 | 0 | //| mov Rw(reg_dst), word [Rq(mem_base)+mem_src]; |
4265 | 0 | dasm_put(Dst, 4253, (reg_dst), (mem_base), mem_src); |
4266 | 0 | #line 2962 "src/jit/x64/emit.dasc" |
4267 | 0 | break; |
4268 | 0 | case 4: |
4269 | 0 | //| mov Rd(reg_dst), dword [Rq(mem_base)+mem_src]; |
4270 | 0 | dasm_put(Dst, 4254, (reg_dst), (mem_base), mem_src); |
4271 | 0 | #line 2965 "src/jit/x64/emit.dasc" |
4272 | 0 | break; |
4273 | 470k | case 8: |
4274 | 470k | //| mov Rq(reg_dst), qword [Rq(mem_base)+mem_src]; |
4275 | 470k | dasm_put(Dst, 4264, (reg_dst), (mem_base), mem_src); |
4276 | 470k | #line 2968 "src/jit/x64/emit.dasc" |
4277 | 470k | break; |
4278 | 470k | } |
4279 | 470k | } |
4280 | 470k | } |
4281 | | |
4282 | | void MVM_jit_emit_store(MVMThreadContext *tc, MVMJitCompiler *compiler, |
4283 | | MVMint32 mem_cls, MVMint32 mem_dst, |
4284 | 114k | MVMint32 reg_cls, MVMint8 reg_src, MVMint32 size) { |
4285 | 114k | |
4286 | 114k | MVMint8 mem_base; |
4287 | 114k | if (mem_cls == MVM_JIT_STORAGE_LOCAL) { |
4288 | 86.0k | mem_base = MVM_JIT_REG(RBX); |
4289 | 28.3k | } else if (mem_cls == MVM_JIT_STORAGE_STACK) { |
4290 | 28.3k | mem_base = MVM_JIT_REG(RSP); |
4291 | 0 | } else { |
4292 | 0 | MVM_panic(1, "Cannot refer to this memory class: %d", mem_cls); |
4293 | 0 | } |
4294 | 114k | if (reg_cls == MVM_JIT_STORAGE_GPR) { |
4295 | 114k | switch (size) { |
4296 | 0 | case 1: |
4297 | 0 | //| mov byte [Rq(mem_base)+mem_dst], Rb(reg_src); |
4298 | 0 | dasm_put(Dst, 4275, (reg_src), (mem_base), mem_dst); |
4299 | 0 | #line 2989 "src/jit/x64/emit.dasc" |
4300 | 0 | break; |
4301 | 0 | case 2: |
4302 | 0 | //| mov word [Rq(mem_base)+mem_dst], Rw(reg_src); |
4303 | 0 | dasm_put(Dst, 4286, (reg_src), (mem_base), mem_dst); |
4304 | 0 | #line 2992 "src/jit/x64/emit.dasc" |
4305 | 0 | break; |
4306 | 0 | case 4: |
4307 | 0 | //| mov dword [Rq(mem_base)+mem_dst], Rd(reg_src); |
4308 | 0 | dasm_put(Dst, 4287, (reg_src), (mem_base), mem_dst); |
4309 | 0 | #line 2995 "src/jit/x64/emit.dasc" |
4310 | 0 | break; |
4311 | 114k | case 8: |
4312 | 114k | //| mov qword [Rq(mem_base)+mem_dst], Rq(reg_src); |
4313 | 114k | dasm_put(Dst, 4297, (reg_src), (mem_base), mem_dst); |
4314 | 114k | #line 2998 "src/jit/x64/emit.dasc" |
4315 | 114k | break; |
4316 | 114k | } |
4317 | 114k | } |
4318 | 114k | } |
4319 | | |
4320 | | void MVM_jit_emit_copy(MVMThreadContext *tc, MVMJitCompiler *compiler, |
4321 | 1.01M | MVMint32 dst_cls, MVMint8 dst_reg, MVMint32 src_cls, MVMint8 src_reg) { |
4322 | 1.01M | if (dst_cls == src_cls) { |
4323 | 1.01M | if (dst_cls == MVM_JIT_STORAGE_GPR) { |
4324 | 1.01M | //| mov Rq(dst_reg), Rq(src_reg); |
4325 | 1.01M | dasm_put(Dst, 4308, (src_reg), (dst_reg)); |
4326 | 1.01M | #line 3008 "src/jit/x64/emit.dasc" |
4327 | 0 | } else { |
4328 | 0 | MVM_oops(tc, "numeric regs nyi"); |
4329 | 0 | } |
4330 | 0 | } else { |
4331 | 0 | MVM_oops(tc, "numeric regs nyi"); |
4332 | 0 | } |
4333 | 1.01M | } |
4334 | | |
4335 | | |
4336 | 0 | void MVM_jit_emit_marker(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMint32 num) { |
4337 | 0 | MVMint32 i; |
4338 | 0 | for (i = 0; i < num; i++) { |
4339 | 0 | //| nop; |
4340 | 0 | dasm_put(Dst, 4317); |
4341 | 0 | #line 3021 "src/jit/x64/emit.dasc" |
4342 | 0 | } |
4343 | 0 | } |
4344 | | |
4345 | | |
4346 | 0 | void MVM_jit_emit_data(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitData *data) { |
4347 | 0 | MVMuint8 *bytes = data->data; |
4348 | 0 | MVMint32 i; |
4349 | 0 | //|.data; |
4350 | 0 | dasm_put(Dst, 208); |
4351 | 0 | #line 3029 "src/jit/x64/emit.dasc" |
4352 | 0 | //|=>(data->label): |
4353 | 0 | dasm_put(Dst, 195, (data->label)); |
4354 | 0 | #line 3030 "src/jit/x64/emit.dasc" |
4355 | 0 | for (i = 0; i < data->size; i++) { |
4356 | 0 | //|.byte bytes[i]; |
4357 | 0 | dasm_put(Dst, 2978, bytes[i]); |
4358 | 0 | #line 3032 "src/jit/x64/emit.dasc" |
4359 | 0 | } |
4360 | 0 | //|.code |
4361 | 0 | dasm_put(Dst, 0); |
4362 | 0 | #line 3034 "src/jit/x64/emit.dasc" |
4363 | 0 | } |
4364 | | |
4365 | | /* import tiles */ |
4366 | | //|.include src/jit/x64/tiles.dasc |
4367 | | #line 1 "src/jit/x64/tiles.dasc" |
4368 | | /* -*-C-*- */ |
4369 | | #include "tile_decl.h" |
4370 | | |
4371 | | /* NB: The rax/eax/ax/al/ah register is *reserved* for internal use in tiles by |
4372 | | * the register allocator. Using rax will never overwrite an allocated value */ |
4373 | | |
4374 | | /* basic memory traffic tiles */ |
4375 | 206k | MVM_JIT_TILE_DECL(addr) { |
4376 | 206k | MVMint8 out = tile->values[0]; |
4377 | 206k | MVMint8 base = tile->values[1]; |
4378 | 206k | MVMint32 ofs = tile->args[0]; |
4379 | 206k | //| lea Rq(out), [Rq(base)+ofs]; |
4380 | 206k | dasm_put(Dst, 4319, (out), (base), ofs); |
4381 | 206k | #line 13 "src/jit/x64/tiles.dasc" |
4382 | 206k | } |
4383 | | |
4384 | | |
4385 | 0 | MVM_JIT_TILE_DECL(idx) { |
4386 | 0 | MVMint8 out = tile->values[0]; |
4387 | 0 | MVMint8 base = tile->values[1]; |
4388 | 0 | MVMint8 idx = tile->values[2]; |
4389 | 0 | MVMint8 scl = tile->args[0]; |
4390 | 0 | if (scl == 8) { |
4391 | 0 | //| lea Rq(out), [Rq(base)+Rq(idx)*8]; |
4392 | 0 | dasm_put(Dst, 4330, (out), (idx), (base), 0); |
4393 | 0 | #line 23 "src/jit/x64/tiles.dasc" |
4394 | 0 | } else { |
4395 | 0 | MVM_oops(tc, "Scales other than 8 NYI\n"); |
4396 | 0 | } |
4397 | 0 | } |
4398 | | |
4399 | | |
4400 | 312k | MVM_JIT_TILE_DECL(const_reg) { |
4401 | 312k | MVMint8 out = tile->values[0]; |
4402 | 312k | MVMint64 val = tile->args[0]; |
4403 | 312k | MVMint32 size = tile->args[1]; |
4404 | 312k | if (size == 8 && !fits_in_32_bit(val)) { |
4405 | 816 | //| mov64 Rq(out), val; |
4406 | 816 | dasm_put(Dst, 4344, (out), (unsigned int)(val), (unsigned int)((val)>>32)); |
4407 | 816 | #line 35 "src/jit/x64/tiles.dasc" |
4408 | 311k | } else { |
4409 | 311k | //| mov Rq(out), val; |
4410 | 311k | dasm_put(Dst, 4352, (out), val); |
4411 | 311k | #line 37 "src/jit/x64/tiles.dasc" |
4412 | 311k | } |
4413 | 312k | } |
4414 | | |
4415 | | |
4416 | 25.0k | MVM_JIT_TILE_DECL(load_reg) { |
4417 | 25.0k | MVMint8 out = tile->values[0]; |
4418 | 25.0k | MVMint8 base = tile->values[1]; |
4419 | 25.0k | MVMint32 size = tile->args[0]; |
4420 | 25.0k | switch (size) { |
4421 | 0 | case 1: |
4422 | 0 | //| mov Rb(out), [Rq(base)]; |
4423 | 0 | dasm_put(Dst, 4360, (out), (base), 0); |
4424 | 0 | #line 48 "src/jit/x64/tiles.dasc" |
4425 | 0 | break; |
4426 | 0 | case 2: |
4427 | 0 | //| mov Rw(out), [Rq(base)]; |
4428 | 0 | dasm_put(Dst, 4253, (out), (base), 0); |
4429 | 0 | #line 51 "src/jit/x64/tiles.dasc" |
4430 | 0 | break; |
4431 | 0 | case 4: |
4432 | 0 | //| mov Rd(out), [Rq(base)]; |
4433 | 0 | dasm_put(Dst, 4254, (out), (base), 0); |
4434 | 0 | #line 54 "src/jit/x64/tiles.dasc" |
4435 | 0 | break; |
4436 | 25.0k | case 8: |
4437 | 25.0k | //| mov Rq(out), [Rq(base)]; |
4438 | 25.0k | dasm_put(Dst, 4264, (out), (base), 0); |
4439 | 25.0k | #line 57 "src/jit/x64/tiles.dasc" |
4440 | 25.0k | break; |
4441 | 0 | default: |
4442 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4443 | 25.0k | } |
4444 | 25.0k | } |
4445 | | |
4446 | 1.19M | MVM_JIT_TILE_DECL(load_addr) { |
4447 | 1.19M | MVMint8 out = tile->values[0]; |
4448 | 1.19M | MVMint8 base = tile->values[1]; |
4449 | 1.19M | MVMint32 ofs = tile->args[0]; |
4450 | 1.19M | MVMint32 size = tile->args[1]; |
4451 | 1.19M | switch (tile->args[1]) { |
4452 | 0 | case 1: |
4453 | 0 | //| mov Rb(out), byte [Rq(base)+ofs]; |
4454 | 0 | dasm_put(Dst, 4242, (out), (base), ofs); |
4455 | 0 | #line 71 "src/jit/x64/tiles.dasc" |
4456 | 0 | break; |
4457 | 0 | case 2: |
4458 | 0 | //| mov Rw(out), word [Rq(base)+ofs]; |
4459 | 0 | dasm_put(Dst, 4253, (out), (base), ofs); |
4460 | 0 | #line 74 "src/jit/x64/tiles.dasc" |
4461 | 0 | break; |
4462 | 6.42k | case 4: |
4463 | 6.42k | //| mov Rd(out), dword [Rq(base)+ofs]; |
4464 | 6.42k | dasm_put(Dst, 4254, (out), (base), ofs); |
4465 | 6.42k | #line 77 "src/jit/x64/tiles.dasc" |
4466 | 6.42k | break; |
4467 | 1.18M | case 8: |
4468 | 1.18M | //| mov Rq(out), qword [Rq(base)+ofs]; |
4469 | 1.18M | dasm_put(Dst, 4264, (out), (base), ofs); |
4470 | 1.18M | #line 80 "src/jit/x64/tiles.dasc" |
4471 | 1.18M | break; |
4472 | 0 | default: |
4473 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4474 | 1.19M | } |
4475 | 1.19M | } |
4476 | | |
4477 | 113k | MVM_JIT_TILE_DECL(load_idx) { |
4478 | 113k | MVMint8 out = tile->values[0]; |
4479 | 113k | MVMint8 base = tile->values[1]; |
4480 | 113k | MVMint8 idx = tile->values[2]; |
4481 | 113k | MVMint8 scl = tile->args[0]; |
4482 | 113k | MVMint32 size = tile->args[1]; |
4483 | 113k | if (scl != 8) { |
4484 | 0 | MVM_oops(tc, "Unsupported scale size: %d\n", scl); |
4485 | 0 | } |
4486 | 113k | switch (size) { |
4487 | 0 | case 1: |
4488 | 0 | //| mov Rb(out), byte [Rq(base)+Rq(idx)*8]; |
4489 | 0 | dasm_put(Dst, 4370, (out), (idx), (base), 0); |
4490 | 0 | #line 98 "src/jit/x64/tiles.dasc" |
4491 | 0 | break; |
4492 | 0 | case 2: |
4493 | 0 | //| mov Rw(out), word [Rq(base)+Rq(idx)*8]; |
4494 | 0 | dasm_put(Dst, 4384, (out), (idx), (base), 0); |
4495 | 0 | #line 101 "src/jit/x64/tiles.dasc" |
4496 | 0 | break; |
4497 | 0 | case 4: |
4498 | 0 | //| mov Rd(out), dword [Rq(base)+Rq(idx)*8]; |
4499 | 0 | dasm_put(Dst, 4385, (out), (idx), (base), 0); |
4500 | 0 | #line 104 "src/jit/x64/tiles.dasc" |
4501 | 0 | break; |
4502 | 113k | case 8: |
4503 | 113k | //| mov Rq(out), qword [Rq(base)+Rq(idx)*8]; |
4504 | 113k | dasm_put(Dst, 4398, (out), (idx), (base), 0); |
4505 | 113k | #line 107 "src/jit/x64/tiles.dasc" |
4506 | 113k | break; |
4507 | 0 | default: |
4508 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4509 | 113k | } |
4510 | 113k | } |
4511 | | |
4512 | | |
4513 | 28.5k | MVM_JIT_TILE_DECL(store) { |
4514 | 28.5k | MVMint8 base = tile->values[1]; |
4515 | 28.5k | MVMint8 value = tile->values[2]; |
4516 | 28.5k | MVMint32 size = tile->args[0]; |
4517 | 28.5k | switch (size) { |
4518 | 0 | case 1: |
4519 | 0 | //| mov byte [Rq(base)], Rb(value); |
4520 | 0 | dasm_put(Dst, 4275, (value), (base), 0); |
4521 | 0 | #line 121 "src/jit/x64/tiles.dasc" |
4522 | 0 | break; |
4523 | 0 | case 2: |
4524 | 0 | //| mov word [Rq(base)], Rw(value); |
4525 | 0 | dasm_put(Dst, 4286, (value), (base), 0); |
4526 | 0 | #line 124 "src/jit/x64/tiles.dasc" |
4527 | 0 | break; |
4528 | 0 | case 4: |
4529 | 0 | //| mov dword [Rq(base)], Rd(value); |
4530 | 0 | dasm_put(Dst, 4287, (value), (base), 0); |
4531 | 0 | #line 127 "src/jit/x64/tiles.dasc" |
4532 | 0 | break; |
4533 | 28.5k | case 8: |
4534 | 28.5k | //| mov qword [Rq(base)], Rq(value); |
4535 | 28.5k | dasm_put(Dst, 4297, (value), (base), 0); |
4536 | 28.5k | #line 130 "src/jit/x64/tiles.dasc" |
4537 | 28.5k | break; |
4538 | 0 | default: |
4539 | 0 | MVM_oops(tc, "Unsupported store size: %d\n", size); |
4540 | 28.5k | } |
4541 | 28.5k | } |
4542 | | |
4543 | 479k | MVM_JIT_TILE_DECL(store_addr) { |
4544 | 479k | MVMint8 base = tile->values[1]; |
4545 | 479k | MVMint8 value = tile->values[2]; |
4546 | 479k | MVMint32 ofs = tile->args[0]; |
4547 | 479k | MVMint32 size = tile->args[1]; |
4548 | 479k | switch (size) { |
4549 | 0 | case 1: |
4550 | 0 | //| mov byte [Rq(base)+ofs], Rb(value); |
4551 | 0 | dasm_put(Dst, 4275, (value), (base), ofs); |
4552 | 0 | #line 144 "src/jit/x64/tiles.dasc" |
4553 | 0 | break; |
4554 | 5.79k | case 2: |
4555 | 5.79k | //| mov word [Rq(base)+ofs], Rw(value); |
4556 | 5.79k | dasm_put(Dst, 4286, (value), (base), ofs); |
4557 | 5.79k | #line 147 "src/jit/x64/tiles.dasc" |
4558 | 5.79k | break; |
4559 | 5.79k | case 4: |
4560 | 5.79k | //| mov dword [Rq(base)+ofs], Rd(value); |
4561 | 5.79k | dasm_put(Dst, 4287, (value), (base), ofs); |
4562 | 5.79k | #line 150 "src/jit/x64/tiles.dasc" |
4563 | 5.79k | break; |
4564 | 467k | case 8: |
4565 | 467k | //| mov qword [Rq(base)+ofs], Rq(value); |
4566 | 467k | dasm_put(Dst, 4297, (value), (base), ofs); |
4567 | 467k | #line 153 "src/jit/x64/tiles.dasc" |
4568 | 467k | break; |
4569 | 0 | default: |
4570 | 0 | MVM_oops(tc, "Unsupported store size: %d\n", size); |
4571 | 479k | } |
4572 | 479k | } |
4573 | | |
4574 | 0 | MVM_JIT_TILE_DECL(store_idx) { |
4575 | 0 | MVMint8 base = tile->values[1]; |
4576 | 0 | MVMint8 idx = tile->values[2]; |
4577 | 0 | MVMint8 scl = tile->args[0]; |
4578 | 0 | MVMint32 size = tile->args[1]; |
4579 | 0 | MVMint8 value = tile->values[3]; |
4580 | 0 | if (scl != 8) |
4581 | 0 | MVM_oops(tc, "Scale %d NYI\n", scl); |
4582 | 0 | switch (size) { |
4583 | 0 | case 1: |
4584 | 0 | //| mov byte [Rq(base)+Rq(idx)*8], Rb(value); |
4585 | 0 | dasm_put(Dst, 4412, (value), (idx), (base), 0); |
4586 | 0 | #line 170 "src/jit/x64/tiles.dasc" |
4587 | 0 | break; |
4588 | 0 | case 2: |
4589 | 0 | //| mov word [Rq(base)+Rq(idx)*8], Rw(value); |
4590 | 0 | dasm_put(Dst, 4426, (value), (idx), (base), 0); |
4591 | 0 | #line 173 "src/jit/x64/tiles.dasc" |
4592 | 0 | break; |
4593 | 0 | case 4: |
4594 | 0 | //| mov dword [Rq(base)+Rq(idx)*8], Rd(value); |
4595 | 0 | dasm_put(Dst, 4427, (value), (idx), (base), 0); |
4596 | 0 | #line 176 "src/jit/x64/tiles.dasc" |
4597 | 0 | break; |
4598 | 0 | case 8: |
4599 | 0 | //| mov qword [Rq(base)+Rq(idx)*8], Rq(value); |
4600 | 0 | dasm_put(Dst, 4440, (value), (idx), (base), 0); |
4601 | 0 | #line 179 "src/jit/x64/tiles.dasc" |
4602 | 0 | break; |
4603 | 0 | default: |
4604 | 0 | MVM_oops(tc, "Unsupported store size: %d\n", size); |
4605 | 0 | } |
4606 | 0 | } |
4607 | | |
4608 | | |
4609 | 5.13k | MVM_JIT_TILE_DECL(cast) { |
4610 | 5.13k | MVMint32 to_size = tile->args[0]; |
4611 | 5.13k | MVMint32 from_size = tile->args[1]; |
4612 | 5.13k | MVMint32 is_signed = tile->args[2]; |
4613 | 5.13k | |
4614 | 5.13k | MVMint8 to_reg = tile->values[0]; |
4615 | 5.13k | MVMint8 from_reg = tile->values[1]; |
4616 | 5.13k | |
4617 | 5.13k | /* possible combinations: 1 -> 2, 4, 8; 2 -> 4, 8; 4 -> 8 |
4618 | 5.13k | * Hence we can combine from_size | (to_size << 3) to get |
4619 | 5.13k | * the following options: |
4620 | 5.13k | * 1 + 2<<3 == 17 |
4621 | 5.13k | * 1 + 4<<3 == 33 |
4622 | 5.13k | * 1 + 8<<3 == 65 |
4623 | 5.13k | * 2 + 4<<3 == 34 |
4624 | 5.13k | * 2 + 8<<3 == 66 |
4625 | 5.13k | * 4 + 8<<3 == 68 |
4626 | 5.13k | */ |
4627 | 5.13k | MVMint32 size_conv = (from_size) | (to_size << 3); |
4628 | 5.13k | if (is_signed == MVM_JIT_SIGNED) { |
4629 | 5.13k | switch (size_conv) { |
4630 | 0 | case 17: |
4631 | 0 | //| movsx Rw(to_reg), Rb(from_reg); |
4632 | 0 | dasm_put(Dst, 4454, (to_reg), (from_reg)); |
4633 | 0 | #line 209 "src/jit/x64/tiles.dasc" |
4634 | 0 | break; |
4635 | 0 | case 33: |
4636 | 0 | //| movsx Rd(to_reg), Rb(from_reg); |
4637 | 0 | dasm_put(Dst, 4455, (to_reg), (from_reg)); |
4638 | 0 | #line 212 "src/jit/x64/tiles.dasc" |
4639 | 0 | break; |
4640 | 0 | case 34: |
4641 | 0 | //| movsx Rd(to_reg), Rw(from_reg); |
4642 | 0 | dasm_put(Dst, 4465, (to_reg), (from_reg)); |
4643 | 0 | #line 215 "src/jit/x64/tiles.dasc" |
4644 | 0 | break; |
4645 | 0 | case 65: |
4646 | 0 | //| movsx Rq(to_reg), Rb(from_reg); |
4647 | 0 | dasm_put(Dst, 4474, (to_reg), (from_reg)); |
4648 | 0 | #line 218 "src/jit/x64/tiles.dasc" |
4649 | 0 | break; |
4650 | 5.13k | case 66: |
4651 | 5.13k | //| movsx Rq(to_reg), Rw(from_reg); |
4652 | 5.13k | dasm_put(Dst, 4484, (to_reg), (from_reg)); |
4653 | 5.13k | #line 221 "src/jit/x64/tiles.dasc" |
4654 | 5.13k | break; |
4655 | 0 | case 68: |
4656 | 0 | /* movsx is apparantly not defined for double-to-quadword conversions, |
4657 | 0 | * which forces us to use the rax register like it's 1978. It might be easier |
4658 | 0 | * to bithack the sign-extension manually, but I'm not sure how.. */ |
4659 | 0 | //| mov eax, Rd(from_reg); |
4660 | 0 | //| cdqe; |
4661 | 0 | //| mov Rq(to_reg), rax; |
4662 | 0 | dasm_put(Dst, 4494, (from_reg), (to_reg)); |
4663 | 0 | #line 229 "src/jit/x64/tiles.dasc" |
4664 | 0 | break; |
4665 | 0 | default: |
4666 | 0 | MVM_oops(tc, "Unsupported signed cast %d -> %d\n", from_size, to_size); |
4667 | 5.13k | } |
4668 | 0 | } else { |
4669 | 0 | switch (size_conv) { |
4670 | 0 | case 17: |
4671 | 0 | //| movzx Rw(to_reg), Rb(from_reg); |
4672 | 0 | dasm_put(Dst, 4508, (to_reg), (from_reg)); |
4673 | 0 | #line 237 "src/jit/x64/tiles.dasc" |
4674 | 0 | break; |
4675 | 0 | case 33: |
4676 | 0 | //| movzx Rd(to_reg), Rb(from_reg); |
4677 | 0 | dasm_put(Dst, 4509, (to_reg), (from_reg)); |
4678 | 0 | #line 240 "src/jit/x64/tiles.dasc" |
4679 | 0 | break; |
4680 | 0 | case 34: |
4681 | 0 | //| movzx Rd(to_reg), Rw(from_reg); |
4682 | 0 | dasm_put(Dst, 4519, (to_reg), (from_reg)); |
4683 | 0 | #line 243 "src/jit/x64/tiles.dasc" |
4684 | 0 | break; |
4685 | 0 | case 65: |
4686 | 0 | //| movzx Rq(to_reg), Rb(from_reg); |
4687 | 0 | dasm_put(Dst, 4528, (to_reg), (from_reg)); |
4688 | 0 | #line 246 "src/jit/x64/tiles.dasc" |
4689 | 0 | break; |
4690 | 0 | case 66: |
4691 | 0 | //| movzx Rq(to_reg), Rw(from_reg); |
4692 | 0 | dasm_put(Dst, 4538, (to_reg), (from_reg)); |
4693 | 0 | #line 249 "src/jit/x64/tiles.dasc" |
4694 | 0 | break; |
4695 | 0 | case 68: |
4696 | 0 | /* In contrast, nothing special is necessary to cast unsigned |
4697 | 0 | * doublewords to quadwords, because using the lower 4 bytes |
4698 | 0 | * automatically clears the upper 4 */ |
4699 | 0 | //| mov Rd(to_reg), Rd(from_reg); |
4700 | 0 | dasm_put(Dst, 4548, (from_reg), (to_reg)); |
4701 | 0 | #line 255 "src/jit/x64/tiles.dasc" |
4702 | 0 | break; |
4703 | 0 | default: |
4704 | 0 | MVM_oops(tc, "Unsupported unsigned cast %d -> %d\n", from_size, to_size); |
4705 | 0 | } |
4706 | 0 | } |
4707 | 5.13k | } |
4708 | | |
4709 | | |
4710 | 0 | MVM_JIT_TILE_DECL(cast_load_addr) { |
4711 | 0 | MVM_oops(tc, "NYI"); |
4712 | 0 | } |
4713 | | |
4714 | | /* binary operations have special requirements because x86 is two-operand form, e.g: |
4715 | | * r0 = r0 <op> r1 |
4716 | | * whereas the JIT uses a three-operand model: |
4717 | | * r0 = r1 <op> r2 */ |
4718 | | |
4719 | 9.36k | static void ensure_two_operand_pre(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitTile *tile, MVMint8 reg[2]) { |
4720 | 9.36k | MVMint8 out = tile->values[0], in1 = tile->values[1], in2 = tile->values[2]; |
4721 | 9.36k | if (out == in1) { |
4722 | 0 | reg[0] = in1; |
4723 | 0 | reg[1] = in2; |
4724 | 9.36k | } else if (out == in2) { |
4725 | 0 | if (MVM_jit_expr_op_is_binary_noncommutative(tc, tile->op)) { |
4726 | 0 | //| mov rax, Rq(in1); |
4727 | 0 | dasm_put(Dst, 4556, (in1)); |
4728 | 0 | #line 280 "src/jit/x64/tiles.dasc" |
4729 | 0 | reg[0] = MVM_JIT_ARCH_X64_RAX; |
4730 | 0 | reg[1] = in2; |
4731 | 0 | } else { |
4732 | 0 | /* in this case, r2 <op> r1 == r0 <op> r1 */ |
4733 | 0 | reg[0] = out; |
4734 | 0 | reg[1] = in1; |
4735 | 0 | } |
4736 | 9.36k | } else { |
4737 | 9.36k | /* insert a copy */ |
4738 | 9.36k | //| mov Rq(out), Rq(in1); |
4739 | 9.36k | dasm_put(Dst, 4308, (in1), (out)); |
4740 | 9.36k | #line 290 "src/jit/x64/tiles.dasc" |
4741 | 9.36k | /* use r0, r2 */ |
4742 | 9.36k | reg[0] = out; |
4743 | 9.36k | reg[1] = in2; |
4744 | 9.36k | } |
4745 | 9.36k | } |
4746 | | |
4747 | 9.36k | static void ensure_two_operand_post(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitTile *tile, MVMint8 reg[2]) { |
4748 | 9.36k | MVMint8 out = tile->values[0]; |
4749 | 9.36k | if (out != reg[0]) { |
4750 | 0 | /* insert a copy afterwards */ |
4751 | 0 | //| mov Rq(out), Rq(reg[0]); |
4752 | 0 | dasm_put(Dst, 4308, (reg[0]), (out)); |
4753 | 0 | #line 301 "src/jit/x64/tiles.dasc" |
4754 | 0 | } |
4755 | 9.36k | } |
4756 | | |
4757 | | |
4758 | 2.34k | MVM_JIT_TILE_DECL(add_reg) { |
4759 | 2.34k | MVMint8 reg[2]; |
4760 | 2.34k | ensure_two_operand_pre(tc, compiler, tile, reg); |
4761 | 2.34k | //| add Rq(reg[0]), Rq(reg[1]); |
4762 | 2.34k | dasm_put(Dst, 4563, (reg[1]), (reg[0])); |
4763 | 2.34k | #line 309 "src/jit/x64/tiles.dasc" |
4764 | 2.34k | ensure_two_operand_post(tc, compiler, tile, reg); |
4765 | 2.34k | } |
4766 | | |
4767 | 41.4k | MVM_JIT_TILE_DECL(add_const) { |
4768 | 41.4k | MVMint8 out = tile->values[0]; |
4769 | 41.4k | MVMint8 in1 = tile->values[1]; |
4770 | 41.4k | MVMint64 val = tile->args[0]; |
4771 | 41.4k | MVMint32 sz = tile->args[1]; |
4772 | 41.4k | if (out == in1) { |
4773 | 1 | if (sz == 8 && !fits_in_32_bit(val)) { |
4774 | 0 | //| mov64 rax, val; |
4775 | 0 | //| add Rq(out), rax; |
4776 | 0 | dasm_put(Dst, 4572, (unsigned int)(val), (unsigned int)((val)>>32), (out)); |
4777 | 0 | #line 321 "src/jit/x64/tiles.dasc" |
4778 | 1 | } else { |
4779 | 1 | //| add Rq(in1), val; |
4780 | 1 | dasm_put(Dst, 4583, (in1), val); |
4781 | 1 | #line 323 "src/jit/x64/tiles.dasc" |
4782 | 1 | } |
4783 | 41.4k | } else { |
4784 | 41.4k | if (sz == 8 && !fits_in_32_bit(val)) { |
4785 | 0 | //| mov64 Rq(out), val; |
4786 | 0 | //| add Rq(out), Rq(in1); |
4787 | 0 | dasm_put(Dst, 4591, (out), (unsigned int)(val), (unsigned int)((val)>>32), (in1), (out)); |
4788 | 0 | #line 328 "src/jit/x64/tiles.dasc" |
4789 | 41.4k | } else { |
4790 | 41.4k | //| mov Rq(out), Rq(in1); |
4791 | 41.4k | //| add Rq(out), val; |
4792 | 41.4k | dasm_put(Dst, 4607, (in1), (out), (out), val); |
4793 | 41.4k | #line 331 "src/jit/x64/tiles.dasc" |
4794 | 41.4k | } |
4795 | 41.4k | } |
4796 | 41.4k | } |
4797 | | |
4798 | 916 | MVM_JIT_TILE_DECL(add_load_addr) { |
4799 | 916 | MVMint8 out = tile->values[0]; |
4800 | 916 | MVMint8 in1 = tile->values[1]; |
4801 | 916 | MVMint8 base = tile->values[2]; |
4802 | 916 | MVMint32 ofs = tile->args[0]; |
4803 | 916 | MVMint32 size = tile->args[1]; |
4804 | 916 | if (in1 != out) { |
4805 | 916 | //| mov Rq(out), Rq(in1); |
4806 | 916 | dasm_put(Dst, 4308, (in1), (out)); |
4807 | 916 | #line 343 "src/jit/x64/tiles.dasc" |
4808 | 916 | } |
4809 | 916 | switch (size) { |
4810 | 0 | case 1: |
4811 | 0 | //| add Rb(out), byte [Rq(base)+ofs]; |
4812 | 0 | dasm_put(Dst, 4623, (out), (base), ofs); |
4813 | 0 | #line 347 "src/jit/x64/tiles.dasc" |
4814 | 0 | break; |
4815 | 0 | case 2: |
4816 | 0 | //| add Rw(out), word [Rq(base)+ofs]; |
4817 | 0 | dasm_put(Dst, 4634, (out), (base), ofs); |
4818 | 0 | #line 350 "src/jit/x64/tiles.dasc" |
4819 | 0 | break; |
4820 | 0 | case 4: |
4821 | 0 | //| add Rd(out), dword [Rq(base)+ofs]; |
4822 | 0 | dasm_put(Dst, 4635, (out), (base), ofs); |
4823 | 0 | #line 353 "src/jit/x64/tiles.dasc" |
4824 | 0 | break; |
4825 | 916 | case 8: |
4826 | 916 | //| add Rq(out), qword [Rq(base)+ofs]; |
4827 | 916 | dasm_put(Dst, 4645, (out), (base), ofs); |
4828 | 916 | #line 356 "src/jit/x64/tiles.dasc" |
4829 | 916 | break; |
4830 | 0 | default: |
4831 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4832 | 916 | } |
4833 | 916 | } |
4834 | | |
4835 | 0 | MVM_JIT_TILE_DECL(add_load_idx) { |
4836 | 0 | MVMint8 out = tile->values[0]; |
4837 | 0 | MVMint8 in1 = tile->values[1]; |
4838 | 0 | MVMint8 base = tile->values[2]; |
4839 | 0 | MVMint8 idx = tile->values[3]; |
4840 | 0 | MVMint32 scl = tile->args[0]; |
4841 | 0 | MVMint32 size = tile->args[1]; |
4842 | 0 | if (in1 != out) { |
4843 | 0 | //| mov Rq(out), Rq(in1); |
4844 | 0 | dasm_put(Dst, 4308, (in1), (out)); |
4845 | 0 | #line 371 "src/jit/x64/tiles.dasc" |
4846 | 0 | } |
4847 | 0 | if (scl != 8) |
4848 | 0 | MVM_oops(tc, "IDX Scale %d NYI\n", scl); |
4849 | 0 | switch (size) { |
4850 | 0 | case 1: |
4851 | 0 | //| add Rb(out), byte [Rq(base)+Rq(idx)*8]; |
4852 | 0 | dasm_put(Dst, 4656, (out), (idx), (base), 0); |
4853 | 0 | #line 377 "src/jit/x64/tiles.dasc" |
4854 | 0 | break; |
4855 | 0 | case 2: |
4856 | 0 | //| add Rw(out), word [Rq(base)+Rq(idx)*8]; |
4857 | 0 | dasm_put(Dst, 4670, (out), (idx), (base), 0); |
4858 | 0 | #line 380 "src/jit/x64/tiles.dasc" |
4859 | 0 | break; |
4860 | 0 | case 4: |
4861 | 0 | //| add Rd(out), dword [Rq(base)+Rq(idx)*8]; |
4862 | 0 | dasm_put(Dst, 4671, (out), (idx), (base), 0); |
4863 | 0 | #line 383 "src/jit/x64/tiles.dasc" |
4864 | 0 | break; |
4865 | 0 | case 8: |
4866 | 0 | //| add Rq(out), qword [Rq(base)+Rq(idx)*8]; |
4867 | 0 | dasm_put(Dst, 4684, (out), (idx), (base), 0); |
4868 | 0 | #line 386 "src/jit/x64/tiles.dasc" |
4869 | 0 | break; |
4870 | 0 | default: |
4871 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4872 | 0 | } |
4873 | 0 | } |
4874 | | |
4875 | | |
4876 | 7 | MVM_JIT_TILE_DECL(and_reg) { |
4877 | 7 | MVMint8 reg[2]; |
4878 | 7 | ensure_two_operand_pre(tc, compiler, tile, reg); |
4879 | 7 | //| and Rq(reg[0]), Rq(reg[1]); |
4880 | 7 | dasm_put(Dst, 4698, (reg[1]), (reg[0])); |
4881 | 7 | #line 397 "src/jit/x64/tiles.dasc" |
4882 | 7 | ensure_two_operand_post(tc, compiler, tile, reg); |
4883 | 7 | } |
4884 | | |
4885 | 0 | MVM_JIT_TILE_DECL(and_const) { |
4886 | 0 | MVMint8 out = tile->values[0]; |
4887 | 0 | MVMint8 in1 = tile->values[1]; |
4888 | 0 | MVMint64 val = tile->args[0]; |
4889 | 0 | MVMint32 sz = tile->args[1]; |
4890 | 0 | if (out == in1) { |
4891 | 0 | if (sz == 8 && !fits_in_32_bit(val)) { |
4892 | 0 | //| mov64 rax, val; |
4893 | 0 | //| and Rq(in1), rax; |
4894 | 0 | dasm_put(Dst, 4707, (unsigned int)(val), (unsigned int)((val)>>32), (in1)); |
4895 | 0 | #line 409 "src/jit/x64/tiles.dasc" |
4896 | 0 | } else { |
4897 | 0 | //| and Rq(in1), val; |
4898 | 0 | dasm_put(Dst, 4718, (in1), val); |
4899 | 0 | #line 411 "src/jit/x64/tiles.dasc" |
4900 | 0 | } |
4901 | 0 | } else { |
4902 | 0 | if (sz == 8 && !fits_in_32_bit(val)) { |
4903 | 0 | //| mov64 Rq(out), val; |
4904 | 0 | //| and Rq(out), Rq(in1); |
4905 | 0 | dasm_put(Dst, 4726, (out), (unsigned int)(val), (unsigned int)((val)>>32), (in1), (out)); |
4906 | 0 | #line 416 "src/jit/x64/tiles.dasc" |
4907 | 0 | } else { |
4908 | 0 | //| mov Rq(out), Rq(in1); |
4909 | 0 | //| and Rq(out), val; |
4910 | 0 | dasm_put(Dst, 4742, (in1), (out), (out), val); |
4911 | 0 | #line 419 "src/jit/x64/tiles.dasc" |
4912 | 0 | } |
4913 | 0 | } |
4914 | 0 | } |
4915 | | |
4916 | 0 | MVM_JIT_TILE_DECL(and_load_addr) { |
4917 | 0 | MVMint8 out = tile->values[0]; |
4918 | 0 | MVMint8 in1 = tile->values[1]; |
4919 | 0 | MVMint8 base = tile->values[2]; |
4920 | 0 | MVMint32 ofs = tile->args[0]; |
4921 | 0 | MVMint32 size = tile->args[1]; |
4922 | 0 | if (in1 != out) { |
4923 | 0 | //| mov Rq(out), Rq(in1); |
4924 | 0 | dasm_put(Dst, 4308, (in1), (out)); |
4925 | 0 | #line 431 "src/jit/x64/tiles.dasc" |
4926 | 0 | } |
4927 | 0 | switch (size) { |
4928 | 0 | case 1: |
4929 | 0 | //| and Rb(out), byte [Rq(base)+ofs]; |
4930 | 0 | dasm_put(Dst, 4758, (out), (base), ofs); |
4931 | 0 | #line 435 "src/jit/x64/tiles.dasc" |
4932 | 0 | break; |
4933 | 0 | case 2: |
4934 | 0 | //| and Rw(out), word [Rq(base)+ofs]; |
4935 | 0 | dasm_put(Dst, 4769, (out), (base), ofs); |
4936 | 0 | #line 438 "src/jit/x64/tiles.dasc" |
4937 | 0 | break; |
4938 | 0 | case 4: |
4939 | 0 | //| and Rd(out), dword [Rq(base)+ofs]; |
4940 | 0 | dasm_put(Dst, 4770, (out), (base), ofs); |
4941 | 0 | #line 441 "src/jit/x64/tiles.dasc" |
4942 | 0 | break; |
4943 | 0 | case 8: |
4944 | 0 | //| and Rq(out), qword [Rq(base)+ofs]; |
4945 | 0 | dasm_put(Dst, 4780, (out), (base), ofs); |
4946 | 0 | #line 444 "src/jit/x64/tiles.dasc" |
4947 | 0 | break; |
4948 | 0 | default: |
4949 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4950 | 0 | } |
4951 | 0 | } |
4952 | | |
4953 | 0 | MVM_JIT_TILE_DECL(and_load_idx) { |
4954 | 0 | MVMint8 out = tile->values[0]; |
4955 | 0 | MVMint8 in1 = tile->values[1]; |
4956 | 0 | MVMint8 base = tile->values[2]; |
4957 | 0 | MVMint8 idx = tile->values[3]; |
4958 | 0 | MVMint32 scl = tile->args[0]; |
4959 | 0 | MVMint32 size = tile->args[1]; |
4960 | 0 |
|
4961 | 0 | if (out != in1) { |
4962 | 0 | //| mov Rq(out), Rq(in1); |
4963 | 0 | dasm_put(Dst, 4308, (in1), (out)); |
4964 | 0 | #line 460 "src/jit/x64/tiles.dasc" |
4965 | 0 | } |
4966 | 0 | if (scl != 8) |
4967 | 0 | MVM_oops(tc, "IDX Scale %d NYI\n", scl); |
4968 | 0 | switch (size) { |
4969 | 0 | case 1: |
4970 | 0 | //| and Rb(out), byte [Rq(base)+Rq(idx)*8]; |
4971 | 0 | dasm_put(Dst, 4791, (out), (idx), (base), 0); |
4972 | 0 | #line 466 "src/jit/x64/tiles.dasc" |
4973 | 0 | break; |
4974 | 0 | case 2: |
4975 | 0 | //| and Rw(out), word [Rq(base)+Rq(idx)*8]; |
4976 | 0 | dasm_put(Dst, 4805, (out), (idx), (base), 0); |
4977 | 0 | #line 469 "src/jit/x64/tiles.dasc" |
4978 | 0 | break; |
4979 | 0 | case 4: |
4980 | 0 | //| and Rd(out), dword [Rq(base)+Rq(idx)*8]; |
4981 | 0 | dasm_put(Dst, 4806, (out), (idx), (base), 0); |
4982 | 0 | #line 472 "src/jit/x64/tiles.dasc" |
4983 | 0 | break; |
4984 | 0 | case 8: |
4985 | 0 | //| and Rq(out), qword [Rq(base)+Rq(idx)*8]; |
4986 | 0 | dasm_put(Dst, 4819, (out), (idx), (base), 0); |
4987 | 0 | #line 475 "src/jit/x64/tiles.dasc" |
4988 | 0 | break; |
4989 | 0 | default: |
4990 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
4991 | 0 | } |
4992 | 0 | } |
4993 | | |
4994 | 3.66k | MVM_JIT_TILE_DECL(or_reg) { |
4995 | 3.66k | MVMint8 reg[2]; |
4996 | 3.66k | ensure_two_operand_pre(tc, compiler, tile, reg); |
4997 | 3.66k | //| or Rq(reg[0]), Rq(reg[1]); |
4998 | 3.66k | dasm_put(Dst, 4833, (reg[1]), (reg[0])); |
4999 | 3.66k | #line 485 "src/jit/x64/tiles.dasc" |
5000 | 3.66k | ensure_two_operand_post(tc, compiler, tile, reg); |
5001 | 3.66k | } |
5002 | | |
5003 | 0 | MVM_JIT_TILE_DECL(xor_reg) { |
5004 | 0 | MVMint8 reg[2]; |
5005 | 0 | ensure_two_operand_pre(tc, compiler, tile, reg); |
5006 | 0 | //| xor Rq(reg[0]), Rq(reg[1]); |
5007 | 0 | dasm_put(Dst, 4842, (reg[1]), (reg[0])); |
5008 | 0 | #line 492 "src/jit/x64/tiles.dasc" |
5009 | 0 | ensure_two_operand_post(tc, compiler, tile, reg); |
5010 | 0 | } |
5011 | | |
5012 | 0 | MVM_JIT_TILE_DECL(not_reg) { |
5013 | 0 | MVMint8 out = tile->values[0]; |
5014 | 0 | MVMint8 in = tile->values[1]; |
5015 | 0 | if (out != in) { |
5016 | 0 | //| mov Rq(out), Rq(in); |
5017 | 0 | dasm_put(Dst, 4308, (in), (out)); |
5018 | 0 | #line 500 "src/jit/x64/tiles.dasc" |
5019 | 0 | } |
5020 | 0 | //| not Rq(out); |
5021 | 0 | dasm_put(Dst, 4851, (out)); |
5022 | 0 | #line 502 "src/jit/x64/tiles.dasc" |
5023 | 0 | } |
5024 | | |
5025 | 3.35k | MVM_JIT_TILE_DECL(sub_reg) { |
5026 | 3.35k | MVMint8 reg[2]; |
5027 | 3.35k | ensure_two_operand_pre(tc, compiler, tile, reg); |
5028 | 3.35k | //| sub Rq(reg[0]), Rq(reg[1]); |
5029 | 3.35k | dasm_put(Dst, 4859, (reg[1]), (reg[0])); |
5030 | 3.35k | #line 508 "src/jit/x64/tiles.dasc" |
5031 | 3.35k | ensure_two_operand_post(tc, compiler, tile, reg); |
5032 | 3.35k | } |
5033 | | |
5034 | 5.16k | MVM_JIT_TILE_DECL(sub_const) { |
5035 | 5.16k | MVMint8 out = tile->values[0]; |
5036 | 5.16k | MVMint8 in1 = tile->values[1]; |
5037 | 5.16k | MVMint64 val = tile->args[0]; |
5038 | 5.16k | MVMint32 sz = tile->args[1]; |
5039 | 5.16k | if (out == in1) { |
5040 | 0 | if (sz == 8 && !fits_in_32_bit(val)) { |
5041 | 0 | //| mov64 rax, val; |
5042 | 0 | //| sub Rq(in1), rax; |
5043 | 0 | dasm_put(Dst, 4868, (unsigned int)(val), (unsigned int)((val)>>32), (in1)); |
5044 | 0 | #line 520 "src/jit/x64/tiles.dasc" |
5045 | 0 | } else { |
5046 | 0 | //| sub Rq(in1), val; |
5047 | 0 | dasm_put(Dst, 4879, (in1), val); |
5048 | 0 | #line 522 "src/jit/x64/tiles.dasc" |
5049 | 0 | } |
5050 | 5.16k | } else { |
5051 | 5.16k | if (sz == 8 && !fits_in_32_bit(val)) { |
5052 | 0 | //| mov64 rax, val; |
5053 | 0 | //| mov Rq(out), Rq(in1); |
5054 | 0 | //| sub Rq(out), rax; |
5055 | 0 | dasm_put(Dst, 4888, (unsigned int)(val), (unsigned int)((val)>>32), (in1), (out), (out)); |
5056 | 0 | #line 528 "src/jit/x64/tiles.dasc" |
5057 | 5.16k | } else { |
5058 | 5.16k | //| mov Rq(out), Rq(in1); |
5059 | 5.16k | //| sub Rq(out), val; |
5060 | 5.16k | dasm_put(Dst, 4907, (in1), (out), (out), val); |
5061 | 5.16k | #line 531 "src/jit/x64/tiles.dasc" |
5062 | 5.16k | } |
5063 | 5.16k | } |
5064 | 5.16k | } |
5065 | | |
5066 | 0 | MVM_JIT_TILE_DECL(sub_load_addr) { |
5067 | 0 | MVMint8 out = tile->values[0]; |
5068 | 0 | MVMint8 in1 = tile->values[1]; |
5069 | 0 | MVMint8 base = tile->values[2]; |
5070 | 0 | MVMint32 ofs = tile->args[0]; |
5071 | 0 | MVMint32 size = tile->args[1]; |
5072 | 0 | if (in1 != out) { |
5073 | 0 | //| mov Rq(out), Rq(in1); |
5074 | 0 | dasm_put(Dst, 4308, (in1), (out)); |
5075 | 0 | #line 543 "src/jit/x64/tiles.dasc" |
5076 | 0 | } |
5077 | 0 | switch (size) { |
5078 | 0 | case 1: |
5079 | 0 | //| sub Rb(out), byte [Rq(base)+ofs]; |
5080 | 0 | dasm_put(Dst, 4924, (out), (base), ofs); |
5081 | 0 | #line 547 "src/jit/x64/tiles.dasc" |
5082 | 0 | break; |
5083 | 0 | case 2: |
5084 | 0 | //| sub Rw(out), word [Rq(base)+ofs]; |
5085 | 0 | dasm_put(Dst, 4935, (out), (base), ofs); |
5086 | 0 | #line 550 "src/jit/x64/tiles.dasc" |
5087 | 0 | break; |
5088 | 0 | case 4: |
5089 | 0 | //| sub Rd(out), dword [Rq(base)+ofs]; |
5090 | 0 | dasm_put(Dst, 4936, (out), (base), ofs); |
5091 | 0 | #line 553 "src/jit/x64/tiles.dasc" |
5092 | 0 | break; |
5093 | 0 | case 8: |
5094 | 0 | //| sub Rq(out), qword [Rq(base)+ofs]; |
5095 | 0 | dasm_put(Dst, 4946, (out), (base), ofs); |
5096 | 0 | #line 556 "src/jit/x64/tiles.dasc" |
5097 | 0 | break; |
5098 | 0 | default: |
5099 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
5100 | 0 | } |
5101 | 0 | } |
5102 | | |
5103 | 0 | MVM_JIT_TILE_DECL(sub_load_idx) { |
5104 | 0 | MVMint8 out = tile->values[0]; |
5105 | 0 | MVMint8 in1 = tile->values[1]; |
5106 | 0 | MVMint8 base = tile->values[2]; |
5107 | 0 | MVMint8 idx = tile->values[3]; |
5108 | 0 | MVMint32 scl = tile->args[0]; |
5109 | 0 | MVMint32 size = tile->args[1]; |
5110 | 0 | if (out != in1) { |
5111 | 0 | //| mov Rq(out), Rq(in1); |
5112 | 0 | dasm_put(Dst, 4308, (in1), (out)); |
5113 | 0 | #line 571 "src/jit/x64/tiles.dasc" |
5114 | 0 | } |
5115 | 0 | if (scl != 8) |
5116 | 0 | MVM_oops(tc, "IDX Scale %d NYI\n", scl); |
5117 | 0 | switch (size) { |
5118 | 0 | case 1: |
5119 | 0 | //| sub Rb(out), byte [Rq(base)+Rq(idx)*8]; |
5120 | 0 | dasm_put(Dst, 4957, (out), (idx), (base), 0); |
5121 | 0 | #line 577 "src/jit/x64/tiles.dasc" |
5122 | 0 | break; |
5123 | 0 | case 2: |
5124 | 0 | //| sub Rw(out), word [Rq(base)+Rq(idx)*8]; |
5125 | 0 | dasm_put(Dst, 4971, (out), (idx), (base), 0); |
5126 | 0 | #line 580 "src/jit/x64/tiles.dasc" |
5127 | 0 | break; |
5128 | 0 | case 4: |
5129 | 0 | //| sub Rd(out), dword [Rq(base)+Rq(idx)*8]; |
5130 | 0 | dasm_put(Dst, 4972, (out), (idx), (base), 0); |
5131 | 0 | #line 583 "src/jit/x64/tiles.dasc" |
5132 | 0 | break; |
5133 | 0 | case 8: |
5134 | 0 | //| sub Rq(out), qword [Rq(base)+Rq(idx)*8]; |
5135 | 0 | dasm_put(Dst, 4985, (out), (idx), (base), 0); |
5136 | 0 | #line 586 "src/jit/x64/tiles.dasc" |
5137 | 0 | break; |
5138 | 0 | default: |
5139 | 0 | MVM_oops(tc, "Unsupported load size: %d\n", size); |
5140 | 0 | } |
5141 | 0 | } |
5142 | | |
5143 | | |
5144 | | |
5145 | | |
5146 | 64.0k | MVM_JIT_TILE_DECL(test) { |
5147 | 64.0k | MVMint8 reg = tile->values[1]; |
5148 | 64.0k | switch (tile->size) { |
5149 | 0 | case 1: |
5150 | 0 | //| test Rb(reg), Rb(reg); |
5151 | 0 | dasm_put(Dst, 4999, (reg), (reg)); |
5152 | 0 | #line 600 "src/jit/x64/tiles.dasc" |
5153 | 0 | break; |
5154 | 1 | case 2: |
5155 | 1 | //| test Rw(reg), Rw(reg); |
5156 | 1 | dasm_put(Dst, 5008, (reg), (reg)); |
5157 | 1 | #line 603 "src/jit/x64/tiles.dasc" |
5158 | 1 | break; |
5159 | 26.7k | case 4: |
5160 | 26.7k | //| test Rd(reg), Rd(reg); |
5161 | 26.7k | dasm_put(Dst, 5009, (reg), (reg)); |
5162 | 26.7k | #line 606 "src/jit/x64/tiles.dasc" |
5163 | 26.7k | break; |
5164 | 37.2k | case 8: |
5165 | 37.2k | default: |
5166 | 37.2k | /* NB - this is a hack, because we don't assign a size to the result of |
5167 | 37.2k | * CALL, its size would be 0, and we'd have nothing compiled. Better fix |
5168 | 37.2k | * would be to assign a result size to CALL. */ |
5169 | 37.2k | //| test Rq(reg), Rq(reg); |
5170 | 37.2k | dasm_put(Dst, 5017, (reg), (reg)); |
5171 | 37.2k | #line 613 "src/jit/x64/tiles.dasc" |
5172 | 37.2k | break; |
5173 | 64.0k | } |
5174 | 64.0k | } |
5175 | | |
5176 | | |
5177 | | |
5178 | 154k | MVM_JIT_TILE_DECL(test_addr) { |
5179 | 154k | MVMint8 base = tile->values[1]; |
5180 | 154k | MVMint32 ofs = tile->args[0]; |
5181 | 154k | MVMint32 size = tile->args[1]; |
5182 | 154k | switch (size) { |
5183 | 0 | case 1: |
5184 | 0 | //| cmp byte [Rq(base)+ofs], 0; |
5185 | 0 | dasm_put(Dst, 5026, (base), ofs); |
5186 | 0 | #line 626 "src/jit/x64/tiles.dasc" |
5187 | 0 | break; |
5188 | 0 | case 2: |
5189 | 0 | //| cmp word [Rq(base)+ofs], 0; |
5190 | 0 | dasm_put(Dst, 5036, (base), ofs); |
5191 | 0 | #line 629 "src/jit/x64/tiles.dasc" |
5192 | 0 | break; |
5193 | 0 | case 4: |
5194 | 0 | //| cmp dword [Rq(base)+ofs], 0; |
5195 | 0 | dasm_put(Dst, 5037, (base), ofs); |
5196 | 0 | #line 632 "src/jit/x64/tiles.dasc" |
5197 | 0 | break; |
5198 | 154k | case 8: |
5199 | 154k | //| cmp qword [Rq(base)+ofs], 0; |
5200 | 154k | dasm_put(Dst, 5046, (base), ofs); |
5201 | 154k | #line 635 "src/jit/x64/tiles.dasc" |
5202 | 154k | break; |
5203 | 0 | default: |
5204 | 0 | MVM_oops(tc, "Unsupported size %d for load\n", size); |
5205 | 154k | } |
5206 | 154k | } |
5207 | | |
5208 | | |
5209 | 54.7k | MVM_JIT_TILE_DECL(test_idx) { |
5210 | 54.7k | MVMint8 base = tile->values[1]; |
5211 | 54.7k | MVMint8 idx = tile->values[2]; |
5212 | 54.7k | MVMint32 scl = tile->args[0]; |
5213 | 54.7k | MVMint32 size = tile->args[1]; |
5214 | 54.7k | if (scl != 8) |
5215 | 0 | MVM_oops(tc, "Scale %d NYI\n", scl); |
5216 | 54.7k | switch(size) { |
5217 | 0 | case 1: |
5218 | 0 | //| cmp byte [Rq(base)+Rq(idx)*8], 0; |
5219 | 0 | dasm_put(Dst, 5056, (idx), (base), 0); |
5220 | 0 | #line 652 "src/jit/x64/tiles.dasc" |
5221 | 0 | break; |
5222 | 0 | case 2: |
5223 | 0 | //| cmp word [Rq(base)+Rq(idx)*8], 0; |
5224 | 0 | dasm_put(Dst, 5069, (idx), (base), 0); |
5225 | 0 | #line 655 "src/jit/x64/tiles.dasc" |
5226 | 0 | break; |
5227 | 0 | case 4: |
5228 | 0 | //| cmp dword [Rq(base)+Rq(idx)*8], 0; |
5229 | 0 | dasm_put(Dst, 5070, (idx), (base), 0); |
5230 | 0 | #line 658 "src/jit/x64/tiles.dasc" |
5231 | 0 | break; |
5232 | 54.7k | case 8: |
5233 | 54.7k | //| cmp qword [Rq(base)+Rq(idx)*8], 0; |
5234 | 54.7k | dasm_put(Dst, 5082, (idx), (base), 0); |
5235 | 54.7k | #line 661 "src/jit/x64/tiles.dasc" |
5236 | 54.7k | break; |
5237 | 0 | default: |
5238 | 0 | MVM_oops(tc, "Unsupported size %d for load\n", tile->size); |
5239 | 54.7k | } |
5240 | 54.7k | } |
5241 | | |
5242 | 0 | MVM_JIT_TILE_DECL(test_and) { |
5243 | 0 | MVMint8 rega = tile->values[1]; |
5244 | 0 | MVMint8 regb = tile->values[2]; |
5245 | 0 | switch(tile->size) { |
5246 | 0 | case 1: |
5247 | 0 | //| test Rb(regb), Rb(rega); |
5248 | 0 | dasm_put(Dst, 4999, (rega), (regb)); |
5249 | 0 | #line 673 "src/jit/x64/tiles.dasc" |
5250 | 0 | break; |
5251 | 0 | case 2: |
5252 | 0 | //| test Rw(regb), Rw(rega); |
5253 | 0 | dasm_put(Dst, 5008, (rega), (regb)); |
5254 | 0 | #line 676 "src/jit/x64/tiles.dasc" |
5255 | 0 | break; |
5256 | 0 | case 4: |
5257 | 0 | //| test Rd(regb), Rd(rega); |
5258 | 0 | dasm_put(Dst, 5009, (rega), (regb)); |
5259 | 0 | #line 679 "src/jit/x64/tiles.dasc" |
5260 | 0 | break; |
5261 | 0 | case 8: |
5262 | 0 | //| test Rq(regb), Rq(rega); |
5263 | 0 | dasm_put(Dst, 5017, (rega), (regb)); |
5264 | 0 | #line 682 "src/jit/x64/tiles.dasc" |
5265 | 0 | break; |
5266 | 0 | } |
5267 | 0 | } |
5268 | | |
5269 | 0 | MVM_JIT_TILE_DECL(test_const) { |
5270 | 0 | MVMint8 reg = tile->values[1]; |
5271 | 0 | MVMint64 val = tile->args[0]; |
5272 | 0 | switch(tile->size) { |
5273 | 0 | case 1: |
5274 | 0 | //| test Rb(reg), val; |
5275 | 0 | dasm_put(Dst, 5095, (reg), val); |
5276 | 0 | #line 692 "src/jit/x64/tiles.dasc" |
5277 | 0 | break; |
5278 | 0 | case 2: |
5279 | 0 | //| test Rw(reg), val; |
5280 | 0 | dasm_put(Dst, 5104, (reg), val); |
5281 | 0 | #line 695 "src/jit/x64/tiles.dasc" |
5282 | 0 | break; |
5283 | 0 | case 4: |
5284 | 0 | //| test Rd(reg), val; |
5285 | 0 | dasm_put(Dst, 5113, (reg), val); |
5286 | 0 | #line 698 "src/jit/x64/tiles.dasc" |
5287 | 0 | break; |
5288 | 0 | case 8: |
5289 | 0 | if (fits_in_32_bit(val)) { |
5290 | 0 | //| test Rq(reg), val; |
5291 | 0 | dasm_put(Dst, 5121, (reg), val); |
5292 | 0 | #line 702 "src/jit/x64/tiles.dasc" |
5293 | 0 | } else { |
5294 | 0 | //| mov64 rax, val; |
5295 | 0 | //| test Rq(reg), rax; |
5296 | 0 | dasm_put(Dst, 5130, (unsigned int)(val), (unsigned int)((val)>>32), (reg)); |
5297 | 0 | #line 705 "src/jit/x64/tiles.dasc" |
5298 | 0 | } |
5299 | 0 | break; |
5300 | 0 | } |
5301 | 0 | } |
5302 | | |
5303 | 107k | MVM_JIT_TILE_DECL(test_addr_const) { |
5304 | 107k | MVMint8 reg = tile->values[1]; |
5305 | 107k | /* args: $ofs $lsize $val $csize */ |
5306 | 107k | MVMint32 ofs = tile->args[0]; |
5307 | 107k | MVMint64 val = tile->args[2]; |
5308 | 107k | switch(tile->size) { |
5309 | 0 | case 1: |
5310 | 0 | //| test byte [Rq(reg)+ofs], val; |
5311 | 0 | dasm_put(Dst, 5141, (reg), ofs, val); |
5312 | 0 | #line 718 "src/jit/x64/tiles.dasc" |
5313 | 0 | break; |
5314 | 107k | case 2: |
5315 | 107k | //| test word [Rq(reg)+ofs], val; |
5316 | 107k | dasm_put(Dst, 5152, (reg), ofs, val); |
5317 | 107k | #line 721 "src/jit/x64/tiles.dasc" |
5318 | 107k | break; |
5319 | 0 | case 4: |
5320 | 0 | //| test dword [Rq(reg)+ofs], val; |
5321 | 0 | dasm_put(Dst, 5163, (reg), ofs, val); |
5322 | 0 | #line 724 "src/jit/x64/tiles.dasc" |
5323 | 0 | break; |
5324 | 0 | case 8: |
5325 | 0 | if (fits_in_32_bit(val)) { |
5326 | 0 | //| test qword [Rq(reg)+ofs], val; |
5327 | 0 | dasm_put(Dst, 5173, (reg), ofs, val); |
5328 | 0 | #line 728 "src/jit/x64/tiles.dasc" |
5329 | 0 | } else { |
5330 | 0 | //| mov64 rax, val; |
5331 | 0 | //| test qword [Rq(reg)+ofs], rax; |
5332 | 0 | dasm_put(Dst, 5184, (unsigned int)(val), (unsigned int)((val)>>32), (reg), ofs); |
5333 | 0 | #line 731 "src/jit/x64/tiles.dasc" |
5334 | 0 | } |
5335 | 0 | break; |
5336 | 107k | } |
5337 | 107k | } |
5338 | | |
5339 | | |
5340 | 44.5k | MVM_JIT_TILE_DECL(cmp) { |
5341 | 44.5k | MVMint8 regl = tile->values[1]; |
5342 | 44.5k | MVMint8 regr = tile->values[2]; |
5343 | 44.5k | switch (tile->size) { |
5344 | 0 | case 1: |
5345 | 0 | //| cmp Rb(regl), Rb(regr); |
5346 | 0 | dasm_put(Dst, 5197, (regr), (regl)); |
5347 | 0 | #line 743 "src/jit/x64/tiles.dasc" |
5348 | 0 | break; |
5349 | 13 | case 2: |
5350 | 13 | //| cmp Rw(regl), Rw(regr); |
5351 | 13 | dasm_put(Dst, 5206, (regr), (regl)); |
5352 | 13 | #line 746 "src/jit/x64/tiles.dasc" |
5353 | 13 | break; |
5354 | 630 | case 4: |
5355 | 630 | //| cmp Rd(regl), Rd(regr); |
5356 | 630 | dasm_put(Dst, 5207, (regr), (regl)); |
5357 | 630 | #line 749 "src/jit/x64/tiles.dasc" |
5358 | 630 | break; |
5359 | 43.9k | case 8: |
5360 | 43.9k | //| cmp Rq(regl), Rq(regr); |
5361 | 43.9k | dasm_put(Dst, 5215, (regr), (regl)); |
5362 | 43.9k | #line 752 "src/jit/x64/tiles.dasc" |
5363 | 43.9k | break; |
5364 | 44.5k | } |
5365 | 44.5k | } |
5366 | | |
5367 | 32.6k | MVM_JIT_TILE_DECL(flagval) { |
5368 | 32.6k | MVMint8 out = tile->values[0]; |
5369 | 32.6k | MVMint32 child = tree->nodes[tile->node + 1]; |
5370 | 32.6k | MVMint32 flag = tree->nodes[child]; |
5371 | 32.6k | switch (flag) { |
5372 | 6.56k | case MVM_JIT_LT: |
5373 | 6.56k | //| setl Rb(out); |
5374 | 6.56k | dasm_put(Dst, 5224, (out)); |
5375 | 6.56k | #line 763 "src/jit/x64/tiles.dasc" |
5376 | 6.56k | break; |
5377 | 583 | case MVM_JIT_LE: |
5378 | 583 | //| setle Rb(out); |
5379 | 583 | dasm_put(Dst, 5232, (out)); |
5380 | 583 | #line 766 "src/jit/x64/tiles.dasc" |
5381 | 583 | break; |
5382 | 15.7k | case MVM_JIT_ZR: |
5383 | 15.7k | case MVM_JIT_EQ: |
5384 | 15.7k | //| setz Rb(out); |
5385 | 15.7k | dasm_put(Dst, 5240, (out)); |
5386 | 15.7k | #line 770 "src/jit/x64/tiles.dasc" |
5387 | 15.7k | break; |
5388 | 964 | case MVM_JIT_NZ: |
5389 | 964 | case MVM_JIT_NE: |
5390 | 964 | //| setnz Rb(out); |
5391 | 964 | dasm_put(Dst, 5248, (out)); |
5392 | 964 | #line 774 "src/jit/x64/tiles.dasc" |
5393 | 964 | break; |
5394 | 1.59k | case MVM_JIT_GE: |
5395 | 1.59k | //| setge Rb(out); |
5396 | 1.59k | dasm_put(Dst, 5256, (out)); |
5397 | 1.59k | #line 777 "src/jit/x64/tiles.dasc" |
5398 | 1.59k | break; |
5399 | 7.23k | case MVM_JIT_GT: |
5400 | 7.23k | //| setg Rb(out); |
5401 | 7.23k | dasm_put(Dst, 5264, (out)); |
5402 | 7.23k | #line 780 "src/jit/x64/tiles.dasc" |
5403 | 7.23k | break; |
5404 | 0 | default: |
5405 | 0 | MVM_panic(1, "No flagval possible"); |
5406 | 0 | break; |
5407 | 32.6k | } |
5408 | 32.6k | /* XXX THIS IS A HACK |
5409 | 32.6k | |
5410 | 32.6k | * The size cast is supposed to be applied by the expression template |
5411 | 32.6k | * builder, but that subtly doesn't work (it's not applied for STORE |
5412 | 32.6k | * operands, and when it is, it causes even subtler errors with CONST |
5413 | 32.6k | * arguments. (const_i64_16 returns a 64 bit signed integer as a 16 bit |
5414 | 32.6k | * signed integer argument, and currently CONST doesn't have a sign, and the |
5415 | 32.6k | * tile yielding the value (fortunately) doesn't respect the size. */ |
5416 | 32.6k | //| movzx Rq(out), Rb(out); |
5417 | 32.6k | dasm_put(Dst, 4528, (out), (out)); |
5418 | 32.6k | #line 794 "src/jit/x64/tiles.dasc" |
5419 | 32.6k | } |
5420 | | |
5421 | | |
5422 | 5.57k | MVM_JIT_TILE_DECL(mark) { |
5423 | 5.57k | MVMint32 label = tile->args[0]; |
5424 | 5.57k | //|=>(label): |
5425 | 5.57k | dasm_put(Dst, 195, (label)); |
5426 | 5.57k | #line 800 "src/jit/x64/tiles.dasc" |
5427 | 5.57k | } |
5428 | | |
5429 | 0 | MVM_JIT_TILE_DECL(label) { |
5430 | 0 | MVMint8 reg = tile->values[0]; |
5431 | 0 | MVMint32 label = tile->args[0]; |
5432 | 0 | //| lea Rq(reg), [=>label]; |
5433 | 0 | dasm_put(Dst, 5272, (reg), label); |
5434 | 0 | #line 806 "src/jit/x64/tiles.dasc" |
5435 | 0 | } |
5436 | | |
5437 | 114k | MVM_JIT_TILE_DECL(branch_label) { |
5438 | 114k | MVMint32 label = tile->args[0]; |
5439 | 114k | if (label >= 0) { |
5440 | 107k | //| jmp =>(label); |
5441 | 107k | dasm_put(Dst, 3654, (label)); |
5442 | 107k | #line 812 "src/jit/x64/tiles.dasc" |
5443 | 7.04k | } else { |
5444 | 7.04k | //| jmp ->exit; |
5445 | 7.04k | dasm_put(Dst, 3649); |
5446 | 7.04k | #line 814 "src/jit/x64/tiles.dasc" |
5447 | 7.04k | } |
5448 | 114k | } |
5449 | | |
5450 | | |
5451 | | |
5452 | 303k | static void move_call_value(MVMThreadContext *tc, MVMJitCompiler *compiler, MVMJitTile *tile) { |
5453 | 303k | if (MVM_JIT_TILE_YIELDS_VALUE(tile)) { |
5454 | 109k | MVMint8 out = tile->values[0]; |
5455 | 109k | //| mov Rq(out), rax; |
5456 | 109k | dasm_put(Dst, 4501, (out)); |
5457 | 109k | #line 823 "src/jit/x64/tiles.dasc" |
5458 | 109k | } |
5459 | 303k | } |
5460 | | |
5461 | 0 | MVM_JIT_TILE_DECL(call) { |
5462 | 0 | MVMint8 reg = tile->values[1]; |
5463 | 0 | //| call Rq(reg); |
5464 | 0 | dasm_put(Dst, 5280, (reg)); |
5465 | 0 | #line 829 "src/jit/x64/tiles.dasc" |
5466 | 0 | move_call_value(tc, compiler, tile); |
5467 | 0 | } |
5468 | | |
5469 | 199k | MVM_JIT_TILE_DECL(call_func) { |
5470 | 199k | MVMint64 ptr = tile->args[0]; |
5471 | 199k | //| callp ptr; |
5472 | 199k | dasm_put(Dst, 208); |
5473 | 199k | dasm_put(Dst, 210, (MVMuint32)((uintptr_t)(ptr)), (MVMuint32)((uintptr_t)(ptr) >> 32)); |
5474 | 199k | dasm_put(Dst, 216); |
5475 | 199k | #line 835 "src/jit/x64/tiles.dasc" |
5476 | 199k | move_call_value(tc, compiler, tile); |
5477 | 199k | } |
5478 | | |
5479 | | |
5480 | 104k | MVM_JIT_TILE_DECL(call_addr) { |
5481 | 104k | MVMint8 reg = tile->values[1]; |
5482 | 104k | MVMint32 ofs = tile->args[0]; |
5483 | 104k | //| call qword [Rq(reg)+ofs]; |
5484 | 104k | dasm_put(Dst, 5287, (reg), ofs); |
5485 | 104k | #line 843 "src/jit/x64/tiles.dasc" |
5486 | 104k | move_call_value(tc, compiler, tile); |
5487 | 104k | } |