diff options
author | David Walter Seikel | 2012-01-23 23:36:30 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-23 23:36:30 +1000 |
commit | 6523585c66c04cea54df50013df8886b589847d8 (patch) | |
tree | 0b22aee7064166d88595eda260ca2d17c0773da5 /libraries/LuaJIT-1.1.7/src/ljit_x86.h | |
parent | Update the EFL to what I'm actually using, coz I'm using some stuff not yet r... (diff) | |
download | SledjHamr-6523585c66c04cea54df50013df8886b589847d8.zip SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.gz SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.bz2 SledjHamr-6523585c66c04cea54df50013df8886b589847d8.tar.xz |
Add luaproc and LuaJIT libraries.
Two versions of LuaJIT, the stable release, and the dev version. Try the dev version first, until ih fails badly.
Diffstat (limited to 'libraries/LuaJIT-1.1.7/src/ljit_x86.h')
-rw-r--r-- | libraries/LuaJIT-1.1.7/src/ljit_x86.h | 2301 |
1 files changed, 2301 insertions, 0 deletions
diff --git a/libraries/LuaJIT-1.1.7/src/ljit_x86.h b/libraries/LuaJIT-1.1.7/src/ljit_x86.h new file mode 100644 index 0000000..fc860bc --- /dev/null +++ b/libraries/LuaJIT-1.1.7/src/ljit_x86.h | |||
@@ -0,0 +1,2301 @@ | |||
1 | /* | ||
2 | ** This file has been pre-processed with DynASM. | ||
3 | ** http://luajit.org/dynasm.html | ||
4 | ** DynASM version 1.1.4, DynASM x86 version 1.1.4 | ||
5 | ** DO NOT EDIT! The original file is in "ljit_x86.dasc". | ||
6 | */ | ||
7 | |||
8 | #if DASM_VERSION != 10104 | ||
9 | #error "Version mismatch between DynASM and included encoding engine" | ||
10 | #endif | ||
11 | |||
12 | /* | ||
13 | ** Bytecode to machine code translation for x86 CPUs. | ||
14 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
15 | */ | ||
16 | |||
17 | #define DASM_SECTION_CODE 0 | ||
18 | #define DASM_SECTION_DEOPT 1 | ||
19 | #define DASM_SECTION_TAIL 2 | ||
20 | #define DASM_SECTION_MFMAP 3 | ||
21 | #define DASM_MAXSECTION 4 | ||
22 | #define Dt1(_V) (int)&(((lua_State *)0)_V) | ||
23 | #define Dt2(_V) (int)&(((TValue *)0)_V) | ||
24 | #define Dt3(_V) (int)&(((TValue *)0)_V) | ||
25 | #define Dt4(_V) (int)&(((CallInfo *)0)_V) | ||
26 | #define Dt5(_V) (int)&(((LClosure *)0)_V) | ||
27 | #define Dt6(_V) (int)&(((global_State *)0)_V) | ||
28 | #define Dt7(_V) (int)&(((TValue *)0)_V) | ||
29 | #define Dt8(_V) (int)&(((Value *)0)_V) | ||
30 | #define Dt9(_V) (int)&(((CallInfo *)0)_V) | ||
31 | #define DtA(_V) (int)&(((GCObject *)0)_V) | ||
32 | #define DtB(_V) (int)&(((TString *)0)_V) | ||
33 | #define DtC(_V) (int)&(((Table *)0)_V) | ||
34 | #define DtD(_V) (int)&(((CClosure *)0)_V) | ||
35 | #define DtE(_V) (int)&(((Proto *)0)_V) | ||
36 | #define DtF(_V) (int)&(((UpVal *)0)_V) | ||
37 | #define Dt10(_V) (int)&(((Node *)0)_V) | ||
38 | static const unsigned char jit_actionlist[5059] = { | ||
39 | 156,90,137,209,129,252,242,0,0,32,0,82,157,156,90,49,192,57,209,15,132,245, | ||
40 | 247,64,83,15,162,91,137,208,249,1,195,255,254,0,251,15,249,10,141,68,36,4, | ||
41 | 195,251,15,249,11,85,137,229,131,252,236,8,137,93,252,252,139,93,12,137,117, | ||
42 | 12,139,117,8,137,125,252,248,139,190,235,139,131,235,139,142,235,102,252, | ||
43 | 255,134,235,252,255,144,235,139,142,235,137,190,235,139,145,235,139,69,16, | ||
44 | 137,150,235,139,145,235,133,192,137,150,235,15,136,245,248,193,224,4,1,195, | ||
45 | 49,201,137,158,235,249,1,137,143,235,129,199,241,57,223,15,130,245,1,249, | ||
46 | 2,255,102,252,255,142,235,184,239,139,125,252,248,139,93,252,252,139,117, | ||
47 | 12,137,252,236,93,195,251,15,249,12,139,144,235,129,186,235,241,15,133,245, | ||
48 | 247,139,146,235,137,144,235,252,255,226,249,1,131,252,236,12,139,129,235, | ||
49 | 137,142,235,137,190,235,199,68,36,8,252,255,252,255,252,255,252,255,137,134, | ||
50 | 235,137,92,36,4,43,158,235,137,52,36,232,244,133,192,15,133,245,248,137,52, | ||
51 | 36,199,68,36,4,1,0,0,0,232,244,249,2,131,196,12,3,158,235,255,139,190,235, | ||
52 | 195,251,15,249,13,141,135,235,131,252,236,12,59,134,235,15,131,245,14,59, | ||
53 | 142,235,141,137,235,15,132,245,15,137,142,235,137,153,235,137,129,235,139, | ||
54 | 147,235,129,195,241,137,190,235,137,158,235,137,153,235,249,16,137,52,36, | ||
55 | 252,255,146,235,249,2,131,196,12,139,142,235,255,193,224,4,139,185,235,15, | ||
56 | 132,245,250,139,158,235,137,218,41,195,249,3,139,3,131,195,4,137,7,131,199, | ||
57 | 4,57,211,15,130,245,3,249,4,139,153,235,129,233,241,137,142,235,195,144,144, | ||
58 | 144,144,144,144,251,15,249,17,252,246,134,235,237,15,133,245,253,249,6,137, | ||
59 | 52,36,252,255,146,235,252,246,134,235,237,15,132,245,2,255,137,195,137,52, | ||
60 | 36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,255,252,255,232,244,137, | ||
61 | 216,233,245,2,249,7,137,211,137,52,36,199,68,36,4,239,199,68,36,8,252,255, | ||
62 | 252,255,252,255,252,255,232,244,137,218,233,245,6,251,15,249,14,41,252,248, | ||
63 | 193,252,248,4,137,190,235,43,158,235,137,76,36,8,137,52,36,137,68,36,4,232, | ||
64 | 244,139,76,36,8,3,158,235,139,190,235,139,131,235,131,196,12,252,255,160, | ||
65 | 235,251,15,249,15,137,190,235,137,52,36,232,244,141,136,235,255,139,131,235, | ||
66 | 137,142,235,131,196,12,252,255,160,235,255,249,18,90,233,245,19,249,20,137, | ||
67 | 190,235,249,19,137,150,235,137,52,36,232,244,139,158,235,139,190,235,252, | ||
68 | 255,224,251,15,255,137,190,235,255,232,245,21,255,251,15,249,21,252,246,134, | ||
69 | 235,237,15,132,245,248,252,255,142,235,15,132,245,247,252,246,134,235,237, | ||
70 | 15,132,245,248,249,1,139,4,36,131,252,236,12,137,52,36,137,68,36,4,232,244, | ||
71 | 131,196,12,139,158,235,139,190,235,249,2,195,255,250,255,233,246,255,250, | ||
72 | 243,255,254,1,233,245,19,254,0,250,254,2,250,251,1,252,255,252,255,254,3, | ||
73 | 242,0,0,0,0,0,0,0,0,0,254,0,141,249,9,186,239,254,0,249,9,186,239,233,245, | ||
74 | 20,254,0,139,142,235,139,129,235,191,247,253,59,129,235,15,131,245,22,249, | ||
75 | 7,255,251,15,249,22,137,52,36,232,244,139,158,235,252,255,231,255,131,187, | ||
76 | 235,5,15,133,245,9,49,192,137,131,235,137,131,235,254,3,238,238,254,0,131, | ||
77 | 190,235,0,15,132,245,9,199,134,235,239,129,195,241,255,141,187,235,255,137, | ||
78 | 158,235,137,190,235,137,52,36,232,244,139,158,235,139,190,235,255,199,135, | ||
79 | 235,0,0,0,0,255,139,139,235,252,243,15,126,131,235,137,139,235,102,15,214, | ||
80 | 131,235,255,139,139,235,139,147,235,139,131,235,137,139,235,137,147,235,137, | ||
81 | 131,235,255,57,223,15,130,245,9,255,131,187,235,8,15,133,245,9,139,131,235, | ||
82 | 131,184,235,0,15,132,245,9,199,134,235,239,137,190,235,137,52,36,137,92,36, | ||
83 | 4,199,68,36,8,239,232,244,139,158,235,255,137,199,255,131,187,235,4,15,133, | ||
84 | 245,9,139,139,235,219,129,235,199,131,235,3,0,0,0,221,155,235,255,141,187, | ||
85 | 235,232,245,23,137,131,235,199,131,235,4,0,0,0,255,141,187,235,232,245,24, | ||
86 | 137,131,235,199,131,235,4,0,0,0,255,131,187,235,3,15,133,245,9,141,134,235, | ||
87 | 221,131,235,219,24,129,56,252,255,0,0,0,15,135,245,9,137,52,36,137,68,36, | ||
88 | 4,199,68,36,8,1,0,0,0,232,244,137,131,235,199,131,235,4,0,0,0,255,251,15, | ||
89 | 249,23,139,135,235,193,224,4,11,135,235,193,224,4,11,135,235,45,51,4,0,0, | ||
90 | 15,133,245,18,221,135,235,221,135,235,219,92,36,8,219,92,36,4,139,143,235, | ||
91 | 139,185,235,139,84,36,8,57,215,15,130,245,250,249,1,11,68,36,4,15,142,245, | ||
92 | 252,249,2,41,194,15,140,245,253,141,140,253,1,235,66,249,3,137,116,36,4,137, | ||
93 | 76,36,8,137,84,36,12,139,190,235,139,135,235,255,59,135,235,15,131,245,254, | ||
94 | 233,244,249,4,15,140,245,251,141,84,58,1,233,245,1,249,5,137,252,250,233, | ||
95 | 245,1,249,6,15,132,245,251,1,252,248,64,15,143,245,2,249,5,184,1,0,0,0,233, | ||
96 | 245,2,249,7,49,210,233,245,3,255,251,15,249,24,139,135,235,193,224,4,11,135, | ||
97 | 235,131,232,67,15,133,245,18,221,135,235,219,92,36,4,139,143,235,139,185, | ||
98 | 235,137,252,250,233,245,1,249,8,131,252,236,12,137,52,36,232,244,131,196, | ||
99 | 12,139,158,235,233,244,255,131,187,235,5,15,133,245,9,255,141,131,235,137, | ||
100 | 52,36,137,68,36,4,232,244,255,141,131,235,141,139,235,137,52,36,137,68,36, | ||
101 | 4,137,76,36,8,232,244,255,139,131,235,137,4,36,232,244,137,4,36,219,4,36, | ||
102 | 221,155,235,199,131,235,3,0,0,0,255,131,187,235,3,15,133,245,9,221,131,235, | ||
103 | 255,139,131,235,193,224,4,11,131,235,131,252,248,51,15,133,245,9,255,217, | ||
104 | 252,254,255,217,252,255,255,217,252,242,221,216,255,217,60,36,217,45,239, | ||
105 | 217,252,252,217,44,36,255,217,225,255,217,252,250,255,221,131,235,221,131, | ||
106 | 235,249,1,217,252,248,223,224,158,15,138,245,1,221,217,255,221,131,235,221, | ||
107 | 131,235,217,252,243,255,221,28,36,232,244,255,131,187,235,6,15,133,245,9, | ||
108 | 129,187,235,239,15,133,245,9,255,141,131,235,57,199,15,133,245,9,255,141, | ||
109 | 187,235,137,190,235,255,131,196,12,129,252,235,241,129,174,235,241,195,255, | ||
110 | 141,187,235,137,52,36,137,124,36,4,232,244,133,192,15,133,246,255,139,131, | ||
111 | 235,64,139,147,235,137,131,235,137,20,36,137,68,36,4,232,244,139,136,235, | ||
112 | 133,201,15,132,245,255,219,131,235,199,131,235,3,0,0,0,221,155,235,139,144, | ||
113 | 235,139,128,235,137,139,235,137,147,235,137,131,235,233,246,249,9,255,141, | ||
114 | 135,235,131,252,236,12,59,134,235,15,131,245,14,59,142,235,141,137,235,15, | ||
115 | 132,245,15,49,192,137,153,235,129,195,241,137,142,235,255,141,147,235,57, | ||
116 | 215,255,137,223,255,15,71,252,250,255,15,134,245,247,137,215,249,1,255,141, | ||
117 | 147,235,137,129,235,137,145,235,137,150,235,137,158,235,137,153,235,255,15, | ||
118 | 130,245,251,249,4,254,2,249,5,137,135,235,129,199,241,57,215,15,130,245,5, | ||
119 | 233,245,4,254,0,137,190,235,137,185,235,137,129,235,255,139,139,235,252,243, | ||
120 | 15,126,131,235,137,143,235,102,15,214,135,235,255,139,139,235,139,147,235, | ||
121 | 137,143,235,139,139,235,137,151,235,137,143,235,255,137,252,251,141,147,235, | ||
122 | 141,187,235,137,145,235,137,150,235,255,137,135,235,255,249,2,137,135,235, | ||
123 | 137,135,235,129,199,241,57,215,15,130,245,2,255,137,52,36,232,244,255,252, | ||
124 | 246,134,235,237,15,132,245,255,232,245,25,249,9,255,251,15,249,25,139,142, | ||
125 | 235,139,185,235,139,135,235,139,184,235,139,135,235,131,192,4,137,134,235, | ||
126 | 131,252,236,12,137,52,36,199,68,36,4,239,199,68,36,8,252,255,252,255,252, | ||
127 | 255,252,255,232,244,131,196,12,139,135,235,137,134,235,139,158,235,195,255, | ||
128 | 137,52,36,137,92,36,4,232,244,255,129,174,235,241,137,223,129,252,235,241, | ||
129 | 131,196,12,255,139,142,235,139,153,235,129,233,241,137,142,235,141,187,235, | ||
130 | 131,196,12,255,252,246,134,235,237,15,132,245,253,232,245,26,249,7,255,139, | ||
131 | 68,36,12,137,134,235,255,251,15,249,26,139,4,36,137,134,235,131,252,236,12, | ||
132 | 137,52,36,199,68,36,4,239,199,68,36,8,252,255,252,255,252,255,252,255,232, | ||
133 | 244,131,196,12,139,158,235,139,190,235,195,255,139,145,235,57,252,251,15, | ||
134 | 131,245,248,249,1,139,3,131,195,4,137,2,131,194,4,57,252,251,15,130,245,1, | ||
135 | 249,2,131,196,12,139,153,235,129,233,241,137,215,137,142,235,195,255,129, | ||
136 | 174,235,241,129,252,235,241,255,131,196,12,141,187,235,195,255,139,142,235, | ||
137 | 139,185,235,129,233,241,137,142,235,255,139,139,235,139,147,235,139,131,235, | ||
138 | 137,143,235,137,151,235,137,135,235,255,131,196,12,137,252,251,255,129,199, | ||
139 | 241,255,139,142,235,131,187,235,6,255,139,131,235,186,239,137,145,235,255, | ||
140 | 15,133,245,20,255,15,133,245,19,255,15,132,245,247,232,245,27,249,1,255,251, | ||
141 | 15,249,27,131,252,236,12,137,150,235,137,190,235,137,52,36,137,92,36,4,232, | ||
142 | 244,131,196,12,137,195,139,190,235,139,131,235,139,142,235,195,255,252,255, | ||
143 | 144,235,255,137,158,235,255,49,192,255,141,147,235,249,1,137,135,235,137, | ||
144 | 135,235,129,199,241,57,215,15,130,245,1,255,131,187,235,6,15,133,245,9,255, | ||
145 | 131,187,235,6,15,133,245,251,254,2,249,5,255,186,239,233,245,28,254,0,251, | ||
146 | 15,249,28,137,150,235,137,190,235,137,52,36,137,92,36,4,232,244,139,142,235, | ||
147 | 139,150,235,139,185,235,249,1,139,24,131,192,4,137,31,131,199,4,57,208,15, | ||
148 | 130,245,1,139,153,235,139,131,235,129,233,241,131,196,12,252,255,160,235, | ||
149 | 255,139,131,235,255,139,139,235,139,147,235,137,139,235,139,139,235,137,147, | ||
150 | 235,137,139,235,255,141,187,235,129,252,235,241,139,142,235,137,131,235,255, | ||
151 | 139,142,235,141,187,235,139,153,235,139,135,235,137,131,235,255,139,135,235, | ||
152 | 252,243,15,126,135,235,137,131,235,102,15,214,131,235,255,139,135,235,139, | ||
153 | 151,235,137,131,235,139,135,235,137,147,235,137,131,235,255,141,187,235,139, | ||
154 | 131,235,255,139,145,235,249,1,139,3,131,195,4,137,2,131,194,4,57,252,251, | ||
155 | 15,130,245,1,139,153,235,137,215,139,131,235,255,199,131,235,0,0,0,0,255, | ||
156 | 186,1,0,0,0,137,147,235,137,147,235,255,199,131,235,0,0,0,0,199,131,235,1, | ||
157 | 0,0,0,255,217,252,238,255,217,232,255,221,5,239,255,199,131,235,239,199,131, | ||
158 | 235,4,0,0,0,255,137,131,235,195,255,141,139,235,141,147,235,249,1,137,1,57, | ||
159 | 209,141,137,235,15,134,245,1,255,139,142,235,139,185,235,139,135,235,255, | ||
160 | 139,136,235,139,185,235,255,139,143,235,252,243,15,126,135,235,137,139,235, | ||
161 | 102,15,214,131,235,255,139,143,235,139,151,235,139,135,235,137,139,235,137, | ||
162 | 147,235,137,131,235,255,139,136,235,139,185,235,139,131,235,139,147,235,137, | ||
163 | 135,235,131,252,248,4,139,131,235,137,151,235,137,135,235,15,131,245,251, | ||
164 | 249,4,254,2,249,5,252,246,130,235,237,15,132,245,4,252,246,129,235,237,15, | ||
165 | 132,245,4,232,245,29,233,245,4,254,0,251,15,249,29,137,84,36,12,137,76,36, | ||
166 | 8,137,116,36,4,233,244,255,251,15,249,30,139,142,235,139,185,235,139,135, | ||
167 | 235,139,184,235,233,245,255,255,251,15,249,31,131,191,235,5,139,191,235,15, | ||
168 | 133,245,18,249,9,15,182,143,235,184,1,0,0,0,211,224,72,35,130,235,193,224, | ||
169 | 5,3,135,235,249,1,131,184,235,4,15,133,245,248,57,144,235,15,133,245,248, | ||
170 | 139,136,235,133,201,15,132,245,249,255,252,243,15,126,128,235,102,15,214, | ||
171 | 131,235,255,139,144,235,139,184,235,137,147,235,137,187,235,255,137,139,235, | ||
172 | 139,158,235,195,249,2,139,128,235,133,192,15,133,245,1,49,201,249,3,139,135, | ||
173 | 235,133,192,15,132,245,250,252,246,128,235,237,15,132,245,251,249,4,137,139, | ||
174 | 235,139,158,235,195,249,5,137,150,235,199,134,235,4,0,0,0,139,12,36,131,252, | ||
175 | 236,12,137,142,235,137,52,36,137,124,36,4,137,92,36,8,232,244,131,196,12, | ||
176 | 139,158,235,255,251,15,249,32,139,135,235,193,224,4,11,129,235,131,252,248, | ||
177 | 84,139,191,235,139,145,235,15,132,245,9,233,245,18,255,251,15,249,33,139, | ||
178 | 142,235,128,167,235,237,139,145,235,137,185,235,137,151,235,195,255,251,15, | ||
179 | 249,34,139,142,235,139,185,235,139,135,235,139,184,235,233,245,255,255,251, | ||
180 | 15,249,35,131,191,235,5,139,191,235,15,133,245,18,249,9,15,182,143,235,184, | ||
181 | 1,0,0,0,211,224,72,35,130,235,193,224,5,3,135,235,249,1,131,184,235,4,15, | ||
182 | 133,245,250,57,144,235,15,133,245,250,131,184,235,0,15,132,245,252,249,2, | ||
183 | 198,135,235,0,249,3,255,252,246,135,235,237,15,133,245,254,249,7,255,139, | ||
184 | 139,235,252,243,15,126,131,235,137,136,235,102,15,214,128,235,255,139,139, | ||
185 | 235,139,147,235,139,187,235,137,136,235,137,144,235,137,184,235,255,139,158, | ||
186 | 235,195,249,8,232,245,33,233,245,7,249,4,139,128,235,133,192,15,133,245,1, | ||
187 | 139,143,235,133,201,15,132,245,251,252,246,129,235,237,15,132,245,253,249, | ||
188 | 5,141,134,235,137,144,235,199,128,235,4,0,0,0,131,252,236,12,137,52,36,137, | ||
189 | 124,36,4,137,68,36,8,232,244,131,196,12,233,245,2,249,6,255,139,143,235,133, | ||
190 | 201,15,132,245,2,252,246,129,235,237,15,133,245,2,249,7,137,150,235,199,134, | ||
191 | 235,4,0,0,0,139,12,36,131,252,236,12,137,142,235,137,52,36,137,124,36,4,137, | ||
192 | 92,36,8,232,244,131,196,12,139,158,235,195,255,251,15,249,36,139,135,235, | ||
193 | 193,224,4,11,129,235,131,252,248,84,139,191,235,139,145,235,15,132,245,9, | ||
194 | 233,245,18,255,137,52,36,199,68,36,4,239,199,68,36,8,239,232,244,137,131, | ||
195 | 235,199,131,235,5,0,0,0,255,186,239,255,232,245,30,255,232,245,34,255,141, | ||
196 | 187,235,186,239,255,141,187,235,141,139,235,255,131,187,235,5,139,187,235, | ||
197 | 15,133,245,255,185,239,139,135,235,59,143,235,15,135,245,251,255,139,131, | ||
198 | 235,193,224,4,11,131,235,131,252,248,83,15,133,245,255,255,252,242,15,16, | ||
199 | 131,235,252,242,15,44,192,252,242,15,42,200,72,102,15,46,200,139,187,235, | ||
200 | 15,133,245,255,15,138,245,255,255,221,131,235,219,20,36,219,4,36,255,223, | ||
201 | 233,221,216,255,218,233,223,224,158,255,15,133,245,255,15,138,245,255,139, | ||
202 | 4,36,139,187,235,72,255,59,135,235,15,131,245,251,193,224,4,3,135,235,255, | ||
203 | 232,245,31,255,232,245,32,255,185,239,255,141,147,235,255,199,134,235,239, | ||
204 | 83,81,82,86,232,244,131,196,16,139,158,235,255,249,1,139,144,235,133,210, | ||
205 | 15,132,245,252,255,139,136,235,139,128,235,137,139,235,137,131,235,255,249, | ||
206 | 2,137,147,235,254,2,232,245,37,255,232,245,38,255,233,245,1,249,6,139,143, | ||
207 | 235,133,201,15,132,245,2,252,246,129,235,237,15,133,245,2,249,9,186,239,233, | ||
208 | 245,19,254,0,251,15,249,37,137,76,36,4,131,252,236,12,137,60,36,137,76,36, | ||
209 | 4,232,244,131,196,12,139,76,36,4,193,225,4,41,200,129,192,241,195,255,251, | ||
210 | 15,249,38,64,137,124,36,4,137,68,36,8,233,244,255,187,239,255,232,245,35, | ||
211 | 255,232,245,36,255,199,134,235,239,82,81,83,86,232,244,131,196,16,139,158, | ||
212 | 235,255,249,1,131,184,235,0,15,132,245,252,249,2,254,2,232,245,39,255,232, | ||
213 | 245,40,255,252,246,135,235,237,15,133,245,253,249,3,254,2,249,7,232,245,33, | ||
214 | 233,245,3,254,0,199,128,235,0,0,0,0,255,186,1,0,0,0,137,144,235,137,144,235, | ||
215 | 255,199,128,235,0,0,0,0,199,128,235,1,0,0,0,255,221,152,235,199,128,235,3, | ||
216 | 0,0,0,255,199,128,235,239,199,128,235,4,0,0,0,255,251,15,249,39,137,76,36, | ||
217 | 4,131,252,236,12,137,52,36,137,124,36,4,137,76,36,8,232,244,131,196,12,139, | ||
218 | 76,36,4,193,225,4,41,200,129,192,241,195,255,251,15,249,40,64,137,116,36, | ||
219 | 4,137,124,36,8,137,68,36,12,233,244,255,137,190,235,141,131,235,41,252,248, | ||
220 | 252,247,216,193,252,248,4,139,187,235,15,132,245,250,255,129,192,241,255, | ||
221 | 57,135,235,15,131,245,247,137,52,36,137,124,36,4,137,68,36,8,232,244,249, | ||
222 | 1,252,246,135,235,237,139,151,235,15,133,245,252,139,190,235,254,2,249,6, | ||
223 | 232,245,33,233,245,1,254,0,139,187,235,129,191,235,241,15,130,245,251,249, | ||
224 | 1,252,246,135,235,237,139,151,235,15,133,245,252,141,187,235,254,2,249,5, | ||
225 | 137,52,36,137,124,36,4,199,68,36,8,239,232,244,233,245,1,249,6,232,245,33, | ||
226 | 233,245,1,254,0,129,194,241,255,141,139,235,249,3,139,1,131,193,4,137,2,131, | ||
227 | 194,4,57,252,249,15,130,245,3,249,4,255,131,187,235,3,139,131,235,15,133, | ||
228 | 245,255,133,192,15,136,245,255,255,221,131,235,221,5,239,255,221,5,239,221, | ||
229 | 131,235,255,139,131,235,193,224,4,11,131,235,131,252,248,51,139,131,235,15, | ||
230 | 133,245,255,11,131,235,15,136,245,255,221,131,235,221,131,235,255,131,187, | ||
231 | 235,3,15,133,245,255,221,131,235,255,216,200,255,217,192,216,200,255,220, | ||
232 | 201,255,222,201,255,199,4,36,239,199,68,36,4,239,199,68,36,8,239,131,187, | ||
233 | 235,3,15,133,245,255,219,44,36,220,139,235,217,192,217,252,252,220,233,217, | ||
234 | 201,217,252,240,217,232,222,193,217,252,253,221,217,255,251,15,249,41,217, | ||
235 | 232,221,68,36,8,217,252,241,139,68,36,4,219,56,195,255,131,187,235,3,15,133, | ||
236 | 245,255,255,131,187,235,3,255,139,131,235,193,224,4,11,131,235,131,252,248, | ||
237 | 51,255,216,192,255,220,131,235,255,220,163,235,255,220,171,235,255,220,139, | ||
238 | 235,255,220,179,235,255,220,187,235,255,131,252,236,16,221,28,36,221,131, | ||
239 | 235,221,92,36,8,232,244,131,196,16,255,131,252,236,16,221,92,36,8,221,131, | ||
240 | 235,221,28,36,232,244,131,196,16,255,217,224,255,15,138,246,255,15,130,246, | ||
241 | 255,15,134,246,255,15,135,246,255,15,131,246,255,199,134,235,239,137,52,36, | ||
242 | 137,76,36,4,137,84,36,8,232,244,133,192,139,158,235,255,15,132,246,255,199, | ||
243 | 134,235,239,199,4,36,239,82,81,83,86,232,244,131,196,16,139,158,235,255,131, | ||
244 | 187,235,5,139,139,235,15,133,245,9,137,12,36,232,244,137,4,36,219,4,36,221, | ||
245 | 155,235,199,131,235,3,0,0,0,255,131,187,235,4,139,139,235,15,133,245,9,219, | ||
246 | 129,235,221,155,235,199,131,235,3,0,0,0,255,199,134,235,239,137,52,36,137, | ||
247 | 92,36,4,137,76,36,8,232,244,139,158,235,255,139,131,235,139,139,235,186,1, | ||
248 | 0,0,0,33,193,209,232,9,193,49,192,57,209,17,192,137,147,235,137,131,235,255, | ||
249 | 232,245,42,137,131,235,199,131,235,4,0,0,0,255,199,134,235,239,137,52,36, | ||
250 | 199,68,36,4,239,199,68,36,8,239,232,244,139,158,235,255,251,15,249,42,137, | ||
251 | 116,36,4,139,131,235,193,224,4,11,131,235,131,232,68,15,133,245,18,249,1, | ||
252 | 139,190,235,139,179,235,139,147,235,139,142,235,133,201,15,132,245,248,11, | ||
253 | 130,235,15,132,245,250,1,200,15,130,245,255,59,135,235,15,135,245,251,139, | ||
254 | 191,235,129,198,241,255,252,243,164,139,138,235,141,178,235,252,243,164,41, | ||
255 | 199,139,116,36,4,137,124,36,8,137,68,36,12,139,158,235,233,244,249,2,137, | ||
256 | 208,249,3,139,116,36,4,139,158,235,195,249,4,137,252,240,233,245,3,249,5, | ||
257 | 139,116,36,4,141,143,235,131,252,236,12,137,52,36,137,76,36,4,137,68,36,8, | ||
258 | 232,244,131,196,12,49,192,233,245,1,249,9,139,116,36,4,233,245,18,255,131, | ||
259 | 187,235,0,255,139,131,235,139,139,235,72,73,9,200,255,139,131,235,72,11,131, | ||
260 | 235,255,131,187,235,3,15,133,246,221,131,235,221,5,239,255,131,187,235,4, | ||
261 | 15,133,246,129,187,235,239,255,139,131,235,59,131,235,15,133,246,255,131, | ||
262 | 252,248,3,15,133,245,9,221,131,235,221,131,235,255,131,252,248,4,15,133,245, | ||
263 | 9,139,139,235,59,139,235,255,141,147,235,141,139,235,199,134,235,239,137, | ||
264 | 52,36,137,76,36,4,137,84,36,8,232,244,72,139,158,235,255,139,131,235,139, | ||
265 | 139,235,137,194,33,202,141,20,80,209,234,255,15,132,245,247,255,15,133,245, | ||
266 | 247,255,139,147,235,137,131,235,137,139,235,137,147,235,233,246,249,1,255, | ||
267 | 139,131,235,193,224,4,11,131,235,131,252,248,51,15,133,245,255,249,4,221, | ||
268 | 131,235,221,131,235,221,147,235,255,249,4,139,131,235,193,224,4,11,131,235, | ||
269 | 193,224,4,11,131,235,61,51,3,0,0,139,131,235,15,133,245,255,221,131,235,221, | ||
270 | 131,235,133,192,221,147,235,15,136,245,247,217,201,249,1,255,199,131,235, | ||
271 | 3,0,0,0,15,130,246,255,249,9,141,131,235,199,134,235,239,137,52,36,137,68, | ||
272 | 36,4,232,244,233,245,4,254,0,221,131,235,221,131,235,220,131,235,221,147, | ||
273 | 235,221,147,235,199,131,235,3,0,0,0,255,139,131,235,221,131,235,221,131,235, | ||
274 | 221,131,235,222,193,221,147,235,221,147,235,199,131,235,3,0,0,0,133,192,15, | ||
275 | 136,245,247,217,201,249,1,255,131,187,235,0,15,132,245,247,255,141,131,235, | ||
276 | 137,68,36,4,255,137,92,36,4,255,139,187,235,255,139,142,235,139,185,235,139, | ||
277 | 191,235,255,139,151,235,137,52,36,199,68,36,4,239,137,84,36,8,232,244,199, | ||
278 | 128,235,239,137,131,235,199,131,235,6,0,0,0,255,139,151,235,137,144,235,255, | ||
279 | 137,52,36,232,244,137,135,235,255,249,1,139,142,235,139,145,235,129,194,241, | ||
280 | 141,132,253,27,235,41,208,59,134,235,15,131,245,251,141,187,235,57,218,15, | ||
281 | 131,245,249,249,2,139,2,131,194,4,137,7,131,199,4,57,218,15,130,245,2,249, | ||
282 | 3,254,2,249,5,43,134,235,193,252,248,4,137,52,36,137,68,36,4,232,244,139, | ||
283 | 158,235,233,245,1,254,0,139,142,235,139,145,235,129,194,241,141,187,235,141, | ||
284 | 139,235,57,218,15,131,245,248,249,1,139,2,131,194,4,137,7,131,199,4,57,207, | ||
285 | 15,131,245,250,57,218,15,130,245,1,249,2,49,192,249,3,137,135,235,129,199, | ||
286 | 241,57,207,15,130,245,3,249,4,255 | ||
287 | }; | ||
288 | |||
289 | enum { | ||
290 | JSUB_STACKPTR, | ||
291 | JSUB_GATE_LJ, | ||
292 | JSUB_GATE_JL, | ||
293 | JSUB_GATE_JC, | ||
294 | JSUB_GROW_STACK, | ||
295 | JSUB_GROW_CI, | ||
296 | JSUB_GATE_JC_PATCH, | ||
297 | JSUB_GATE_JC_DEBUG, | ||
298 | JSUB_DEOPTIMIZE_CALLER, | ||
299 | JSUB_DEOPTIMIZE, | ||
300 | JSUB_DEOPTIMIZE_OPEN, | ||
301 | JSUB_HOOKINS, | ||
302 | JSUB_GCSTEP, | ||
303 | JSUB_STRING_SUB3, | ||
304 | JSUB_STRING_SUB2, | ||
305 | JSUB_HOOKCALL, | ||
306 | JSUB_HOOKRET, | ||
307 | JSUB_METACALL, | ||
308 | JSUB_METATAILCALL, | ||
309 | JSUB_BARRIERF, | ||
310 | JSUB_GETGLOBAL, | ||
311 | JSUB_GETTABLE_KSTR, | ||
312 | JSUB_GETTABLE_STR, | ||
313 | JSUB_BARRIERBACK, | ||
314 | JSUB_SETGLOBAL, | ||
315 | JSUB_SETTABLE_KSTR, | ||
316 | JSUB_SETTABLE_STR, | ||
317 | JSUB_GETTABLE_KNUM, | ||
318 | JSUB_GETTABLE_NUM, | ||
319 | JSUB_SETTABLE_KNUM, | ||
320 | JSUB_SETTABLE_NUM, | ||
321 | JSUB_LOG2_TWORD, | ||
322 | JSUB_CONCAT_STR2, | ||
323 | JSUB__MAX | ||
324 | }; | ||
325 | |||
326 | /* ------------------------------------------------------------------------ */ | ||
327 | |||
328 | /* Arch string. */ | ||
329 | const char luaJIT_arch[] = "x86"; | ||
330 | |||
331 | /* Forward declarations for C functions called from jsubs. */ | ||
332 | static void jit_hookins(lua_State *L, const Instruction *newpc); | ||
333 | static void jit_gettable_fb(lua_State *L, Table *t, StkId dest); | ||
334 | static void jit_settable_fb(lua_State *L, Table *t, StkId val); | ||
335 | |||
336 | /* ------------------------------------------------------------------------ */ | ||
337 | |||
338 | /* Detect CPU features and set JIT flags. */ | ||
339 | static int jit_cpudetect(jit_State *J) | ||
340 | { | ||
341 | void *mcode; | ||
342 | size_t sz; | ||
343 | int status; | ||
344 | /* Some of the jsubs need the flags. So compile this separately. */ | ||
345 | unsigned int feature; | ||
346 | dasm_setup(Dst, jit_actionlist); | ||
347 | dasm_put(Dst, 0); | ||
348 | (void)dasm_checkstep(Dst, DASM_SECTION_CODE); | ||
349 | status = luaJIT_link(J, &mcode, &sz); | ||
350 | if (status != JIT_S_OK) | ||
351 | return status; | ||
352 | /* Check feature bits. See the Intel/AMD manuals for the bit definitions. */ | ||
353 | feature = ((unsigned int (*)(void))mcode)(); | ||
354 | if (feature & (1<<15)) J->flags |= JIT_F_CPU_CMOV; | ||
355 | if (feature & (1<<26)) J->flags |= JIT_F_CPU_SSE2; | ||
356 | luaJIT_freemcode(J, mcode, sz); /* We don't need this code anymore. */ | ||
357 | return JIT_S_OK; | ||
358 | } | ||
359 | |||
360 | /* Check some assumptions. Should compile to nop. */ | ||
361 | static int jit_consistency_check(jit_State *J) | ||
362 | { | ||
363 | do { | ||
364 | /* Force a compiler error for inconsistent structure sizes. */ | ||
365 | /* Check LUA_TVALUE_ALIGN in luaconf.h, too. */ | ||
366 | int check_TVALUE_SIZE_in_ljit_x86_dash[1+16-sizeof(TValue)]; | ||
367 | int check_TVALUE_SIZE_in_ljit_x86_dash_[1+sizeof(TValue)-16]; | ||
368 | ((void)check_TVALUE_SIZE_in_ljit_x86_dash[0]); | ||
369 | ((void)check_TVALUE_SIZE_in_ljit_x86_dash_[0]); | ||
370 | if (LUA_TNIL != 0 || LUA_TBOOLEAN != 1 || PCRLUA != 0) break; | ||
371 | if ((int)&(((Node *)0)->i_val) != (int)&(((StkId)0)->value)) break; | ||
372 | return JIT_S_OK; | ||
373 | } while (0); | ||
374 | J->dasmstatus = 999999999; /* Recognizable error. */ | ||
375 | return JIT_S_COMPILER_ERROR; | ||
376 | } | ||
377 | |||
378 | /* Compile JIT subroutines (once). */ | ||
379 | static int jit_compile_jsub(jit_State *J) | ||
380 | { | ||
381 | int status = jit_consistency_check(J); | ||
382 | if (status != JIT_S_OK) return status; | ||
383 | status = jit_cpudetect(J); | ||
384 | if (status != JIT_S_OK) return status; | ||
385 | dasm_setup(Dst, jit_actionlist); | ||
386 | dasm_put(Dst, 34); | ||
387 | dasm_put(Dst, 36, Dt1(->top), Dt2(->value), Dt1(->ci), Dt1(->nCcalls), Dt5(->jit_gate), Dt1(->ci), Dt1(->top), Dt4(->savedpc), Dt1(->savedpc), Dt4(->base), Dt1(->base), Dt1(->top), Dt3(->tt), sizeof(TValue)); | ||
388 | dasm_put(Dst, 145, Dt1(->nCcalls), PCRC, Dt5(->p), DtE(->jit_status), JIT_S_OK, DtE(->jit_mcode), Dt5(->jit_gate), Dt4(->savedpc), Dt1(->ci), Dt1(->top), Dt1(->savedpc), Dt1(->stack), (ptrdiff_t)(luaD_precall), (ptrdiff_t)(luaV_execute), Dt1(->stack)); | ||
389 | dasm_put(Dst, 262, Dt1(->top), Dt3([LUA_MINSTACK]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt1(->ci), Dt4(->func), Dt4(->top), Dt2(->value), sizeof(TValue), Dt1(->top), Dt1(->base), Dt4(->base), DtD(->f), Dt1(->ci)); | ||
390 | dasm_put(Dst, 336, Dt4(->func), Dt1(->top), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt1(->hookmask), LUA_MASKCALL, DtD(->f), Dt1(->hookmask), LUA_MASKRET); | ||
391 | dasm_put(Dst, 421, LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), Dt1(->top), Dt1(->stack), (ptrdiff_t)(luaD_growstack), Dt1(->stack), Dt1(->top), Dt2(->value), Dt5(->jit_gate), Dt1(->top), (ptrdiff_t)(luaD_growCI), Dt9([-1])); | ||
392 | dasm_put(Dst, 547, Dt2(->value), Dt1(->ci), Dt5(->jit_gate)); | ||
393 | dasm_put(Dst, 602, Dt1(->hookmask), LUA_MASKLINE|LUA_MASKCOUNT, Dt1(->hookcount), Dt1(->hookmask), LUA_MASKLINE, (ptrdiff_t)(jit_hookins), Dt1(->base), Dt1(->top)); | ||
394 | dasm_put(Dst, 737, (ptrdiff_t)(luaC_step), Dt1(->base)); | ||
395 | dasm_put(Dst, 1026, Dt3([0].tt), Dt3([1].tt), Dt3([2].tt), Dt3([1].value), Dt3([2].value), Dt3([0].value), DtB(->tsv.len), sizeof(TString)-1, Dt1(->l_G), Dt6(->totalbytes)); | ||
396 | dasm_put(Dst, 1129, Dt6(->GCthreshold), (ptrdiff_t)(luaS_newlstr)); | ||
397 | dasm_put(Dst, 1191, Dt3([0].tt), Dt3([1].tt), Dt3([1].value), Dt3([0].value), DtB(->tsv.len), (ptrdiff_t)(luaC_step), Dt1(->base), (ptrdiff_t)(luaS_newlstr)); | ||
398 | dasm_put(Dst, 1755, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->p), DtE(->code), Dt1(->savedpc), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), DtE(->code), Dt1(->savedpc), Dt1(->base)); | ||
399 | dasm_put(Dst, 1886, Dt1(->savedpc), LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), Dt1(->base), Dt1(->top)); | ||
400 | dasm_put(Dst, 2077, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->top), Dt2(->value), Dt1(->ci)); | ||
401 | dasm_put(Dst, 2178, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->ci), Dt1(->top), Dt4(->func), Dt4(->func), Dt2(->value), sizeof(CallInfo), Dt5(->jit_gate)); | ||
402 | dasm_put(Dst, 2570, (ptrdiff_t)(luaC_barrierf)); | ||
403 | dasm_put(Dst, 2589, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env)); | ||
404 | dasm_put(Dst, 2609, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt)); | ||
405 | if (J->flags & JIT_F_CPU_SSE2) { | ||
406 | dasm_put(Dst, 2674, Dt10(->i_val.value), Dt2(->value)); | ||
407 | } else { | ||
408 | dasm_put(Dst, 2686, Dt10(->i_val.value), Dt10(->i_val.value.na[1]), Dt2(->value), Dt2(->value.na[1])); | ||
409 | } | ||
410 | dasm_put(Dst, 2699, Dt2(->tt), Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_INDEX, Dt2([0].tt), Dt1(->base), Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_gettable_fb), Dt1(->base)); | ||
411 | dasm_put(Dst, 32); | ||
412 | dasm_put(Dst, 2790, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value)); | ||
413 | dasm_put(Dst, 2821, Dt1(->l_G), DtC(->marked), (~bitmask(BLACKBIT))&0xff, Dt6(->grayagain), Dt6(->grayagain), DtC(->gclist)); | ||
414 | dasm_put(Dst, 2843, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env)); | ||
415 | dasm_put(Dst, 2863, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt), DtC(->flags)); | ||
416 | dasm_put(Dst, 2935, DtC(->marked), bitmask(BLACKBIT)); | ||
417 | if (J->flags & JIT_F_CPU_SSE2) { | ||
418 | dasm_put(Dst, 2947, Dt2([0].tt), Dt2([0].value), Dt7([0].tt), Dt7([0].value)); | ||
419 | } else { | ||
420 | dasm_put(Dst, 2965, Dt2([0].value), Dt2([0].value.na[1]), Dt2([0].tt), Dt7([0].value), Dt7([0].value.na[1]), Dt7([0].tt)); | ||
421 | } | ||
422 | dasm_put(Dst, 2984, Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env), Dt7([0].value), Dt7([0].tt), (ptrdiff_t)(luaH_newkey)); | ||
423 | dasm_put(Dst, 3066, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_settable_fb), Dt1(->base)); | ||
424 | dasm_put(Dst, 3127, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value)); | ||
425 | dasm_put(Dst, 3438, (ptrdiff_t)(luaH_getnum), sizeof(TValue)); | ||
426 | dasm_put(Dst, 3476, (ptrdiff_t)(luaH_getnum)); | ||
427 | dasm_put(Dst, 3623, (ptrdiff_t)(luaH_setnum), sizeof(TValue)); | ||
428 | dasm_put(Dst, 3665, (ptrdiff_t)(luaH_setnum)); | ||
429 | dasm_put(Dst, 3992); | ||
430 | dasm_put(Dst, 4325, Dt2([0].tt), Dt2([1].tt), Dt1(->l_G), Dt2([0].value), Dt2([1].value), DtB(->tsv.len), DtB(->tsv.len), Dt6(->buff.buffsize), Dt6(->buff.buffer), sizeof(TString)); | ||
431 | dasm_put(Dst, 4396, DtB(->tsv.len), DtB([1]), Dt1(->base), (ptrdiff_t)(luaS_newlstr), Dt1(->base), Dt6(->buff), (ptrdiff_t)(luaZ_openspace)); | ||
432 | dasm_put(Dst, 561, Dt1(->top), Dt1(->savedpc), (ptrdiff_t)(luaJIT_deoptimize), Dt1(->base), Dt1(->top)); | ||
433 | |||
434 | (void)dasm_checkstep(Dst, DASM_SECTION_CODE); | ||
435 | status = luaJIT_link(J, &J->jsubmcode, &J->szjsubmcode); | ||
436 | if (status != JIT_S_OK) | ||
437 | return status; | ||
438 | |||
439 | /* Copy the callgates from the globals to the global state. */ | ||
440 | G(J->L)->jit_gateLJ = (luaJIT_GateLJ)J->jsub[JSUB_GATE_LJ]; | ||
441 | G(J->L)->jit_gateJL = (lua_CFunction)J->jsub[JSUB_GATE_JL]; | ||
442 | G(J->L)->jit_gateJC = (lua_CFunction)J->jsub[JSUB_GATE_JC]; | ||
443 | return JIT_S_OK; | ||
444 | } | ||
445 | |||
446 | /* Match with number of nops above. Avoid confusing the instruction decoder. */ | ||
447 | #define DEBUGPATCH_SIZE 6 | ||
448 | |||
449 | /* Notify backend that the debug mode may have changed. */ | ||
450 | void luaJIT_debugnotify(jit_State *J) | ||
451 | { | ||
452 | unsigned char *patch = (unsigned char *)J->jsub[JSUB_GATE_JC_PATCH]; | ||
453 | unsigned char *target = (unsigned char *)J->jsub[JSUB_GATE_JC_DEBUG]; | ||
454 | /* Yep, this is self-modifying code -- don't tell anyone. */ | ||
455 | if (patch[0] == 0xe9) { /* Debug patch is active. */ | ||
456 | if (!(J->flags & JIT_F_DEBUG_CALL)) /* Deactivate it. */ | ||
457 | memcpy(patch, target-DEBUGPATCH_SIZE, DEBUGPATCH_SIZE); | ||
458 | } else { /* Debug patch is inactive. */ | ||
459 | if (J->flags & JIT_F_DEBUG_CALL) { /* Activate it. */ | ||
460 | int rel = target-(patch+5); | ||
461 | memcpy(target-DEBUGPATCH_SIZE, patch, DEBUGPATCH_SIZE); | ||
462 | patch[0] = 0xe9; /* jmp */ | ||
463 | memcpy(patch+1, &rel, 4); /* Relative address. */ | ||
464 | memset(patch+5, 0x90, DEBUGPATCH_SIZE-5); /* nop */ | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | |||
469 | /* Patch a jmp into existing mcode. */ | ||
470 | static void jit_patch_jmp(jit_State *J, void *mcode, void *to) | ||
471 | { | ||
472 | unsigned char *patch = (unsigned char *)mcode; | ||
473 | int rel = ((unsigned char *)to)-(patch+5); | ||
474 | patch[0] = 0xe9; /* jmp */ | ||
475 | memcpy((void *)(patch+1), &rel, 4); /* Relative addr. */ | ||
476 | } | ||
477 | |||
478 | /* ------------------------------------------------------------------------ */ | ||
479 | |||
480 | /* Call line/count hook. */ | ||
481 | static void jit_hookins(lua_State *L, const Instruction *newpc) | ||
482 | { | ||
483 | Proto *pt = ci_func(L->ci)->l.p; | ||
484 | int pc = luaJIT_findpc(pt, newpc); /* Sloooow with mcode addrs. */ | ||
485 | const Instruction *savedpc = L->savedpc; | ||
486 | L->savedpc = pt->code + pc + 1; | ||
487 | if (L->hookmask > LUA_MASKLINE && L->hookcount == 0) { | ||
488 | resethookcount(L); | ||
489 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | ||
490 | } | ||
491 | if (L->hookmask & LUA_MASKLINE) { | ||
492 | int newline = getline(pt, pc); | ||
493 | if (pc != 0) { | ||
494 | int oldpc = luaJIT_findpc(pt, savedpc); | ||
495 | if (!(pc <= oldpc || newline != getline(pt, oldpc))) return; | ||
496 | } | ||
497 | luaD_callhook(L, LUA_HOOKLINE, newline); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | /* Insert hook check for each instruction in full debug mode. */ | ||
502 | static void jit_ins_debug(jit_State *J, int openop) | ||
503 | { | ||
504 | if (openop) { | ||
505 | dasm_put(Dst, 594, Dt1(->top)); | ||
506 | } | ||
507 | dasm_put(Dst, 598); | ||
508 | |||
509 | } | ||
510 | |||
511 | /* Called before every instruction. */ | ||
512 | static void jit_ins_start(jit_State *J) | ||
513 | { | ||
514 | dasm_put(Dst, 663, J->nextpc); | ||
515 | } | ||
516 | |||
517 | /* Chain to another instruction. */ | ||
518 | static void jit_ins_chainto(jit_State *J, int pc) | ||
519 | { | ||
520 | dasm_put(Dst, 665, pc); | ||
521 | } | ||
522 | |||
523 | /* Set PC label. */ | ||
524 | static void jit_ins_setpc(jit_State *J, int pc, void *target) | ||
525 | { | ||
526 | dasm_put(Dst, 668, pc, (ptrdiff_t)(target)); | ||
527 | } | ||
528 | |||
529 | /* Called after the last instruction has been encoded. */ | ||
530 | static void jit_ins_last(jit_State *J, int lastpc, int sizemfm) | ||
531 | { | ||
532 | if (J->tflags & JIT_TF_USED_DEOPT) { /* Deopt section has been used? */ | ||
533 | dasm_put(Dst, 671); | ||
534 | dasm_put(Dst, 673); | ||
535 | } | ||
536 | dasm_put(Dst, 678, lastpc+1); | ||
537 | dasm_put(Dst, 681, lastpc+2); | ||
538 | dasm_put(Dst, 690, sizemfm); | ||
539 | } | ||
540 | |||
541 | /* Add a deoptimize target for the current instruction. */ | ||
542 | static void jit_deopt_target(jit_State *J, int nargs) | ||
543 | { | ||
544 | if (nargs != -1) { | ||
545 | dasm_put(Dst, 671); | ||
546 | dasm_put(Dst, 702, (ptrdiff_t)(J->nextins)); | ||
547 | J->tflags |= JIT_TF_USED_DEOPT; | ||
548 | } else { | ||
549 | dasm_put(Dst, 679); | ||
550 | dasm_put(Dst, 709, (ptrdiff_t)(J->nextins)); | ||
551 | } | ||
552 | } | ||
553 | |||
554 | /* luaC_checkGC() inlined. Destroys caller-saves + TOP (edi). Uses label 7:. */ | ||
555 | /* Use this only at the _end_ of an instruction. */ | ||
556 | static void jit_checkGC(jit_State *J) | ||
557 | { | ||
558 | dasm_put(Dst, 718, Dt1(->l_G), Dt6(->totalbytes), Dt6(->GCthreshold)); | ||
559 | |||
560 | } | ||
561 | |||
562 | /* ------------------------------------------------------------------------ */ | ||
563 | |||
564 | |||
565 | |||
566 | /* | ||
567 | ** Function inlining support for x86 CPUs. | ||
568 | ** Copyright (C) 2005-2011 Mike Pall. See Copyright Notice in luajit.h | ||
569 | */ | ||
570 | |||
571 | /* ------------------------------------------------------------------------ */ | ||
572 | |||
573 | /* Private structure holding function inlining info. */ | ||
574 | typedef struct jit_InlineInfo { | ||
575 | int func; /* Function slot. 1st arg slot = func+1. */ | ||
576 | int res; /* 1st result slot. Overlaps func/ci->func. */ | ||
577 | int nargs; /* Number of args. */ | ||
578 | int nresults; /* Number of results. */ | ||
579 | int xnargs; /* Expected number of args. */ | ||
580 | int xnresults; /* Returned number of results. */ | ||
581 | int hidx; /* Library/function index numbers. */ | ||
582 | } jit_InlineInfo; | ||
583 | |||
584 | /* ------------------------------------------------------------------------ */ | ||
585 | |||
586 | enum { TFOR_FUNC, TFOR_TAB, TFOR_CTL, TFOR_KEY, TFOR_VAL }; | ||
587 | |||
588 | static void jit_inline_base(jit_State *J, jit_InlineInfo *ii) | ||
589 | { | ||
590 | int func = ii->func; | ||
591 | switch (JIT_IH_IDX(ii->hidx)) { | ||
592 | case JIT_IH_BASE_PAIRS: | ||
593 | case JIT_IH_BASE_IPAIRS: | ||
594 | dasm_put(Dst, 753, Dt2([func+TFOR_TAB].tt), Dt2([func+TFOR_CTL].tt), Dt2([func+TFOR_CTL].value)); | ||
595 | dasm_put(Dst, 771, JIT_MFM_DEOPT_PAIRS, J->nextpc-1); | ||
596 | break; | ||
597 | default: | ||
598 | jit_assert(0); | ||
599 | break; | ||
600 | } | ||
601 | } | ||
602 | |||
603 | /* ------------------------------------------------------------------------ */ | ||
604 | |||
605 | #ifndef COCO_DISABLE | ||
606 | |||
607 | /* Helper function for inlined coroutine.resume(). */ | ||
608 | static StkId jit_coroutine_resume(lua_State *L, StkId base, int nresults) | ||
609 | { | ||
610 | lua_State *co = thvalue(base-1); | ||
611 | /* Check for proper usage. Merge of lua_resume() and auxresume() checks. */ | ||
612 | if (co->status != LUA_YIELD) { | ||
613 | if (co->status > LUA_YIELD) { | ||
614 | errdead: | ||
615 | setsvalue(L, base-1, luaS_newliteral(L, "cannot resume dead coroutine")); | ||
616 | goto err; | ||
617 | } else if (co->ci != co->base_ci) { | ||
618 | setsvalue(L, base-1, | ||
619 | luaS_newliteral(L, "cannot resume non-suspended coroutine")); | ||
620 | goto err; | ||
621 | } else if (co->base == co->top) { | ||
622 | goto errdead; | ||
623 | } | ||
624 | } | ||
625 | { | ||
626 | ptrdiff_t ndelta = (char *)L->top - (char *)base; | ||
627 | int nargs = ndelta/sizeof(TValue); /* Compute nargs. */ | ||
628 | int status; | ||
629 | if ((char *)co->stack_last-(char *)co->top <= ndelta) { | ||
630 | co->ci->top = (StkId)(((char *)co->top) + ndelta); /* Ok before grow. */ | ||
631 | luaD_growstack(co, nargs); /* Grow thread stack. */ | ||
632 | } | ||
633 | /* Copy args. */ | ||
634 | co->top = (StkId)(((char *)co->top) + ndelta); | ||
635 | { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); } | ||
636 | L->top = base; | ||
637 | status = luaCOCO_resume(co, nargs); /* Resume Coco thread. */ | ||
638 | if (status == 0 || status == LUA_YIELD) { /* Ok. */ | ||
639 | StkId f; | ||
640 | if (nresults == 0) return NULL; | ||
641 | if (nresults == -1) { | ||
642 | luaD_checkstack(L, co->top - co->base); /* Grow own stack. */ | ||
643 | } | ||
644 | base = L->top - 2; | ||
645 | setbvalue(base++, 1); /* true */ | ||
646 | /* Copy results. Fill unused result slots with nil. */ | ||
647 | f = co->base; | ||
648 | while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++); | ||
649 | while (nresults-- > 0) setnilvalue(base++); | ||
650 | co->top = co->base; | ||
651 | return base; | ||
652 | } else { /* Error. */ | ||
653 | base = L->top; | ||
654 | setobj2s(L, base-1, co->top-1); /* Copy error object. */ | ||
655 | err: | ||
656 | setbvalue(base-2, 0); /* false */ | ||
657 | nresults -= 2; | ||
658 | while (--nresults >= 0) setnilvalue(base+nresults); /* Fill results. */ | ||
659 | return base; | ||
660 | } | ||
661 | } | ||
662 | } | ||
663 | |||
664 | static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii) | ||
665 | { | ||
666 | int arg = ii->func+1; | ||
667 | int res = ii->res; | ||
668 | int i; | ||
669 | switch (JIT_IH_IDX(ii->hidx)) { | ||
670 | case JIT_IH_COROUTINE_YIELD: | ||
671 | dasm_put(Dst, 775, ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), arg*sizeof(TValue)); | ||
672 | if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
673 | dasm_put(Dst, 791, Dt2([ii->nargs])); | ||
674 | } | ||
675 | dasm_put(Dst, 795, Dt1(->base), Dt1(->top), (ptrdiff_t)(luaCOCO_yield), Dt1(->base), Dt1(->top)); | ||
676 | jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK); | ||
677 | for (i = 0; i < ii->nresults; i++) { | ||
678 | dasm_put(Dst, 813, Dt3([i].tt)); | ||
679 | if (J->flags & JIT_F_CPU_SSE2) { | ||
680 | dasm_put(Dst, 821, Dt2([arg+i].tt), Dt2([arg+i].value), Dt2([res+i].tt), Dt2([res+i].value)); | ||
681 | } else { | ||
682 | dasm_put(Dst, 839, Dt2([arg+i].value), Dt2([arg+i].value.na[1]), Dt2([arg+i].tt), Dt2([res+i].value), Dt2([res+i].value.na[1]), Dt2([res+i].tt)); | ||
683 | } | ||
684 | } | ||
685 | ii->nargs = -1; /* Force restore of L->top. */ | ||
686 | break; | ||
687 | case JIT_IH_COROUTINE_RESUME: | ||
688 | jit_assert(ii->nargs != 0 && ii->res == ii->func); | ||
689 | dasm_put(Dst, 787, (arg+1)*sizeof(TValue)); | ||
690 | if (ii->nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
691 | dasm_put(Dst, 791, Dt2([ii->nargs-1])); | ||
692 | } else { | ||
693 | dasm_put(Dst, 858); | ||
694 | } | ||
695 | dasm_put(Dst, 865, Dt2([-1].tt), Dt2([-1].value), ((int)&LHASCOCO((lua_State *)0)), Dt1(->savedpc), (ptrdiff_t)(J->nextins), Dt1(->top), ii->nresults, (ptrdiff_t)(jit_coroutine_resume), Dt1(->base)); | ||
696 | if (ii->nresults == -1) { | ||
697 | dasm_put(Dst, 909); | ||
698 | } | ||
699 | ii->nargs = -1; /* Force restore of L->top. */ | ||
700 | break; | ||
701 | default: | ||
702 | jit_assert(0); | ||
703 | break; | ||
704 | } | ||
705 | } | ||
706 | |||
707 | #endif /* COCO_DISABLE */ | ||
708 | |||
709 | /* ------------------------------------------------------------------------ */ | ||
710 | |||
711 | static void jit_inline_string(jit_State *J, jit_InlineInfo *ii) | ||
712 | { | ||
713 | int arg = ii->func+1; | ||
714 | int res = ii->res; | ||
715 | switch (JIT_IH_IDX(ii->hidx)) { | ||
716 | case JIT_IH_STRING_LEN: | ||
717 | dasm_put(Dst, 912, Dt2([arg].tt), Dt2([arg].value), DtB(->tsv.len), Dt2([res].tt), Dt2([res].value)); | ||
718 | break; | ||
719 | case JIT_IH_STRING_SUB: | ||
720 | /* TODO: inline numeric constants with help from the optimizer. */ | ||
721 | /* But this would save only another 15-20% in a trivial loop. */ | ||
722 | jit_assert(ii->nargs >= 2); /* Open op caveat is ok, too. */ | ||
723 | if (ii->nargs > 2) { | ||
724 | dasm_put(Dst, 937, Dt2([arg]), Dt2([res].value), Dt2([res].tt)); | ||
725 | } else { | ||
726 | dasm_put(Dst, 954, Dt2([arg]), Dt2([res].value), Dt2([res].tt)); | ||
727 | } | ||
728 | break; | ||
729 | case JIT_IH_STRING_CHAR: | ||
730 | dasm_put(Dst, 971, Dt2([arg].tt), Dt1(->env), Dt2([arg].value), (ptrdiff_t)(luaS_newlstr), Dt2([res].value), Dt2([res].tt)); | ||
731 | break; | ||
732 | default: | ||
733 | jit_assert(0); | ||
734 | break; | ||
735 | } | ||
736 | |||
737 | } | ||
738 | |||
739 | /* ------------------------------------------------------------------------ */ | ||
740 | |||
741 | /* Helper functions for inlined calls to table.*. */ | ||
742 | static void jit_table_insert(lua_State *L, TValue *arg) | ||
743 | { | ||
744 | setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1); | ||
745 | luaC_barriert(L, hvalue(arg), arg+1); | ||
746 | } | ||
747 | |||
748 | static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res) | ||
749 | { | ||
750 | int n = luaH_getn(hvalue(arg)); | ||
751 | if (n == 0) { | ||
752 | setnilvalue(res); /* For the nresults == 1 case. Harmless otherwise. */ | ||
753 | return res; /* For the nresults == -1 case. */ | ||
754 | } else { | ||
755 | TValue *val = luaH_setnum(L, hvalue(arg), n); | ||
756 | setobj2s(L, res, val); | ||
757 | setnilvalue(val); | ||
758 | return res+1; /* For the nresults == -1 case. */ | ||
759 | } | ||
760 | } | ||
761 | |||
762 | static void jit_inline_table(jit_State *J, jit_InlineInfo *ii) | ||
763 | { | ||
764 | int arg = ii->func+1; | ||
765 | int res = ii->res; | ||
766 | dasm_put(Dst, 1250, Dt2([arg].tt)); | ||
767 | switch (JIT_IH_IDX(ii->hidx)) { | ||
768 | case JIT_IH_TABLE_INSERT: | ||
769 | dasm_put(Dst, 1259, Dt2([arg]), (ptrdiff_t)(jit_table_insert)); | ||
770 | break; | ||
771 | case JIT_IH_TABLE_REMOVE: | ||
772 | dasm_put(Dst, 1272, Dt2([arg]), Dt2([res]), (ptrdiff_t)(jit_table_remove)); | ||
773 | if (ii->nresults == -1) { | ||
774 | ii->xnresults = -1; | ||
775 | dasm_put(Dst, 909); | ||
776 | } | ||
777 | break; | ||
778 | case JIT_IH_TABLE_GETN: | ||
779 | dasm_put(Dst, 1292, Dt2([arg].value), (ptrdiff_t)(luaH_getn), Dt2([res].value), Dt2([res].tt)); | ||
780 | break; | ||
781 | default: | ||
782 | jit_assert(0); | ||
783 | break; | ||
784 | } | ||
785 | } | ||
786 | |||
787 | /* ------------------------------------------------------------------------ */ | ||
788 | |||
789 | /* This typedef must match the libm function signature. */ | ||
790 | /* Serves as a check against wrong lua_Number or wrong calling conventions. */ | ||
791 | typedef lua_Number (*mathfunc_11)(lua_Number); | ||
792 | |||
793 | /* Partially inlined math functions. */ | ||
794 | /* CHECK: must match with jit_hints.h and jit.opt_lib. */ | ||
795 | static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = { | ||
796 | log, log10, exp, sinh, cosh, tanh, asin, acos, atan | ||
797 | }; | ||
798 | |||
799 | /* FPU control words for ceil and floor (exceptions masked, full precision). */ | ||
800 | static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f }; | ||
801 | |||
802 | static void jit_inline_math(jit_State *J, jit_InlineInfo *ii) | ||
803 | { | ||
804 | int arg = ii->func+1; | ||
805 | int res = ii->res; | ||
806 | int idx = JIT_IH_IDX(ii->hidx); | ||
807 | |||
808 | if (idx < JIT_IH_MATH__21) { | ||
809 | dasm_put(Dst, 1317, Dt2([arg].tt), Dt2([arg].value)); | ||
810 | } else { | ||
811 | jit_assert(idx < JIT_IH_MATH__LAST); | ||
812 | dasm_put(Dst, 1329, Dt2([arg].tt), Dt2([arg+1].tt)); | ||
813 | } | ||
814 | switch (idx) { | ||
815 | /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */ | ||
816 | case JIT_IH_MATH_SIN: | ||
817 | dasm_put(Dst, 1347); | ||
818 | break; | ||
819 | case JIT_IH_MATH_COS: | ||
820 | dasm_put(Dst, 1351); | ||
821 | break; | ||
822 | case JIT_IH_MATH_TAN: | ||
823 | dasm_put(Dst, 1355); | ||
824 | break; | ||
825 | case JIT_IH_MATH_CEIL: | ||
826 | case JIT_IH_MATH_FLOOR: | ||
827 | dasm_put(Dst, 1361, (ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]); | ||
828 | break; | ||
829 | case JIT_IH_MATH_ABS: | ||
830 | dasm_put(Dst, 1374); | ||
831 | break; | ||
832 | case JIT_IH_MATH_SQRT: | ||
833 | dasm_put(Dst, 1377); | ||
834 | break; | ||
835 | case JIT_IH_MATH_FMOD: | ||
836 | dasm_put(Dst, 1381, Dt2([arg+1].value), Dt2([arg].value)); | ||
837 | break; | ||
838 | case JIT_IH_MATH_ATAN2: | ||
839 | dasm_put(Dst, 1402, Dt2([arg].value), Dt2([arg+1].value)); | ||
840 | break; | ||
841 | default: | ||
842 | dasm_put(Dst, 1412, (ptrdiff_t)(jit_mathfuncs_11[idx])); | ||
843 | break; | ||
844 | } | ||
845 | dasm_put(Dst, 926, Dt2([res].tt), Dt2([res].value)); | ||
846 | } | ||
847 | |||
848 | /* ------------------------------------------------------------------------ */ | ||
849 | |||
850 | /* Try to inline a CALL or TAILCALL instruction. */ | ||
851 | static int jit_inline_call(jit_State *J, int func, int nargs, int nresults) | ||
852 | { | ||
853 | const TValue *callable = hint_get(J, TYPE); /* TYPE hint = callable. */ | ||
854 | int cltype = ttype(callable); | ||
855 | const TValue *oidx; | ||
856 | jit_InlineInfo ii; | ||
857 | int idx; | ||
858 | |||
859 | if (cltype != LUA_TFUNCTION) goto fail; | ||
860 | if (J->flags & JIT_F_DEBUG) goto fail; /* DWIM. */ | ||
861 | |||
862 | oidx = hint_get(J, INLINE); /* INLINE hint = library/function index. */ | ||
863 | if (!ttisnumber(oidx)) goto fail; | ||
864 | |||
865 | ii.hidx = (int)nvalue(oidx); | ||
866 | idx = JIT_IH_IDX(ii.hidx); | ||
867 | |||
868 | if (nresults == -2) { /* Tailcall. */ | ||
869 | /* Tailcalls from vararg functions don't work with BASE[-1]. */ | ||
870 | if (J->pt->is_vararg) goto fail; /* So forget about this rare case. */ | ||
871 | ii.res = -1; /* Careful: 2nd result overlaps 1st stack slot. */ | ||
872 | ii.nresults = -1; | ||
873 | } else { | ||
874 | ii.res = func; | ||
875 | ii.nresults = nresults; | ||
876 | } | ||
877 | ii.func = func; | ||
878 | ii.nargs = nargs; | ||
879 | ii.xnargs = ii.xnresults = 1; /* Default: 1 arg, 1 result. */ | ||
880 | |||
881 | /* Check for the currently supported cases. */ | ||
882 | switch (JIT_IH_LIB(ii.hidx)) { | ||
883 | case JIT_IHLIB_BASE: | ||
884 | switch (idx) { | ||
885 | case JIT_IH_BASE_PAIRS: | ||
886 | case JIT_IH_BASE_IPAIRS: | ||
887 | if (nresults == -2) goto fail; /* Not useful for tailcalls. */ | ||
888 | ii.xnresults = 3; | ||
889 | goto check; | ||
890 | } | ||
891 | break; | ||
892 | #ifndef COCO_DISABLE | ||
893 | case JIT_IHLIB_COROUTINE: | ||
894 | switch (idx) { | ||
895 | case JIT_IH_COROUTINE_YIELD: | ||
896 | /* Only support common cases: no tailcalls, low number of results. */ | ||
897 | if (nresults < 0 || nresults > EXTRA_STACK) goto fail; | ||
898 | ii.xnargs = ii.xnresults = -1; | ||
899 | goto ok; /* Anything else is ok. */ | ||
900 | case JIT_IH_COROUTINE_RESUME: | ||
901 | /* Only support common cases: no tailcalls, not with 0 args (error). */ | ||
902 | if (nresults == -2 || nargs == 0) goto fail; | ||
903 | ii.xnargs = ii.xnresults = -1; | ||
904 | goto ok; /* Anything else is ok. */ | ||
905 | } | ||
906 | break; | ||
907 | #endif | ||
908 | case JIT_IHLIB_STRING: | ||
909 | switch (idx) { | ||
910 | case JIT_IH_STRING_LEN: | ||
911 | goto check; | ||
912 | case JIT_IH_STRING_SUB: | ||
913 | if (nargs < 2) goto fail; /* No support for open calls, too. */ | ||
914 | goto ok; /* 2 or more args are ok. */ | ||
915 | case JIT_IH_STRING_CHAR: | ||
916 | goto check; /* Only single arg supported. */ | ||
917 | } | ||
918 | break; | ||
919 | case JIT_IHLIB_TABLE: | ||
920 | switch (idx) { | ||
921 | case JIT_IH_TABLE_INSERT: | ||
922 | ii.xnargs = 2; | ||
923 | goto check; /* Only push (append) supported. */ | ||
924 | case JIT_IH_TABLE_REMOVE: | ||
925 | goto check; /* Only pop supported. */ | ||
926 | case JIT_IH_TABLE_GETN: | ||
927 | goto check; | ||
928 | } | ||
929 | break; | ||
930 | case JIT_IHLIB_MATH: | ||
931 | if (idx >= JIT_IH_MATH__LAST) goto fail; | ||
932 | if (idx >= JIT_IH_MATH__21) ii.xnargs = 2; | ||
933 | goto check; | ||
934 | } | ||
935 | fail: | ||
936 | return cltype; /* Call could not be inlined. Return type of callable. */ | ||
937 | |||
938 | check: | ||
939 | if (nargs != ii.xnargs && nargs != -1) goto fail; | ||
940 | /* The optimizer already checks the number of results (avoid setnil). */ | ||
941 | |||
942 | ok: /* Whew, all checks done. Go for it! */ | ||
943 | |||
944 | /* Start with the common leadin for inlined calls. */ | ||
945 | jit_deopt_target(J, nargs); | ||
946 | dasm_put(Dst, 1418, Dt2([func].tt), Dt2([func].value), (ptrdiff_t)(clvalue(callable))); | ||
947 | if (nargs == -1 && ii.xnargs >= 0) { | ||
948 | dasm_put(Dst, 1435, Dt2([func+1+ii.xnargs])); | ||
949 | } | ||
950 | |||
951 | /* Now inline the function itself. */ | ||
952 | switch (JIT_IH_LIB(ii.hidx)) { | ||
953 | case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break; | ||
954 | #ifndef COCO_DISABLE | ||
955 | case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break; | ||
956 | #endif | ||
957 | case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break; | ||
958 | case JIT_IHLIB_TABLE: jit_inline_table(J, &ii); break; | ||
959 | case JIT_IHLIB_MATH: jit_inline_math(J, &ii); break; | ||
960 | default: jit_assert(0); break; | ||
961 | } | ||
962 | |||
963 | /* And add the common leadout for inlined calls. */ | ||
964 | if (ii.nresults == -1) { | ||
965 | if (ii.xnresults >= 0) { | ||
966 | dasm_put(Dst, 791, Dt2([ii.res+ii.xnresults])); | ||
967 | } | ||
968 | } else if (ii.nargs == -1) { /* Restore L->top only if needed. */ | ||
969 | dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); | ||
970 | } | ||
971 | |||
972 | if (nresults == -2) { /* Results are in place. Add return for tailcalls. */ | ||
973 | dasm_put(Dst, 1452, sizeof(TValue), Dt1(->ci), sizeof(CallInfo)); | ||
974 | } | ||
975 | |||
976 | return -1; /* Success, call has been inlined. */ | ||
977 | } | ||
978 | |||
979 | /* ------------------------------------------------------------------------ */ | ||
980 | |||
981 | /* Helper function for inlined iterator code. Paraphrased from luaH_next. */ | ||
982 | /* TODO: GCC has trouble optimizing this. */ | ||
983 | static int jit_table_next(lua_State *L, TValue *ra) | ||
984 | { | ||
985 | Table *t = hvalue(&ra[TFOR_TAB]); | ||
986 | int i = ra[TFOR_CTL].value.b; /* Hidden control variable. */ | ||
987 | for (; i < t->sizearray; i++) { /* First the array part. */ | ||
988 | if (!ttisnil(&t->array[i])) { | ||
989 | setnvalue(&ra[TFOR_KEY], cast_num(i+1)); | ||
990 | setobj2s(L, &ra[TFOR_VAL], &t->array[i]); | ||
991 | ra[TFOR_CTL].value.b = i+1; | ||
992 | return 1; | ||
993 | } | ||
994 | } | ||
995 | for (i -= t->sizearray; i < sizenode(t); i++) { /* Then the hash part. */ | ||
996 | if (!ttisnil(gval(gnode(t, i)))) { | ||
997 | setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i))); | ||
998 | setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i))); | ||
999 | ra[TFOR_CTL].value.b = i+1+t->sizearray; | ||
1000 | return 1; | ||
1001 | } | ||
1002 | } | ||
1003 | return 0; /* End of iteration. */ | ||
1004 | } | ||
1005 | |||
1006 | /* Try to inline a TFORLOOP instruction. */ | ||
1007 | static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target) | ||
1008 | { | ||
1009 | const TValue *oidx = hint_get(J, INLINE); /* INLINE hint = lib/func idx. */ | ||
1010 | int idx; | ||
1011 | |||
1012 | if (!ttisnumber(oidx)) return 0; /* No hint: don't inline anything. */ | ||
1013 | idx = (int)nvalue(oidx); | ||
1014 | if (J->flags & JIT_F_DEBUG) return 0; /* DWIM. */ | ||
1015 | |||
1016 | switch (idx) { | ||
1017 | case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS): | ||
1018 | dasm_put(Dst, 1465, Dt2([ra]), (ptrdiff_t)(jit_table_next), target); | ||
1019 | return 1; /* Success, iterator has been inlined. */ | ||
1020 | case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS): | ||
1021 | dasm_put(Dst, 1483, Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_TAB].value), Dt2([ra+TFOR_CTL].value), (ptrdiff_t)(luaH_getnum), Dt7(->tt), Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_KEY].tt), Dt2([ra+TFOR_KEY].value), Dt7(->value), Dt7(->value.na[1]), Dt2([ra+TFOR_VAL].tt), Dt2([ra+TFOR_VAL].value), Dt2([ra+TFOR_VAL].value.na[1]), target); | ||
1022 | return 1; /* Success, iterator has been inlined. */ | ||
1023 | } | ||
1024 | |||
1025 | return 0; /* No support for inlining any other iterators. */ | ||
1026 | } | ||
1027 | |||
1028 | /* ------------------------------------------------------------------------ */ | ||
1029 | |||
1030 | |||
1031 | |||
1032 | #ifdef LUA_COMPAT_VARARG | ||
1033 | static void jit_vararg_table(lua_State *L) | ||
1034 | { | ||
1035 | Table *tab; | ||
1036 | StkId base, func; | ||
1037 | int i, num, numparams; | ||
1038 | luaC_checkGC(L); | ||
1039 | base = L->base; | ||
1040 | func = L->ci->func; | ||
1041 | numparams = clvalue(func)->l.p->numparams; | ||
1042 | num = base - func - numparams - 1; | ||
1043 | tab = luaH_new(L, num, 1); | ||
1044 | for (i = 0; i < num; i++) | ||
1045 | setobj2n(L, luaH_setnum(L, tab, i+1), base - num + i); | ||
1046 | setnvalue(luaH_setstr(L, tab, luaS_newliteral(L, "n")), (lua_Number)num); | ||
1047 | sethvalue(L, base + numparams, tab); | ||
1048 | } | ||
1049 | #endif | ||
1050 | |||
1051 | /* Encode JIT function prologue. */ | ||
1052 | static void jit_prologue(jit_State *J) | ||
1053 | { | ||
1054 | Proto *pt = J->pt; | ||
1055 | int numparams = pt->numparams; | ||
1056 | int stacksize = pt->maxstacksize; | ||
1057 | |||
1058 | dasm_put(Dst, 1544, Dt3([stacksize]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt4(->func), sizeof(TValue), Dt1(->ci)); | ||
1059 | |||
1060 | if (numparams > 0) { | ||
1061 | dasm_put(Dst, 1580, Dt2([numparams])); | ||
1062 | } | ||
1063 | |||
1064 | if (!pt->is_vararg) { /* Fixarg function. */ | ||
1065 | /* Must cap L->top at L->base+numparams because 1st LOADNIL is omitted. */ | ||
1066 | if (numparams == 0) { | ||
1067 | dasm_put(Dst, 1586); | ||
1068 | } else if (J->flags & JIT_F_CPU_CMOV) { | ||
1069 | dasm_put(Dst, 1589); | ||
1070 | } else { | ||
1071 | dasm_put(Dst, 1594); | ||
1072 | } | ||
1073 | dasm_put(Dst, 1603, Dt2([stacksize]), Dt4(->tailcalls), Dt4(->top), Dt1(->top), Dt1(->base), Dt4(->base)); | ||
1074 | } else { /* Vararg function. */ | ||
1075 | int i; | ||
1076 | if (numparams > 0) { | ||
1077 | dasm_put(Dst, 1622); | ||
1078 | dasm_put(Dst, 1630, Dt3(->tt), sizeof(TValue)); | ||
1079 | } | ||
1080 | dasm_put(Dst, 1649, Dt1(->base), Dt4(->base), Dt4(->tailcalls)); | ||
1081 | for (i = 0; i < numparams; i++) { /* Move/clear fixargs. */ | ||
1082 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1083 | dasm_put(Dst, 1659, Dt2([i].tt), Dt2([i].value), Dt3([i].tt), Dt3([i].value)); | ||
1084 | } else { | ||
1085 | dasm_put(Dst, 1677, Dt2([i].value), Dt2([i].value.na[1]), Dt3([i].value), Dt2([i].tt), Dt3([i].value.na[1]), Dt3([i].tt)); | ||
1086 | } | ||
1087 | dasm_put(Dst, 854, Dt2([i].tt)); | ||
1088 | } | ||
1089 | if (numparams > 0) { | ||
1090 | dasm_put(Dst, 332, Dt1(->ci)); | ||
1091 | } | ||
1092 | dasm_put(Dst, 1696, Dt2([stacksize]), Dt2([numparams]), Dt4(->top), Dt1(->top)); | ||
1093 | stacksize -= numparams; /* Fixargs are already cleared. */ | ||
1094 | } | ||
1095 | |||
1096 | /* Clear undefined args and all vars. Still assumes eax = LUA_TNIL = 0. */ | ||
1097 | /* Note: cannot clear only args because L->top has grown. */ | ||
1098 | if (stacksize <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ | ||
1099 | int i; | ||
1100 | for (i = 0; i < stacksize; i++) { | ||
1101 | dasm_put(Dst, 1712, Dt3([i].tt)); | ||
1102 | } | ||
1103 | } else { /* Standard loop. */ | ||
1104 | dasm_put(Dst, 1716, Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue)); | ||
1105 | } | ||
1106 | |||
1107 | #ifdef LUA_COMPAT_VARARG | ||
1108 | if (pt->is_vararg & VARARG_NEEDSARG) { | ||
1109 | dasm_put(Dst, 1734, (ptrdiff_t)(jit_vararg_table)); | ||
1110 | } | ||
1111 | #endif | ||
1112 | |||
1113 | /* Call hook check. */ | ||
1114 | if (J->flags & JIT_F_DEBUG_CALL) { | ||
1115 | dasm_put(Dst, 1740, Dt1(->hookmask), LUA_MASKCALL); | ||
1116 | |||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | /* Check if we can combine 'return const'. */ | ||
1121 | static int jit_return_k(jit_State *J) | ||
1122 | { | ||
1123 | if (!J->combine) return 0; /* COMBINE hint set? */ | ||
1124 | /* May need to close open upvalues. */ | ||
1125 | if (!fhint_isset(J, NOCLOSE)) { | ||
1126 | dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); | ||
1127 | } | ||
1128 | if (!J->pt->is_vararg) { /* Fixarg function. */ | ||
1129 | dasm_put(Dst, 1830, Dt1(->ci), sizeof(CallInfo), sizeof(TValue)); | ||
1130 | } else { /* Vararg function. */ | ||
1131 | dasm_put(Dst, 1844, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt2([1])); | ||
1132 | } | ||
1133 | jit_assert(J->combine == 1); /* Required to skip next RETURN instruction. */ | ||
1134 | return 1; | ||
1135 | } | ||
1136 | |||
1137 | static void jit_op_return(jit_State *J, int rbase, int nresults) | ||
1138 | { | ||
1139 | /* Return hook check. */ | ||
1140 | if (J->flags & JIT_F_DEBUG_CALL) { | ||
1141 | if (nresults < 0 && !(J->flags & JIT_F_DEBUG_INS)) { | ||
1142 | dasm_put(Dst, 594, Dt1(->top)); | ||
1143 | } | ||
1144 | dasm_put(Dst, 1863, Dt1(->hookmask), LUA_MASKRET); | ||
1145 | if (J->flags & JIT_F_DEBUG_INS) { | ||
1146 | dasm_put(Dst, 1878, Dt1(->savedpc)); | ||
1147 | } | ||
1148 | |||
1149 | } | ||
1150 | |||
1151 | /* May need to close open upvalues. */ | ||
1152 | if (!fhint_isset(J, NOCLOSE)) { | ||
1153 | dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); | ||
1154 | } | ||
1155 | |||
1156 | /* Previous op was open: 'return f()' or 'return ...' */ | ||
1157 | if (nresults < 0) { | ||
1158 | dasm_put(Dst, 332, Dt1(->ci)); | ||
1159 | if (rbase) { | ||
1160 | dasm_put(Dst, 787, rbase*sizeof(TValue)); | ||
1161 | } | ||
1162 | dasm_put(Dst, 1933, Dt4(->func), Dt4(->func), sizeof(CallInfo), Dt1(->ci)); | ||
1163 | return; | ||
1164 | } | ||
1165 | |||
1166 | if (!J->pt->is_vararg) { /* Fixarg function, nresults >= 0. */ | ||
1167 | int i; | ||
1168 | dasm_put(Dst, 1980, Dt1(->ci), sizeof(CallInfo), sizeof(TValue)); | ||
1169 | for (i = 0; i < nresults; i++) { | ||
1170 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1171 | dasm_put(Dst, 821, Dt2([rbase+i+1].tt), Dt2([rbase+i+1].value), Dt2([i].tt), Dt2([i].value)); | ||
1172 | } else { | ||
1173 | dasm_put(Dst, 839, Dt2([rbase+i+1].value), Dt2([rbase+i+1].value.na[1]), Dt2([rbase+i+1].tt), Dt2([i].value), Dt2([i].value.na[1]), Dt2([i].tt)); | ||
1174 | } | ||
1175 | } | ||
1176 | dasm_put(Dst, 1989, Dt2([nresults])); | ||
1177 | } else { /* Vararg function, nresults >= 0. */ | ||
1178 | int i; | ||
1179 | dasm_put(Dst, 1997, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci)); | ||
1180 | for (i = 0; i < nresults; i++) { | ||
1181 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1182 | dasm_put(Dst, 1659, Dt2([rbase+i].tt), Dt2([rbase+i].value), Dt3([i].tt), Dt3([i].value)); | ||
1183 | } else { | ||
1184 | dasm_put(Dst, 2010, Dt2([rbase+i].value), Dt2([rbase+i].value.na[1]), Dt2([rbase+i].tt), Dt3([i].value), Dt3([i].value.na[1]), Dt3([i].tt)); | ||
1185 | } | ||
1186 | } | ||
1187 | dasm_put(Dst, 2029); | ||
1188 | if (nresults) { | ||
1189 | dasm_put(Dst, 2036, nresults*sizeof(TValue)); | ||
1190 | } | ||
1191 | dasm_put(Dst, 32); | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | static void jit_op_call(jit_State *J, int func, int nargs, int nresults) | ||
1196 | { | ||
1197 | int cltype = jit_inline_call(J, func, nargs, nresults); | ||
1198 | if (cltype < 0) return; /* Inlined? */ | ||
1199 | |||
1200 | if (func) { | ||
1201 | dasm_put(Dst, 787, func*sizeof(TValue)); | ||
1202 | } | ||
1203 | dasm_put(Dst, 2040, Dt1(->ci), Dt2([0].tt)); | ||
1204 | if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
1205 | dasm_put(Dst, 791, Dt2([1+nargs])); | ||
1206 | } | ||
1207 | dasm_put(Dst, 2048, Dt2(->value), (ptrdiff_t)(J->nextins), Dt4(->savedpc)); | ||
1208 | if (cltype == LUA_TFUNCTION) { | ||
1209 | if (nargs == -1) { | ||
1210 | dasm_put(Dst, 2057); | ||
1211 | } else { | ||
1212 | dasm_put(Dst, 2062); | ||
1213 | } | ||
1214 | } else { | ||
1215 | dasm_put(Dst, 2067); | ||
1216 | |||
1217 | } | ||
1218 | dasm_put(Dst, 2116, Dt5(->jit_gate)); | ||
1219 | if (func) { | ||
1220 | dasm_put(Dst, 1984, func*sizeof(TValue)); | ||
1221 | } | ||
1222 | dasm_put(Dst, 2121, Dt1(->base)); | ||
1223 | |||
1224 | /* Clear undefined results TOP <= o < func+nresults. */ | ||
1225 | if (nresults > 0) { | ||
1226 | dasm_put(Dst, 2125); | ||
1227 | if (nresults <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ | ||
1228 | int i; | ||
1229 | for (i = 0; i < nresults; i++) { | ||
1230 | dasm_put(Dst, 1712, Dt3([i].tt)); | ||
1231 | } | ||
1232 | } else { /* Standard loop. TODO: move to .tail? */ | ||
1233 | dasm_put(Dst, 2128, Dt2([func+nresults]), Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue)); | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1237 | if (nresults >= 0) { /* Not an open ins. Restore L->top. */ | ||
1238 | dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); | ||
1239 | } /* Otherwise keep TOP for next instruction. */ | ||
1240 | } | ||
1241 | |||
1242 | static void jit_op_tailcall(jit_State *J, int func, int nargs) | ||
1243 | { | ||
1244 | int cltype; | ||
1245 | |||
1246 | if (!fhint_isset(J, NOCLOSE)) { /* May need to close open upvalues. */ | ||
1247 | dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); | ||
1248 | } | ||
1249 | |||
1250 | cltype = jit_inline_call(J, func, nargs, -2); | ||
1251 | if (cltype < 0) goto finish; /* Inlined? */ | ||
1252 | |||
1253 | if (cltype == LUA_TFUNCTION) { | ||
1254 | jit_deopt_target(J, nargs); | ||
1255 | dasm_put(Dst, 2149, Dt2([func].tt)); | ||
1256 | } else { | ||
1257 | dasm_put(Dst, 2158, Dt2([func].tt)); | ||
1258 | dasm_put(Dst, 2168); | ||
1259 | if (func) { | ||
1260 | dasm_put(Dst, 787, func*sizeof(TValue)); | ||
1261 | } | ||
1262 | if (nargs >= 0) { | ||
1263 | dasm_put(Dst, 791, Dt2([1+nargs])); | ||
1264 | } | ||
1265 | dasm_put(Dst, 2171, (ptrdiff_t)(J->nextins)); | ||
1266 | |||
1267 | } | ||
1268 | |||
1269 | if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ | ||
1270 | int i; | ||
1271 | /* Relocate [BASE+func, BASE+func+nargs] -> [ci->func, ci->func+nargs]. */ | ||
1272 | /* TODO: loop for large nargs? */ | ||
1273 | if (!J->pt->is_vararg) { /* Fixarg function. */ | ||
1274 | dasm_put(Dst, 2241, Dt2([func].value)); | ||
1275 | for (i = 0; i < nargs; i++) { | ||
1276 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1277 | dasm_put(Dst, 821, Dt2([func+1+i].tt), Dt2([func+1+i].value), Dt2([i].tt), Dt2([i].value)); | ||
1278 | } else { | ||
1279 | dasm_put(Dst, 2245, Dt2([func+1+i].value), Dt2([func+1+i].value.na[1]), Dt2([i].value), Dt2([func+1+i].tt), Dt2([i].value.na[1]), Dt2([i].tt)); | ||
1280 | } | ||
1281 | } | ||
1282 | dasm_put(Dst, 2264, Dt2([nargs]), sizeof(TValue), Dt1(->ci), Dt2(->value)); | ||
1283 | } else { /* Vararg function. */ | ||
1284 | dasm_put(Dst, 2278, Dt1(->ci), Dt2([func]), Dt4(->func), Dt3(->value), Dt2(->value)); | ||
1285 | for (i = 0; i < nargs; i++) { | ||
1286 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1287 | dasm_put(Dst, 2294, Dt3([i+1].tt), Dt3([i+1].value), Dt2([i+1].tt), Dt2([i+1].value)); | ||
1288 | } else { | ||
1289 | dasm_put(Dst, 2312, Dt3([i+1].value), Dt3([i+1].value.na[1]), Dt2([i+1].value), Dt3([i+1].tt), Dt2([i+1].value.na[1]), Dt2([i+1].tt)); | ||
1290 | } | ||
1291 | } | ||
1292 | dasm_put(Dst, 2331, Dt2([1+nargs]), Dt2(->value)); | ||
1293 | } | ||
1294 | } else { /* Previous op was open and set TOP. */ | ||
1295 | dasm_put(Dst, 332, Dt1(->ci)); | ||
1296 | if (func) { | ||
1297 | dasm_put(Dst, 787, func*sizeof(TValue)); | ||
1298 | } | ||
1299 | dasm_put(Dst, 2338, Dt4(->func), Dt4(->func), Dt2(->value)); | ||
1300 | } | ||
1301 | dasm_put(Dst, 2230, sizeof(CallInfo), Dt5(->jit_gate)); | ||
1302 | |||
1303 | finish: | ||
1304 | J->combine++; /* Combine with following return instruction. */ | ||
1305 | } | ||
1306 | |||
1307 | /* ------------------------------------------------------------------------ */ | ||
1308 | |||
1309 | static void jit_op_move(jit_State *J, int dest, int src) | ||
1310 | { | ||
1311 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1312 | dasm_put(Dst, 821, Dt2([src].tt), Dt2([src].value), Dt2([dest].tt), Dt2([dest].value)); | ||
1313 | } else { | ||
1314 | dasm_put(Dst, 839, Dt2([src].value), Dt2([src].value.na[1]), Dt2([src].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | static void jit_op_loadk(jit_State *J, int dest, int kidx) | ||
1319 | { | ||
1320 | const TValue *kk = &J->pt->k[kidx]; | ||
1321 | int rk = jit_return_k(J); | ||
1322 | if (rk) dest = 0; | ||
1323 | switch (ttype(kk)) { | ||
1324 | case 0: | ||
1325 | dasm_put(Dst, 2369, Dt2([dest].tt)); | ||
1326 | break; | ||
1327 | case 1: | ||
1328 | if (bvalue(kk)) { /* true */ | ||
1329 | dasm_put(Dst, 2377, Dt2([dest].value), Dt2([dest].tt)); | ||
1330 | } else { /* false */ | ||
1331 | dasm_put(Dst, 2389, Dt2([dest].value), Dt2([dest].tt)); | ||
1332 | } | ||
1333 | break; | ||
1334 | case 3: { | ||
1335 | if ((&(kk)->value)->n == (lua_Number)0) { | ||
1336 | dasm_put(Dst, 2404); | ||
1337 | } else if ((&(kk)->value)->n == (lua_Number)1) { | ||
1338 | dasm_put(Dst, 2408); | ||
1339 | } else { | ||
1340 | dasm_put(Dst, 2411, &(kk)->value); | ||
1341 | } | ||
1342 | dasm_put(Dst, 1306, Dt2([dest].value), Dt2([dest].tt)); | ||
1343 | break; | ||
1344 | } | ||
1345 | case 4: | ||
1346 | dasm_put(Dst, 2415, Dt2([dest].value), (ptrdiff_t)(gcvalue(kk)), Dt2([dest].tt)); | ||
1347 | break; | ||
1348 | default: lua_assert(0); break; | ||
1349 | } | ||
1350 | if (rk) { | ||
1351 | dasm_put(Dst, 32); | ||
1352 | } | ||
1353 | } | ||
1354 | |||
1355 | static void jit_op_loadnil(jit_State *J, int first, int last) | ||
1356 | { | ||
1357 | int idx, num = last - first + 1; | ||
1358 | int rk = jit_return_k(J); | ||
1359 | dasm_put(Dst, 2125); | ||
1360 | if (rk) { | ||
1361 | dasm_put(Dst, 2427, Dt2([0].tt)); | ||
1362 | } else if (num <= 8) { | ||
1363 | for (idx = first; idx <= last; idx++) { | ||
1364 | dasm_put(Dst, 854, Dt2([idx].tt)); | ||
1365 | } | ||
1366 | } else { | ||
1367 | dasm_put(Dst, 2432, Dt2([first].tt), Dt2([last].tt), sizeof(TValue)); | ||
1368 | } | ||
1369 | } | ||
1370 | |||
1371 | static void jit_op_loadbool(jit_State *J, int dest, int b, int dojump) | ||
1372 | { | ||
1373 | int rk = jit_return_k(J); | ||
1374 | if (rk) dest = 0; | ||
1375 | if (b) { /* true */ | ||
1376 | dasm_put(Dst, 2377, Dt2([dest].value), Dt2([dest].tt)); | ||
1377 | } else { /* false */ | ||
1378 | dasm_put(Dst, 2389, Dt2([dest].value), Dt2([dest].tt)); | ||
1379 | } | ||
1380 | if (rk) { | ||
1381 | dasm_put(Dst, 32); | ||
1382 | } else if (dojump) { | ||
1383 | const TValue *h = hint_getpc(J, COMBINE, J->nextpc); | ||
1384 | if (!(ttisboolean(h) && bvalue(h) == 0)) { /* Avoid jmp around dead ins. */ | ||
1385 | dasm_put(Dst, 665, J->nextpc+1); | ||
1386 | } | ||
1387 | } | ||
1388 | } | ||
1389 | |||
1390 | /* ------------------------------------------------------------------------ */ | ||
1391 | |||
1392 | static void jit_op_getupval(jit_State *J, int dest, int uvidx) | ||
1393 | { | ||
1394 | if (!J->pt->is_vararg) { | ||
1395 | dasm_put(Dst, 2241, Dt2([-1].value)); | ||
1396 | } else { | ||
1397 | dasm_put(Dst, 2452, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
1398 | } | ||
1399 | dasm_put(Dst, 2462, Dt5(->upvals[uvidx]), DtF(->v)); | ||
1400 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1401 | dasm_put(Dst, 2469, Dt3([0].tt), Dt3([0].value), Dt2([dest].tt), Dt2([dest].value)); | ||
1402 | } else { | ||
1403 | dasm_put(Dst, 2487, Dt3([0].value), Dt3([0].value.na[1]), Dt3([0].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
1404 | } | ||
1405 | } | ||
1406 | |||
1407 | static void jit_op_setupval(jit_State *J, int src, int uvidx) | ||
1408 | { | ||
1409 | if (!J->pt->is_vararg) { | ||
1410 | dasm_put(Dst, 2241, Dt2([-1].value)); | ||
1411 | } else { | ||
1412 | dasm_put(Dst, 2452, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
1413 | } | ||
1414 | dasm_put(Dst, 2506, Dt5(->upvals[uvidx]), DtF(->v), Dt2([src].tt), Dt2([src].value), Dt3(->tt), Dt2([src].value.na[1]), Dt3(->value), Dt3(->value.na[1])); | ||
1415 | dasm_put(Dst, 2542, DtA(->gch.marked), WHITEBITS, DtF(->marked), bitmask(BLACKBIT)); | ||
1416 | |||
1417 | } | ||
1418 | |||
1419 | /* ------------------------------------------------------------------------ */ | ||
1420 | |||
1421 | /* Optimized table lookup routines. Enter via jsub, fallback to C. */ | ||
1422 | |||
1423 | /* Fallback for GETTABLE_*. Temporary key is in L->env. */ | ||
1424 | static void jit_gettable_fb(lua_State *L, Table *t, StkId dest) | ||
1425 | { | ||
1426 | Table *mt = t->metatable; | ||
1427 | const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_INDEX]); | ||
1428 | if (ttisnil(tm)) { /* No __index method? */ | ||
1429 | mt->flags |= 1<<TM_INDEX; /* Cache this fact. */ | ||
1430 | setnilvalue(dest); | ||
1431 | } else if (ttisfunction(tm)) { /* __index function? */ | ||
1432 | ptrdiff_t destr = savestack(L, dest); | ||
1433 | setobj2s(L, L->top, tm); | ||
1434 | sethvalue(L, L->top+1, t); | ||
1435 | setobj2s(L, L->top+2, &L->env); | ||
1436 | luaD_checkstack(L, 3); | ||
1437 | L->top += 3; | ||
1438 | luaD_call(L, L->top - 3, 1); | ||
1439 | dest = restorestack(L, destr); | ||
1440 | L->top--; | ||
1441 | setobjs2s(L, dest, L->top); | ||
1442 | } else { /* Let luaV_gettable() continue with the __index object. */ | ||
1443 | luaV_gettable(L, tm, &L->env, dest); | ||
1444 | } | ||
1445 | |||
1446 | } | ||
1447 | |||
1448 | /* Fallback for SETTABLE_*STR. Temporary (string) key is in L->env. */ | ||
1449 | static void jit_settable_fb(lua_State *L, Table *t, StkId val) | ||
1450 | { | ||
1451 | Table *mt = t->metatable; | ||
1452 | const TValue *tm = luaH_getstr(mt, G(L)->tmname[TM_NEWINDEX]); | ||
1453 | if (ttisnil(tm)) { /* No __newindex method? */ | ||
1454 | mt->flags |= 1<<TM_NEWINDEX; /* Cache this fact. */ | ||
1455 | t->flags = 0; /* But need to clear the cache for the table itself. */ | ||
1456 | setobj2t(L, luaH_setstr(L, t, rawtsvalue(&L->env)), val); | ||
1457 | luaC_barriert(L, t, val); | ||
1458 | } else if (ttisfunction(tm)) { /* __newindex function? */ | ||
1459 | setobj2s(L, L->top, tm); | ||
1460 | sethvalue(L, L->top+1, t); | ||
1461 | setobj2s(L, L->top+2, &L->env); | ||
1462 | setobj2s(L, L->top+3, val); | ||
1463 | luaD_checkstack(L, 4); | ||
1464 | L->top += 4; | ||
1465 | luaD_call(L, L->top - 4, 0); | ||
1466 | } else { /* Let luaV_settable() continue with the __newindex object. */ | ||
1467 | luaV_settable(L, tm, &L->env, val); | ||
1468 | } | ||
1469 | |||
1470 | } | ||
1471 | |||
1472 | /* ------------------------------------------------------------------------ */ | ||
1473 | |||
1474 | static void jit_op_newtable(jit_State *J, int dest, int lnarray, int lnhash) | ||
1475 | { | ||
1476 | dasm_put(Dst, 3158, luaO_fb2int(lnarray), luaO_fb2int(lnhash), (ptrdiff_t)(luaH_new), Dt2([dest].value), Dt2([dest].tt)); | ||
1477 | jit_checkGC(J); | ||
1478 | } | ||
1479 | |||
1480 | static void jit_op_getglobal(jit_State *J, int dest, int kidx) | ||
1481 | { | ||
1482 | const TValue *kk = &J->pt->k[kidx]; | ||
1483 | jit_assert(ttisstring(kk)); | ||
1484 | dasm_put(Dst, 3184, (ptrdiff_t)(&kk->value.gc->ts)); | ||
1485 | if (dest) { | ||
1486 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1487 | } | ||
1488 | dasm_put(Dst, 3187); | ||
1489 | } | ||
1490 | |||
1491 | static void jit_op_setglobal(jit_State *J, int rval, int kidx) | ||
1492 | { | ||
1493 | const TValue *kk = &J->pt->k[kidx]; | ||
1494 | jit_assert(ttisstring(kk)); | ||
1495 | dasm_put(Dst, 3184, (ptrdiff_t)(&kk->value.gc->ts)); | ||
1496 | if (rval) { | ||
1497 | dasm_put(Dst, 787, rval*sizeof(TValue)); | ||
1498 | } | ||
1499 | dasm_put(Dst, 3191); | ||
1500 | } | ||
1501 | |||
1502 | enum { TKEY_KSTR = -2, TKEY_STR = -1, TKEY_ANY = 0 }; | ||
1503 | |||
1504 | /* Optimize key lookup depending on consts or hints type. */ | ||
1505 | static int jit_keylookup(jit_State *J, int tab, int rkey) | ||
1506 | { | ||
1507 | const TValue *tabt = hint_get(J, TYPE); | ||
1508 | const TValue *key; | ||
1509 | if (!ttistable(tabt)) return TKEY_ANY; /* Not a table? Use fallback. */ | ||
1510 | key = ISK(rkey) ? &J->pt->k[INDEXK(rkey)] : hint_get(J, TYPEKEY); | ||
1511 | if (ttisstring(key)) { /* String key? */ | ||
1512 | if (ISK(rkey)) { | ||
1513 | dasm_put(Dst, 3195, Dt2([tab]), (ptrdiff_t)(&key->value.gc->ts)); | ||
1514 | return TKEY_KSTR; /* Const string key. */ | ||
1515 | } else { | ||
1516 | dasm_put(Dst, 3201, Dt2([tab]), Dt2([rkey])); | ||
1517 | return TKEY_STR; /* Var string key. */ | ||
1518 | } | ||
1519 | } else if (ttisnumber(key)) { /* Number key? */ | ||
1520 | lua_Number n = nvalue(key); | ||
1521 | int k; | ||
1522 | lua_number2int(k, n); | ||
1523 | if (!(k >= 1 && k < (1 << 26) && (lua_Number)k == n)) | ||
1524 | return TKEY_ANY; /* Not a proper array key? Use fallback. */ | ||
1525 | if (ISK(rkey)) { | ||
1526 | dasm_put(Dst, 3208, Dt2([tab].tt), Dt2([tab].value), k, DtC(->array), DtC(->sizearray)); | ||
1527 | return k; /* Const array key (>= 1). */ | ||
1528 | } else { | ||
1529 | dasm_put(Dst, 3232, Dt2([tab].tt), Dt2([rkey].tt)); | ||
1530 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1531 | dasm_put(Dst, 3250, Dt2([rkey]), Dt2([tab].value)); | ||
1532 | } else { | ||
1533 | dasm_put(Dst, 3283, Dt2([rkey].value)); | ||
1534 | if (J->flags & JIT_F_CPU_CMOV) { | ||
1535 | dasm_put(Dst, 3293); | ||
1536 | } else { | ||
1537 | dasm_put(Dst, 3298); | ||
1538 | } | ||
1539 | dasm_put(Dst, 3304, Dt2([tab].value)); | ||
1540 | } | ||
1541 | dasm_put(Dst, 3320, DtC(->sizearray), DtC(->array)); | ||
1542 | return 1; /* Variable array key. */ | ||
1543 | } | ||
1544 | } | ||
1545 | return TKEY_ANY; /* Use fallback. */ | ||
1546 | } | ||
1547 | |||
1548 | static void jit_op_gettable(jit_State *J, int dest, int tab, int rkey) | ||
1549 | { | ||
1550 | int k = jit_keylookup(J, tab, rkey); | ||
1551 | switch (k) { | ||
1552 | case TKEY_KSTR: /* Const string key. */ | ||
1553 | if (dest) { | ||
1554 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1555 | } | ||
1556 | dasm_put(Dst, 3334); | ||
1557 | break; | ||
1558 | case TKEY_STR: /* Variable string key. */ | ||
1559 | if (dest) { | ||
1560 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1561 | } | ||
1562 | dasm_put(Dst, 3338); | ||
1563 | break; | ||
1564 | case TKEY_ANY: /* Generic gettable fallback. */ | ||
1565 | if (ISK(rkey)) { | ||
1566 | dasm_put(Dst, 3342, (ptrdiff_t)(&J->pt->k[INDEXK(rkey)])); | ||
1567 | } else { | ||
1568 | dasm_put(Dst, 3204, Dt2([rkey])); | ||
1569 | } | ||
1570 | dasm_put(Dst, 3345, Dt2([tab])); | ||
1571 | if (dest) { | ||
1572 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1573 | } | ||
1574 | dasm_put(Dst, 3349, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_gettable), Dt1(->base)); | ||
1575 | break; | ||
1576 | default: /* Array key. */ | ||
1577 | dasm_put(Dst, 3366, Dt7([k-1].tt)); | ||
1578 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1579 | dasm_put(Dst, 2674, Dt7([k-1].value), Dt2([dest].value)); | ||
1580 | } else { | ||
1581 | dasm_put(Dst, 3378, Dt7([k-1].value), Dt7([k-1].value.na[1]), Dt2([dest].value), Dt2([dest].value.na[1])); | ||
1582 | } | ||
1583 | dasm_put(Dst, 3391, Dt2([dest].tt)); | ||
1584 | dasm_put(Dst, 2168); | ||
1585 | if (ISK(rkey)) { | ||
1586 | dasm_put(Dst, 3398); | ||
1587 | } else { | ||
1588 | dasm_put(Dst, 3402); | ||
1589 | } | ||
1590 | dasm_put(Dst, 3406, DtC(->metatable), DtC(->flags), 1<<TM_INDEX, (ptrdiff_t)(J->nextins)); | ||
1591 | break; | ||
1592 | } | ||
1593 | |||
1594 | } | ||
1595 | |||
1596 | static void jit_op_settable(jit_State *J, int tab, int rkey, int rval) | ||
1597 | { | ||
1598 | const TValue *val = ISK(rval) ? &J->pt->k[INDEXK(rval)] : NULL; | ||
1599 | int k = jit_keylookup(J, tab, rkey); | ||
1600 | switch (k) { | ||
1601 | case TKEY_KSTR: /* Const string key. */ | ||
1602 | case TKEY_STR: /* Variable string key. */ | ||
1603 | if (ISK(rval)) { | ||
1604 | dasm_put(Dst, 3492, (ptrdiff_t)(val)); | ||
1605 | } else { | ||
1606 | if (rval) { | ||
1607 | dasm_put(Dst, 787, rval*sizeof(TValue)); | ||
1608 | } | ||
1609 | } | ||
1610 | if (k == TKEY_KSTR) { | ||
1611 | dasm_put(Dst, 3495); | ||
1612 | } else { | ||
1613 | dasm_put(Dst, 3499); | ||
1614 | } | ||
1615 | break; | ||
1616 | case TKEY_ANY: /* Generic settable fallback. */ | ||
1617 | if (ISK(rkey)) { | ||
1618 | dasm_put(Dst, 3342, (ptrdiff_t)(&J->pt->k[INDEXK(rkey)])); | ||
1619 | } else { | ||
1620 | dasm_put(Dst, 3204, Dt2([rkey])); | ||
1621 | } | ||
1622 | if (ISK(rval)) { | ||
1623 | dasm_put(Dst, 3184, (ptrdiff_t)(val)); | ||
1624 | } else { | ||
1625 | dasm_put(Dst, 3345, Dt2([rval])); | ||
1626 | } | ||
1627 | if (tab) { | ||
1628 | dasm_put(Dst, 787, tab*sizeof(TValue)); | ||
1629 | } | ||
1630 | dasm_put(Dst, 3503, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_settable), Dt1(->base)); | ||
1631 | break; | ||
1632 | default: /* Array key. */ | ||
1633 | dasm_put(Dst, 3520, Dt7([k-1].tt)); | ||
1634 | dasm_put(Dst, 2168); | ||
1635 | if (ISK(rkey)) { | ||
1636 | dasm_put(Dst, 3534); | ||
1637 | } else { | ||
1638 | dasm_put(Dst, 3538); | ||
1639 | } | ||
1640 | dasm_put(Dst, 3406, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, (ptrdiff_t)(J->nextins)); | ||
1641 | if (!ISK(rval) || iscollectable(val)) { | ||
1642 | dasm_put(Dst, 3542, DtC(->marked), bitmask(BLACKBIT)); | ||
1643 | dasm_put(Dst, 3555); | ||
1644 | } | ||
1645 | if (ISK(rval)) { | ||
1646 | switch (ttype(val)) { | ||
1647 | case 0: | ||
1648 | dasm_put(Dst, 3565, Dt7([k-1].tt)); | ||
1649 | break; | ||
1650 | case 1: | ||
1651 | if (bvalue(val)) { /* true */ | ||
1652 | dasm_put(Dst, 3573, Dt7([k-1].value), Dt7([k-1].tt)); | ||
1653 | } else { /* false */ | ||
1654 | dasm_put(Dst, 3585, Dt7([k-1].value), Dt7([k-1].tt)); | ||
1655 | } | ||
1656 | break; | ||
1657 | case 3: { | ||
1658 | if ((&(val)->value)->n == (lua_Number)0) { | ||
1659 | dasm_put(Dst, 2404); | ||
1660 | } else if ((&(val)->value)->n == (lua_Number)1) { | ||
1661 | dasm_put(Dst, 2408); | ||
1662 | } else { | ||
1663 | dasm_put(Dst, 2411, &(val)->value); | ||
1664 | } | ||
1665 | dasm_put(Dst, 3600, Dt7([k-1].value), Dt7([k-1].tt)); | ||
1666 | break; | ||
1667 | } | ||
1668 | case 4: | ||
1669 | dasm_put(Dst, 3611, Dt7([k-1].value), (ptrdiff_t)(gcvalue(val)), Dt7([k-1].tt)); | ||
1670 | break; | ||
1671 | default: lua_assert(0); break; | ||
1672 | } | ||
1673 | } else { | ||
1674 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1675 | dasm_put(Dst, 2947, Dt2([rval].tt), Dt2([rval].value), Dt7([k-1].tt), Dt7([k-1].value)); | ||
1676 | } else { | ||
1677 | dasm_put(Dst, 2965, Dt2([rval].value), Dt2([rval].value.na[1]), Dt2([rval].tt), Dt7([k-1].value), Dt7([k-1].value.na[1]), Dt7([k-1].tt)); | ||
1678 | } | ||
1679 | } | ||
1680 | break; | ||
1681 | } | ||
1682 | |||
1683 | } | ||
1684 | |||
1685 | static void jit_op_self(jit_State *J, int dest, int tab, int rkey) | ||
1686 | { | ||
1687 | if (J->flags & JIT_F_CPU_SSE2) { | ||
1688 | dasm_put(Dst, 821, Dt2([tab].tt), Dt2([tab].value), Dt2([dest+1].tt), Dt2([dest+1].value)); | ||
1689 | } else { | ||
1690 | dasm_put(Dst, 839, Dt2([tab].value), Dt2([tab].value.na[1]), Dt2([tab].tt), Dt2([dest+1].value), Dt2([dest+1].value.na[1]), Dt2([dest+1].tt)); | ||
1691 | } | ||
1692 | jit_op_gettable(J, dest, tab, rkey); | ||
1693 | } | ||
1694 | |||
1695 | /* ------------------------------------------------------------------------ */ | ||
1696 | |||
1697 | static void jit_op_setlist(jit_State *J, int ra, int num, int batch) | ||
1698 | { | ||
1699 | if (batch == 0) { batch = (int)(*J->nextins); J->combine++; } | ||
1700 | batch = (batch-1)*LFIELDS_PER_FLUSH; | ||
1701 | if (num == 0) { /* Previous op was open and set TOP: {f()} or {...}. */ | ||
1702 | dasm_put(Dst, 3685, Dt1(->env.value), Dt2([ra+1]), Dt2([ra].value)); | ||
1703 | if (batch > 0) { | ||
1704 | dasm_put(Dst, 3709, batch); | ||
1705 | } | ||
1706 | dasm_put(Dst, 3713, DtC(->sizearray), (ptrdiff_t)(luaH_resizearray), DtC(->marked), bitmask(BLACKBIT), DtC(->array), Dt1(->env.value)); | ||
1707 | dasm_put(Dst, 3752); | ||
1708 | } else { /* Set fixed number of args. */ | ||
1709 | dasm_put(Dst, 3762, Dt2([ra].value), DtC(->sizearray), batch+num, DtC(->marked), bitmask(BLACKBIT), DtC(->array), Dt2([ra+1+num])); | ||
1710 | dasm_put(Dst, 3792, batch+num, (ptrdiff_t)(luaH_resizearray)); | ||
1711 | } | ||
1712 | if (batch > 0) { | ||
1713 | dasm_put(Dst, 3821, batch*sizeof(TValue)); | ||
1714 | } | ||
1715 | dasm_put(Dst, 3825, Dt2([ra+1])); | ||
1716 | if (num == 0) { /* Previous op was open. Restore L->top. */ | ||
1717 | dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | /* ------------------------------------------------------------------------ */ | ||
1722 | |||
1723 | static void jit_op_arith(jit_State *J, int dest, int rkb, int rkc, int ev) | ||
1724 | { | ||
1725 | const TValue *kkb = ISK(rkb) ? &J->pt->k[INDEXK(rkb)] : NULL; | ||
1726 | const TValue *kkc = ISK(rkc) ? &J->pt->k[INDEXK(rkc)] : NULL; | ||
1727 | const Value *kval; | ||
1728 | int idx, rev; | ||
1729 | int target = (ev == TM_LT || ev == TM_LE) ? jit_jmp_target(J) : 0; | ||
1730 | int hastail = 0; | ||
1731 | |||
1732 | /* The bytecode compiler already folds constants except for: k/0, k%0, */ | ||
1733 | /* NaN results, k1<k2, k1<=k2. No point in optimizing these cases. */ | ||
1734 | if (ISK(rkb&rkc)) goto fallback; | ||
1735 | |||
1736 | /* Avoid optimization when non-numeric constants are present. */ | ||
1737 | if (kkb ? !ttisnumber(kkb) : (kkc && !ttisnumber(kkc))) goto fallback; | ||
1738 | |||
1739 | /* The TYPE hint selects numeric inlining and/or fallback encoding. */ | ||
1740 | switch (ttype(hint_get(J, TYPE))) { | ||
1741 | case LUA_TNIL: hastail = 1; break; /* No hint: numeric + fallback. */ | ||
1742 | case LUA_TNUMBER: break; /* Numbers: numeric + deoptimization. */ | ||
1743 | default: goto fallback; /* Mixed/other types: fallback only. */ | ||
1744 | } | ||
1745 | |||
1746 | /* The checks above ensure: at most one of the operands is a constant. */ | ||
1747 | /* Reverse operation and swap operands so the 2nd operand is a variable. */ | ||
1748 | if (kkc) { kval = &kkc->value; idx = rkb; rev = 1; } | ||
1749 | else { kval = kkb ? &kkb->value : NULL; idx = rkc; rev = 0; } | ||
1750 | |||
1751 | /* Special handling for some operators. */ | ||
1752 | switch (ev) { | ||
1753 | case TM_MOD: | ||
1754 | /* Check for modulo with positive numbers, so we can use fprem. */ | ||
1755 | if (kval) { | ||
1756 | if (kval->na[1] < 0) { hastail = 0; goto fallback; } /* x%-k, -k%x */ | ||
1757 | dasm_put(Dst, 3850, Dt2([idx].tt), Dt2([idx].value.na[1])); | ||
1758 | if (kkb) { | ||
1759 | dasm_put(Dst, 3868, Dt2([rkc].value), kval); | ||
1760 | } else { | ||
1761 | dasm_put(Dst, 3875, kval, Dt2([rkb].value)); | ||
1762 | } | ||
1763 | } else { | ||
1764 | dasm_put(Dst, 3882, Dt2([rkb].tt), Dt2([rkc].tt), Dt2([rkb].value.na[1]), Dt2([rkc].value.na[1]), Dt2([rkc].value), Dt2([rkb].value)); | ||
1765 | } | ||
1766 | dasm_put(Dst, 1387); | ||
1767 | goto fpstore; | ||
1768 | case TM_POW: | ||
1769 | if (hastail || !kval) break; /* Avoid this if not optimizing. */ | ||
1770 | if (rev) { /* x^k for k > 0, k integer. */ | ||
1771 | lua_Number n = kval->n; | ||
1772 | int k; | ||
1773 | lua_number2int(k, n); | ||
1774 | /* All positive integers would work. But need to limit code explosion. */ | ||
1775 | if (k > 0 && k <= 65536 && (lua_Number)k == n) { | ||
1776 | dasm_put(Dst, 3916, Dt2([idx].tt), Dt2([idx])); | ||
1777 | for (; (k & 1) == 0; k >>= 1) { /* Handle leading zeroes (2^k). */ | ||
1778 | dasm_put(Dst, 3928); | ||
1779 | } | ||
1780 | if ((k >>= 1) != 0) { /* Handle trailing bits. */ | ||
1781 | dasm_put(Dst, 3931); | ||
1782 | for (; k != 1; k >>= 1) { | ||
1783 | if (k & 1) { | ||
1784 | dasm_put(Dst, 3936); | ||
1785 | } | ||
1786 | dasm_put(Dst, 3928); | ||
1787 | } | ||
1788 | dasm_put(Dst, 3939); | ||
1789 | } | ||
1790 | goto fpstore; | ||
1791 | } | ||
1792 | } else if (kval->n > (lua_Number)0) { /* k^x for k > 0. */ | ||
1793 | int log2kval[3]; /* Enough storage for a tword (80 bits). */ | ||
1794 | log2kval[2] = 0; /* Avoid leaking garbage. */ | ||
1795 | /* Double precision log2(k) doesn't cut it (3^x != 3 for x = 1). */ | ||
1796 | ((void (*)(int *, double))J->jsub[JSUB_LOG2_TWORD])(log2kval, kval->n); | ||
1797 | dasm_put(Dst, 3942, log2kval[0], log2kval[1], log2kval[2], Dt2([idx].tt), Dt2([idx].value)); | ||
1798 | |||
1799 | goto fpstore; | ||
1800 | } | ||
1801 | break; | ||
1802 | } | ||
1803 | |||
1804 | /* Check number type and load 1st operand. */ | ||
1805 | if (kval) { | ||
1806 | dasm_put(Dst, 4013, Dt2([idx].tt)); | ||
1807 | if ((kval)->n == (lua_Number)0) { | ||
1808 | dasm_put(Dst, 2404); | ||
1809 | } else if ((kval)->n == (lua_Number)1) { | ||
1810 | dasm_put(Dst, 2408); | ||
1811 | } else { | ||
1812 | dasm_put(Dst, 2411, kval); | ||
1813 | } | ||
1814 | } else { | ||
1815 | if (rkb == rkc) { | ||
1816 | dasm_put(Dst, 4022, Dt2([rkb].tt)); | ||
1817 | } else { | ||
1818 | dasm_put(Dst, 4027, Dt2([rkb].tt), Dt2([rkc].tt)); | ||
1819 | } | ||
1820 | dasm_put(Dst, 3920, Dt2([rkb].value)); | ||
1821 | } | ||
1822 | |||
1823 | /* Encode arithmetic operation with 2nd operand. */ | ||
1824 | switch ((ev<<1)+rev) { | ||
1825 | case TM_ADD<<1: case (TM_ADD<<1)+1: | ||
1826 | if (rkb == rkc) { | ||
1827 | dasm_put(Dst, 4041); | ||
1828 | } else { | ||
1829 | dasm_put(Dst, 4044, Dt2([idx].value)); | ||
1830 | } | ||
1831 | break; | ||
1832 | case TM_SUB<<1: | ||
1833 | dasm_put(Dst, 4048, Dt2([idx].value)); | ||
1834 | break; | ||
1835 | case (TM_SUB<<1)+1: | ||
1836 | dasm_put(Dst, 4052, Dt2([idx].value)); | ||
1837 | break; | ||
1838 | case TM_MUL<<1: case (TM_MUL<<1)+1: | ||
1839 | if (rkb == rkc) { | ||
1840 | dasm_put(Dst, 3928); | ||
1841 | } else { | ||
1842 | dasm_put(Dst, 4056, Dt2([idx].value)); | ||
1843 | } | ||
1844 | break; | ||
1845 | case TM_DIV<<1: | ||
1846 | dasm_put(Dst, 4060, Dt2([idx].value)); | ||
1847 | break; | ||
1848 | case (TM_DIV<<1)+1: | ||
1849 | dasm_put(Dst, 4064, Dt2([idx].value)); | ||
1850 | break; | ||
1851 | case TM_POW<<1: | ||
1852 | dasm_put(Dst, 4068, Dt2([idx].value), (ptrdiff_t)(pow)); | ||
1853 | break; | ||
1854 | case (TM_POW<<1)+1: | ||
1855 | dasm_put(Dst, 4088, Dt2([idx].value), (ptrdiff_t)(pow)); | ||
1856 | break; | ||
1857 | case TM_UNM<<1: case (TM_UNM<<1)+1: | ||
1858 | dasm_put(Dst, 4108); | ||
1859 | break; | ||
1860 | default: /* TM_LT or TM_LE. */ | ||
1861 | dasm_put(Dst, 1325, Dt2([idx].value)); | ||
1862 | if (J->flags & JIT_F_CPU_CMOV) { | ||
1863 | dasm_put(Dst, 3293); | ||
1864 | } else { | ||
1865 | dasm_put(Dst, 3298); | ||
1866 | } | ||
1867 | dasm_put(Dst, 4111, dest?(J->nextpc+1):target); | ||
1868 | jit_assert(dest == 0 || dest == 1); /* Really cond. */ | ||
1869 | switch (((rev^dest)<<1)+(dest^(ev == TM_LT))) { | ||
1870 | case 0: | ||
1871 | dasm_put(Dst, 4115, target); | ||
1872 | break; | ||
1873 | case 1: | ||
1874 | dasm_put(Dst, 4119, target); | ||
1875 | break; | ||
1876 | case 2: | ||
1877 | dasm_put(Dst, 4123, target); | ||
1878 | break; | ||
1879 | case 3: | ||
1880 | dasm_put(Dst, 4127, target); | ||
1881 | break; | ||
1882 | } | ||
1883 | goto skipstore; | ||
1884 | } | ||
1885 | fpstore: | ||
1886 | /* Store result and set result type (if necessary). */ | ||
1887 | dasm_put(Dst, 933, Dt2([dest].value)); | ||
1888 | if (dest != rkb && dest != rkc) { | ||
1889 | dasm_put(Dst, 1309, Dt2([dest].tt)); | ||
1890 | } | ||
1891 | |||
1892 | skipstore: | ||
1893 | if (!hastail) { | ||
1894 | jit_deopt_target(J, 0); | ||
1895 | return; | ||
1896 | } | ||
1897 | |||
1898 | dasm_put(Dst, 1626); | ||
1899 | dasm_put(Dst, 1541); | ||
1900 | |||
1901 | fallback: | ||
1902 | /* Generic fallback for arithmetic ops. */ | ||
1903 | if (kkb) { | ||
1904 | dasm_put(Dst, 3342, (ptrdiff_t)(kkb)); | ||
1905 | } else { | ||
1906 | dasm_put(Dst, 3204, Dt2([rkb])); | ||
1907 | } | ||
1908 | if (kkc) { | ||
1909 | dasm_put(Dst, 3184, (ptrdiff_t)(kkc)); | ||
1910 | } else { | ||
1911 | dasm_put(Dst, 3345, Dt2([rkc])); | ||
1912 | } | ||
1913 | if (target) { /* TM_LT or TM_LE. */ | ||
1914 | dasm_put(Dst, 4131, Dt1(->savedpc), (ptrdiff_t)((J->nextins+1)), (ptrdiff_t)(ev==TM_LT?luaV_lessthan:luaV_lessequal), Dt1(->base)); | ||
1915 | if (dest) { /* cond */ | ||
1916 | dasm_put(Dst, 1479, target); | ||
1917 | } else { | ||
1918 | dasm_put(Dst, 4154, target); | ||
1919 | } | ||
1920 | } else { | ||
1921 | if (dest) { | ||
1922 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1923 | } | ||
1924 | dasm_put(Dst, 4158, Dt1(->savedpc), (ptrdiff_t)(J->nextins), ev, (ptrdiff_t)(luaV_arith), Dt1(->base)); | ||
1925 | } | ||
1926 | |||
1927 | if (hastail) { | ||
1928 | dasm_put(Dst, 1644); | ||
1929 | } | ||
1930 | } | ||
1931 | |||
1932 | /* ------------------------------------------------------------------------ */ | ||
1933 | |||
1934 | static void jit_fallback_len(lua_State *L, StkId ra, const TValue *rb) | ||
1935 | { | ||
1936 | switch (ttype(rb)) { | ||
1937 | case LUA_TTABLE: | ||
1938 | setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); | ||
1939 | break; | ||
1940 | case LUA_TSTRING: | ||
1941 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
1942 | break; | ||
1943 | default: { | ||
1944 | const TValue *tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
1945 | if (ttisfunction(tm)) { | ||
1946 | ptrdiff_t rasave = savestack(L, ra); | ||
1947 | setobj2s(L, L->top, tm); | ||
1948 | setobj2s(L, L->top+1, rb); | ||
1949 | luaD_checkstack(L, 2); | ||
1950 | L->top += 2; | ||
1951 | luaD_call(L, L->top - 2, 1); | ||
1952 | ra = restorestack(L, rasave); | ||
1953 | L->top--; | ||
1954 | setobjs2s(L, ra, L->top); | ||
1955 | } else { | ||
1956 | luaG_typeerror(L, rb, "get length of"); | ||
1957 | } | ||
1958 | break; | ||
1959 | } | ||
1960 | } | ||
1961 | } | ||
1962 | |||
1963 | static void jit_op_len(jit_State *J, int dest, int rb) | ||
1964 | { | ||
1965 | switch (ttype(hint_get(J, TYPE))) { | ||
1966 | case LUA_TTABLE: | ||
1967 | jit_deopt_target(J, 0); | ||
1968 | dasm_put(Dst, 4179, Dt2([rb].tt), Dt2([rb].value), (ptrdiff_t)(luaH_getn), Dt2([dest].value), Dt2([dest].tt)); | ||
1969 | break; | ||
1970 | case LUA_TSTRING: | ||
1971 | jit_deopt_target(J, 0); | ||
1972 | dasm_put(Dst, 4212, Dt2([rb].tt), Dt2([rb].value), DtB(->tsv.len), Dt2([dest].value), Dt2([dest].tt)); | ||
1973 | break; | ||
1974 | default: | ||
1975 | dasm_put(Dst, 3204, Dt2([rb])); | ||
1976 | if (dest) { | ||
1977 | dasm_put(Dst, 787, dest*sizeof(TValue)); | ||
1978 | } | ||
1979 | dasm_put(Dst, 4237, Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(jit_fallback_len), Dt1(->base)); | ||
1980 | break; | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | static void jit_op_not(jit_State *J, int dest, int rb) | ||
1985 | { | ||
1986 | /* l_isfalse() without a branch -- truly devious. */ | ||
1987 | /* ((value & tt) | (tt>>1)) is only zero for nil/false. */ | ||
1988 | /* Assumes: LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */ | ||
1989 | dasm_put(Dst, 4258, Dt2([rb].tt), Dt2([rb].value), Dt2([dest].tt), Dt2([dest].value)); | ||
1990 | } | ||
1991 | |||
1992 | /* ------------------------------------------------------------------------ */ | ||
1993 | |||
1994 | static void jit_op_concat(jit_State *J, int dest, int first, int last) | ||
1995 | { | ||
1996 | int num = last-first+1; | ||
1997 | if (num == 2 && ttisstring(hint_get(J, TYPE))) { /* Optimize common case. */ | ||
1998 | if (first) { | ||
1999 | dasm_put(Dst, 787, first*sizeof(TValue)); | ||
2000 | } | ||
2001 | dasm_put(Dst, 4288, Dt2([dest].value), Dt2([dest].tt)); | ||
2002 | } else { /* Generic fallback. */ | ||
2003 | dasm_put(Dst, 4302, Dt1(->savedpc), (ptrdiff_t)(J->nextins), num, last, (ptrdiff_t)(luaV_concat), Dt1(->base)); | ||
2004 | if (dest != first) { | ||
2005 | if (J->flags & JIT_F_CPU_SSE2) { | ||
2006 | dasm_put(Dst, 821, Dt2([first].tt), Dt2([first].value), Dt2([dest].tt), Dt2([dest].value)); | ||
2007 | } else { | ||
2008 | dasm_put(Dst, 839, Dt2([first].value), Dt2([first].value.na[1]), Dt2([first].tt), Dt2([dest].value), Dt2([dest].value.na[1]), Dt2([dest].tt)); | ||
2009 | } | ||
2010 | } | ||
2011 | } | ||
2012 | jit_checkGC(J); /* Always do this, even for the optimized variant. */ | ||
2013 | |||
2014 | } | ||
2015 | |||
2016 | /* ------------------------------------------------------------------------ */ | ||
2017 | |||
2018 | static void jit_op_eq(jit_State *J, int cond, int rkb, int rkc) | ||
2019 | { | ||
2020 | int target = jit_jmp_target(J); | ||
2021 | int condtarget = cond ? (J->nextpc+1) : target; | ||
2022 | jit_assert(cond == 0 || cond == 1); | ||
2023 | |||
2024 | /* Comparison of two constants. Evaluate at compile time. */ | ||
2025 | if (ISK(rkb&rkc)) { | ||
2026 | if ((rkb == rkc) == cond) { /* Constants are already unique. */ | ||
2027 | dasm_put(Dst, 665, target); | ||
2028 | } | ||
2029 | return; | ||
2030 | } | ||
2031 | |||
2032 | if (ISK(rkb|rkc)) { /* Compare a variable and a constant. */ | ||
2033 | const TValue *kk; | ||
2034 | if (ISK(rkb)) { int t = rkc; rkc = rkb; rkb = t; } /* rkc holds const. */ | ||
2035 | kk = &J->pt->k[INDEXK(rkc)]; | ||
2036 | switch (ttype(kk)) { | ||
2037 | case LUA_TNIL: | ||
2038 | dasm_put(Dst, 4493, Dt2([rkb].tt)); | ||
2039 | break; | ||
2040 | case LUA_TBOOLEAN: | ||
2041 | if (bvalue(kk)) { | ||
2042 | dasm_put(Dst, 4498, Dt2([rkb].tt), Dt2([rkb].value)); | ||
2043 | } else { | ||
2044 | dasm_put(Dst, 4509, Dt2([rkb].tt), Dt2([rkb].value)); | ||
2045 | } | ||
2046 | break; | ||
2047 | case LUA_TNUMBER: | ||
2048 | dasm_put(Dst, 4517, Dt2([rkb].tt), condtarget, Dt2([rkb].value), &kk->value); | ||
2049 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2050 | dasm_put(Dst, 3293); | ||
2051 | } else { | ||
2052 | dasm_put(Dst, 3298); | ||
2053 | } | ||
2054 | dasm_put(Dst, 4111, condtarget); | ||
2055 | break; | ||
2056 | case LUA_TSTRING: | ||
2057 | dasm_put(Dst, 4531, Dt2([rkb].tt), condtarget, Dt2([rkb].value), (ptrdiff_t)(rawtsvalue(kk))); | ||
2058 | break; | ||
2059 | default: jit_assert(0); break; | ||
2060 | } | ||
2061 | } else { /* Compare two variables. */ | ||
2062 | dasm_put(Dst, 4543, Dt2([rkb].tt), Dt2([rkc].tt), condtarget); | ||
2063 | switch (ttype(hint_get(J, TYPE))) { | ||
2064 | case LUA_TNUMBER: | ||
2065 | jit_deopt_target(J, 0); | ||
2066 | dasm_put(Dst, 4553, Dt2([rkb].value), Dt2([rkc].value)); | ||
2067 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2068 | dasm_put(Dst, 3293); | ||
2069 | } else { | ||
2070 | dasm_put(Dst, 3298); | ||
2071 | } | ||
2072 | dasm_put(Dst, 4111, condtarget); | ||
2073 | break; | ||
2074 | case LUA_TSTRING: | ||
2075 | jit_deopt_target(J, 0); | ||
2076 | dasm_put(Dst, 4568, Dt2([rkb].value), Dt2([rkc].value)); | ||
2077 | break; | ||
2078 | default: | ||
2079 | dasm_put(Dst, 4583, Dt2([rkc]), Dt2([rkb]), Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(luaV_equalval), Dt1(->base)); | ||
2080 | break; | ||
2081 | } | ||
2082 | } | ||
2083 | if (cond) { | ||
2084 | dasm_put(Dst, 4154, target); | ||
2085 | } else { | ||
2086 | dasm_put(Dst, 1479, target); | ||
2087 | } | ||
2088 | } | ||
2089 | |||
2090 | /* ------------------------------------------------------------------------ */ | ||
2091 | |||
2092 | static void jit_op_test(jit_State *J, int cond, int dest, int src) | ||
2093 | { | ||
2094 | int target = jit_jmp_target(J); | ||
2095 | |||
2096 | /* l_isfalse() without a branch. But this time preserve tt/value. */ | ||
2097 | /* (((value & tt) * 2 + tt) >> 1) is only zero for nil/false. */ | ||
2098 | /* Assumes: 3*tt < 2^32, LUA_TNIL == 0, LUA_TBOOLEAN == 1, bvalue() == 0/1 */ | ||
2099 | dasm_put(Dst, 4611, Dt2([src].tt), Dt2([src].value)); | ||
2100 | |||
2101 | /* Check if we can omit the stack copy. */ | ||
2102 | if (dest == src) { /* Yes, invert branch condition. */ | ||
2103 | if (cond) { | ||
2104 | dasm_put(Dst, 1479, target); | ||
2105 | } else { | ||
2106 | dasm_put(Dst, 4154, target); | ||
2107 | } | ||
2108 | } else { /* No, jump around copy code. */ | ||
2109 | if (cond) { | ||
2110 | dasm_put(Dst, 4627); | ||
2111 | } else { | ||
2112 | dasm_put(Dst, 4632); | ||
2113 | } | ||
2114 | dasm_put(Dst, 4637, Dt2([src].value.na[1]), Dt2([dest].tt), Dt2([dest].value), Dt2([dest].value.na[1]), target); | ||
2115 | } | ||
2116 | } | ||
2117 | |||
2118 | static void jit_op_jmp(jit_State *J, int target) | ||
2119 | { | ||
2120 | dasm_put(Dst, 665, target); | ||
2121 | } | ||
2122 | |||
2123 | /* ------------------------------------------------------------------------ */ | ||
2124 | |||
2125 | enum { FOR_IDX, FOR_LIM, FOR_STP, FOR_EXT }; | ||
2126 | |||
2127 | static const char *const jit_for_coerce_error[] = { | ||
2128 | LUA_QL("for") " initial value must be a number", | ||
2129 | LUA_QL("for") " limit must be a number", | ||
2130 | LUA_QL("for") " step must be a number", | ||
2131 | }; | ||
2132 | |||
2133 | /* Try to coerce for slots with strings to numbers in place or complain. */ | ||
2134 | static void jit_for_coerce(lua_State *L, TValue *o) | ||
2135 | { | ||
2136 | int i; | ||
2137 | for (i = FOR_IDX; i <= FOR_STP; i++, o++) { | ||
2138 | lua_Number num; | ||
2139 | if (ttisnumber(o)) continue; | ||
2140 | if (ttisstring(o) && luaO_str2d(svalue(o), &num)) { | ||
2141 | setnvalue(o, num); | ||
2142 | } else { | ||
2143 | luaG_runerror(L, jit_for_coerce_error[i]); | ||
2144 | } | ||
2145 | } | ||
2146 | } | ||
2147 | |||
2148 | static void jit_op_forprep(jit_State *J, int ra, int target) | ||
2149 | { | ||
2150 | const TValue *step = hint_get(J, FOR_STEP_K); | ||
2151 | if (ttisnumber(step)) { | ||
2152 | dasm_put(Dst, 4654, Dt2([ra+FOR_IDX].tt), Dt2([ra+FOR_LIM].tt), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value)); | ||
2153 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2154 | dasm_put(Dst, 3293); | ||
2155 | } else { | ||
2156 | dasm_put(Dst, 3298); | ||
2157 | } | ||
2158 | dasm_put(Dst, 1309, Dt2([ra+FOR_EXT].tt)); | ||
2159 | if (nvalue(step) < (lua_Number)0) { | ||
2160 | dasm_put(Dst, 4115, target+1); | ||
2161 | } else { | ||
2162 | dasm_put(Dst, 4123, target+1); | ||
2163 | } | ||
2164 | } else { | ||
2165 | dasm_put(Dst, 4683, Dt2([ra+FOR_IDX].tt), Dt2([ra+FOR_LIM].tt), Dt2([ra+FOR_STP].tt), Dt2([ra+FOR_STP].value.na[1]), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value)); | ||
2166 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2167 | dasm_put(Dst, 3293); | ||
2168 | } else { | ||
2169 | dasm_put(Dst, 3298); | ||
2170 | } | ||
2171 | dasm_put(Dst, 4732, Dt2([ra+FOR_EXT].tt), target+1); | ||
2172 | } | ||
2173 | if (ttisnumber(hint_get(J, TYPE))) { | ||
2174 | jit_deopt_target(J, 0); | ||
2175 | } else { | ||
2176 | dasm_put(Dst, 679); | ||
2177 | dasm_put(Dst, 4743, Dt2([ra]), Dt1(->savedpc), (ptrdiff_t)(J->nextins), (ptrdiff_t)(jit_for_coerce)); | ||
2178 | } | ||
2179 | } | ||
2180 | |||
2181 | static void jit_op_forloop(jit_State *J, int ra, int target) | ||
2182 | { | ||
2183 | const TValue *step = hint_getpc(J, FOR_STEP_K, target-1); | ||
2184 | if (ttisnumber(step)) { | ||
2185 | dasm_put(Dst, 4766, Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_STP].value), Dt2([ra+FOR_EXT].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].tt)); | ||
2186 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2187 | dasm_put(Dst, 3293); | ||
2188 | } else { | ||
2189 | dasm_put(Dst, 3298); | ||
2190 | } | ||
2191 | if (nvalue(step) < (lua_Number)0) { | ||
2192 | dasm_put(Dst, 4127, target); | ||
2193 | } else { | ||
2194 | dasm_put(Dst, 4119, target); | ||
2195 | } | ||
2196 | } else { | ||
2197 | dasm_put(Dst, 4789, Dt2([ra+FOR_STP].value.na[1]), Dt2([ra+FOR_LIM].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_STP].value), Dt2([ra+FOR_IDX].value), Dt2([ra+FOR_EXT].value), Dt2([ra+FOR_EXT].tt)); | ||
2198 | if (J->flags & JIT_F_CPU_CMOV) { | ||
2199 | dasm_put(Dst, 3293); | ||
2200 | } else { | ||
2201 | dasm_put(Dst, 3298); | ||
2202 | } | ||
2203 | dasm_put(Dst, 4127, target); | ||
2204 | } | ||
2205 | } | ||
2206 | |||
2207 | /* ------------------------------------------------------------------------ */ | ||
2208 | |||
2209 | static void jit_op_tforloop(jit_State *J, int ra, int nresults) | ||
2210 | { | ||
2211 | int target = jit_jmp_target(J); | ||
2212 | int i; | ||
2213 | if (jit_inline_tforloop(J, ra, nresults, target)) return; /* Inlined? */ | ||
2214 | for (i = 2; i >= 0; i--) { | ||
2215 | if (J->flags & JIT_F_CPU_SSE2) { | ||
2216 | dasm_put(Dst, 821, Dt2([ra+i].tt), Dt2([ra+i].value), Dt2([ra+i+3].tt), Dt2([ra+i+3].value)); | ||
2217 | } else { | ||
2218 | dasm_put(Dst, 839, Dt2([ra+i].value), Dt2([ra+i].value.na[1]), Dt2([ra+i].tt), Dt2([ra+i+3].value), Dt2([ra+i+3].value.na[1]), Dt2([ra+i+3].tt)); | ||
2219 | } | ||
2220 | } | ||
2221 | jit_op_call(J, ra+3, 2, nresults); | ||
2222 | dasm_put(Dst, 4827, Dt2([ra+3].tt)); | ||
2223 | if (J->flags & JIT_F_CPU_SSE2) { | ||
2224 | dasm_put(Dst, 821, Dt2([ra+3].tt), Dt2([ra+3].value), Dt2([ra+2].tt), Dt2([ra+2].value)); | ||
2225 | } else { | ||
2226 | dasm_put(Dst, 839, Dt2([ra+3].value), Dt2([ra+3].value.na[1]), Dt2([ra+3].tt), Dt2([ra+2].value), Dt2([ra+2].value.na[1]), Dt2([ra+2].tt)); | ||
2227 | } | ||
2228 | dasm_put(Dst, 4649, target); | ||
2229 | } | ||
2230 | |||
2231 | /* ------------------------------------------------------------------------ */ | ||
2232 | |||
2233 | static void jit_op_close(jit_State *J, int ra) | ||
2234 | { | ||
2235 | if (ra) { | ||
2236 | dasm_put(Dst, 4836, Dt2([ra])); | ||
2237 | } else { | ||
2238 | dasm_put(Dst, 4844); | ||
2239 | } | ||
2240 | dasm_put(Dst, 1734, (ptrdiff_t)(luaF_close)); | ||
2241 | } | ||
2242 | |||
2243 | static void jit_op_closure(jit_State *J, int dest, int ptidx) | ||
2244 | { | ||
2245 | Proto *npt = J->pt->p[ptidx]; | ||
2246 | int nup = npt->nups; | ||
2247 | if (!J->pt->is_vararg) { | ||
2248 | dasm_put(Dst, 4849, Dt2([-1].value)); | ||
2249 | } else { | ||
2250 | dasm_put(Dst, 4853, Dt1(->ci), Dt4(->func), Dt3(->value)); | ||
2251 | } | ||
2252 | dasm_put(Dst, 4863, Dt5(->env), nup, (ptrdiff_t)(luaF_newLclosure), Dt5(->p), (ptrdiff_t)(npt), Dt2([dest].value), Dt2([dest].tt)); | ||
2253 | /* Process pseudo-instructions for upvalues. */ | ||
2254 | if (nup > 0) { | ||
2255 | const Instruction *uvcode = J->nextins; | ||
2256 | int i, uvuv; | ||
2257 | /* Check which of the two types we need. */ | ||
2258 | for (i = 0, uvuv = 0; i < nup; i++) | ||
2259 | if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) uvuv++; | ||
2260 | /* Copy upvalues from parent first. */ | ||
2261 | if (uvuv) { | ||
2262 | /* LCL:eax->upvals (new closure) <-- LCL:edi->upvals (own closure). */ | ||
2263 | for (i = 0; i < nup; i++) | ||
2264 | if (GET_OPCODE(uvcode[i]) == OP_GETUPVAL) { | ||
2265 | dasm_put(Dst, 4895, Dt5(->upvals[GETARG_B(uvcode[i])]), Dt5(->upvals[i])); | ||
2266 | } | ||
2267 | } | ||
2268 | /* Next find or create upvalues for our own stack slots. */ | ||
2269 | if (nup > uvuv) { | ||
2270 | dasm_put(Dst, 909); | ||
2271 | /* LCL:edi->upvals (new closure) <-- upvalue for stack slot. */ | ||
2272 | for (i = 0; i < nup; i++) | ||
2273 | if (GET_OPCODE(uvcode[i]) == OP_MOVE) { | ||
2274 | int rb = GETARG_B(uvcode[i]); | ||
2275 | if (rb) { | ||
2276 | dasm_put(Dst, 4836, Dt2([rb])); | ||
2277 | } else { | ||
2278 | dasm_put(Dst, 4844); | ||
2279 | } | ||
2280 | dasm_put(Dst, 4902, (ptrdiff_t)(luaF_findupval), Dt5(->upvals[i])); | ||
2281 | } | ||
2282 | } | ||
2283 | J->combine += nup; /* Skip pseudo-instructions. */ | ||
2284 | } | ||
2285 | jit_checkGC(J); | ||
2286 | } | ||
2287 | |||
2288 | /* ------------------------------------------------------------------------ */ | ||
2289 | |||
2290 | static void jit_op_vararg(jit_State *J, int dest, int num) | ||
2291 | { | ||
2292 | if (num < 0) { /* Copy all varargs. */ | ||
2293 | dasm_put(Dst, 4911, Dt1(->ci), Dt4(->func), (1+J->pt->numparams)*sizeof(TValue), J->pt->maxstacksize*sizeof(TValue), Dt1(->stack_last), Dt2([dest])); | ||
2294 | dasm_put(Dst, 4967, Dt1(->top), (ptrdiff_t)(luaD_growstack), Dt1(->base)); | ||
2295 | } else if (num > 0) { /* Copy limited number of varargs. */ | ||
2296 | dasm_put(Dst, 4993, Dt1(->ci), Dt4(->func), (1+J->pt->numparams)*sizeof(TValue), Dt2([dest]), Dt2([dest+num]), Dt3([0].tt), sizeof(TValue)); | ||
2297 | } | ||
2298 | } | ||
2299 | |||
2300 | /* ------------------------------------------------------------------------ */ | ||
2301 | |||