aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/LuaJIT-1.1.7/src/ljit_x86.dash
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/LuaJIT-1.1.7/src/ljit_x86.dash')
-rw-r--r--libraries/LuaJIT-1.1.7/src/ljit_x86.dash297
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|