diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/LuaJIT-1.1.7/src/ljit_x86.dash | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.dash b/libraries/LuaJIT-1.1.7/src/ljit_x86.dash new file mode 100644 index 0000000..432e1c8 --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.dash | |||
@@ -0,0 +1,297 @@ | |||
1 | |// | ||
2 | |// Common DynASM definitions and macros for x86 CPUs. | ||
3 | |// Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
4 | |// | ||
5 | | | ||
6 | |// Standard DynASM declarations. | ||
7 | |.arch x86 | ||
8 | |.section code, deopt, tail, mfmap | ||
9 | | | ||
10 | |// Type definitions with (almost) global validity. | ||
11 | |.type L, lua_State, esi // L. | ||
12 | |.type BASE, TValue, ebx // L->base. | ||
13 | |.type TOP, TValue, edi // L->top (calls/open ops). | ||
14 | |.type CI, CallInfo, ecx // L->ci (calls, locally). | ||
15 | |.type LCL, LClosure, eax // func->value (calls). | ||
16 | | | ||
17 | |// Type definitions with local validity. | ||
18 | |.type GL, global_State | ||
19 | |.type TVALUE, TValue | ||
20 | |.type VALUE, Value | ||
21 | |.type CINFO, CallInfo | ||
22 | |.type GCOBJECT, GCObject | ||
23 | |.type TSTRING, TString | ||
24 | |.type TABLE, Table | ||
25 | |.type CCLOSURE, CClosure | ||
26 | |.type PROTO, Proto | ||
27 | |.type UPVAL, UpVal | ||
28 | |.type NODE, Node | ||
29 | | | ||
30 | |// Definitions copied to DynASM domain to avoid unnecessary constant args. | ||
31 | |// CHECK: must match with the definitions in lua.h! | ||
32 | |.define LUA_TNIL, 0 | ||
33 | |.define LUA_TBOOLEAN, 1 | ||
34 | |.define LUA_TLIGHTUSERDATA, 2 | ||
35 | |.define LUA_TNUMBER, 3 | ||
36 | |.define LUA_TSTRING, 4 | ||
37 | |.define LUA_TTABLE, 5 | ||
38 | |.define LUA_TFUNCTION, 6 | ||
39 | |.define LUA_TUSERDATA, 7 | ||
40 | |.define LUA_TTHREAD, 8 | ||
41 | | | ||
42 | |.define LUA_TNUM_NUM, 0x33 | ||
43 | |.define LUA_TNUM_NUM_NUM, 0x333 | ||
44 | |.define LUA_TSTR_STR, 0x44 | ||
45 | |.define LUA_TSTR_NUM, 0x43 | ||
46 | |.define LUA_TSTR_NUM_NUM, 0x433 | ||
47 | |.define LUA_TTABLE_NUM, 0x53 | ||
48 | |.define LUA_TTABLE_STR, 0x54 | ||
49 | | | ||
50 | |// Macros to test, set and copy stack slots. | ||
51 | |.macro istt, idx, tp; cmp dword BASE[idx].tt, tp; .endmacro | ||
52 | |.macro isnil, idx; istt idx, LUA_TNIL; .endmacro | ||
53 | |.macro isnumber, idx; istt idx, LUA_TNUMBER; .endmacro | ||
54 | |.macro isstring, idx; istt idx, LUA_TSTRING; .endmacro | ||
55 | |.macro istable, idx; istt idx, LUA_TTABLE; .endmacro | ||
56 | |.macro isfunction, idx; istt idx, LUA_TFUNCTION; .endmacro | ||
57 | | | ||
58 | |.macro isnumber2, idx1, idx2, reg | ||
59 | | mov reg, BASE[idx1].tt; shl reg, 4; or reg, BASE[idx2].tt | ||
60 | | cmp reg, LUA_TNUM_NUM | ||
61 | |.endmacro | ||
62 | |.macro isnumber2, idx1, idx2; isnumber2, idx1, idx2, eax; .endmacro | ||
63 | | | ||
64 | |.macro isnumber3, idx1, idx2, idx3, reg | ||
65 | | mov reg, BASE[idx1].tt; shl reg, 4; or reg, BASE[idx2].tt | ||
66 | | shl reg, 4; or reg, BASE[idx3].tt; cmp reg, LUA_TNUM_NUM_NUM | ||
67 | |.endmacro | ||
68 | |.macro isnumber3, idx1, idx2, idx3; isnumber3, idx1, idx2, idx3, eax; .endmacro | ||
69 | | | ||
70 | |.macro tvisnil, tv; cmp dword tv.tt, LUA_TNIL; .endmacro | ||
71 | | | ||
72 | |.macro settt, tv, tp; mov dword tv.tt, tp; .endmacro | ||
73 | |.macro setnilvalue, tv; settt tv, LUA_TNIL; .endmacro | ||
74 | | | ||
75 | |.macro setbvalue, tv, val // May use edx. | ||
76 | ||if (val) { /* true */ | ||
77 | | mov edx, LUA_TBOOLEAN | ||
78 | | mov dword tv.value, edx // Assumes: LUA_TBOOLEAN == 1 | ||
79 | | settt tv, edx | ||
80 | ||} else { /* false */ | ||
81 | | mov dword tv.value, 0 | ||
82 | | settt tv, LUA_TBOOLEAN | ||
83 | ||} | ||
84 | |.endmacro | ||
85 | | | ||
86 | |.macro loadnvaluek, vptr | ||
87 | ||if ((vptr)->n == (lua_Number)0) { | ||
88 | | fldz | ||
89 | ||} else if ((vptr)->n == (lua_Number)1) { | ||
90 | | fld1 | ||
91 | ||} else { | ||
92 | | fld qword [vptr] | ||
93 | ||} | ||
94 | |.endmacro | ||
95 | | | ||
96 | |.macro setnvaluek, tv, vptr // Pass a Value *! With permanent addr. | ||
97 | | // SSE2 does not pay off here (I tried). | ||
98 | | loadnvaluek vptr | ||
99 | | fstp qword tv.value | ||
100 | | settt tv, LUA_TNUMBER | ||
101 | |.endmacro | ||
102 | | | ||
103 | |.macro setnvalue, tv, vptr // Pass a Value *! Temporary ok. | ||
104 | | mov dword tv.value, (vptr)->na[0] | ||
105 | | mov dword tv.value.na[1], (vptr)->na[1] | ||
106 | | settt tv, LUA_TNUMBER | ||
107 | |.endmacro | ||
108 | | | ||
109 | |.macro setsvalue, tv, vptr | ||
110 | | mov aword tv.value, vptr | ||
111 | | settt tv, LUA_TSTRING | ||
112 | |.endmacro | ||
113 | | | ||
114 | |.macro sethvalue, tv, vptr | ||
115 | | mov aword tv.value, vptr | ||
116 | | settt tv, LUA_TTABLE | ||
117 | |.endmacro | ||
118 | | | ||
119 | |.macro copyslotSSE, D, S, R1 // May use xmm0. | ||
120 | | mov R1, S.tt; movq xmm0, qword S.value | ||
121 | | mov D.tt, R1; movq qword D.value, xmm0 | ||
122 | |.endmacro | ||
123 | | | ||
124 | |.macro copyslot, D, S, R1, R2, R3 | ||
125 | ||if (J->flags & JIT_F_CPU_SSE2) { | ||
126 | | copyslotSSE D, S, R1 | ||
127 | ||} else { | ||
128 | | mov R1, S.value; mov R2, S.value.na[1]; mov R3, S.tt | ||
129 | | mov D.value, R1; mov D.value.na[1], R2; mov D.tt, R3 | ||
130 | ||} | ||
131 | |.endmacro | ||
132 | | | ||
133 | |.macro copyslot, D, S, R1, R2 | ||
134 | ||if (J->flags & JIT_F_CPU_SSE2) { | ||
135 | | copyslotSSE D, S, R1 | ||
136 | ||} else { | ||
137 | | mov R1, S.value; mov R2, S.value.na[1]; mov D.value, R1 | ||
138 | | mov R1, S.tt; mov D.value.na[1], R2; mov D.tt, R1 | ||
139 | ||} | ||
140 | |.endmacro | ||
141 | | | ||
142 | |.macro copyslot, D, S | ||
143 | | copyslot D, S, ecx, edx, eax | ||
144 | |.endmacro | ||
145 | | | ||
146 | |.macro copyconst, tv, tvk // May use edx. | ||
147 | ||switch (ttype(tvk)) { | ||
148 | ||case LUA_TNIL: | ||
149 | | setnilvalue tv | ||
150 | || break; | ||
151 | ||case LUA_TBOOLEAN: | ||
152 | | setbvalue tv, bvalue(tvk) // May use edx. | ||
153 | || break; | ||
154 | ||case LUA_TNUMBER: { | ||
155 | | setnvaluek tv, &(tvk)->value | ||
156 | || break; | ||
157 | ||} | ||
158 | ||case LUA_TSTRING: | ||
159 | | setsvalue tv, &gcvalue(tvk) | ||
160 | || break; | ||
161 | ||default: lua_assert(0); break; | ||
162 | ||} | ||
163 | |.endmacro | ||
164 | | | ||
165 | |// Macros to get Lua structures. | ||
166 | |.macro getLCL, reg // May use CI and TOP (edi). | ||
167 | ||if (!J->pt->is_vararg) { | ||
168 | | mov LCL:reg, BASE[-1].value | ||
169 | ||} else { | ||
170 | | mov CI, L->ci | ||
171 | | mov TOP, CI->func | ||
172 | | mov LCL:reg, TOP->value | ||
173 | ||} | ||
174 | |.endmacro | ||
175 | |.macro getLCL; getLCL eax; .endmacro | ||
176 | | | ||
177 | |// Macros to handle variants. | ||
178 | |.macro addidx, type, idx | ||
179 | ||if (idx) { | ||
180 | | add type, idx*#type | ||
181 | ||} | ||
182 | |.endmacro | ||
183 | | | ||
184 | |.macro subidx, type, idx | ||
185 | ||if (idx) { | ||
186 | | sub type, idx*#type | ||
187 | ||} | ||
188 | |.endmacro | ||
189 | | | ||
190 | |// Annoying x87 stuff: support for two compare variants. | ||
191 | |.macro fcomparepp // Compare and pop st0 >< st1. | ||
192 | ||if (J->flags & JIT_F_CPU_CMOV) { | ||
193 | | fucomip st1 | ||
194 | | fpop | ||
195 | ||} else { | ||
196 | | fucompp | ||
197 | | fnstsw ax // eax modified! | ||
198 | | sahf | ||
199 | | // Sometimes test ah, imm8 would be faster. | ||
200 | | // But all following compares need to be changed then. | ||
201 | | // Don't bother since this is only compatibility stuff for old CPUs. | ||
202 | ||} | ||
203 | |.endmacro | ||
204 | | | ||
205 | |// If you change LUA_TVALUE_ALIGN, be sure to change the Makefile, too: | ||
206 | |// DASMFLAGS= -D TVALUE_SIZE=... | ||
207 | |// Then rerun make. Or change the default below: | ||
208 | |.if not TVALUE_SIZE; .define TVALUE_SIZE, 16; .endif | ||
209 | | | ||
210 | |.if TVALUE_SIZE == 16 | ||
211 | | .macro TValuemul, reg; sal reg, 4; .endmacro // *16 | ||
212 | | .macro TValuediv, reg; sar reg, 4; .endmacro // /16 | ||
213 | | .macro Nodemul, reg; sal reg, 5; .endmacro // *32 | ||
214 | |.elif TVALUE_SIZE == 12 | ||
215 | | .macro TValuemul, reg; sal reg, 2; lea reg, [reg+reg*2]; .endmacro // *12 | ||
216 | | .macro TValuediv, reg; sal reg, 2; imul reg, 0xaaaaaaab; .endmacro // /12 | ||
217 | | .macro Nodemul, reg; imul reg, 28; .endmacro // *28 | ||
218 | |.else | ||
219 | | .fatal Unsupported TValue size `TVALUE_SIZE'. | ||
220 | |.endif | ||
221 | | | ||
222 | |// | ||
223 | |// x86 C calling conventions and stack frame layout during a JIT call: | ||
224 | |// | ||
225 | |// ebp+aword*4 CARG2 nresults | ||
226 | |// ebp+aword*3 CARG2 func (also used as SAVER3 for L) | ||
227 | |// ebp+aword*2 CARG1 L | ||
228 | |// ------------------------------- call to GATE_LJ | ||
229 | |// ebp+aword*1 retaddr | ||
230 | |// ebp+aword*0 frameptr ebp | ||
231 | |// ebp-aword*1 SAVER1 TOP edi | ||
232 | |// ebp-aword*2 SAVER2 BASE ebx | ||
233 | |// ------------------------------- | ||
234 | |// GATE_LJ retaddr | ||
235 | |// esp+aword*2 ARG3 | ||
236 | |// esp+aword*1 ARG2 | ||
237 | |// esp+aword*0 ARG1 <-- esp for first JIT frame | ||
238 | |// ------------------------------- | ||
239 | |// 1st JIT frame retaddr | ||
240 | |// esp+aword*2 ARG3 | ||
241 | |// esp+aword*1 ARG2 | ||
242 | |// esp+aword*0 ARG1 <-- esp for second JIT frame | ||
243 | |// ------------------------------- | ||
244 | |// 2nd JIT frame retaddr | ||
245 | |// | ||
246 | |// We could omit the fixed frame pointer (ebp) and have one more register | ||
247 | |// available. But there is no pressing need (could use it for CI). | ||
248 | |// And it's easier for debugging (gdb is still confused -- why?). | ||
249 | |// | ||
250 | |// The stack is aligned to 4 awords (16 bytes). Calls to C functions | ||
251 | |// with up to 3 arguments do not need any stack pointer adjustment. | ||
252 | |// | ||
253 | | | ||
254 | |.define CARG3, [ebp+aword*4] | ||
255 | |.define CARG2, [ebp+aword*3] | ||
256 | |.define CARG1, [ebp+aword*2] | ||
257 | |.define SAVER1, [ebp-aword*1] | ||
258 | |.define SAVER2, [ebp-aword*2] | ||
259 | |.define ARG7, aword [esp+aword*6] // Requires large frame. | ||
260 | |.define ARG6, aword [esp+aword*5] // Requires large frame. | ||
261 | |.define ARG5, aword [esp+aword*4] // Requires large frame. | ||
262 | |.define ARG4, aword [esp+aword*3] // Requires large frame. | ||
263 | |.define ARG3, aword [esp+aword*2] | ||
264 | |.define ARG2, aword [esp+aword*1] | ||
265 | |.define ARG1, aword [esp] | ||
266 | |.define FRAME_RETADDR, aword [esp+aword*3] | ||
267 | |.define TMP3, [esp+aword*2] | ||
268 | |.define TMP2, [esp+aword*1] | ||
269 | |.define TMP1, [esp] | ||
270 | |.define FPARG2, qword [esp+qword*1] // Requires large frame. | ||
271 | |.define FPARG1, qword [esp] | ||
272 | |.define LJFRAME_OFFSET, aword*2 // 16 byte aligned with retaddr + ebp. | ||
273 | |.define FRAME_OFFSET, aword*3 // 16 byte aligned with retaddr. | ||
274 | |.define LFRAME_OFFSET, aword*7 // 16 byte aligned with retaddr. | ||
275 | |.define S2LFRAME_OFFSET, aword*4 // Delta to large frame. | ||
276 | | | ||
277 | |.macro call, target, a1 | ||
278 | | mov ARG1, a1; call target; .endmacro | ||
279 | |.macro call, target, a1, a2 | ||
280 | | mov ARG1, a1; mov ARG2, a2; call target; .endmacro | ||
281 | |.macro call, target, a1, a2, a3 | ||
282 | | mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; call target; .endmacro | ||
283 | |.macro call, target, a1, a2, a3, a4 | ||
284 | | push a4; push a3; push a2; push a1 | ||
285 | | call target; add esp, S2LFRAME_OFFSET; .endmacro | ||
286 | |.macro call, target, a1, a2, a3, a4, a5 | ||
287 | | mov ARG1, a5; push a4; push a3; push a2; push a1 | ||
288 | | call target; add esp, S2LFRAME_OFFSET; .endmacro | ||
289 | | | ||
290 | |// The following macros require a large frame. | ||
291 | |.macro call_LFRAME, target, a1, a2, a3, a4 | ||
292 | | mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; mov ARG4, a4 | ||
293 | | call target; .endmacro | ||
294 | |.macro call_LFRAME, target, a1, a2, a3, a4, a5 | ||
295 | | mov ARG1, a1; mov ARG2, a2; mov ARG3, a3; mov ARG4, a4; mov ARG5, a5 | ||
296 | | call target; .endmacro | ||
297 | | | ||