1/*
2** This file has been pre-processed with DynASM.
3** http://luajit.org/dynasm.html
4** DynASM version 1.3.0, DynASM x64 version 1.3.0
5** DO NOT EDIT! The original file is in "vm_x86.dasc".
6*/
7
8#line 1 "vm_x86.dasc"
9//|// Low-level VM code for x86 CPUs.
10//|// Bytecode interpreter, fast functions and helper functions.
11//|// Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
12//|
13//|.if P64
14//|.arch x64
15#if DASM_VERSION != 10300
16#error "Version mismatch between DynASM and included encoding engine"
17#endif
18#line 7 "vm_x86.dasc"
19//|.else
20//|.arch x86
21//|.endif
22//|.section code_op, code_sub
23#define DASM_SECTION_CODE_OP 0
24#define DASM_SECTION_CODE_SUB 1
25#define DASM_MAXSECTION 2
26#line 11 "vm_x86.dasc"
27//|
28//|.actionlist build_actionlist
29static const unsigned char build_actionlist[14361] = {
30 254,1,248,10,252,247,195,237,15,132,244,11,131,227,252,248,41,218,72,141,
31 76,25,252,248,139,90,252,252,199,68,10,4,237,248,12,131,192,1,15,132,244,
32 13,137,68,36,4,252,247,195,237,15,132,244,14,248,15,129,252,243,239,252,247,
33 195,237,15,133,244,10,65,199,134,233,237,131,227,252,248,41,211,252,247,219,
34 131,232,1,15,132,244,248,248,1,255,72,139,44,10,72,137,106,252,248,131,194,
35 8,131,232,1,15,133,244,1,248,2,139,108,36,24,137,157,233,248,3,139,68,36,
36 4,139,76,36,16,248,4,57,193,15,133,244,252,248,5,131,252,234,8,137,149,233,
37 248,16,72,139,76,36,32,72,137,141,233,49,192,248,17,72,131,196,40,65,94,65,
38 95,91,93,195,248,6,15,130,244,253,59,149,233,15,135,244,254,199,66,252,252,
39 237,255,131,194,8,131,192,1,252,233,244,4,248,7,133,201,15,132,244,5,41,193,
40 141,20,202,252,233,244,5,248,8,137,149,233,137,68,36,4,137,206,137,252,239,
41 232,251,1,0,139,149,233,252,233,244,3,248,13,176,235,252,233,244,18,248,19,
42 137,252,240,72,137,252,252,248,18,139,108,36,24,139,173,233,199,133,233,237,
43 255,252,233,244,17,248,20,139,124,36,24,137,198,72,131,196,40,65,94,65,95,
44 91,93,252,233,251,1,1,248,21,72,129,231,239,72,137,252,252,248,22,139,108,
45 36,24,72,199,193,252,248,252,255,252,255,252,255,184,237,139,149,233,68,139,
46 181,233,65,129,198,239,139,90,252,252,199,66,252,252,237,65,199,134,233,237,
47 252,233,244,12,248,23,190,237,252,233,244,248,248,24,255,131,232,8,252,233,
48 244,247,248,25,141,68,194,252,248,248,1,15,182,139,233,131,195,4,137,149,
49 233,137,133,233,137,92,36,28,137,206,248,2,137,252,239,232,251,1,0,139,149,
50 233,139,133,233,139,106,252,248,41,208,193,232,3,131,192,1,139,157,233,139,
51 11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,26,85,83,
52 65,87,65,86,72,131,252,236,40,137,252,253,137,124,36,24,137,252,241,187,237,
53 49,192,76,141,188,253,36,233,68,139,181,233,65,129,198,239,76,137,189,233,
54 137,68,36,28,72,137,68,36,32,137,68,36,16,137,68,36,20,56,133,233,15,132,
55 244,249,255,65,199,134,233,237,136,133,233,139,149,233,139,133,233,41,200,
56 193,232,3,131,192,1,41,209,139,90,252,252,137,68,36,4,252,247,195,237,15,
57 132,244,14,252,233,244,15,248,27,85,83,65,87,65,86,72,131,252,236,40,187,
58 237,137,76,36,20,252,233,244,247,248,28,85,83,65,87,65,86,72,131,252,236,
59 40,187,237,248,1,137,84,36,16,137,252,253,137,124,36,24,137,252,241,76,139,
60 189,233,76,137,124,36,32,137,108,36,28,72,137,165,233,248,2,255,68,139,181,
61 233,65,129,198,239,248,3,65,199,134,233,237,139,149,233,1,203,41,211,139,
62 133,233,41,200,193,232,3,131,192,1,248,29,139,105,252,248,129,121,253,252,
63 252,239,15,133,244,30,248,31,137,202,137,90,252,252,139,157,233,139,11,15,
64 182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,32,85,83,65,87,
65 65,86,72,131,252,236,40,137,252,253,137,124,36,24,137,108,36,28,68,139,189,
66 233,68,43,189,233,199,68,36,20,0,0,0,0,68,137,124,36,16,76,139,189,233,76,
67 137,124,36,32,72,137,165,233,252,255,209,133,192,15,132,244,16,255,137,193,
68 187,237,252,233,244,2,248,11,1,209,131,227,252,248,137,213,41,218,199,68,
69 193,252,252,237,137,200,139,93,252,244,72,99,77,252,240,131,252,249,1,15,
70 134,244,247,76,141,61,245,76,1,252,249,68,139,122,252,248,69,139,191,233,
71 69,139,191,233,252,255,225,248,1,15,132,244,33,41,213,193,252,237,3,141,69,
72 252,255,252,233,244,34,248,35,15,182,75,252,255,131,252,237,16,141,12,202,
73 41,252,233,15,132,244,36,252,247,217,193,252,233,3,139,124,36,24,137,151,
74 233,255,137,202,72,139,8,72,137,77,0,137,252,238,252,233,244,37,248,38,137,
75 4,36,199,68,36,4,237,72,141,4,36,128,123,252,252,235,15,133,244,247,65,141,
76 142,233,137,41,199,65,4,237,137,205,252,233,244,248,248,39,15,182,67,252,
77 254,252,242,15,42,192,252,242,15,17,4,36,72,141,4,36,252,233,244,247,248,
78 40,15,182,67,252,254,141,4,194,248,1,15,182,107,252,255,141,44,252,234,248,
79 2,139,124,36,24,137,151,233,137,252,238,72,137,194,137,252,253,137,92,36,
80 28,232,251,1,2,139,149,233,133,192,15,132,244,249,248,36,255,15,182,75,252,
81 253,72,139,40,72,137,44,202,139,3,15,182,204,15,182,232,131,195,4,193,232,
82 16,65,252,255,36,252,238,248,3,139,141,233,137,89,252,244,141,153,233,41,
83 211,139,105,252,248,184,237,252,233,244,31,248,41,137,4,36,199,68,36,4,237,
84 72,141,4,36,128,123,252,252,235,15,133,244,247,65,141,142,233,137,41,199,
85 65,4,237,137,205,252,233,244,248,248,42,15,182,67,252,254,252,242,15,42,192,
86 252,242,15,17,4,36,72,141,4,36,252,233,244,247,248,43,15,182,67,252,254,141,
87 4,194,248,1,255,15,182,107,252,255,141,44,252,234,248,2,139,124,36,24,137,
88 151,233,137,252,238,72,137,194,137,252,253,137,92,36,28,232,251,1,3,139,149,
89 233,133,192,15,132,244,249,15,182,75,252,253,72,139,44,202,72,137,40,248,
90 44,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,
91 248,3,139,141,233,137,89,252,244,15,182,67,252,253,72,139,44,194,72,137,105,
92 16,141,153,233,41,211,139,105,252,248,184,237,252,233,244,31,248,45,139,108,
93 36,24,137,149,233,141,52,202,141,20,194,137,252,239,15,182,75,252,252,137,
94 92,36,28,232,251,1,4,248,3,139,149,233,131,252,248,1,15,135,244,46,248,4,
95 141,91,4,15,130,244,252,248,5,255,15,183,67,252,254,141,156,253,131,233,248,
96 6,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,
97 248,47,131,195,4,129,120,253,4,239,15,130,244,5,252,233,244,6,248,48,129,
98 120,253,4,239,252,233,244,4,248,49,131,252,235,4,137,206,137,252,233,139,
99 108,36,24,137,149,233,137,194,137,252,239,137,92,36,28,232,251,1,5,252,233,
100 244,3,248,50,131,252,235,4,139,108,36,24,137,149,233,137,252,239,139,115,
101 252,252,137,92,36,28,232,251,1,6,252,233,244,3,248,51,248,52,255,65,141,4,
102 199,252,233,244,247,248,53,248,54,65,141,4,199,141,44,252,234,149,252,233,
103 244,248,248,55,141,4,194,137,197,252,233,244,248,248,56,248,57,141,4,194,
104 248,1,141,44,252,234,248,2,141,12,202,68,15,182,67,252,252,137,206,137,193,
105 139,124,36,24,137,151,233,137,252,234,137,252,253,137,92,36,28,232,251,1,
106 7,139,149,233,133,192,15,132,244,44,248,46,137,193,41,208,137,89,252,244,
107 141,152,233,184,237,255,252,233,244,29,248,58,139,108,36,24,137,149,233,141,
108 52,194,137,252,239,137,92,36,28,232,251,1,8,139,149,233,255,133,192,15,133,
109 244,46,15,183,67,252,254,139,60,194,252,233,244,59,255,252,233,244,46,255,
110 248,60,141,76,202,8,248,30,137,76,36,4,137,4,36,131,252,233,8,139,108,36,
111 24,137,149,233,137,206,141,20,193,137,252,239,137,92,36,28,232,251,1,9,139,
112 149,233,139,76,36,4,139,4,36,139,105,252,248,131,192,1,65,57,215,15,132,244,
113 61,137,202,137,90,252,252,139,157,233,139,11,15,182,252,233,15,182,205,131,
114 195,4,65,252,255,36,252,238,248,62,139,108,36,24,137,149,233,137,206,137,
115 252,239,137,92,36,28,232,251,1,10,139,149,233,139,67,252,252,15,182,204,15,
116 182,232,193,232,16,65,252,255,164,253,252,238,233,248,63,129,252,248,239,
117 15,130,244,64,139,106,4,129,252,253,239,15,131,244,64,139,90,252,252,137,
118 68,36,4,137,106,252,252,139,42,137,106,252,248,131,232,2,15,132,244,248,255,
119 137,209,248,1,131,193,8,72,139,41,72,137,105,252,248,131,232,1,15,133,244,
120 1,248,2,139,68,36,4,252,233,244,65,248,66,129,252,248,239,15,130,244,64,139,
121 106,4,137,252,233,193,252,249,15,131,252,249,252,254,15,132,244,249,184,237,
122 252,247,213,57,232,15,71,197,248,2,139,106,252,248,139,132,253,197,233,139,
123 90,252,252,199,66,252,252,237,137,66,252,248,252,233,244,67,248,3,184,237,
124 255,252,233,244,2,248,68,129,252,248,239,15,130,244,64,139,106,4,139,90,252,
125 252,129,252,253,239,15,133,244,252,248,1,139,42,139,173,233,248,2,133,252,
126 237,199,66,252,252,237,15,132,244,67,65,139,134,233,199,66,252,252,237,137,
127 106,252,248,139,141,233,35,136,233,105,201,239,255,3,141,233,248,3,129,185,
128 233,239,15,133,244,250,57,129,233,15,132,244,251,248,4,139,137,233,133,201,
129 15,133,244,3,252,233,244,67,248,5,139,105,4,129,252,253,239,15,132,244,67,
130 139,1,137,106,252,252,137,66,252,248,252,233,244,67,248,6,255,129,252,253,
131 239,15,132,244,1,129,252,253,239,15,135,244,254,129,252,253,239,15,134,244,
132 253,189,237,252,233,244,254,248,7,189,237,248,8,252,247,213,65,139,172,253,
133 174,233,252,233,244,2,248,69,129,252,248,239,255,15,130,244,64,129,122,253,
134 4,239,15,133,244,64,139,42,131,189,233,0,15,133,244,64,129,122,253,12,239,
135 15,133,244,64,139,66,8,137,133,233,139,90,252,252,199,66,252,252,237,137,
136 106,252,248,252,246,133,233,235,15,132,244,247,128,165,233,235,65,139,134,
137 233,255,65,137,174,233,137,133,233,248,1,252,233,244,67,248,70,129,252,248,
138 239,15,130,244,64,129,122,253,4,239,15,133,244,64,137,213,139,50,141,82,8,
139 139,124,36,24,232,251,1,11,137,252,234,72,139,40,139,90,252,252,72,137,106,
140 252,248,252,233,244,67,248,71,129,252,248,239,15,133,244,64,129,122,253,4,
141 239,15,131,244,64,255,252,242,15,16,2,252,233,244,72,248,73,129,252,248,239,
142 15,130,244,64,139,90,252,252,129,122,253,4,239,15,133,244,249,139,2,248,2,
143 199,66,252,252,237,137,66,252,248,252,233,244,67,248,3,129,122,253,4,239,
144 15,135,244,64,65,131,190,233,0,15,133,244,64,255,65,139,174,233,65,59,174,
145 233,15,130,244,247,232,244,74,248,1,139,108,36,24,137,149,233,137,92,36,28,
146 137,214,137,252,239,232,251,1,12,139,149,233,252,233,244,2,248,75,129,252,
147 248,239,15,130,244,64,15,132,244,248,248,1,129,122,253,4,239,15,133,244,64,
148 255,139,108,36,24,137,149,233,137,149,233,139,90,252,252,139,50,141,82,8,
149 137,252,239,137,92,36,28,232,251,1,13,139,149,233,133,192,15,132,244,249,
150 72,139,106,8,72,139,66,16,72,137,106,252,248,72,137,2,248,76,184,237,252,
151 233,244,77,248,2,199,66,12,237,252,233,244,1,248,3,199,66,252,252,237,252,
152 233,244,67,248,78,129,252,248,239,15,130,244,64,255,139,42,129,122,253,4,
153 239,15,133,244,64,255,131,189,233,0,15,133,244,64,255,139,106,252,248,139,
154 133,233,139,90,252,252,199,66,252,252,237,137,66,252,248,199,66,12,237,184,
155 237,252,233,244,77,248,79,129,252,248,239,15,130,244,64,129,122,253,4,239,
156 15,133,244,64,129,122,253,12,239,15,131,244,64,139,90,252,252,252,242,15,
157 16,66,8,72,189,237,237,102,72,15,110,205,252,242,15,88,193,252,242,15,45,
158 192,252,242,15,17,66,252,248,139,42,59,133,233,15,131,244,248,255,193,224,
159 3,3,133,233,248,1,129,120,253,4,239,15,132,244,80,72,139,40,72,137,42,252,
160 233,244,76,248,2,131,189,233,0,15,132,244,80,137,252,239,137,213,137,198,
161 232,251,1,14,137,252,234,133,192,15,133,244,1,248,80,184,237,252,233,244,
162 77,248,81,129,252,248,239,15,130,244,64,255,139,106,252,248,139,133,233,139,
163 90,252,252,199,66,252,252,237,137,66,252,248,15,87,192,252,242,15,17,66,8,
164 184,237,252,233,244,77,248,82,129,252,248,239,15,130,244,64,141,74,8,131,
165 232,1,187,237,248,1,65,15,182,174,233,193,252,237,235,131,229,1,1,252,235,
166 252,233,244,29,248,83,129,252,248,239,15,130,244,64,129,122,253,12,239,255,
167 15,133,244,64,139,106,4,137,106,12,199,66,4,237,139,42,139,90,8,137,106,8,
168 137,26,141,74,16,131,232,2,187,237,252,233,244,1,248,84,129,252,248,239,15,
169 130,244,64,139,42,139,90,252,252,137,92,36,28,137,44,36,129,122,253,4,239,
170 15,133,244,64,72,131,189,233,0,15,133,244,64,128,189,233,235,15,135,244,64,
171 255,139,141,233,15,132,244,247,59,141,233,15,132,244,64,248,1,141,92,193,
172 252,240,59,157,233,15,135,244,64,137,157,233,139,108,36,24,137,149,233,131,
173 194,8,137,149,233,141,108,194,232,72,41,221,57,203,15,132,244,249,248,2,72,
174 139,4,43,72,137,67,252,248,131,252,235,8,57,203,15,133,244,2,248,3,137,206,
175 139,60,36,232,244,26,255,65,199,134,233,237,139,108,36,24,139,28,36,139,149,
176 233,129,252,248,239,15,135,244,254,248,4,139,139,233,68,139,187,233,137,139,
177 233,68,137,252,251,41,203,15,132,244,252,141,4,26,193,252,235,3,59,133,233,
178 15,135,244,255,137,213,72,41,205,248,5,72,139,1,72,137,4,41,131,193,8,68,
179 57,252,249,15,133,244,5,248,6,141,67,2,199,66,252,252,237,248,7,255,139,92,
180 36,28,137,68,36,4,72,199,193,252,248,252,255,252,255,252,255,252,247,195,
181 237,15,132,244,14,252,233,244,15,248,8,199,66,252,252,237,139,139,233,131,
182 252,233,8,137,139,233,72,139,1,72,137,2,184,237,252,233,244,7,248,9,139,12,
183 36,68,137,185,233,137,222,137,252,239,232,251,1,0,139,28,36,139,149,233,252,
184 233,244,4,248,85,139,106,252,248,139,173,233,139,90,252,252,137,92,36,28,
185 137,44,36,72,131,189,233,0,255,15,133,244,64,128,189,233,235,15,135,244,64,
186 139,141,233,15,132,244,247,59,141,233,15,132,244,64,248,1,141,92,193,252,
187 248,59,157,233,15,135,244,64,137,157,233,139,108,36,24,137,149,233,137,149,
188 233,141,108,194,252,240,72,41,221,57,203,15,132,244,249,248,2,255,72,139,
189 4,43,72,137,67,252,248,131,252,235,8,57,203,15,133,244,2,248,3,137,206,139,
190 60,36,232,244,26,65,199,134,233,237,139,108,36,24,139,28,36,139,149,233,129,
191 252,248,239,15,135,244,254,248,4,139,139,233,68,139,187,233,137,139,233,68,
192 137,252,251,41,203,15,132,244,252,141,4,26,193,252,235,3,59,133,233,15,135,
193 244,255,255,137,213,72,41,205,248,5,72,139,1,72,137,4,41,131,193,8,68,57,
194 252,249,15,133,244,5,248,6,141,67,1,248,7,139,92,36,28,137,68,36,4,49,201,
195 252,247,195,237,15,132,244,14,252,233,244,15,248,8,137,222,137,252,239,232,
196 251,1,15,248,9,139,12,36,68,137,185,233,137,222,137,252,239,232,251,1,0,139,
197 28,36,139,149,233,252,233,244,4,248,86,139,108,36,24,72,252,247,133,233,237,
198 15,132,244,64,255,137,149,233,141,68,194,252,248,137,133,233,49,192,72,137,
199 133,233,176,235,136,133,233,252,233,244,17,248,87,248,88,139,90,252,252,221,
200 90,252,248,252,233,244,67,248,89,129,252,248,239,15,130,244,64,129,122,253,
201 4,239,15,131,244,64,252,242,15,16,2,72,184,237,237,255,102,72,15,110,200,
202 15,84,193,248,72,139,90,252,252,252,242,15,17,66,252,248,248,67,184,237,248,
203 77,137,68,36,4,248,65,252,247,195,237,15,133,244,253,248,5,56,67,252,255,
204 15,135,244,252,15,182,75,252,253,72,252,247,209,141,20,202,139,3,15,182,204,
205 15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,6,199,68,194,252,
206 244,237,131,192,1,252,233,244,5,248,7,72,199,193,252,248,252,255,252,255,
207 252,255,252,233,244,15,248,90,129,122,253,4,239,255,15,131,244,64,252,242,
208 15,16,2,232,244,91,252,233,244,72,248,92,129,122,253,4,239,15,131,244,64,
209 252,242,15,16,2,232,244,93,252,233,244,72,248,94,129,252,248,239,15,130,244,
210 64,129,122,253,4,239,15,131,244,64,255,252,242,15,81,2,252,233,244,72,248,
211 95,129,252,248,239,15,133,244,64,129,122,253,4,239,15,131,244,64,217,252,
212 237,221,2,217,252,241,252,233,244,88,248,96,129,252,248,239,15,130,244,64,
213 129,122,253,4,239,15,131,244,64,217,252,236,221,2,217,252,241,252,233,244,
214 88,248,97,255,129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,
215 64,221,2,232,244,98,252,233,244,88,248,99,129,252,248,239,15,130,244,64,129,
216 122,253,4,239,15,131,244,64,221,2,217,252,254,252,233,244,88,248,100,255,
217 129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,221,2,217,252,
218 255,252,233,244,88,248,101,129,252,248,239,15,130,244,64,129,122,253,4,239,
219 15,131,244,64,221,2,217,252,242,221,216,252,233,244,88,248,102,129,252,248,
220 239,15,130,244,64,255,129,122,253,4,239,15,131,244,64,221,2,217,192,216,200,
221 217,232,222,225,217,252,250,217,252,243,252,233,244,88,248,103,129,252,248,
222 239,15,130,244,64,129,122,253,4,239,15,131,244,64,221,2,217,192,216,200,217,
223 232,222,225,217,252,250,217,201,217,252,243,252,233,244,88,248,104,129,252,
224 248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,255,221,2,217,232,217,
225 252,243,252,233,244,88,248,105,129,252,248,239,15,130,244,64,129,122,253,
226 4,239,15,131,244,64,252,242,15,16,2,137,213,232,251,1,16,137,252,234,252,
227 233,244,72,248,106,129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,
228 244,64,252,242,15,16,2,137,213,232,251,1,17,137,252,234,252,233,244,72,248,
229 107,255,129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,252,
230 242,15,16,2,137,213,232,251,1,18,137,252,234,252,233,244,72,248,108,248,109,
231 129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,252,242,15,
232 16,2,139,106,252,248,252,242,15,89,133,233,252,233,244,72,248,110,255,129,
233 252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,129,122,253,12,
234 239,15,131,244,64,221,2,221,66,8,217,252,243,252,233,244,88,248,111,129,252,
235 248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,129,122,253,12,239,
236 15,131,244,64,255,221,66,8,221,2,217,252,253,221,217,252,233,244,88,248,112,
237 129,252,248,239,15,130,244,64,139,106,4,129,252,253,239,15,131,244,64,139,
238 90,252,252,139,2,137,106,252,252,137,66,252,248,209,229,129,252,253,0,0,224,
239 252,255,15,131,244,249,9,232,15,132,244,249,184,252,254,3,0,0,129,252,253,
240 0,0,32,0,15,130,244,250,248,1,193,252,237,21,41,197,252,242,15,42,197,139,
241 106,252,252,129,229,252,255,252,255,15,128,129,205,0,0,224,63,137,106,252,
242 252,248,2,252,242,15,17,2,184,237,252,233,244,77,248,3,255,15,87,192,252,
243 233,244,2,248,4,252,242,15,16,2,72,189,237,237,102,72,15,110,205,252,242,
244 15,89,193,252,242,15,17,66,252,248,139,106,252,252,184,52,4,0,0,209,229,252,
245 233,244,1,248,113,129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,
246 244,64,252,242,15,16,2,139,106,4,139,90,252,252,209,229,129,252,253,0,0,224,
247 252,255,15,132,244,250,15,40,224,232,244,114,252,242,15,92,224,248,1,252,
248 242,15,17,66,252,248,252,242,15,17,34,139,66,252,252,139,106,4,49,232,15,
249 136,244,249,248,2,255,184,237,252,233,244,77,248,3,129,252,245,0,0,0,128,
250 137,106,4,252,233,244,2,248,4,15,87,228,252,233,244,1,248,115,129,252,248,
251 239,15,130,244,64,129,122,253,4,239,15,131,244,64,129,122,253,12,239,15,131,
252 244,64,221,66,8,221,2,248,1,255,217,252,248,223,224,158,15,138,244,1,221,
253 217,252,233,244,88,248,116,129,252,248,239,15,130,244,64,129,122,253,4,239,
254 15,131,244,64,129,122,253,12,239,15,131,244,64,252,242,15,16,2,252,242,15,
255 16,74,8,232,244,117,252,233,244,72,248,118,185,2,0,0,0,129,122,253,4,239,
256 255,15,131,244,64,252,242,15,16,2,248,5,57,193,15,131,244,72,129,124,253,
257 202,252,252,239,15,131,244,64,248,6,252,242,15,16,76,202,252,248,248,7,252,
258 242,15,93,193,131,193,1,252,233,244,5,248,119,185,2,0,0,0,129,122,253,4,239,
259 15,131,244,64,252,242,15,16,2,248,5,57,193,15,131,244,72,129,124,253,202,
260 252,252,239,255,15,131,244,64,248,6,252,242,15,16,76,202,252,248,248,7,252,
261 242,15,95,193,131,193,1,252,233,244,5,248,120,129,252,248,239,15,130,244,
262 64,129,122,253,4,239,15,133,244,64,139,42,252,242,15,42,133,233,252,233,244,
263 72,248,121,129,252,248,239,15,133,244,64,255,129,122,253,4,239,15,133,244,
264 64,139,42,139,90,252,252,131,189,233,1,15,130,244,80,15,182,173,233,252,242,
265 15,42,197,252,233,244,72,248,122,65,139,174,233,65,59,174,233,15,130,244,
266 247,232,244,74,248,1,129,252,248,239,15,133,244,64,255,129,122,253,4,239,
267 15,131,244,64,252,242,15,44,42,129,252,253,252,255,0,0,0,15,135,244,64,137,
268 108,36,4,199,68,36,8,1,0,0,0,72,141,68,36,4,248,123,139,108,36,24,137,149,
269 233,139,84,36,8,72,137,198,137,252,239,137,92,36,28,232,251,1,19,139,149,
270 233,139,90,252,252,199,66,252,252,237,137,66,252,248,252,233,244,67,248,124,
271 65,139,174,233,65,59,174,233,15,130,244,247,232,244,74,248,1,199,68,36,4,
272 252,255,252,255,252,255,252,255,129,252,248,239,255,15,130,244,64,15,134,
273 244,247,129,122,253,20,239,15,131,244,64,252,242,15,44,106,16,137,108,36,
274 4,248,1,129,122,253,4,239,15,133,244,64,129,122,253,12,239,15,131,244,64,
275 139,42,137,108,36,8,139,173,233,252,242,15,44,74,8,139,68,36,4,57,197,15,
276 130,244,251,248,2,133,201,15,142,244,253,248,3,255,139,108,36,8,41,200,15,
277 140,244,125,141,172,253,13,233,131,192,1,248,4,137,68,36,8,137,232,252,233,
278 244,123,248,5,15,140,244,252,141,68,40,1,252,233,244,2,248,6,137,232,252,
279 233,244,2,248,7,15,132,244,254,1,252,233,131,193,1,15,143,244,3,248,8,255,
280 185,1,0,0,0,252,233,244,3,248,125,49,192,252,233,244,4,248,126,65,139,174,
281 233,65,59,174,233,15,130,244,247,232,244,74,248,1,129,252,248,239,15,133,
282 244,64,129,122,253,4,239,15,133,244,64,129,122,253,12,239,255,139,42,15,131,
283 244,64,252,242,15,44,66,8,133,192,15,142,244,125,131,189,233,1,15,130,244,
284 125,15,133,244,127,65,57,134,233,15,130,244,127,15,182,141,233,65,139,174,
285 233,137,68,36,8,248,1,136,77,0,131,197,1,131,232,1,15,133,244,1,65,139,134,
286 233,252,233,244,123,248,128,255,129,252,248,239,15,130,244,64,65,139,174,
287 233,65,59,174,233,15,130,244,247,232,244,74,248,1,129,122,253,4,239,15,133,
288 244,64,139,42,139,133,233,133,192,15,132,244,125,65,57,134,233,15,130,244,
289 129,129,197,239,255,137,92,36,4,137,68,36,8,65,139,158,233,248,1,15,182,77,
290 0,131,197,1,131,232,1,136,12,3,15,133,244,1,137,216,139,92,36,4,252,233,244,
291 123,248,130,129,252,248,239,15,130,244,64,65,139,174,233,65,59,174,233,15,
292 130,244,247,232,244,74,248,1,129,122,253,4,239,15,133,244,64,255,139,42,139,
293 133,233,65,57,134,233,15,130,244,129,129,197,239,137,92,36,4,137,68,36,8,
294 65,139,158,233,252,233,244,249,248,1,15,182,76,5,0,131,252,249,65,15,130,
295 244,248,131,252,249,90,15,135,244,248,131,252,241,32,248,2,136,12,3,248,3,
296 131,232,1,15,137,244,1,137,216,139,92,36,4,252,233,244,123,248,131,255,129,
297 252,248,239,15,130,244,64,65,139,174,233,65,59,174,233,15,130,244,247,232,
298 244,74,248,1,129,122,253,4,239,15,133,244,64,139,42,139,133,233,65,57,134,
299 233,15,130,244,129,129,197,239,137,92,36,4,137,68,36,8,65,139,158,233,252,
300 233,244,249,248,1,255,15,182,76,5,0,131,252,249,97,15,130,244,248,131,252,
301 249,122,15,135,244,248,131,252,241,32,248,2,136,12,3,248,3,131,232,1,15,137,
302 244,1,137,216,139,92,36,4,252,233,244,123,248,132,129,252,248,239,15,130,
303 244,64,129,122,253,4,239,15,133,244,64,137,213,139,58,232,251,1,20,137,252,
304 234,252,242,15,42,192,252,233,244,72,248,133,255,129,252,248,239,15,130,244,
305 64,129,122,253,4,239,15,131,244,64,252,242,15,16,2,72,189,237,237,102,72,
306 15,110,205,252,242,15,88,193,102,15,126,197,248,2,252,233,244,134,248,135,
307 129,252,248,239,15,130,244,64,72,189,237,237,102,72,15,110,205,129,122,253,
308 4,239,15,131,244,64,255,252,242,15,16,2,252,242,15,88,193,102,15,126,197,
309 248,2,137,68,36,4,141,68,194,252,240,248,1,57,208,15,134,244,134,129,120,
310 253,4,239,15,131,244,136,252,242,15,16,0,252,242,15,88,193,102,15,126,193,
311 33,205,131,232,8,252,233,244,1,248,137,129,252,248,239,15,130,244,64,72,189,
312 237,237,102,72,15,110,205,129,122,253,4,239,15,131,244,64,252,242,15,16,2,
313 252,242,15,88,193,102,15,126,197,248,2,137,68,36,4,141,68,194,252,240,248,
314 1,255,57,208,15,134,244,134,129,120,253,4,239,15,131,244,136,252,242,15,16,
315 0,252,242,15,88,193,102,15,126,193,9,205,131,232,8,252,233,244,1,248,138,
316 129,252,248,239,15,130,244,64,72,189,237,237,102,72,15,110,205,129,122,253,
317 4,239,15,131,244,64,252,242,15,16,2,252,242,15,88,193,102,15,126,197,248,
318 2,137,68,36,4,141,68,194,252,240,248,1,57,208,15,134,244,134,255,129,120,
319 253,4,239,15,131,244,136,252,242,15,16,0,252,242,15,88,193,102,15,126,193,
320 49,205,131,232,8,252,233,244,1,248,139,129,252,248,239,15,130,244,64,129,
321 122,253,4,239,15,131,244,64,252,242,15,16,2,72,189,237,237,102,72,15,110,
322 205,252,242,15,88,193,102,15,126,197,248,2,15,205,252,233,244,134,248,140,
323 129,252,248,239,15,130,244,64,255,129,122,253,4,239,15,131,244,64,252,242,
324 15,16,2,72,189,237,237,102,72,15,110,205,252,242,15,88,193,102,15,126,197,
325 248,2,252,247,213,248,134,252,242,15,42,197,252,233,244,72,248,136,139,68,
326 36,4,252,233,244,64,248,141,129,252,248,239,15,130,244,64,129,122,253,4,239,
327 15,131,244,64,129,122,253,12,239,255,15,131,244,64,252,242,15,16,2,252,242,
328 15,16,74,8,72,189,237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,
329 88,202,102,15,126,197,102,15,126,201,211,229,252,233,244,134,248,142,129,
330 252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,129,122,253,12,
331 239,15,131,244,64,252,242,15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,
332 15,110,213,252,242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,
333 201,211,252,237,252,233,244,134,248,143,255,129,252,248,239,15,130,244,64,
334 129,122,253,4,239,15,131,244,64,129,122,253,12,239,15,131,244,64,252,242,
335 15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,15,110,213,252,242,15,88,
336 194,252,242,15,88,202,102,15,126,197,102,15,126,201,211,252,253,252,233,244,
337 134,248,144,129,252,248,239,15,130,244,64,129,122,253,4,239,15,131,244,64,
338 255,129,122,253,12,239,15,131,244,64,252,242,15,16,2,252,242,15,16,74,8,72,
339 189,237,237,102,72,15,110,213,252,242,15,88,194,252,242,15,88,202,102,15,
340 126,197,102,15,126,201,211,197,252,233,244,134,248,145,129,252,248,239,15,
341 130,244,64,129,122,253,4,239,15,131,244,64,129,122,253,12,239,15,131,244,
342 64,252,242,15,16,2,252,242,15,16,74,8,72,189,237,237,102,72,15,110,213,252,
343 242,15,88,194,252,242,15,88,202,102,15,126,197,102,15,126,201,211,205,252,
344 233,244,134,248,127,255,184,237,252,233,244,64,248,129,184,237,248,64,139,
345 108,36,24,139,90,252,252,137,92,36,28,137,149,233,141,68,194,252,248,141,
346 136,233,137,133,233,139,66,252,248,59,141,233,15,135,244,251,137,252,239,
347 252,255,144,233,139,149,233,133,192,15,143,244,77,248,1,139,141,233,41,209,
348 193,252,233,3,133,192,141,65,1,139,106,252,248,15,133,244,34,255,139,157,
349 233,139,11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,
350 34,137,209,252,247,195,237,15,133,244,249,15,182,107,252,253,72,252,247,213,
351 141,20,252,234,252,233,244,29,248,3,137,221,131,229,252,248,41,252,234,252,
352 233,244,29,248,5,190,237,137,252,239,232,251,1,0,139,149,233,49,192,252,233,
353 244,1,248,74,93,72,137,108,36,8,139,108,36,24,137,92,36,28,137,149,233,141,
354 68,194,252,248,137,252,239,137,133,233,232,251,1,21,139,149,233,139,133,233,
355 255,41,208,193,232,3,131,192,1,72,139,108,36,8,85,195,248,146,65,15,182,134,
356 233,168,235,15,133,244,251,168,235,15,133,244,247,168,235,15,132,244,247,
357 65,252,255,142,233,252,233,244,247,248,147,65,15,182,134,233,168,235,15,133,
358 244,251,252,233,244,247,248,148,255,65,15,182,134,233,168,235,15,133,244,
359 251,168,235,15,132,244,251,65,252,255,142,233,15,132,244,247,168,235,15,132,
360 244,251,248,1,139,108,36,24,137,149,233,137,222,137,252,239,232,251,1,22,
361 248,3,139,149,233,248,4,15,182,75,252,253,248,5,15,182,107,252,252,15,183,
362 67,252,254,65,252,255,164,253,252,238,233,248,149,255,131,195,4,139,77,232,
363 137,76,36,4,252,233,244,4,248,150,139,106,252,248,139,173,233,15,182,133,
364 233,141,4,194,139,108,36,24,137,149,233,137,133,233,137,222,65,141,190,233,
365 73,137,174,233,137,92,36,28,232,251,1,23,252,233,244,3,248,151,137,92,36,
366 28,252,233,244,247,248,152,137,92,36,28,131,203,1,248,1,141,68,194,252,248,
367 139,108,36,24,137,149,233,137,133,233,137,222,137,252,239,232,251,1,24,199,
368 68,36,28,0,0,0,0,131,227,252,254,139,149,233,72,137,193,139,133,233,255,41,
369 208,72,137,205,15,182,75,252,253,193,232,3,131,192,1,252,255,229,248,153,
370 65,85,65,84,65,83,65,82,65,81,65,80,87,86,85,72,141,108,36,88,85,83,82,81,
371 80,15,182,69,252,248,138,101,252,240,76,137,125,252,248,76,137,117,252,240,
372 68,139,117,0,65,139,142,233,65,199,134,233,237,65,137,134,233,65,137,142,
373 233,72,129,252,236,239,72,131,197,128,252,242,68,15,17,125,252,248,252,242,
374 68,15,17,117,252,240,252,242,68,15,17,109,232,252,242,68,15,17,101,224,252,
375 242,68,15,17,93,216,252,242,68,15,17,85,208,252,242,68,15,17,77,200,252,242,
376 68,15,17,69,192,252,242,15,17,125,184,252,242,15,17,117,176,252,242,15,17,
377 109,168,252,242,15,17,101,160,252,242,15,17,93,152,252,242,15,17,85,144,252,
378 242,15,17,77,136,252,242,15,17,69,128,65,139,174,233,65,139,150,233,73,137,
379 174,233,65,199,134,233,0,0,0,0,137,149,233,72,137,230,65,141,190,233,232,
380 251,1,25,72,139,141,233,72,129,225,239,72,137,204,137,169,233,139,149,233,
381 139,153,233,252,233,244,247,248,154,255,72,131,196,16,248,1,76,139,108,36,
382 8,76,139,36,36,133,192,15,136,244,249,137,68,36,4,68,139,122,252,248,69,139,
383 191,233,69,139,191,233,65,199,134,233,0,0,0,0,65,199,134,233,237,139,3,15,
384 182,204,15,182,232,131,195,4,193,232,16,129,252,253,239,15,130,244,248,139,
385 68,36,4,248,2,65,252,255,36,252,238,248,3,252,247,216,137,252,239,137,198,
386 232,251,1,1,248,91,248,155,72,184,237,237,102,72,15,110,208,72,184,237,237,
387 102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,247,255,
388 102,15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,237,
389 237,102,72,15,110,208,252,242,15,194,193,1,102,15,84,194,252,242,15,92,200,
390 15,40,193,248,1,195,248,93,248,156,72,184,237,237,102,72,15,110,208,72,184,
391 237,237,102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,15,134,244,
392 247,102,15,85,208,252,242,15,88,203,252,242,15,92,203,102,15,86,202,72,184,
393 237,237,102,72,15,110,208,252,242,15,194,193,6,102,15,84,194,252,242,15,92,
394 200,15,40,193,248,1,195,248,114,248,157,72,184,237,237,102,72,15,110,208,
395 72,184,237,237,255,102,72,15,110,216,15,40,200,102,15,84,202,102,15,46,217,
396 15,134,244,247,102,15,85,208,15,40,193,252,242,15,88,203,252,242,15,92,203,
397 72,184,237,237,102,72,15,110,216,252,242,15,194,193,1,102,15,84,195,252,242,
398 15,92,200,102,15,86,202,15,40,193,248,1,195,248,158,15,40,232,252,242,15,
399 94,193,72,184,237,237,102,72,15,110,208,72,184,237,237,102,72,15,110,216,
400 15,40,224,102,15,84,226,102,15,46,220,15,134,244,247,102,15,85,208,252,242,
401 15,88,227,252,242,15,92,227,102,15,86,226,72,184,237,237,102,72,15,110,208,
402 252,242,15,194,196,1,102,15,84,194,252,242,15,92,224,15,40,197,252,242,15,
403 89,204,252,242,15,92,193,195,248,1,252,242,15,89,200,15,40,197,252,242,15,
404 92,193,195,248,159,252,242,15,17,68,36,252,248,217,232,221,68,36,252,248,
405 217,252,241,221,92,36,252,248,252,242,15,16,68,36,252,248,195,248,98,217,
406 252,234,222,201,248,160,217,84,36,252,248,129,124,36,252,248,0,0,128,127,
407 15,132,244,247,255,129,124,36,252,248,0,0,128,252,255,15,132,244,248,248,
408 161,217,192,217,252,252,220,252,233,217,201,217,252,240,217,232,222,193,217,
409 252,253,221,217,248,1,195,248,2,221,216,217,252,238,195,248,117,248,162,252,
410 242,15,45,193,252,242,15,42,208,102,15,46,202,15,133,244,254,15,138,244,255,
411 248,163,131,252,248,1,15,142,244,252,248,1,169,1,0,0,0,15,133,244,248,252,
412 242,15,89,192,209,232,252,233,244,1,248,2,255,209,232,15,132,244,251,15,40,
413 200,248,3,252,242,15,89,192,209,232,15,132,244,250,15,131,244,3,252,242,15,
414 89,200,252,233,244,3,248,4,252,242,15,89,193,248,5,195,248,6,15,132,244,5,
415 15,130,244,253,252,247,216,232,244,1,72,184,237,237,255,102,72,15,110,200,
416 252,242,15,94,200,15,40,193,195,248,7,72,184,237,237,102,72,15,110,192,195,
417 248,8,102,72,15,126,200,72,209,224,72,193,192,12,72,61,252,254,15,0,0,15,
418 132,244,248,102,72,15,126,192,72,209,224,15,132,244,250,72,193,192,12,72,
419 61,252,254,15,0,0,15,132,244,251,252,242,15,17,76,36,252,240,252,242,15,17,
420 68,36,252,248,221,68,36,252,240,221,68,36,252,248,217,252,241,217,192,217,
421 252,252,220,252,233,217,201,217,252,240,217,232,222,193,217,252,253,221,217,
422 221,92,36,252,248,252,242,15,16,68,36,252,248,195,248,9,72,184,237,237,102,
423 72,15,110,208,102,15,46,194,15,132,244,247,15,40,193,248,1,195,248,2,72,184,
424 237,237,102,72,15,110,208,102,15,84,194,72,184,237,237,255,102,72,15,110,
425 208,102,15,46,194,15,132,244,1,102,15,80,193,15,87,192,136,196,15,146,208,
426 48,224,15,133,244,1,248,3,72,184,237,237,102,72,15,110,192,195,248,4,102,
427 15,80,193,133,192,15,133,244,3,15,87,192,195,248,5,102,15,80,193,133,192,
428 15,132,244,3,15,87,192,195,248,164,131,252,255,1,15,130,244,91,15,132,244,
429 93,131,252,255,3,15,130,244,114,255,15,135,244,248,252,242,15,81,192,195,
430 248,2,252,242,15,17,68,36,252,248,221,68,36,252,248,131,252,255,5,15,135,
431 244,248,15,132,244,247,232,244,98,252,233,244,253,248,1,232,244,160,252,233,
432 244,253,248,2,131,252,255,7,15,132,244,247,15,135,244,248,255,217,252,237,
433 217,201,217,252,241,252,233,244,253,248,1,217,232,217,201,217,252,241,252,
434 233,244,253,248,2,131,252,255,9,15,132,244,247,15,135,244,248,217,252,236,
435 217,201,217,252,241,252,233,244,253,248,1,217,252,254,252,233,244,253,248,
436 2,131,252,255,11,15,132,244,247,15,135,244,255,255,217,252,255,252,233,244,
437 253,248,1,217,252,242,221,216,248,7,221,92,36,252,248,252,242,15,16,68,36,
438 252,248,195,248,9,204,248,165,131,252,255,1,15,132,244,247,15,135,244,248,
439 252,242,15,88,193,195,248,1,252,242,15,92,193,195,248,2,131,252,255,3,15,
440 132,244,247,15,135,244,248,252,242,15,89,193,195,248,1,252,242,15,94,193,
441 195,248,2,131,252,255,5,15,130,244,158,255,15,132,244,117,131,252,255,7,15,
442 132,244,247,15,135,244,248,72,184,237,237,102,72,15,110,200,15,87,193,195,
443 248,1,72,184,237,237,102,72,15,110,200,15,84,193,195,248,2,131,252,255,9,
444 15,135,244,248,252,242,15,17,68,36,252,248,252,242,15,17,76,36,252,240,221,
445 68,36,252,248,221,68,36,252,240,15,132,244,247,217,252,243,248,7,221,92,36,
446 252,248,252,242,15,16,68,36,252,248,195,248,1,217,201,217,252,253,221,217,
447 252,233,244,7,248,2,255,131,252,255,11,15,132,244,247,15,135,244,255,252,
448 242,15,93,193,195,248,1,252,242,15,95,193,195,248,9,204,248,166,137,252,248,
449 83,15,162,137,6,137,94,4,137,78,8,137,86,12,91,195,248,167,255,204,255,204,
450 248,168,83,65,87,65,86,72,131,252,236,40,68,141,181,233,139,157,233,15,183,
451 192,137,131,233,72,137,187,233,72,137,179,233,72,137,147,233,72,137,139,233,
452 252,242,15,17,131,233,252,242,15,17,139,233,252,242,15,17,147,233,252,242,
453 15,17,155,233,72,141,132,253,36,233,76,137,131,233,76,137,139,233,252,242,
454 15,17,163,233,252,242,15,17,171,233,252,242,15,17,179,233,252,242,15,17,187,
455 233,72,137,131,233,255,72,137,230,137,92,36,28,137,223,232,251,1,26,65,199,
456 134,233,237,139,144,233,139,128,233,41,208,139,106,252,248,193,232,3,131,
457 192,1,139,157,233,139,11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,
458 252,238,248,33,139,76,36,24,65,139,158,233,72,137,139,233,137,145,233,137,
459 169,233,137,223,137,198,232,251,1,27,72,139,131,233,252,242,15,16,131,233,
460 252,233,244,17,248,169,85,72,137,229,83,72,137,252,251,139,131,233,72,41,
461 196,15,182,139,233,131,252,233,1,15,136,244,248,248,1,255,72,139,132,253,
462 203,233,72,137,132,253,204,233,131,252,233,1,15,137,244,1,248,2,15,182,131,
463 233,72,139,187,233,72,139,179,233,72,139,147,233,72,139,139,233,76,139,131,
464 233,76,139,139,233,133,192,15,132,244,251,15,40,131,233,15,40,139,233,15,
465 40,147,233,15,40,155,233,131,252,248,4,15,134,244,251,255,15,40,163,233,15,
466 40,171,233,15,40,179,233,15,40,187,233,248,5,252,255,147,233,72,137,131,233,
467 15,41,131,233,72,137,147,233,15,41,139,233,72,139,93,252,248,201,195,255,
468 129,124,253,202,4,239,15,131,244,45,129,124,253,194,4,239,15,131,244,45,248,
469 1,252,242,15,16,4,194,248,2,131,195,4,102,15,46,4,202,248,3,255,15,135,244,
470 247,255,15,130,244,247,255,15,131,244,247,255,15,183,67,252,254,141,156,253,
471 131,233,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,
472 36,252,238,255,139,108,194,4,131,195,4,255,129,252,253,239,15,131,244,251,
473 129,124,253,202,4,239,15,131,244,251,248,1,252,242,15,16,4,202,248,2,102,
474 15,46,4,194,248,4,255,15,138,244,248,15,133,244,248,255,15,138,244,248,15,
475 132,244,247,255,248,1,15,183,67,252,254,141,156,253,131,233,248,2,255,248,
476 2,15,183,67,252,254,141,156,253,131,233,248,1,255,252,233,244,9,255,248,5,
477 129,252,253,239,15,132,244,50,129,124,253,202,4,239,15,132,244,50,57,108,
478 202,4,15,133,244,2,129,252,253,239,15,131,244,1,139,12,202,139,4,194,57,193,
479 15,132,244,1,129,252,253,239,15,135,244,2,129,252,253,239,15,130,244,2,255,
480 139,169,233,133,252,237,15,132,244,2,252,246,133,233,235,15,133,244,2,255,
481 49,252,237,255,189,1,0,0,0,255,252,233,244,49,255,248,3,129,252,253,239,255,
482 15,133,244,9,255,252,233,244,50,255,72,252,247,208,139,108,202,4,131,195,
483 4,129,252,253,239,15,133,244,249,139,12,202,65,59,12,135,255,139,108,202,
484 4,131,195,4,255,129,252,253,239,15,131,244,249,248,1,252,242,65,15,16,4,199,
485 248,2,102,15,46,4,202,248,4,255,72,252,247,208,139,108,202,4,131,195,4,57,
486 197,255,15,133,244,249,15,183,67,252,254,141,156,253,131,233,248,2,139,3,
487 15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,129,
488 252,253,239,15,133,244,2,252,233,244,50,255,15,132,244,248,129,252,253,239,
489 15,132,244,50,15,183,67,252,254,141,156,253,131,233,248,2,139,3,15,182,204,
490 15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,139,108,194,4,131,
491 195,4,129,252,253,239,255,137,108,202,4,139,44,194,137,44,202,255,72,139,
492 44,194,72,137,44,202,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,
493 252,255,36,252,238,255,49,252,237,129,124,253,194,4,239,129,213,239,137,108,
494 202,4,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
495 238,255,129,124,253,194,4,239,15,131,244,55,252,242,15,16,4,194,72,184,237,
496 237,102,72,15,110,200,15,87,193,252,242,15,17,4,202,139,3,15,182,204,15,182,
497 232,131,195,4,193,232,16,65,252,255,36,252,238,255,129,124,253,194,4,239,
498 15,133,244,248,139,4,194,15,87,192,252,242,15,42,128,233,248,1,252,242,15,
499 17,4,202,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
500 238,248,2,129,124,253,194,4,239,15,133,244,58,139,60,194,255,139,175,233,
501 131,252,253,0,15,133,244,255,248,3,255,248,59,137,213,232,251,1,20,252,242,
502 15,42,192,137,252,234,15,182,75,252,253,252,233,244,1,255,248,9,252,246,133,
503 233,235,15,133,244,3,252,233,244,58,255,15,182,252,236,15,182,192,255,129,
504 124,253,252,234,4,239,15,131,244,52,252,242,15,16,4,252,234,252,242,65,15,
505 88,4,199,255,129,124,253,252,234,4,239,15,131,244,54,252,242,65,15,16,4,199,
506 252,242,15,88,4,252,234,255,129,124,253,252,234,4,239,15,131,244,57,129,124,
507 253,194,4,239,15,131,244,57,252,242,15,16,4,252,234,252,242,15,88,4,194,255,
508 129,124,253,252,234,4,239,15,131,244,52,252,242,15,16,4,252,234,252,242,65,
509 15,92,4,199,255,129,124,253,252,234,4,239,15,131,244,54,252,242,65,15,16,
510 4,199,252,242,15,92,4,252,234,255,129,124,253,252,234,4,239,15,131,244,57,
511 129,124,253,194,4,239,15,131,244,57,252,242,15,16,4,252,234,252,242,15,92,
512 4,194,255,129,124,253,252,234,4,239,15,131,244,52,252,242,15,16,4,252,234,
513 252,242,65,15,89,4,199,255,129,124,253,252,234,4,239,15,131,244,54,252,242,
514 65,15,16,4,199,252,242,15,89,4,252,234,255,129,124,253,252,234,4,239,15,131,
515 244,57,129,124,253,194,4,239,15,131,244,57,252,242,15,16,4,252,234,252,242,
516 15,89,4,194,255,129,124,253,252,234,4,239,15,131,244,52,252,242,15,16,4,252,
517 234,252,242,65,15,94,4,199,255,129,124,253,252,234,4,239,15,131,244,54,252,
518 242,65,15,16,4,199,252,242,15,94,4,252,234,255,129,124,253,252,234,4,239,
519 15,131,244,57,129,124,253,194,4,239,15,131,244,57,252,242,15,16,4,252,234,
520 252,242,15,94,4,194,255,129,124,253,252,234,4,239,15,131,244,52,252,242,15,
521 16,4,252,234,252,242,65,15,16,12,199,255,129,124,253,252,234,4,239,15,131,
522 244,54,252,242,65,15,16,4,199,252,242,15,16,12,252,234,255,129,124,253,252,
523 234,4,239,15,131,244,57,129,124,253,194,4,239,15,131,244,57,252,242,15,16,
524 4,252,234,252,242,15,16,12,194,255,248,170,232,244,158,252,242,15,17,4,202,
525 139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,
526 252,233,244,170,255,232,244,117,252,242,15,17,4,202,139,3,15,182,204,15,182,
527 232,131,195,4,193,232,16,65,252,255,36,252,238,255,15,182,252,236,15,182,
528 192,139,124,36,24,137,151,233,141,52,194,137,194,41,252,234,248,37,137,252,
529 253,137,92,36,28,232,251,1,28,139,149,233,133,192,15,133,244,46,15,182,107,
530 252,255,15,182,75,252,253,72,139,4,252,234,72,137,4,202,139,3,15,182,204,
531 15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,72,252,247,208,
532 65,139,4,135,199,68,202,4,237,137,4,202,139,3,15,182,204,15,182,232,131,195,
533 4,193,232,16,65,252,255,36,252,238,255,15,191,192,252,242,15,42,192,252,242,
534 15,17,4,202,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,
535 252,238,255,252,242,65,15,16,4,199,252,242,15,17,4,202,139,3,15,182,204,15,
536 182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,72,252,247,208,137,
537 68,202,4,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,
538 238,255,141,76,202,12,141,68,194,4,189,237,137,105,252,248,248,1,137,41,131,
539 193,8,57,193,15,134,244,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,
540 65,252,255,36,252,238,255,139,106,252,248,139,172,253,133,233,139,173,233,
541 72,139,69,0,72,137,4,202,139,3,15,182,204,15,182,232,131,195,4,193,232,16,
542 65,252,255,36,252,238,255,139,106,252,248,139,172,253,141,233,128,189,233,
543 0,139,173,233,139,12,194,139,68,194,4,137,77,0,137,69,4,15,132,244,247,252,
544 246,133,233,235,15,133,244,248,248,1,139,3,15,182,204,15,182,232,131,195,
545 4,193,232,16,65,252,255,36,252,238,248,2,129,232,239,129,252,248,239,15,134,
546 244,1,252,246,129,233,235,15,132,244,1,137,252,238,137,213,65,141,190,233,
547 255,232,251,1,29,137,252,234,252,233,244,1,255,72,252,247,208,139,106,252,
548 248,139,172,253,141,233,65,139,12,135,139,133,233,137,8,199,64,4,237,252,
549 246,133,233,235,15,133,244,248,248,1,139,3,15,182,204,15,182,232,131,195,
550 4,193,232,16,65,252,255,36,252,238,248,2,252,246,129,233,235,15,132,244,1,
551 128,189,233,0,15,132,244,1,137,213,137,198,65,141,190,233,232,251,1,29,137,
552 252,234,252,233,244,1,255,139,106,252,248,252,242,65,15,16,4,199,139,172,
553 253,141,233,139,141,233,252,242,15,17,1,139,3,15,182,204,15,182,232,131,195,
554 4,193,232,16,65,252,255,36,252,238,255,72,252,247,208,139,106,252,248,139,
555 172,253,141,233,139,141,233,137,65,4,139,3,15,182,204,15,182,232,131,195,
556 4,193,232,16,65,252,255,36,252,238,255,141,156,253,131,233,139,108,36,24,
557 131,189,233,0,15,132,244,247,137,149,233,141,52,202,137,252,239,232,251,1,
558 30,139,149,233,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,
559 252,255,36,252,238,255,72,252,247,208,139,108,36,24,137,149,233,139,82,252,
560 248,65,139,52,135,137,252,239,137,92,36,28,232,251,1,31,139,149,233,15,182,
561 75,252,253,137,4,202,199,68,202,4,237,139,3,15,182,204,15,182,232,131,195,
562 4,193,232,16,65,252,255,36,252,238,255,139,108,36,24,137,149,233,65,139,142,
563 233,65,59,142,233,137,92,36,28,15,131,244,251,248,1,137,194,37,252,255,7,
564 0,0,193,252,234,11,61,252,255,7,0,0,15,132,244,249,248,2,137,252,239,137,
565 198,232,251,1,32,139,149,233,15,182,75,252,253,137,4,202,199,68,202,4,237,
566 139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,
567 3,184,1,8,0,0,252,233,244,2,248,5,137,252,239,232,251,1,33,15,183,67,252,
568 254,252,233,244,1,255,72,252,247,208,139,108,36,24,65,139,142,233,137,92,
569 36,28,65,59,142,233,137,149,233,15,131,244,249,248,2,65,139,52,135,137,252,
570 239,232,251,1,34,139,149,233,15,182,75,252,253,137,4,202,199,68,202,4,237,
571 139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,
572 3,137,252,239,232,251,1,33,15,183,67,252,254,72,252,247,208,252,233,244,2,
573 255,72,252,247,208,139,106,252,248,139,173,233,65,139,4,135,252,233,244,171,
574 255,72,252,247,208,139,106,252,248,139,173,233,65,139,4,135,252,233,244,172,
575 255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,40,139,
576 44,252,234,129,124,253,194,4,239,15,131,244,251,252,242,15,16,4,194,252,242,
577 15,45,192,252,242,15,42,200,102,15,46,193,15,133,244,40,59,133,233,15,131,
578 244,40,193,224,3,3,133,233,129,120,253,4,239,15,132,244,248,72,139,40,72,
579 137,44,202,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
580 255,36,252,238,248,2,131,189,233,0,15,132,244,249,255,139,141,233,252,246,
581 129,233,235,15,132,244,40,15,182,75,252,253,248,3,199,68,202,4,237,252,233,
582 244,1,248,5,129,124,253,194,4,239,15,133,244,40,139,4,194,252,233,244,171,
583 255,15,182,252,236,15,182,192,72,252,247,208,65,139,4,135,129,124,253,252,
584 234,4,239,15,133,244,38,139,44,252,234,248,171,139,141,233,35,136,233,105,
585 201,239,3,141,233,248,1,129,185,233,239,15,133,244,250,57,129,233,15,133,
586 244,250,129,121,253,4,239,15,132,244,251,15,182,67,252,253,72,139,41,72,137,
587 44,194,248,2,255,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
588 255,36,252,238,248,3,15,182,67,252,253,199,68,194,4,237,252,233,244,2,248,
589 4,139,137,233,133,201,15,133,244,1,248,5,139,141,233,133,201,15,132,244,3,
590 252,246,129,233,235,15,133,244,3,252,233,244,38,255,15,182,252,236,15,182,
591 192,129,124,253,252,234,4,239,15,133,244,39,139,44,252,234,59,133,233,15,
592 131,244,39,193,224,3,3,133,233,129,120,253,4,239,15,132,244,248,72,139,40,
593 72,137,44,202,248,1,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
594 255,36,252,238,248,2,131,189,233,0,15,132,244,249,139,141,233,252,246,129,
595 233,235,15,132,244,39,255,15,182,75,252,253,248,3,199,68,202,4,237,252,233,
596 244,1,255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,244,
597 43,139,44,252,234,129,124,253,194,4,239,15,131,244,251,252,242,15,16,4,194,
598 252,242,15,45,192,252,242,15,42,200,102,15,46,193,15,133,244,43,59,133,233,
599 15,131,244,43,193,224,3,3,133,233,129,120,253,4,239,15,132,244,249,248,1,
600 252,246,133,233,235,15,133,244,253,248,2,255,72,139,44,202,72,137,40,139,
601 3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,
602 131,189,233,0,15,132,244,1,139,141,233,252,246,129,233,235,15,132,244,43,
603 15,182,75,252,253,252,233,244,1,248,5,129,124,253,194,4,239,15,133,244,43,
604 139,4,194,252,233,244,172,248,7,128,165,233,235,255,65,139,142,233,65,137,
605 174,233,137,141,233,15,182,75,252,253,252,233,244,2,255,15,182,252,236,15,
606 182,192,72,252,247,208,65,139,4,135,129,124,253,252,234,4,239,15,133,244,
607 41,139,44,252,234,248,172,139,141,233,35,136,233,105,201,239,198,133,233,
608 0,3,141,233,248,1,129,185,233,239,15,133,244,251,57,129,233,15,133,244,251,
609 129,121,253,4,239,15,132,244,250,248,2,255,252,246,133,233,235,15,133,244,
610 253,248,3,15,182,67,252,253,72,139,44,194,72,137,41,139,3,15,182,204,15,182,
611 232,131,195,4,193,232,16,65,252,255,36,252,238,248,4,131,189,233,0,15,132,
612 244,2,137,12,36,139,141,233,252,246,129,233,235,15,132,244,41,139,12,36,252,
613 233,244,2,248,5,139,137,233,133,201,15,133,244,1,255,139,141,233,133,201,
614 15,132,244,252,252,246,129,233,235,15,132,244,41,248,6,137,4,36,199,68,36,
615 4,237,137,108,36,8,139,124,36,24,137,151,233,72,141,20,36,137,252,238,137,
616 252,253,137,92,36,28,232,251,1,35,139,149,233,139,108,36,8,137,193,252,233,
617 244,2,248,7,128,165,233,235,65,139,134,233,65,137,174,233,137,133,233,252,
618 233,244,3,255,15,182,252,236,15,182,192,129,124,253,252,234,4,239,15,133,
619 244,42,139,44,252,234,59,133,233,15,131,244,42,193,224,3,3,133,233,129,120,
620 253,4,239,15,132,244,249,248,1,252,246,133,233,235,15,133,244,253,248,2,72,
621 139,12,202,72,137,8,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,
622 255,36,252,238,248,3,131,189,233,0,15,132,244,1,255,139,141,233,252,246,129,
623 233,235,15,132,244,42,15,182,75,252,253,252,233,244,1,248,7,128,165,233,235,
624 65,139,142,233,65,137,174,233,137,141,233,15,182,75,252,253,252,233,244,2,
625 255,68,137,60,36,69,139,60,199,248,1,141,12,202,139,105,252,248,252,246,133,
626 233,235,15,133,244,253,248,2,139,68,36,4,131,232,1,15,132,244,250,68,1,252,
627 248,59,133,233,15,135,244,251,68,41,252,248,65,193,231,3,68,3,189,233,248,
628 3,72,139,41,131,193,8,73,137,47,65,131,199,8,131,232,1,15,133,244,3,248,4,
629 68,139,60,36,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,
630 36,252,238,248,5,139,124,36,24,137,151,233,137,252,238,137,194,137,252,253,
631 137,92,36,28,232,251,1,36,139,149,233,15,182,75,252,253,252,233,244,1,248,
632 7,255,128,165,233,235,65,139,134,233,65,137,174,233,137,133,233,252,233,244,
633 2,255,3,68,36,4,255,129,124,253,202,4,239,139,44,202,15,133,244,60,141,84,
634 202,8,137,90,252,252,139,157,233,139,11,15,182,252,233,15,182,205,131,195,
635 4,65,252,255,36,252,238,255,141,76,202,8,65,137,215,139,105,252,248,129,121,
636 253,252,252,239,15,133,244,30,248,61,139,90,252,252,252,247,195,237,15,133,
637 244,253,248,1,137,106,252,248,137,68,36,4,131,232,1,15,132,244,249,248,2,
638 72,139,41,131,193,8,73,137,47,65,131,199,8,131,232,1,15,133,244,2,139,106,
639 252,248,248,3,139,68,36,4,128,189,233,1,15,135,244,251,248,4,139,157,233,
640 139,11,15,182,252,233,15,182,205,131,195,4,65,252,255,36,252,238,248,5,255,
641 252,247,195,237,15,133,244,4,15,182,75,252,253,72,252,247,209,141,12,202,
642 68,139,121,252,248,69,139,191,233,69,139,191,233,252,233,244,4,248,7,129,
643 252,235,239,252,247,195,237,15,133,244,254,41,218,65,137,215,139,90,252,252,
644 252,233,244,1,248,8,129,195,239,252,233,244,1,255,141,76,202,8,72,139,105,
645 232,72,139,65,252,240,72,137,41,72,137,65,8,139,105,224,139,65,228,137,105,
646 252,248,137,65,252,252,129,252,248,239,184,237,15,133,244,30,137,202,137,
647 90,252,252,139,157,233,139,11,15,182,252,233,15,182,205,131,195,4,65,252,
648 255,36,252,238,255,68,137,60,36,68,137,116,36,4,139,108,202,252,240,139,68,
649 202,252,248,68,139,181,233,131,195,4,68,139,189,233,248,1,68,57,252,240,15,
650 131,244,251,65,129,124,253,199,4,239,15,132,244,250,252,242,15,42,192,73,
651 139,44,199,72,137,108,202,8,131,192,1,252,242,15,17,4,202,137,68,202,252,
652 248,248,2,15,183,67,252,254,141,156,253,131,233,248,3,68,139,116,36,4,68,
653 139,60,36,139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,
654 252,238,248,4,131,192,1,252,233,244,1,248,5,68,41,252,240,248,6,59,133,233,
655 15,135,244,3,68,105,252,248,239,255,68,3,189,233,65,129,191,233,239,15,132,
656 244,253,70,141,116,48,1,73,139,175,233,73,139,135,233,72,137,44,202,72,137,
657 68,202,8,68,137,116,202,252,248,252,233,244,2,248,7,131,192,1,252,233,244,
658 6,255,129,124,253,202,252,236,239,15,133,244,251,139,108,202,232,129,124,
659 253,202,252,244,239,15,133,244,251,129,124,253,202,252,252,239,15,133,244,
660 251,128,189,233,235,15,133,244,251,141,156,253,131,233,199,68,202,252,248,
661 0,0,0,0,199,68,202,252,252,252,255,127,252,254,252,255,248,1,139,3,15,182,
662 204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,5,198,67,252,
663 252,235,141,156,253,131,233,198,3,235,252,233,244,1,255,15,182,252,236,15,
664 182,192,68,137,60,36,68,141,188,253,194,233,141,12,202,68,43,122,252,252,
665 133,252,237,15,132,244,251,141,108,252,233,252,248,65,57,215,15,131,244,248,
666 248,1,73,139,71,252,248,65,131,199,8,72,137,1,131,193,8,57,252,233,15,131,
667 244,249,65,57,215,15,130,244,1,248,2,199,65,4,237,131,193,8,57,252,233,15,
668 130,244,2,248,3,68,139,60,36,139,3,15,182,204,15,182,232,131,195,4,193,232,
669 16,65,252,255,36,252,238,248,5,199,68,36,4,1,0,0,0,137,208,68,41,252,248,
670 15,134,244,3,137,197,193,252,237,3,131,197,1,137,108,36,4,139,108,36,24,1,
671 200,59,133,233,15,135,244,253,248,6,255,73,139,71,252,248,65,131,199,8,72,
672 137,1,131,193,8,65,57,215,15,130,244,6,252,233,244,3,248,7,137,149,233,137,
673 141,233,137,92,36,28,65,41,215,139,116,36,4,131,252,238,1,137,252,239,232,
674 251,1,0,139,149,233,139,141,233,65,1,215,252,233,244,6,255,193,225,3,255,
675 248,1,139,90,252,252,137,68,36,4,252,247,195,237,15,133,244,253,255,248,14,
676 65,137,215,131,232,1,15,132,244,249,248,2,73,139,44,15,73,137,111,252,248,
677 65,131,199,8,131,232,1,15,133,244,2,248,3,139,68,36,4,15,182,107,252,255,
678 248,5,57,197,15,135,244,252,255,72,139,44,10,72,137,106,252,248,255,248,5,
679 56,67,252,255,15,135,244,252,255,15,182,75,252,253,72,252,247,209,141,20,
680 202,68,139,122,252,248,69,139,191,233,69,139,191,233,139,3,15,182,204,15,
681 182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,6,255,65,199,71,252,
682 252,237,65,131,199,8,255,199,68,194,252,244,237,255,131,192,1,252,233,244,
683 5,248,7,141,171,233,252,247,197,237,15,133,244,15,41,252,234,255,1,252,233,
684 255,137,221,209,252,237,129,229,239,102,65,129,172,253,46,233,238,15,130,
685 244,150,255,141,12,202,255,129,121,253,4,239,15,133,244,255,255,129,121,253,
686 12,239,15,133,244,62,129,121,253,20,239,15,133,244,62,139,41,131,121,16,0,
687 15,140,244,251,255,129,121,253,12,239,15,133,244,167,129,121,253,20,239,15,
688 133,244,167,255,139,105,16,133,252,237,15,136,244,251,3,41,15,128,244,247,
689 137,41,255,59,105,8,199,65,28,237,137,105,24,255,15,142,244,253,248,1,248,
690 6,141,156,253,131,233,255,141,156,253,131,233,15,183,67,252,254,15,142,245,
691 248,1,248,6,255,15,143,244,253,248,6,141,156,253,131,233,248,1,255,248,7,
692 139,3,15,182,204,15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,
693 5,255,3,41,15,128,244,1,137,41,255,15,141,244,7,255,141,156,253,131,233,15,
694 183,67,252,254,15,141,245,255,15,140,244,7,255,252,233,244,6,248,9,255,129,
695 121,253,4,239,255,15,131,244,62,129,121,253,12,239,15,131,244,62,255,129,
696 121,253,12,239,15,131,244,167,129,121,253,20,239,15,131,244,167,255,139,105,
697 20,255,129,252,253,239,15,131,244,62,255,252,242,15,16,1,252,242,15,16,73,
698 8,255,252,242,15,88,65,16,252,242,15,17,1,133,252,237,15,136,244,249,255,
699 15,140,244,249,255,102,15,46,200,248,1,252,242,15,17,65,24,255,15,131,244,
700 248,141,156,253,131,233,255,141,156,253,131,233,15,183,67,252,254,15,131,
701 245,255,15,130,244,248,141,156,253,131,233,255,248,2,139,3,15,182,204,15,
702 182,232,131,195,4,193,232,16,65,252,255,36,252,238,248,3,102,15,46,193,252,
703 233,244,1,255,141,12,202,139,105,4,129,252,253,239,15,132,244,247,255,137,
704 105,252,252,139,41,137,105,252,248,252,233,245,255,141,156,253,131,233,139,
705 1,137,105,252,252,137,65,252,248,255,65,139,142,233,139,4,129,72,139,128,
706 233,139,108,36,24,65,137,150,233,65,137,174,233,76,137,36,36,76,137,108,36,
707 8,72,131,252,236,16,252,255,224,255,141,156,253,131,233,139,3,15,182,204,
708 15,182,232,131,195,4,193,232,16,65,252,255,36,252,238,255,137,221,209,252,
709 237,129,229,239,102,65,129,172,253,46,233,238,15,130,244,152,255,68,139,187,
710 233,139,108,36,24,141,12,202,59,141,233,15,135,244,25,15,182,139,233,57,200,
711 15,134,244,249,248,2,255,15,183,67,252,254,252,233,245,255,248,3,199,68,194,
712 252,252,237,131,192,1,57,200,15,134,244,3,252,233,244,2,255,141,44,197,237,
713 141,4,194,68,139,122,252,248,137,104,252,252,68,137,120,252,248,139,108,36,
714 24,141,12,200,59,141,233,15,135,244,24,137,209,137,194,15,182,171,233,133,
715 252,237,15,132,244,248,248,1,131,193,8,57,209,15,131,244,249,68,139,121,252,
716 248,68,137,56,68,139,121,252,252,68,137,120,4,131,192,8,199,65,252,252,237,
717 131,252,237,1,15,133,244,1,248,2,255,68,139,187,233,139,3,15,182,204,15,182,
718 232,131,195,4,193,232,16,65,252,255,36,252,238,255,248,3,199,64,4,237,131,
719 192,8,131,252,237,1,15,133,244,3,252,233,244,2,255,139,106,252,248,76,139,
720 189,233,139,108,36,24,141,68,194,252,248,137,149,233,141,136,233,59,141,233,
721 137,133,233,255,137,252,239,255,76,137,252,254,137,252,239,255,15,135,244,
722 23,65,199,134,233,237,255,65,252,255,215,255,65,252,255,150,233,255,65,199,
723 134,233,237,139,149,233,141,12,194,252,247,217,3,141,233,139,90,252,252,252,
724 233,244,12,255,254,0
725};
726
727#line 13 "vm_x86.dasc"
728//|.globals GLOB_
729enum {
730 GLOB_vm_returnp,
731 GLOB_cont_dispatch,
732 GLOB_vm_returnc,
733 GLOB_vm_unwind_yield,
734 GLOB_BC_RET_Z,
735 GLOB_vm_return,
736 GLOB_vm_leave_cp,
737 GLOB_vm_leave_unw,
738 GLOB_vm_unwind_c_eh,
739 GLOB_vm_unwind_c,
740 GLOB_vm_unwind_rethrow,
741 GLOB_vm_unwind_ff,
742 GLOB_vm_unwind_ff_eh,
743 GLOB_vm_growstack_c,
744 GLOB_vm_growstack_v,
745 GLOB_vm_growstack_f,
746 GLOB_vm_resume,
747 GLOB_vm_pcall,
748 GLOB_vm_call,
749 GLOB_vm_call_dispatch,
750 GLOB_vmeta_call,
751 GLOB_vm_call_dispatch_f,
752 GLOB_vm_cpcall,
753 GLOB_cont_ffi_callback,
754 GLOB_vm_call_tail,
755 GLOB_cont_cat,
756 GLOB_cont_ra,
757 GLOB_BC_CAT_Z,
758 GLOB_vmeta_tgets,
759 GLOB_vmeta_tgetb,
760 GLOB_vmeta_tgetv,
761 GLOB_vmeta_tsets,
762 GLOB_vmeta_tsetb,
763 GLOB_vmeta_tsetv,
764 GLOB_cont_nop,
765 GLOB_vmeta_comp,
766 GLOB_vmeta_binop,
767 GLOB_cont_condt,
768 GLOB_cont_condf,
769 GLOB_vmeta_equal,
770 GLOB_vmeta_equal_cd,
771 GLOB_vmeta_arith_vno,
772 GLOB_vmeta_arith_vn,
773 GLOB_vmeta_arith_nvo,
774 GLOB_vmeta_arith_nv,
775 GLOB_vmeta_unm,
776 GLOB_vmeta_arith_vvo,
777 GLOB_vmeta_arith_vv,
778 GLOB_vmeta_len,
779 GLOB_BC_LEN_Z,
780 GLOB_vmeta_call_ra,
781 GLOB_BC_CALLT_Z,
782 GLOB_vmeta_for,
783 GLOB_ff_assert,
784 GLOB_fff_fallback,
785 GLOB_fff_res_,
786 GLOB_ff_type,
787 GLOB_fff_res1,
788 GLOB_ff_getmetatable,
789 GLOB_ff_setmetatable,
790 GLOB_ff_rawget,
791 GLOB_ff_tonumber,
792 GLOB_fff_resxmm0,
793 GLOB_ff_tostring,
794 GLOB_fff_gcstep,
795 GLOB_ff_next,
796 GLOB_fff_res2,
797 GLOB_fff_res,
798 GLOB_ff_pairs,
799 GLOB_ff_ipairs_aux,
800 GLOB_fff_res0,
801 GLOB_ff_ipairs,
802 GLOB_ff_pcall,
803 GLOB_ff_xpcall,
804 GLOB_ff_coroutine_resume,
805 GLOB_ff_coroutine_wrap_aux,
806 GLOB_ff_coroutine_yield,
807 GLOB_fff_resi,
808 GLOB_fff_resn,
809 GLOB_ff_math_abs,
810 GLOB_ff_math_floor,
811 GLOB_vm_floor,
812 GLOB_ff_math_ceil,
813 GLOB_vm_ceil,
814 GLOB_ff_math_sqrt,
815 GLOB_ff_math_log,
816 GLOB_ff_math_log10,
817 GLOB_ff_math_exp,
818 GLOB_vm_exp_x87,
819 GLOB_ff_math_sin,
820 GLOB_ff_math_cos,
821 GLOB_ff_math_tan,
822 GLOB_ff_math_asin,
823 GLOB_ff_math_acos,
824 GLOB_ff_math_atan,
825 GLOB_ff_math_sinh,
826 GLOB_ff_math_cosh,
827 GLOB_ff_math_tanh,
828 GLOB_ff_math_deg,
829 GLOB_ff_math_rad,
830 GLOB_ff_math_atan2,
831 GLOB_ff_math_ldexp,
832 GLOB_ff_math_frexp,
833 GLOB_ff_math_modf,
834 GLOB_vm_trunc,
835 GLOB_ff_math_fmod,
836 GLOB_ff_math_pow,
837 GLOB_vm_pow,
838 GLOB_ff_math_min,
839 GLOB_ff_math_max,
840 GLOB_ff_string_len,
841 GLOB_ff_string_byte,
842 GLOB_ff_string_char,
843 GLOB_fff_newstr,
844 GLOB_ff_string_sub,
845 GLOB_fff_emptystr,
846 GLOB_ff_string_rep,
847 GLOB_fff_fallback_2,
848 GLOB_ff_string_reverse,
849 GLOB_fff_fallback_1,
850 GLOB_ff_string_lower,
851 GLOB_ff_string_upper,
852 GLOB_ff_table_getn,
853 GLOB_ff_bit_tobit,
854 GLOB_fff_resbit,
855 GLOB_ff_bit_band,
856 GLOB_fff_fallback_bit_op,
857 GLOB_ff_bit_bor,
858 GLOB_ff_bit_bxor,
859 GLOB_ff_bit_bswap,
860 GLOB_ff_bit_bnot,
861 GLOB_ff_bit_lshift,
862 GLOB_ff_bit_rshift,
863 GLOB_ff_bit_arshift,
864 GLOB_ff_bit_rol,
865 GLOB_ff_bit_ror,
866 GLOB_vm_record,
867 GLOB_vm_rethook,
868 GLOB_vm_inshook,
869 GLOB_cont_hook,
870 GLOB_vm_hotloop,
871 GLOB_vm_callhook,
872 GLOB_vm_hotcall,
873 GLOB_vm_exit_handler,
874 GLOB_vm_exit_interp,
875 GLOB_vm_floor_sse,
876 GLOB_vm_ceil_sse,
877 GLOB_vm_trunc_sse,
878 GLOB_vm_mod,
879 GLOB_vm_log2,
880 GLOB_vm_exp2_x87,
881 GLOB_vm_exp2raw,
882 GLOB_vm_pow_sse,
883 GLOB_vm_powi_sse,
884 GLOB_vm_foldfpm,
885 GLOB_vm_foldarith,
886 GLOB_vm_cpuid,
887 GLOB_assert_bad_for_arg_type,
888 GLOB_vm_ffi_callback,
889 GLOB_vm_ffi_call,
890 GLOB_BC_MODVN_Z,
891 GLOB_BC_TGETS_Z,
892 GLOB_BC_TSETS_Z,
893 GLOB__MAX
894};
895#line 14 "vm_x86.dasc"
896//|.globalnames globnames
897static const char *const globnames[] = {
898 "vm_returnp",
899 "cont_dispatch",
900 "vm_returnc",
901 "vm_unwind_yield",
902 "BC_RET_Z",
903 "vm_return",
904 "vm_leave_cp",
905 "vm_leave_unw",
906 "vm_unwind_c_eh",
907 "vm_unwind_c@8",
908 "vm_unwind_rethrow",
909 "vm_unwind_ff@4",
910 "vm_unwind_ff_eh",
911 "vm_growstack_c",
912 "vm_growstack_v",
913 "vm_growstack_f",
914 "vm_resume",
915 "vm_pcall",
916 "vm_call",
917 "vm_call_dispatch",
918 "vmeta_call",
919 "vm_call_dispatch_f",
920 "vm_cpcall",
921 "cont_ffi_callback",
922 "vm_call_tail",
923 "cont_cat",
924 "cont_ra",
925 "BC_CAT_Z",
926 "vmeta_tgets",
927 "vmeta_tgetb",
928 "vmeta_tgetv",
929 "vmeta_tsets",
930 "vmeta_tsetb",
931 "vmeta_tsetv",
932 "cont_nop",
933 "vmeta_comp",
934 "vmeta_binop",
935 "cont_condt",
936 "cont_condf",
937 "vmeta_equal",
938 "vmeta_equal_cd",
939 "vmeta_arith_vno",
940 "vmeta_arith_vn",
941 "vmeta_arith_nvo",
942 "vmeta_arith_nv",
943 "vmeta_unm",
944 "vmeta_arith_vvo",
945 "vmeta_arith_vv",
946 "vmeta_len",
947 "BC_LEN_Z",
948 "vmeta_call_ra",
949 "BC_CALLT_Z",
950 "vmeta_for",
951 "ff_assert",
952 "fff_fallback",
953 "fff_res_",
954 "ff_type",
955 "fff_res1",
956 "ff_getmetatable",
957 "ff_setmetatable",
958 "ff_rawget",
959 "ff_tonumber",
960 "fff_resxmm0",
961 "ff_tostring",
962 "fff_gcstep",
963 "ff_next",
964 "fff_res2",
965 "fff_res",
966 "ff_pairs",
967 "ff_ipairs_aux",
968 "fff_res0",
969 "ff_ipairs",
970 "ff_pcall",
971 "ff_xpcall",
972 "ff_coroutine_resume",
973 "ff_coroutine_wrap_aux",
974 "ff_coroutine_yield",
975 "fff_resi",
976 "fff_resn",
977 "ff_math_abs",
978 "ff_math_floor",
979 "vm_floor",
980 "ff_math_ceil",
981 "vm_ceil",
982 "ff_math_sqrt",
983 "ff_math_log",
984 "ff_math_log10",
985 "ff_math_exp",
986 "vm_exp_x87",
987 "ff_math_sin",
988 "ff_math_cos",
989 "ff_math_tan",
990 "ff_math_asin",
991 "ff_math_acos",
992 "ff_math_atan",
993 "ff_math_sinh",
994 "ff_math_cosh",
995 "ff_math_tanh",
996 "ff_math_deg",
997 "ff_math_rad",
998 "ff_math_atan2",
999 "ff_math_ldexp",
1000 "ff_math_frexp",
1001 "ff_math_modf",
1002 "vm_trunc",
1003 "ff_math_fmod",
1004 "ff_math_pow",
1005 "vm_pow",
1006 "ff_math_min",
1007 "ff_math_max",
1008 "ff_string_len",
1009 "ff_string_byte",
1010 "ff_string_char",
1011 "fff_newstr",
1012 "ff_string_sub",
1013 "fff_emptystr",
1014 "ff_string_rep",
1015 "fff_fallback_2",
1016 "ff_string_reverse",
1017 "fff_fallback_1",
1018 "ff_string_lower",
1019 "ff_string_upper",
1020 "ff_table_getn",
1021 "ff_bit_tobit",
1022 "fff_resbit",
1023 "ff_bit_band",
1024 "fff_fallback_bit_op",
1025 "ff_bit_bor",
1026 "ff_bit_bxor",
1027 "ff_bit_bswap",
1028 "ff_bit_bnot",
1029 "ff_bit_lshift",
1030 "ff_bit_rshift",
1031 "ff_bit_arshift",
1032 "ff_bit_rol",
1033 "ff_bit_ror",
1034 "vm_record",
1035 "vm_rethook",
1036 "vm_inshook",
1037 "cont_hook",
1038 "vm_hotloop",
1039 "vm_callhook",
1040 "vm_hotcall",
1041 "vm_exit_handler",
1042 "vm_exit_interp",
1043 "vm_floor_sse",
1044 "vm_ceil_sse",
1045 "vm_trunc_sse",
1046 "vm_mod",
1047 "vm_log2",
1048 "vm_exp2_x87",
1049 "vm_exp2raw",
1050 "vm_pow_sse",
1051 "vm_powi_sse",
1052 "vm_foldfpm",
1053 "vm_foldarith",
1054 "vm_cpuid",
1055 "assert_bad_for_arg_type",
1056 "vm_ffi_callback",
1057 "vm_ffi_call@4",
1058 "BC_MODVN_Z",
1059 "BC_TGETS_Z",
1060 "BC_TSETS_Z",
1061 (const char *)0
1062};
1063#line 15 "vm_x86.dasc"
1064//|.externnames extnames
1065static const char *const extnames[] = {
1066 "lj_state_growstack@8",
1067 "lj_err_throw@8",
1068 "lj_meta_tget",
1069 "lj_meta_tset",
1070 "lj_meta_comp",
1071 "lj_meta_equal",
1072 "lj_meta_equal_cd@8",
1073 "lj_meta_arith",
1074 "lj_meta_len@8",
1075 "lj_meta_call",
1076 "lj_meta_for@8",
1077 "lj_tab_get",
1078 "lj_str_fromnum@8",
1079 "lj_tab_next",
1080 "lj_tab_getinth@8",
1081 "lj_ffh_coroutine_wrap_err@8",
1082 "lj_vm_sinh",
1083 "lj_vm_cosh",
1084 "lj_vm_tanh",
1085 "lj_str_new",
1086 "lj_tab_len@4",
1087 "lj_gc_step@4",
1088 "lj_dispatch_ins@8",
1089 "lj_trace_hot@8",
1090 "lj_dispatch_call@8",
1091 "lj_trace_exit@8",
1092 "lj_ccallback_enter@8",
1093 "lj_ccallback_leave@8",
1094 "lj_meta_cat",
1095 "lj_gc_barrieruv@8",
1096 "lj_func_closeuv@8",
1097 "lj_func_newL_gc",
1098 "lj_tab_new",
1099 "lj_gc_step_fixtop@4",
1100 "lj_tab_dup@8",
1101 "lj_tab_newkey",
1102 "lj_tab_reasize",
1103 (const char *)0
1104};
1105#line 16 "vm_x86.dasc"
1106//|
1107//|//-----------------------------------------------------------------------
1108//|
1109//|.if P64
1110//|.define X64, 1
1111//|.define SSE, 1
1112//|.if WIN
1113//|.define X64WIN, 1
1114//|.endif
1115//|.endif
1116//|
1117//|// Fixed register assignments for the interpreter.
1118//|// This is very fragile and has many dependencies. Caveat emptor.
1119//|.define BASE, edx // Not C callee-save, refetched anyway.
1120//|.if not X64
1121//|.define KBASE, edi // Must be C callee-save.
1122//|.define KBASEa, KBASE
1123//|.define PC, esi // Must be C callee-save.
1124//|.define PCa, PC
1125//|.define DISPATCH, ebx // Must be C callee-save.
1126//|.elif X64WIN
1127//|.define KBASE, edi // Must be C callee-save.
1128//|.define KBASEa, rdi
1129//|.define PC, esi // Must be C callee-save.
1130//|.define PCa, rsi
1131//|.define DISPATCH, ebx // Must be C callee-save.
1132//|.else
1133//|.define KBASE, r15d // Must be C callee-save.
1134//|.define KBASEa, r15
1135//|.define PC, ebx // Must be C callee-save.
1136//|.define PCa, rbx
1137//|.define DISPATCH, r14d // Must be C callee-save.
1138//|.endif
1139//|
1140//|.define RA, ecx
1141//|.define RAH, ch
1142//|.define RAL, cl
1143//|.define RB, ebp // Must be ebp (C callee-save).
1144//|.define RC, eax // Must be eax.
1145//|.define RCW, ax
1146//|.define RCH, ah
1147//|.define RCL, al
1148//|.define OP, RB
1149//|.define RD, RC
1150//|.define RDW, RCW
1151//|.define RDL, RCL
1152//|.if X64
1153//|.define RAa, rcx
1154//|.define RBa, rbp
1155//|.define RCa, rax
1156//|.define RDa, rax
1157//|.else
1158//|.define RAa, RA
1159//|.define RBa, RB
1160//|.define RCa, RC
1161//|.define RDa, RD
1162//|.endif
1163//|
1164//|.if not X64
1165//|.define FCARG1, ecx // x86 fastcall arguments.
1166//|.define FCARG2, edx
1167//|.elif X64WIN
1168//|.define CARG1, rcx // x64/WIN64 C call arguments.
1169//|.define CARG2, rdx
1170//|.define CARG3, r8
1171//|.define CARG4, r9
1172//|.define CARG1d, ecx
1173//|.define CARG2d, edx
1174//|.define CARG3d, r8d
1175//|.define CARG4d, r9d
1176//|.define FCARG1, CARG1d // Upwards compatible to x86 fastcall.
1177//|.define FCARG2, CARG2d
1178//|.else
1179//|.define CARG1, rdi // x64/POSIX C call arguments.
1180//|.define CARG2, rsi
1181//|.define CARG3, rdx
1182//|.define CARG4, rcx
1183//|.define CARG5, r8
1184//|.define CARG6, r9
1185//|.define CARG1d, edi
1186//|.define CARG2d, esi
1187//|.define CARG3d, edx
1188//|.define CARG4d, ecx
1189//|.define CARG5d, r8d
1190//|.define CARG6d, r9d
1191//|.define FCARG1, CARG1d // Simulate x86 fastcall.
1192//|.define FCARG2, CARG2d
1193//|.endif
1194//|
1195//|// Type definitions. Some of these are only used for documentation.
1196//|.type L, lua_State
1197#define Dt1(_V) (int)(ptrdiff_t)&(((lua_State *)0)_V)
1198#line 107 "vm_x86.dasc"
1199//|.type GL, global_State
1200#define Dt2(_V) (int)(ptrdiff_t)&(((global_State *)0)_V)
1201#line 108 "vm_x86.dasc"
1202//|.type TVALUE, TValue
1203#define Dt3(_V) (int)(ptrdiff_t)&(((TValue *)0)_V)
1204#line 109 "vm_x86.dasc"
1205//|.type GCOBJ, GCobj
1206#define Dt4(_V) (int)(ptrdiff_t)&(((GCobj *)0)_V)
1207#line 110 "vm_x86.dasc"
1208//|.type STR, GCstr
1209#define Dt5(_V) (int)(ptrdiff_t)&(((GCstr *)0)_V)
1210#line 111 "vm_x86.dasc"
1211//|.type TAB, GCtab
1212#define Dt6(_V) (int)(ptrdiff_t)&(((GCtab *)0)_V)
1213#line 112 "vm_x86.dasc"
1214//|.type LFUNC, GCfuncL
1215#define Dt7(_V) (int)(ptrdiff_t)&(((GCfuncL *)0)_V)
1216#line 113 "vm_x86.dasc"
1217//|.type CFUNC, GCfuncC
1218#define Dt8(_V) (int)(ptrdiff_t)&(((GCfuncC *)0)_V)
1219#line 114 "vm_x86.dasc"
1220//|.type PROTO, GCproto
1221#define Dt9(_V) (int)(ptrdiff_t)&(((GCproto *)0)_V)
1222#line 115 "vm_x86.dasc"
1223//|.type UPVAL, GCupval
1224#define DtA(_V) (int)(ptrdiff_t)&(((GCupval *)0)_V)
1225#line 116 "vm_x86.dasc"
1226//|.type NODE, Node
1227#define DtB(_V) (int)(ptrdiff_t)&(((Node *)0)_V)
1228#line 117 "vm_x86.dasc"
1229//|.type NARGS, int
1230#define DtC(_V) (int)(ptrdiff_t)&(((int *)0)_V)
1231#line 118 "vm_x86.dasc"
1232//|.type TRACE, GCtrace
1233#define DtD(_V) (int)(ptrdiff_t)&(((GCtrace *)0)_V)
1234#line 119 "vm_x86.dasc"
1235//|
1236//|// Stack layout while in interpreter. Must match with lj_frame.h.
1237//|//-----------------------------------------------------------------------
1238//|.if not X64 // x86 stack layout.
1239//|
1240//|.define CFRAME_SPACE, aword*7 // Delta for esp (see <--).
1241//|.macro saveregs_
1242//| push edi; push esi; push ebx
1243//| sub esp, CFRAME_SPACE
1244//|.endmacro
1245//|.macro saveregs
1246//| push ebp; saveregs_
1247//|.endmacro
1248//|.macro restoreregs
1249//| add esp, CFRAME_SPACE
1250//| pop ebx; pop esi; pop edi; pop ebp
1251//|.endmacro
1252//|
1253//|.define SAVE_ERRF, aword [esp+aword*15] // vm_pcall/vm_cpcall only.
1254//|.define SAVE_NRES, aword [esp+aword*14]
1255//|.define SAVE_CFRAME, aword [esp+aword*13]
1256//|.define SAVE_L, aword [esp+aword*12]
1257//|//----- 16 byte aligned, ^^^ arguments from C caller
1258//|.define SAVE_RET, aword [esp+aword*11] //<-- esp entering interpreter.
1259//|.define SAVE_R4, aword [esp+aword*10]
1260//|.define SAVE_R3, aword [esp+aword*9]
1261//|.define SAVE_R2, aword [esp+aword*8]
1262//|//----- 16 byte aligned
1263//|.define SAVE_R1, aword [esp+aword*7] //<-- esp after register saves.
1264//|.define SAVE_PC, aword [esp+aword*6]
1265//|.define TMP2, aword [esp+aword*5]
1266//|.define TMP1, aword [esp+aword*4]
1267//|//----- 16 byte aligned
1268//|.define ARG4, aword [esp+aword*3]
1269//|.define ARG3, aword [esp+aword*2]
1270//|.define ARG2, aword [esp+aword*1]
1271//|.define ARG1, aword [esp] //<-- esp while in interpreter.
1272//|//----- 16 byte aligned, ^^^ arguments for C callee
1273//|
1274//|// FPARGx overlaps ARGx and ARG(x+1) on x86.
1275//|.define FPARG3, qword [esp+qword*1]
1276//|.define FPARG1, qword [esp]
1277//|// TMPQ overlaps TMP1/TMP2. ARG5/MULTRES overlap TMP1/TMP2 (and TMPQ).
1278//|.define TMPQ, qword [esp+aword*4]
1279//|.define TMP3, ARG4
1280//|.define ARG5, TMP1
1281//|.define TMPa, TMP1
1282//|.define MULTRES, TMP2
1283//|
1284//|// Arguments for vm_call and vm_pcall.
1285//|.define INARG_BASE, SAVE_CFRAME // Overwritten by SAVE_CFRAME!
1286//|
1287//|// Arguments for vm_cpcall.
1288//|.define INARG_CP_CALL, SAVE_ERRF
1289//|.define INARG_CP_UD, SAVE_NRES
1290//|.define INARG_CP_FUNC, SAVE_CFRAME
1291//|
1292//|//-----------------------------------------------------------------------
1293//|.elif X64WIN // x64/Windows stack layout
1294//|
1295//|.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--).
1296//|.macro saveregs_
1297//| push rdi; push rsi; push rbx
1298//| sub rsp, CFRAME_SPACE
1299//|.endmacro
1300//|.macro saveregs
1301//| push rbp; saveregs_
1302//|.endmacro
1303//|.macro restoreregs
1304//| add rsp, CFRAME_SPACE
1305//| pop rbx; pop rsi; pop rdi; pop rbp
1306//|.endmacro
1307//|
1308//|.define SAVE_CFRAME, aword [rsp+aword*13]
1309//|.define SAVE_PC, dword [rsp+dword*25]
1310//|.define SAVE_L, dword [rsp+dword*24]
1311//|.define SAVE_ERRF, dword [rsp+dword*23]
1312//|.define SAVE_NRES, dword [rsp+dword*22]
1313//|.define TMP2, dword [rsp+dword*21]
1314//|.define TMP1, dword [rsp+dword*20]
1315//|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by interpreter
1316//|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter.
1317//|.define SAVE_R4, aword [rsp+aword*8]
1318//|.define SAVE_R3, aword [rsp+aword*7]
1319//|.define SAVE_R2, aword [rsp+aword*6]
1320//|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
1321//|.define ARG5, aword [rsp+aword*4]
1322//|.define CSAVE_4, aword [rsp+aword*3]
1323//|.define CSAVE_3, aword [rsp+aword*2]
1324//|.define CSAVE_2, aword [rsp+aword*1]
1325//|.define CSAVE_1, aword [rsp] //<-- rsp while in interpreter.
1326//|//----- 16 byte aligned, ^^^ 32 byte register save area, owned by callee
1327//|
1328//|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
1329//|.define TMPQ, qword [rsp+aword*10]
1330//|.define MULTRES, TMP2
1331//|.define TMPa, ARG5
1332//|.define ARG5d, dword [rsp+aword*4]
1333//|.define TMP3, ARG5d
1334//|
1335//|//-----------------------------------------------------------------------
1336//|.else // x64/POSIX stack layout
1337//|
1338//|.define CFRAME_SPACE, aword*5 // Delta for rsp (see <--).
1339//|.macro saveregs_
1340//| push rbx; push r15; push r14
1341//| sub rsp, CFRAME_SPACE
1342//|.endmacro
1343//|.macro saveregs
1344//| push rbp; saveregs_
1345//|.endmacro
1346//|.macro restoreregs
1347//| add rsp, CFRAME_SPACE
1348//| pop r14; pop r15; pop rbx; pop rbp
1349//|.endmacro
1350//|
1351//|//----- 16 byte aligned,
1352//|.define SAVE_RET, aword [rsp+aword*9] //<-- rsp entering interpreter.
1353//|.define SAVE_R4, aword [rsp+aword*8]
1354//|.define SAVE_R3, aword [rsp+aword*7]
1355//|.define SAVE_R2, aword [rsp+aword*6]
1356//|.define SAVE_R1, aword [rsp+aword*5] //<-- rsp after register saves.
1357//|.define SAVE_CFRAME, aword [rsp+aword*4]
1358//|.define SAVE_PC, dword [rsp+dword*7]
1359//|.define SAVE_L, dword [rsp+dword*6]
1360//|.define SAVE_ERRF, dword [rsp+dword*5]
1361//|.define SAVE_NRES, dword [rsp+dword*4]
1362//|.define TMPa, aword [rsp+aword*1]
1363//|.define TMP2, dword [rsp+dword*1]
1364//|.define TMP1, dword [rsp] //<-- rsp while in interpreter.
1365//|//----- 16 byte aligned
1366//|
1367//|// TMPQ overlaps TMP1/TMP2. MULTRES overlaps TMP2 (and TMPQ).
1368//|.define TMPQ, qword [rsp]
1369//|.define TMP3, dword [rsp+aword*1]
1370//|.define MULTRES, TMP2
1371//|
1372//|.endif
1373//|
1374//|//-----------------------------------------------------------------------
1375//|
1376//|// Instruction headers.
1377//|.macro ins_A; .endmacro
1378//|.macro ins_AD; .endmacro
1379//|.macro ins_AJ; .endmacro
1380//|.macro ins_ABC; movzx RB, RCH; movzx RC, RCL; .endmacro
1381//|.macro ins_AB_; movzx RB, RCH; .endmacro
1382//|.macro ins_A_C; movzx RC, RCL; .endmacro
1383//|.macro ins_AND; not RDa; .endmacro
1384//|
1385//|// Instruction decode+dispatch. Carefully tuned (nope, lodsd is not faster).
1386//|.macro ins_NEXT
1387//| mov RC, [PC]
1388//| movzx RA, RCH
1389//| movzx OP, RCL
1390//| add PC, 4
1391//| shr RC, 16
1392//|.if X64
1393//| jmp aword [DISPATCH+OP*8]
1394//|.else
1395//| jmp aword [DISPATCH+OP*4]
1396//|.endif
1397//|.endmacro
1398//|
1399//|// Instruction footer.
1400//|.if 1
1401//| // Replicated dispatch. Less unpredictable branches, but higher I-Cache use.
1402//| .define ins_next, ins_NEXT
1403//| .define ins_next_, ins_NEXT
1404//|.else
1405//| // Common dispatch. Lower I-Cache use, only one (very) unpredictable branch.
1406//| // Affects only certain kinds of benchmarks (and only with -j off).
1407//| // Around 10%-30% slower on Core2, a lot more slower on P4.
1408//| .macro ins_next
1409//| jmp ->ins_next
1410//| .endmacro
1411//| .macro ins_next_
1412//| ->ins_next:
1413//| ins_NEXT
1414//| .endmacro
1415//|.endif
1416//|
1417//|// Call decode and dispatch.
1418//|.macro ins_callt
1419//| // BASE = new base, RB = LFUNC, RD = nargs+1, [BASE-4] = PC
1420//| mov PC, LFUNC:RB->pc
1421//| mov RA, [PC]
1422//| movzx OP, RAL
1423//| movzx RA, RAH
1424//| add PC, 4
1425//|.if X64
1426//| jmp aword [DISPATCH+OP*8]
1427//|.else
1428//| jmp aword [DISPATCH+OP*4]
1429//|.endif
1430//|.endmacro
1431//|
1432//|.macro ins_call
1433//| // BASE = new base, RB = LFUNC, RD = nargs+1
1434//| mov [BASE-4], PC
1435//| ins_callt
1436//|.endmacro
1437//|
1438//|//-----------------------------------------------------------------------
1439//|
1440//|// Macros to test operand types.
1441//|.macro checktp, reg, tp; cmp dword [BASE+reg*8+4], tp; .endmacro
1442//|.macro checknum, reg, target; checktp reg, LJ_TISNUM; jae target; .endmacro
1443//|.macro checkint, reg, target; checktp reg, LJ_TISNUM; jne target; .endmacro
1444//|.macro checkstr, reg, target; checktp reg, LJ_TSTR; jne target; .endmacro
1445//|.macro checktab, reg, target; checktp reg, LJ_TTAB; jne target; .endmacro
1446//|
1447//|// These operands must be used with movzx.
1448//|.define PC_OP, byte [PC-4]
1449//|.define PC_RA, byte [PC-3]
1450//|.define PC_RB, byte [PC-1]
1451//|.define PC_RC, byte [PC-2]
1452//|.define PC_RD, word [PC-2]
1453//|
1454//|.macro branchPC, reg
1455//| lea PC, [PC+reg*4-BCBIAS_J*4]
1456//|.endmacro
1457//|
1458//|// Assumes DISPATCH is relative to GL.
1459#define DISPATCH_GL(field) (GG_DISP2G + (int)offsetof(global_State, field))
1460#define DISPATCH_J(field) (GG_DISP2J + (int)offsetof(jit_State, field))
1461//|
1462#define PC2PROTO(field) ((int)offsetof(GCproto, field)-(int)sizeof(GCproto))
1463//|
1464//|// Decrement hashed hotcount and trigger trace recorder if zero.
1465//|.macro hotloop, reg
1466//| mov reg, PC
1467//| shr reg, 1
1468//| and reg, HOTCOUNT_PCMASK
1469//| sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_LOOP
1470//| jb ->vm_hotloop
1471//|.endmacro
1472//|
1473//|.macro hotcall, reg
1474//| mov reg, PC
1475//| shr reg, 1
1476//| and reg, HOTCOUNT_PCMASK
1477//| sub word [DISPATCH+reg+GG_DISP2HOT], HOTCOUNT_CALL
1478//| jb ->vm_hotcall
1479//|.endmacro
1480//|
1481//|// Set current VM state.
1482//|.macro set_vmstate, st
1483//| mov dword [DISPATCH+DISPATCH_GL(vmstate)], ~LJ_VMST_..st
1484//|.endmacro
1485//|
1486//|// x87 compares.
1487//|.macro fcomparepp // Compare and pop st0 >< st1.
1488//| fucomip st1
1489//| fpop
1490//|.endmacro
1491//|
1492//|.macro fdup; fld st0; .endmacro
1493//|.macro fpop1; fstp st1; .endmacro
1494//|
1495//|// Synthesize SSE FP constants.
1496//|.macro sseconst_abs, reg, tmp // Synthesize abs mask.
1497//|.if X64
1498//| mov64 tmp, U64x(7fffffff,ffffffff); movd reg, tmp
1499//|.else
1500//| pxor reg, reg; pcmpeqd reg, reg; psrlq reg, 1
1501//|.endif
1502//|.endmacro
1503//|
1504//|.macro sseconst_hi, reg, tmp, val // Synthesize hi-32 bit const.
1505//|.if X64
1506//| mov64 tmp, U64x(val,00000000); movd reg, tmp
1507//|.else
1508//| mov tmp, 0x .. val; movd reg, tmp; pshufd reg, reg, 0x51
1509//|.endif
1510//|.endmacro
1511//|
1512//|.macro sseconst_sign, reg, tmp // Synthesize sign mask.
1513//| sseconst_hi reg, tmp, 80000000
1514//|.endmacro
1515//|.macro sseconst_1, reg, tmp // Synthesize 1.0.
1516//| sseconst_hi reg, tmp, 3ff00000
1517//|.endmacro
1518//|.macro sseconst_m1, reg, tmp // Synthesize -1.0.
1519//| sseconst_hi reg, tmp, bff00000
1520//|.endmacro
1521//|.macro sseconst_2p52, reg, tmp // Synthesize 2^52.
1522//| sseconst_hi reg, tmp, 43300000
1523//|.endmacro
1524//|.macro sseconst_tobit, reg, tmp // Synthesize 2^52 + 2^51.
1525//| sseconst_hi reg, tmp, 43380000
1526//|.endmacro
1527//|
1528//|// Move table write barrier back. Overwrites reg.
1529//|.macro barrierback, tab, reg
1530//| and byte tab->marked, (uint8_t)~LJ_GC_BLACK // black2gray(tab)
1531//| mov reg, [DISPATCH+DISPATCH_GL(gc.grayagain)]
1532//| mov [DISPATCH+DISPATCH_GL(gc.grayagain)], tab
1533//| mov tab->gclist, reg
1534//|.endmacro
1535//|
1536//|//-----------------------------------------------------------------------
1537
1538/* Generate subroutines used by opcodes and other parts of the VM. */
1539/* The .code_sub section should be last to help static branch prediction. */
1540static void build_subroutines(BuildCtx *ctx)
1541{
1542 //|.code_sub
1543 dasm_put(Dst, 0);
1544#line 427 "vm_x86.dasc"
1545 //|
1546 //|//-----------------------------------------------------------------------
1547 //|//-- Return handling ----------------------------------------------------
1548 //|//-----------------------------------------------------------------------
1549 //|
1550 //|->vm_returnp:
1551 //| test PC, FRAME_P
1552 //| jz ->cont_dispatch
1553 //|
1554 //| // Return from pcall or xpcall fast func.
1555 //| and PC, -8
1556 //| sub BASE, PC // Restore caller base.
1557 //| lea RAa, [RA+PC-8] // Rebase RA and prepend one result.
1558 //| mov PC, [BASE-4] // Fetch PC of previous frame.
1559 //| // Prepending may overwrite the pcall frame, so do it at the end.
1560 //| mov dword [BASE+RA+4], LJ_TTRUE // Prepend true to results.
1561 //|
1562 //|->vm_returnc:
1563 //| add RD, 1 // RD = nresults+1
1564 //| jz ->vm_unwind_yield
1565 //| mov MULTRES, RD
1566 //| test PC, FRAME_TYPE
1567 //| jz ->BC_RET_Z // Handle regular return to Lua.
1568 //|
1569 //|->vm_return:
1570 //| // BASE = base, RA = resultofs, RD = nresults+1 (= MULTRES), PC = return
1571 //| xor PC, FRAME_C
1572 //| test PC, FRAME_TYPE
1573 //| jnz ->vm_returnp
1574 //|
1575 //| // Return to C.
1576 //| set_vmstate C
1577 //| and PC, -8
1578 //| sub PC, BASE
1579 //| neg PC // Previous base = BASE - delta.
1580 //|
1581 //| sub RD, 1
1582 //| jz >2
1583 //|1: // Move results down.
1584 //|.if X64
1585 //| mov RBa, [BASE+RA]
1586 dasm_put(Dst, 2, FRAME_P, LJ_TTRUE, FRAME_TYPE, FRAME_C, FRAME_TYPE, DISPATCH_GL(vmstate), ~LJ_VMST_C);
1587#line 468 "vm_x86.dasc"
1588 //| mov [BASE-8], RBa
1589 //|.else
1590 //| mov RB, [BASE+RA]
1591 //| mov [BASE-8], RB
1592 //| mov RB, [BASE+RA+4]
1593 //| mov [BASE-4], RB
1594 //|.endif
1595 //| add BASE, 8
1596 //| sub RD, 1
1597 //| jnz <1
1598 //|2:
1599 //| mov L:RB, SAVE_L
1600 //| mov L:RB->base, PC
1601 //|3:
1602 //| mov RD, MULTRES
1603 //| mov RA, SAVE_NRES // RA = wanted nresults+1
1604 //|4:
1605 //| cmp RA, RD
1606 //| jne >6 // More/less results wanted?
1607 //|5:
1608 //| sub BASE, 8
1609 //| mov L:RB->top, BASE
1610 //|
1611 //|->vm_leave_cp:
1612 //| mov RAa, SAVE_CFRAME // Restore previous C frame.
1613 //| mov L:RB->cframe, RAa
1614 //| xor eax, eax // Ok return status for vm_pcall.
1615 //|
1616 //|->vm_leave_unw:
1617 //| restoreregs
1618 //| ret
1619 //|
1620 //|6:
1621 //| jb >7 // Less results wanted?
1622 //| // More results wanted. Check stack size and fill up results with nil.
1623 //| cmp BASE, L:RB->maxstack
1624 //| ja >8
1625 //| mov dword [BASE-4], LJ_TNIL
1626 //| add BASE, 8
1627 dasm_put(Dst, 92, Dt1(->base), Dt1(->top), Dt1(->cframe), Dt1(->maxstack), LJ_TNIL);
1628#line 507 "vm_x86.dasc"
1629 //| add RD, 1
1630 //| jmp <4
1631 //|
1632 //|7: // Less results wanted.
1633 //| test RA, RA
1634 //| jz <5 // But check for LUA_MULTRET+1.
1635 //| sub RA, RD // Negative result!
1636 //| lea BASE, [BASE+RA*8] // Correct top.
1637 //| jmp <5
1638 //|
1639 //|8: // Corner case: need to grow stack for filling up results.
1640 //| // This can happen if:
1641 //| // - A C function grows the stack (a lot).
1642 //| // - The GC shrinks the stack in between.
1643 //| // - A return back from a lua_call() with (high) nresults adjustment.
1644 //| mov L:RB->top, BASE // Save current top held in BASE (yes).
1645 //| mov MULTRES, RD // Need to fill only remainder with nil.
1646 //| mov FCARG2, RA
1647 //| mov FCARG1, L:RB
1648 //| call extern lj_state_growstack@8 // (lua_State *L, int n)
1649 //| mov BASE, L:RB->top // Need the (realloced) L->top in BASE.
1650 //| jmp <3
1651 //|
1652 //|->vm_unwind_yield:
1653 //| mov al, LUA_YIELD
1654 //| jmp ->vm_unwind_c_eh
1655 //|
1656 //|->vm_unwind_c@8: // Unwind C stack, return from vm_pcall.
1657 //| // (void *cframe, int errcode)
1658 //|.if X64
1659 //| mov eax, CARG2d // Error return status for vm_pcall.
1660 //| mov rsp, CARG1
1661 //|.else
1662 //| mov eax, FCARG2 // Error return status for vm_pcall.
1663 //| mov esp, FCARG1
1664 //|.endif
1665 //|->vm_unwind_c_eh: // Landing pad for external unwinder.
1666 //| mov L:RB, SAVE_L
1667 //| mov GL:RB, L:RB->glref
1668 //| mov dword GL:RB->vmstate, ~LJ_VMST_C
1669 //| jmp ->vm_leave_unw
1670 dasm_put(Dst, 192, Dt1(->top), Dt1(->top), LUA_YIELD, Dt1(->glref), Dt2(->vmstate), ~LJ_VMST_C);
1671#line 548 "vm_x86.dasc"
1672 //|
1673 //|->vm_unwind_rethrow:
1674 //|.if X64 and not X64WIN
1675 //| mov FCARG1, SAVE_L
1676 //| mov FCARG2, eax
1677 //| restoreregs
1678 //| jmp extern lj_err_throw@8 // (lua_State *L, int errcode)
1679 //|.endif
1680 //|
1681 //|->vm_unwind_ff@4: // Unwind C stack, return from ff pcall.
1682 //| // (void *cframe)
1683 //|.if X64
1684 //| and CARG1, CFRAME_RAWMASK
1685 //| mov rsp, CARG1
1686 //|.else
1687 //| and FCARG1, CFRAME_RAWMASK
1688 //| mov esp, FCARG1
1689 //|.endif
1690 //|->vm_unwind_ff_eh: // Landing pad for external unwinder.
1691 //| mov L:RB, SAVE_L
1692 //| mov RAa, -8 // Results start at BASE+RA = BASE-8.
1693 //| mov RD, 1+1 // Really 1+2 results, incr. later.
1694 //| mov BASE, L:RB->base
1695 //| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
1696 //| add DISPATCH, GG_G2DISP
1697 //| mov PC, [BASE-4] // Fetch PC of previous frame.
1698 //| mov dword [BASE-4], LJ_TFALSE // Prepend false to error message.
1699 //| set_vmstate INTERP
1700 //| jmp ->vm_returnc // Increments RD/MULTRES and returns.
1701 //|
1702 //|//-----------------------------------------------------------------------
1703 //|//-- Grow stack for calls -----------------------------------------------
1704 //|//-----------------------------------------------------------------------
1705 //|
1706 //|->vm_growstack_c: // Grow stack for C function.
1707 //| mov FCARG2, LUA_MINSTACK
1708 //| jmp >2
1709 //|
1710 //|->vm_growstack_v: // Grow stack for vararg Lua function.
1711 //| sub RD, 8
1712 dasm_put(Dst, 275, CFRAME_RAWMASK, 1+1, Dt1(->base), Dt1(->glref), GG_G2DISP, LJ_TFALSE, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, LUA_MINSTACK);
1713#line 588 "vm_x86.dasc"
1714 //| jmp >1
1715 //|
1716 //|->vm_growstack_f: // Grow stack for fixarg Lua function.
1717 //| // BASE = new base, RD = nargs+1, RB = L, PC = first PC
1718 //| lea RD, [BASE+NARGS:RD*8-8]
1719 //|1:
1720 //| movzx RA, byte [PC-4+PC2PROTO(framesize)]
1721 //| add PC, 4 // Must point after first instruction.
1722 //| mov L:RB->base, BASE
1723 //| mov L:RB->top, RD
1724 //| mov SAVE_PC, PC
1725 //| mov FCARG2, RA
1726 //|2:
1727 //| // RB = L, L->base = new base, L->top = top
1728 //| mov FCARG1, L:RB
1729 //| call extern lj_state_growstack@8 // (lua_State *L, int n)
1730 //| mov BASE, L:RB->base
1731 //| mov RD, L:RB->top
1732 //| mov LFUNC:RB, [BASE-8]
1733 //| sub RD, BASE
1734 //| shr RD, 3
1735 //| add NARGS:RD, 1
1736 //| // BASE = new base, RB = LFUNC, RD = nargs+1
1737 //| ins_callt // Just retry the call.
1738 //|
1739 //|//-----------------------------------------------------------------------
1740 //|//-- Entry points into the assembler VM ---------------------------------
1741 //|//-----------------------------------------------------------------------
1742 //|
1743 //|->vm_resume: // Setup C frame and resume thread.
1744 //| // (lua_State *L, TValue *base, int nres1 = 0, ptrdiff_t ef = 0)
1745 //| saveregs
1746 //|.if X64
1747 //| mov L:RB, CARG1d // Caveat: CARG1d may be RA.
1748 //| mov SAVE_L, CARG1d
1749 //| mov RA, CARG2d
1750 //|.else
1751 //| mov L:RB, SAVE_L
1752 //| mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
1753 //|.endif
1754 //| mov PC, FRAME_CP
1755 //| xor RD, RD
1756 //| lea KBASEa, [esp+CFRAME_RESUME]
1757 //| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
1758 //| add DISPATCH, GG_G2DISP
1759 //| mov L:RB->cframe, KBASEa
1760 //| mov SAVE_PC, RD // Any value outside of bytecode is ok.
1761 //| mov SAVE_CFRAME, RDa
1762 //|.if X64
1763 //| mov SAVE_NRES, RD
1764 //| mov SAVE_ERRF, RD
1765 //|.endif
1766 //| cmp byte L:RB->status, RDL
1767 //| je >3 // Initial resume (like a call).
1768 //|
1769 //| // Resume after yield (like a return).
1770 //| set_vmstate INTERP
1771 dasm_put(Dst, 371, -4+PC2PROTO(framesize), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top), Dt7(->pc), FRAME_CP, CFRAME_RESUME, Dt1(->glref), GG_G2DISP, Dt1(->cframe), Dt1(->status));
1772#line 645 "vm_x86.dasc"
1773 //| mov byte L:RB->status, RDL
1774 //| mov BASE, L:RB->base
1775 //| mov RD, L:RB->top
1776 //| sub RD, RA
1777 //| shr RD, 3
1778 //| add RD, 1 // RD = nresults+1
1779 //| sub RA, BASE // RA = resultofs
1780 //| mov PC, [BASE-4]
1781 //| mov MULTRES, RD
1782 //| test PC, FRAME_TYPE
1783 //| jz ->BC_RET_Z
1784 //| jmp ->vm_return
1785 //|
1786 //|->vm_pcall: // Setup protected C frame and enter VM.
1787 //| // (lua_State *L, TValue *base, int nres1, ptrdiff_t ef)
1788 //| saveregs
1789 //| mov PC, FRAME_CP
1790 //|.if X64
1791 //| mov SAVE_ERRF, CARG4d
1792 //|.endif
1793 //| jmp >1
1794 //|
1795 //|->vm_call: // Setup C frame and enter VM.
1796 //| // (lua_State *L, TValue *base, int nres1)
1797 //| saveregs
1798 //| mov PC, FRAME_C
1799 //|
1800 //|1: // Entry point for vm_pcall above (PC = ftype).
1801 //|.if X64
1802 //| mov SAVE_NRES, CARG3d
1803 //| mov L:RB, CARG1d // Caveat: CARG1d may be RA.
1804 //| mov SAVE_L, CARG1d
1805 //| mov RA, CARG2d
1806 //|.else
1807 //| mov L:RB, SAVE_L
1808 //| mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
1809 //|.endif
1810 //|
1811 //| mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
1812 //| mov SAVE_CFRAME, KBASEa
1813 //| mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
1814 //|.if X64
1815 //| mov L:RB->cframe, rsp
1816 //|.else
1817 //| mov L:RB->cframe, esp
1818 //|.endif
1819 //|
1820 //|2: // Entry point for vm_cpcall below (RA = base, RB = L, PC = ftype).
1821 //| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
1822 dasm_put(Dst, 524, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->status), Dt1(->base), Dt1(->top), FRAME_TYPE, FRAME_CP, FRAME_C, Dt1(->cframe), Dt1(->cframe));
1823#line 694 "vm_x86.dasc"
1824 //| add DISPATCH, GG_G2DISP
1825 //|
1826 //|3: // Entry point for vm_resume above (RA = base, RB = L, PC = ftype).
1827 //| set_vmstate INTERP
1828 //| mov BASE, L:RB->base // BASE = old base (used in vmeta_call).
1829 //| add PC, RA
1830 //| sub PC, BASE // PC = frame delta + frame type
1831 //|
1832 //| mov RD, L:RB->top
1833 //| sub RD, RA
1834 //| shr NARGS:RD, 3
1835 //| add NARGS:RD, 1 // RD = nargs+1
1836 //|
1837 //|->vm_call_dispatch:
1838 //| mov LFUNC:RB, [RA-8]
1839 //| cmp dword [RA-4], LJ_TFUNC
1840 //| jne ->vmeta_call // Ensure KBASE defined and != BASE.
1841 //|
1842 //|->vm_call_dispatch_f:
1843 //| mov BASE, RA
1844 //| ins_call
1845 //| // BASE = new base, RB = func, RD = nargs+1, PC = caller PC
1846 //|
1847 //|->vm_cpcall: // Setup protected C frame, call C.
1848 //| // (lua_State *L, lua_CFunction func, void *ud, lua_CPFunction cp)
1849 //| saveregs
1850 //|.if X64
1851 //| mov L:RB, CARG1d // Caveat: CARG1d may be RA.
1852 //| mov SAVE_L, CARG1d
1853 //|.else
1854 //| mov L:RB, SAVE_L
1855 //| // Caveat: INARG_CP_* and SAVE_CFRAME/SAVE_NRES/SAVE_ERRF overlap!
1856 //| mov RC, INARG_CP_UD // Get args before they are overwritten.
1857 //| mov RA, INARG_CP_FUNC
1858 //| mov BASE, INARG_CP_CALL
1859 //|.endif
1860 //| mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
1861 //|
1862 //| mov KBASE, L:RB->stack // Compute -savestack(L, L->top).
1863 //| sub KBASE, L:RB->top
1864 //| mov SAVE_ERRF, 0 // No error function.
1865 //| mov SAVE_NRES, KBASE // Neg. delta means cframe w/o frame.
1866 //| // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe).
1867 //|
1868 //|.if X64
1869 //| mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
1870 //| mov SAVE_CFRAME, KBASEa
1871 //| mov L:RB->cframe, rsp
1872 //|
1873 //| call CARG4 // (lua_State *L, lua_CFunction func, void *ud)
1874 //|.else
1875 //| mov ARG3, RC // Have to copy args downwards.
1876 //| mov ARG2, RA
1877 //| mov ARG1, L:RB
1878 //|
1879 //| mov KBASE, L:RB->cframe // Add our C frame to cframe chain.
1880 //| mov SAVE_CFRAME, KBASE
1881 //| mov L:RB->cframe, esp
1882 //|
1883 //| call BASE // (lua_State *L, lua_CFunction func, void *ud)
1884 //|.endif
1885 //| // TValue * (new base) or NULL returned in eax (RC).
1886 //| test RC, RC
1887 //| jz ->vm_leave_cp // No base? Just remove C frame.
1888 //| mov RA, RC
1889 dasm_put(Dst, 642, Dt1(->glref), GG_G2DISP, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top), LJ_TFUNC, Dt7(->pc), Dt1(->stack), Dt1(->top), Dt1(->cframe), Dt1(->cframe));
1890#line 759 "vm_x86.dasc"
1891 //| mov PC, FRAME_CP
1892 //| jmp <2 // Else continue with the call.
1893 //|
1894 //|//-----------------------------------------------------------------------
1895 //|//-- Metamethod handling ------------------------------------------------
1896 //|//-----------------------------------------------------------------------
1897 //|
1898 //|//-- Continuation dispatch ----------------------------------------------
1899 //|
1900 //|->cont_dispatch:
1901 //| // BASE = meta base, RA = resultofs, RD = nresults+1 (also in MULTRES)
1902 //| add RA, BASE
1903 //| and PC, -8
1904 //| mov RB, BASE
1905 //| sub BASE, PC // Restore caller BASE.
1906 //| mov dword [RA+RD*8-4], LJ_TNIL // Ensure one valid arg.
1907 //| mov RC, RA // ... in [RC]
1908 //| mov PC, [RB-12] // Restore PC from [cont|PC].
1909 //|.if X64
1910 //| movsxd RAa, dword [RB-16] // May be negative on WIN64 with debug.
1911 //|.if FFI
1912 //| cmp RA, 1
1913 //| jbe >1
1914 //|.endif
1915 //| lea KBASEa, qword [=>0]
1916 //| add RAa, KBASEa
1917 //|.else
1918 //| mov RA, dword [RB-16]
1919 //|.if FFI
1920 //| cmp RA, 1
1921 //| jbe >1
1922 //|.endif
1923 //|.endif
1924 //| mov LFUNC:KBASE, [BASE-8]
1925 //| mov KBASE, LFUNC:KBASE->pc
1926 //| mov KBASE, [KBASE+PC2PROTO(k)]
1927 //| // BASE = base, RC = result, RB = meta base
1928 //| jmp RAa // Jump to continuation.
1929 //|
1930 //|.if FFI
1931 //|1:
1932 //| je ->cont_ffi_callback // cont = 1: return from FFI callback.
1933 //| // cont = 0: Tail call from C function.
1934 //| sub RB, BASE
1935 //| shr RB, 3
1936 //| lea RD, [RB-1]
1937 //| jmp ->vm_call_tail
1938 //|.endif
1939 //|
1940 //|->cont_cat: // BASE = base, RC = result, RB = mbase
1941 //| movzx RA, PC_RB
1942 //| sub RB, 16
1943 //| lea RA, [BASE+RA*8]
1944 //| sub RA, RB
1945 //| je ->cont_ra
1946 //| neg RA
1947 //| shr RA, 3
1948 //|.if X64WIN
1949 //| mov CARG3d, RA
1950 //| mov L:CARG1d, SAVE_L
1951 //| mov L:CARG1d->base, BASE
1952 //| mov RCa, [RC]
1953 //| mov [RB], RCa
1954 //| mov CARG2d, RB
1955 //|.elif X64
1956 //| mov L:CARG1d, SAVE_L
1957 //| mov L:CARG1d->base, BASE
1958 //| mov CARG3d, RA
1959 dasm_put(Dst, 788, FRAME_CP, LJ_TNIL, 0, Dt7(->pc), PC2PROTO(k), Dt1(->base));
1960#line 827 "vm_x86.dasc"
1961 //| mov RAa, [RC]
1962 //| mov [RB], RAa
1963 //| mov CARG2d, RB
1964 //|.else
1965 //| mov ARG3, RA
1966 //| mov RA, [RC+4]
1967 //| mov RC, [RC]
1968 //| mov [RB+4], RA
1969 //| mov [RB], RC
1970 //| mov ARG2, RB
1971 //|.endif
1972 //| jmp ->BC_CAT_Z
1973 //|
1974 //|//-- Table indexing metamethods -----------------------------------------
1975 //|
1976 //|->vmeta_tgets:
1977 //| mov TMP1, RC // RC = GCstr *
1978 //| mov TMP2, LJ_TSTR
1979 //| lea RCa, TMP1 // Store temp. TValue in TMP1/TMP2.
1980 //| cmp PC_OP, BC_GGET
1981 //| jne >1
1982 //| lea RA, [DISPATCH+DISPATCH_GL(tmptv)] // Store fn->l.env in g->tmptv.
1983 //| mov [RA], TAB:RB // RB = GCtab *
1984 //| mov dword [RA+4], LJ_TTAB
1985 //| mov RB, RA
1986 //| jmp >2
1987 //|
1988 //|->vmeta_tgetb:
1989 //| movzx RC, PC_RC
1990 //|.if DUALNUM
1991 //| mov TMP2, LJ_TISNUM
1992 //| mov TMP1, RC
1993 //|.elif SSE
1994 //| cvtsi2sd xmm0, RC
1995 //| movsd TMPQ, xmm0
1996 //|.else
1997 //| mov ARG4, RC
1998 //| fild ARG4
1999 //| fstp TMPQ
2000 //|.endif
2001 //| lea RCa, TMPQ // Store temp. TValue in TMPQ.
2002 //| jmp >1
2003 //|
2004 //|->vmeta_tgetv:
2005 //| movzx RC, PC_RC // Reload TValue *k from RC.
2006 //| lea RC, [BASE+RC*8]
2007 //|1:
2008 //| movzx RB, PC_RB // Reload TValue *t from RB.
2009 //| lea RB, [BASE+RB*8]
2010 //|2:
2011 //|.if X64
2012 //| mov L:CARG1d, SAVE_L
2013 //| mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
2014 //| mov CARG2d, RB
2015 //| mov CARG3, RCa // May be 64 bit ptr to stack.
2016 //| mov L:RB, L:CARG1d
2017 //|.else
2018 //| mov ARG2, RB
2019 //| mov L:RB, SAVE_L
2020 //| mov ARG3, RC
2021 //| mov ARG1, L:RB
2022 //| mov L:RB->base, BASE
2023 //|.endif
2024 //| mov SAVE_PC, PC
2025 //| call extern lj_meta_tget // (lua_State *L, TValue *o, TValue *k)
2026 //| // TValue * (finished) or NULL (metamethod) returned in eax (RC).
2027 //| mov BASE, L:RB->base
2028 //| test RC, RC
2029 //| jz >3
2030 //|->cont_ra: // BASE = base, RC = result
2031 //| movzx RA, PC_RA
2032 dasm_put(Dst, 913, LJ_TSTR, BC_GGET, DISPATCH_GL(tmptv), LJ_TTAB, Dt1(->base), Dt1(->base));
2033#line 898 "vm_x86.dasc"
2034 //|.if X64
2035 //| mov RBa, [RC]
2036 //| mov [BASE+RA*8], RBa
2037 //|.else
2038 //| mov RB, [RC+4]
2039 //| mov RC, [RC]
2040 //| mov [BASE+RA*8+4], RB
2041 //| mov [BASE+RA*8], RC
2042 //|.endif
2043 //| ins_next
2044 //|
2045 //|3: // Call __index metamethod.
2046 //| // BASE = base, L->top = new base, stack = cont/func/t/k
2047 //| mov RA, L:RB->top
2048 //| mov [RA-12], PC // [cont|PC]
2049 //| lea PC, [RA+FRAME_CONT]
2050 //| sub PC, BASE
2051 //| mov LFUNC:RB, [RA-8] // Guaranteed to be a function here.
2052 //| mov NARGS:RD, 2+1 // 2 args for func(t, k).
2053 //| jmp ->vm_call_dispatch_f
2054 //|
2055 //|//-----------------------------------------------------------------------
2056 //|
2057 //|->vmeta_tsets:
2058 //| mov TMP1, RC // RC = GCstr *
2059 //| mov TMP2, LJ_TSTR
2060 //| lea RCa, TMP1 // Store temp. TValue in TMP1/TMP2.
2061 //| cmp PC_OP, BC_GSET
2062 //| jne >1
2063 //| lea RA, [DISPATCH+DISPATCH_GL(tmptv)] // Store fn->l.env in g->tmptv.
2064 //| mov [RA], TAB:RB // RB = GCtab *
2065 //| mov dword [RA+4], LJ_TTAB
2066 //| mov RB, RA
2067 //| jmp >2
2068 //|
2069 //|->vmeta_tsetb:
2070 //| movzx RC, PC_RC
2071 //|.if DUALNUM
2072 //| mov TMP2, LJ_TISNUM
2073 //| mov TMP1, RC
2074 //|.elif SSE
2075 //| cvtsi2sd xmm0, RC
2076 //| movsd TMPQ, xmm0
2077 //|.else
2078 //| mov ARG4, RC
2079 //| fild ARG4
2080 //| fstp TMPQ
2081 //|.endif
2082 //| lea RCa, TMPQ // Store temp. TValue in TMPQ.
2083 //| jmp >1
2084 //|
2085 //|->vmeta_tsetv:
2086 //| movzx RC, PC_RC // Reload TValue *k from RC.
2087 //| lea RC, [BASE+RC*8]
2088 //|1:
2089 //| movzx RB, PC_RB // Reload TValue *t from RB.
2090 dasm_put(Dst, 1053, Dt1(->top), FRAME_CONT, 2+1, LJ_TSTR, BC_GSET, DISPATCH_GL(tmptv), LJ_TTAB);
2091#line 954 "vm_x86.dasc"
2092 //| lea RB, [BASE+RB*8]
2093 //|2:
2094 //|.if X64
2095 //| mov L:CARG1d, SAVE_L
2096 //| mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
2097 //| mov CARG2d, RB
2098 //| mov CARG3, RCa // May be 64 bit ptr to stack.
2099 //| mov L:RB, L:CARG1d
2100 //|.else
2101 //| mov ARG2, RB
2102 //| mov L:RB, SAVE_L
2103 //| mov ARG3, RC
2104 //| mov ARG1, L:RB
2105 //| mov L:RB->base, BASE
2106 //|.endif
2107 //| mov SAVE_PC, PC
2108 //| call extern lj_meta_tset // (lua_State *L, TValue *o, TValue *k)
2109 //| // TValue * (finished) or NULL (metamethod) returned in eax (RC).
2110 //| mov BASE, L:RB->base
2111 //| test RC, RC
2112 //| jz >3
2113 //| // NOBARRIER: lj_meta_tset ensures the table is not black.
2114 //| movzx RA, PC_RA
2115 //|.if X64
2116 //| mov RBa, [BASE+RA*8]
2117 //| mov [RC], RBa
2118 //|.else
2119 //| mov RB, [BASE+RA*8+4]
2120 //| mov RA, [BASE+RA*8]
2121 //| mov [RC+4], RB
2122 //| mov [RC], RA
2123 //|.endif
2124 //|->cont_nop: // BASE = base, (RC = result)
2125 //| ins_next
2126 //|
2127 //|3: // Call __newindex metamethod.
2128 //| // BASE = base, L->top = new base, stack = cont/func/t/k/(v)
2129 //| mov RA, L:RB->top
2130 //| mov [RA-12], PC // [cont|PC]
2131 //| movzx RC, PC_RA
2132 //| // Copy value to third argument.
2133 //|.if X64
2134 //| mov RBa, [BASE+RC*8]
2135 //| mov [RA+16], RBa
2136 //|.else
2137 //| mov RB, [BASE+RC*8+4]
2138 //| mov RC, [BASE+RC*8]
2139 //| mov [RA+20], RB
2140 //| mov [RA+16], RC
2141 //|.endif
2142 //| lea PC, [RA+FRAME_CONT]
2143 //| sub PC, BASE
2144 //| mov LFUNC:RB, [RA-8] // Guaranteed to be a function here.
2145 //| mov NARGS:RD, 3+1 // 3 args for func(t, k, v).
2146 //| jmp ->vm_call_dispatch_f
2147 //|
2148 //|//-- Comparison metamethods ---------------------------------------------
2149 //|
2150 //|->vmeta_comp:
2151 //|.if X64
2152 //| mov L:RB, SAVE_L
2153 //| mov L:RB->base, BASE // Caveat: CARG2d/CARG3d == BASE.
2154 //|.if X64WIN
2155 //| lea CARG3d, [BASE+RD*8]
2156 //| lea CARG2d, [BASE+RA*8]
2157 //|.else
2158 //| lea CARG2d, [BASE+RA*8]
2159 //| lea CARG3d, [BASE+RD*8]
2160 //|.endif
2161 //| mov CARG1d, L:RB // Caveat: CARG1d/CARG4d == RA.
2162 //| movzx CARG4d, PC_OP
2163 //|.else
2164 //| movzx RB, PC_OP
2165 //| lea RD, [BASE+RD*8]
2166 //| lea RA, [BASE+RA*8]
2167 //| mov ARG4, RB
2168 //| mov L:RB, SAVE_L
2169 //| mov ARG3, RD
2170 //| mov ARG2, RA
2171 //| mov ARG1, L:RB
2172 //| mov L:RB->base, BASE
2173 //|.endif
2174 //| mov SAVE_PC, PC
2175 //| call extern lj_meta_comp // (lua_State *L, TValue *o1, *o2, int op)
2176 //| // 0/1 or TValue * (metamethod) returned in eax (RC).
2177 //|3:
2178 //| mov BASE, L:RB->base
2179 //| cmp RC, 1
2180 //| ja ->vmeta_binop
2181 //|4:
2182 //| lea PC, [PC+4]
2183 //| jb >6
2184 //|5:
2185 //| movzx RD, PC_RD
2186 dasm_put(Dst, 1187, Dt1(->base), Dt1(->base), Dt1(->top), FRAME_CONT, 3+1, Dt1(->base), Dt1(->base));
2187#line 1048 "vm_x86.dasc"
2188 //| branchPC RD
2189 //|6:
2190 //| ins_next
2191 //|
2192 //|->cont_condt: // BASE = base, RC = result
2193 //| add PC, 4
2194 //| cmp dword [RC+4], LJ_TISTRUECOND // Branch if result is true.
2195 //| jb <5
2196 //| jmp <6
2197 //|
2198 //|->cont_condf: // BASE = base, RC = result
2199 //| cmp dword [RC+4], LJ_TISTRUECOND // Branch if result is false.
2200 //| jmp <4
2201 //|
2202 //|->vmeta_equal:
2203 //| sub PC, 4
2204 //|.if X64WIN
2205 //| mov CARG3d, RD
2206 //| mov CARG4d, RB
2207 //| mov L:RB, SAVE_L
2208 //| mov L:RB->base, BASE // Caveat: CARG2d == BASE.
2209 //| mov CARG2d, RA
2210 //| mov CARG1d, L:RB // Caveat: CARG1d == RA.
2211 //|.elif X64
2212 //| mov CARG2d, RA
2213 //| mov CARG4d, RB // Caveat: CARG4d == RA.
2214 //| mov L:RB, SAVE_L
2215 //| mov L:RB->base, BASE // Caveat: CARG3d == BASE.
2216 //| mov CARG3d, RD
2217 //| mov CARG1d, L:RB
2218 //|.else
2219 //| mov ARG4, RB
2220 //| mov L:RB, SAVE_L
2221 //| mov ARG3, RD
2222 //| mov ARG2, RA
2223 //| mov ARG1, L:RB
2224 //| mov L:RB->base, BASE
2225 //|.endif
2226 //| mov SAVE_PC, PC
2227 //| call extern lj_meta_equal // (lua_State *L, GCobj *o1, *o2, int ne)
2228 //| // 0/1 or TValue * (metamethod) returned in eax (RC).
2229 //| jmp <3
2230 //|
2231 //|->vmeta_equal_cd:
2232 //|.if FFI
2233 //| sub PC, 4
2234 //| mov L:RB, SAVE_L
2235 //| mov L:RB->base, BASE
2236 //| mov FCARG1, L:RB
2237 //| mov FCARG2, dword [PC-4]
2238 //| mov SAVE_PC, PC
2239 //| call extern lj_meta_equal_cd@8 // (lua_State *L, BCIns ins)
2240 //| // 0/1 or TValue * (metamethod) returned in eax (RC).
2241 //| jmp <3
2242 //|.endif
2243 //|
2244 //|//-- Arithmetic metamethods ---------------------------------------------
2245 //|
2246 //|->vmeta_arith_vno:
2247 //|.if DUALNUM
2248 //| movzx RB, PC_RB
2249 //|.endif
2250 //|->vmeta_arith_vn:
2251 //| lea RC, [KBASE+RC*8]
2252 dasm_put(Dst, 1358, -BCBIAS_J*4, LJ_TISTRUECOND, LJ_TISTRUECOND, Dt1(->base), Dt1(->base));
2253#line 1112 "vm_x86.dasc"
2254 //| jmp >1
2255 //|
2256 //|->vmeta_arith_nvo:
2257 //|.if DUALNUM
2258 //| movzx RC, PC_RC
2259 //|.endif
2260 //|->vmeta_arith_nv:
2261 //| lea RC, [KBASE+RC*8]
2262 //| lea RB, [BASE+RB*8]
2263 //| xchg RB, RC
2264 //| jmp >2
2265 //|
2266 //|->vmeta_unm:
2267 //| lea RC, [BASE+RD*8]
2268 //| mov RB, RC
2269 //| jmp >2
2270 //|
2271 //|->vmeta_arith_vvo:
2272 //|.if DUALNUM
2273 //| movzx RB, PC_RB
2274 //|.endif
2275 //|->vmeta_arith_vv:
2276 //| lea RC, [BASE+RC*8]
2277 //|1:
2278 //| lea RB, [BASE+RB*8]
2279 //|2:
2280 //| lea RA, [BASE+RA*8]
2281 //|.if X64WIN
2282 //| mov CARG3d, RB
2283 //| mov CARG4d, RC
2284 //| movzx RC, PC_OP
2285 //| mov ARG5d, RC
2286 //| mov L:RB, SAVE_L
2287 //| mov L:RB->base, BASE // Caveat: CARG2d == BASE.
2288 //| mov CARG2d, RA
2289 //| mov CARG1d, L:RB // Caveat: CARG1d == RA.
2290 //|.elif X64
2291 //| movzx CARG5d, PC_OP
2292 //| mov CARG2d, RA
2293 //| mov CARG4d, RC // Caveat: CARG4d == RA.
2294 //| mov L:CARG1d, SAVE_L
2295 //| mov L:CARG1d->base, BASE // Caveat: CARG3d == BASE.
2296 //| mov CARG3d, RB
2297 //| mov L:RB, L:CARG1d
2298 //|.else
2299 //| mov ARG3, RB
2300 //| mov L:RB, SAVE_L
2301 //| mov ARG4, RC
2302 //| movzx RC, PC_OP
2303 //| mov ARG2, RA
2304 //| mov ARG5, RC
2305 //| mov ARG1, L:RB
2306 //| mov L:RB->base, BASE
2307 //|.endif
2308 //| mov SAVE_PC, PC
2309 //| call extern lj_meta_arith // (lua_State *L, TValue *ra,*rb,*rc, BCReg op)
2310 //| // NULL (finished) or TValue * (metamethod) returned in eax (RC).
2311 //| mov BASE, L:RB->base
2312 //| test RC, RC
2313 //| jz ->cont_nop
2314 //|
2315 //| // Call metamethod for binary op.
2316 //|->vmeta_binop:
2317 //| // BASE = base, RC = new base, stack = cont/func/o1/o2
2318 //| mov RA, RC
2319 //| sub RC, BASE
2320 //| mov [RA-12], PC // [cont|PC]
2321 //| lea PC, [RC+FRAME_CONT]
2322 //| mov NARGS:RD, 2+1 // 2 args for func(o1, o2).
2323 //| jmp ->vm_call_dispatch
2324 dasm_put(Dst, 1491, Dt1(->base), Dt1(->base), FRAME_CONT, 2+1);
2325#line 1182 "vm_x86.dasc"
2326 //|
2327 //|->vmeta_len:
2328 //| mov L:RB, SAVE_L
2329 //| mov L:RB->base, BASE
2330 //| lea FCARG2, [BASE+RD*8] // Caveat: FCARG2 == BASE
2331 //| mov L:FCARG1, L:RB
2332 //| mov SAVE_PC, PC
2333 //| call extern lj_meta_len@8 // (lua_State *L, TValue *o)
2334 //| // NULL (retry) or TValue * (metamethod) returned in eax (RC).
2335 //| mov BASE, L:RB->base
2336 dasm_put(Dst, 1601, Dt1(->base), Dt1(->base));
2337#line 1192 "vm_x86.dasc"
2338#if LJ_52
2339 //| test RC, RC
2340 //| jne ->vmeta_binop // Binop call for compatibility.
2341 //| movzx RD, PC_RD
2342 //| mov TAB:FCARG1, [BASE+RD*8]
2343 //| jmp ->BC_LEN_Z
2344 dasm_put(Dst, 1632);
2345#line 1198 "vm_x86.dasc"
2346#else
2347 //| jmp ->vmeta_binop // Binop call for compatibility.
2348 dasm_put(Dst, 1651);
2349#line 1200 "vm_x86.dasc"
2350#endif
2351 //|
2352 //|//-- Call metamethod ----------------------------------------------------
2353 //|
2354 //|->vmeta_call_ra:
2355 //| lea RA, [BASE+RA*8+8]
2356 //|->vmeta_call: // Resolve and call __call metamethod.
2357 //| // BASE = old base, RA = new base, RC = nargs+1, PC = return
2358 //| mov TMP2, RA // Save RA, RC for us.
2359 //| mov TMP1, NARGS:RD
2360 //| sub RA, 8
2361 //|.if X64
2362 //| mov L:RB, SAVE_L
2363 //| mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
2364 //| mov CARG2d, RA
2365 //| lea CARG3d, [RA+NARGS:RD*8]
2366 //| mov CARG1d, L:RB // Caveat: CARG1d may be RA.
2367 //|.else
2368 //| lea RC, [RA+NARGS:RD*8]
2369 //| mov L:RB, SAVE_L
2370 //| mov ARG2, RA
2371 //| mov ARG3, RC
2372 //| mov ARG1, L:RB
2373 //| mov L:RB->base, BASE // This is the callers base!
2374 //|.endif
2375 //| mov SAVE_PC, PC
2376 //| call extern lj_meta_call // (lua_State *L, TValue *func, TValue *top)
2377 //| mov BASE, L:RB->base
2378 //| mov RA, TMP2
2379 //| mov NARGS:RD, TMP1
2380 //| mov LFUNC:RB, [RA-8]
2381 //| add NARGS:RD, 1
2382 //| // This is fragile. L->base must not move, KBASE must always be defined.
2383 //| cmp KBASE, BASE // Continue with CALLT if flag set.
2384 //| je ->BC_CALLT_Z
2385 //| mov BASE, RA
2386 //| ins_call // Otherwise call resolved metamethod.
2387 //|
2388 //|//-- Argument coercion for 'for' statement ------------------------------
2389 //|
2390 //|->vmeta_for:
2391 //| mov L:RB, SAVE_L
2392 //| mov L:RB->base, BASE
2393 //| mov FCARG2, RA // Caveat: FCARG2 == BASE
2394 //| mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
2395 //| mov SAVE_PC, PC
2396 //| call extern lj_meta_for@8 // (lua_State *L, TValue *base)
2397 //| mov BASE, L:RB->base
2398 //| mov RC, [PC-4]
2399 //| movzx RA, RCH
2400 //| movzx OP, RCL
2401 //| shr RC, 16
2402 //|.if X64
2403 //| jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Retry FORI or JFORI.
2404 //|.else
2405 //| jmp aword [DISPATCH+OP*4+GG_DISP2STATIC] // Retry FORI or JFORI.
2406 //|.endif
2407 //|
2408 //|//-----------------------------------------------------------------------
2409 //|//-- Fast functions -----------------------------------------------------
2410 //|//-----------------------------------------------------------------------
2411 //|
2412 //|.macro .ffunc, name
2413 //|->ff_ .. name:
2414 //|.endmacro
2415 //|
2416 //|.macro .ffunc_1, name
2417 //|->ff_ .. name:
2418 //| cmp NARGS:RD, 1+1; jb ->fff_fallback
2419 //|.endmacro
2420 //|
2421 //|.macro .ffunc_2, name
2422 //|->ff_ .. name:
2423 //| cmp NARGS:RD, 2+1; jb ->fff_fallback
2424 //|.endmacro
2425 //|
2426 //|.macro .ffunc_n, name
2427 //| .ffunc_1 name
2428 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2429 //| fld qword [BASE]
2430 //|.endmacro
2431 //|
2432 //|.macro .ffunc_n, name, op
2433 //| .ffunc_1 name
2434 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2435 //| op
2436 //| fld qword [BASE]
2437 //|.endmacro
2438 //|
2439 //|.macro .ffunc_nsse, name, op
2440 //| .ffunc_1 name
2441 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2442 //| op xmm0, qword [BASE]
2443 //|.endmacro
2444 //|
2445 //|.macro .ffunc_nsse, name
2446 //| .ffunc_nsse name, movsd
2447 //|.endmacro
2448 //|
2449 //|.macro .ffunc_nn, name
2450 //| .ffunc_2 name
2451 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2452 //| cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
2453 //| fld qword [BASE]
2454 //| fld qword [BASE+8]
2455 //|.endmacro
2456 //|
2457 //|.macro .ffunc_nnsse, name
2458 //| .ffunc_2 name
2459 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2460 //| cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
2461 //| movsd xmm0, qword [BASE]
2462 //| movsd xmm1, qword [BASE+8]
2463 //|.endmacro
2464 //|
2465 //|.macro .ffunc_nnr, name
2466 //| .ffunc_2 name
2467 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
2468 //| cmp dword [BASE+12], LJ_TISNUM; jae ->fff_fallback
2469 //| fld qword [BASE+8]
2470 //| fld qword [BASE]
2471 //|.endmacro
2472 //|
2473 //|// Inlined GC threshold check. Caveat: uses label 1.
2474 //|.macro ffgccheck
2475 //| mov RB, [DISPATCH+DISPATCH_GL(gc.total)]
2476 //| cmp RB, [DISPATCH+DISPATCH_GL(gc.threshold)]
2477 //| jb >1
2478 //| call ->fff_gcstep
2479 //|1:
2480 //|.endmacro
2481 //|
2482 //|//-- Base library: checks -----------------------------------------------
2483 //|
2484 //|.ffunc_1 assert
2485 //| mov RB, [BASE+4]
2486 //| cmp RB, LJ_TISTRUECOND; jae ->fff_fallback
2487 //| mov PC, [BASE-4]
2488 //| mov MULTRES, RD
2489 //| mov [BASE-4], RB
2490 //| mov RB, [BASE]
2491 //| mov [BASE-8], RB
2492 //| sub RD, 2
2493 //| jz >2
2494 //| mov RA, BASE
2495 dasm_put(Dst, 1656, Dt1(->base), Dt1(->base), Dt7(->pc), Dt1(->base), Dt1(->base), GG_DISP2STATIC, 1+1, LJ_TISTRUECOND);
2496#line 1345 "vm_x86.dasc"
2497 //|1:
2498 //| add RA, 8
2499 //|.if X64
2500 //| mov RBa, [RA]
2501 //| mov [RA-8], RBa
2502 //|.else
2503 //| mov RB, [RA+4]
2504 //| mov [RA-4], RB
2505 //| mov RB, [RA]
2506 //| mov [RA-8], RB
2507 //|.endif
2508 //| sub RD, 1
2509 //| jnz <1
2510 //|2:
2511 //| mov RD, MULTRES
2512 //| jmp ->fff_res_
2513 //|
2514 //|.ffunc_1 type
2515 //| mov RB, [BASE+4]
2516 //|.if X64
2517 //| mov RA, RB
2518 //| sar RA, 15
2519 //| cmp RA, -2
2520 //| je >3
2521 //|.endif
2522 //| mov RC, ~LJ_TNUMX
2523 //| not RB
2524 //| cmp RC, RB
2525 //| cmova RC, RB
2526 //|2:
2527 //| mov CFUNC:RB, [BASE-8]
2528 //| mov STR:RC, [CFUNC:RB+RC*8+((char *)(&((GCfuncC *)0)->upvalue))]
2529 //| mov PC, [BASE-4]
2530 //| mov dword [BASE-4], LJ_TSTR
2531 //| mov [BASE-8], STR:RC
2532 //| jmp ->fff_res1
2533 //|.if X64
2534 //|3:
2535 //| mov RC, ~LJ_TLIGHTUD
2536 //| jmp <2
2537 dasm_put(Dst, 1842, 1+1, ~LJ_TNUMX, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, ~LJ_TLIGHTUD);
2538#line 1385 "vm_x86.dasc"
2539 //|.endif
2540 //|
2541 //|//-- Base library: getters and setters ---------------------------------
2542 //|
2543 //|.ffunc_1 getmetatable
2544 //| mov RB, [BASE+4]
2545 //| mov PC, [BASE-4]
2546 //| cmp RB, LJ_TTAB; jne >6
2547 //|1: // Field metatable must be at same offset for GCtab and GCudata!
2548 //| mov TAB:RB, [BASE]
2549 //| mov TAB:RB, TAB:RB->metatable
2550 //|2:
2551 //| test TAB:RB, TAB:RB
2552 //| mov dword [BASE-4], LJ_TNIL
2553 //| jz ->fff_res1
2554 //| mov STR:RC, [DISPATCH+DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable)]
2555 //| mov dword [BASE-4], LJ_TTAB // Store metatable as default result.
2556 //| mov [BASE-8], TAB:RB
2557 //| mov RA, TAB:RB->hmask
2558 //| and RA, STR:RC->hash
2559 //| imul RA, #NODE
2560 //| add NODE:RA, TAB:RB->node
2561 dasm_put(Dst, 1946, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node));
2562#line 1407 "vm_x86.dasc"
2563 //|3: // Rearranged logic, because we expect _not_ to find the key.
2564 //| cmp dword NODE:RA->key.it, LJ_TSTR
2565 //| jne >4
2566 //| cmp dword NODE:RA->key.gcr, STR:RC
2567 //| je >5
2568 //|4:
2569 //| mov NODE:RA, NODE:RA->next
2570 //| test NODE:RA, NODE:RA
2571 //| jnz <3
2572 //| jmp ->fff_res1 // Not found, keep default result.
2573 //|5:
2574 //| mov RB, [RA+4]
2575 //| cmp RB, LJ_TNIL; je ->fff_res1 // Ditto for nil value.
2576 //| mov RC, [RA]
2577 //| mov [BASE-4], RB // Return value of mt.__metatable.
2578 //| mov [BASE-8], RC
2579 //| jmp ->fff_res1
2580 //|
2581 //|6:
2582 //| cmp RB, LJ_TUDATA; je <1
2583 dasm_put(Dst, 2019, Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next), LJ_TNIL);
2584#line 1427 "vm_x86.dasc"
2585 //|.if X64
2586 //| cmp RB, LJ_TNUMX; ja >8
2587 //| cmp RB, LJ_TISNUM; jbe >7
2588 //| mov RB, LJ_TLIGHTUD
2589 //| jmp >8
2590 //|7:
2591 //|.else
2592 //| cmp RB, LJ_TISNUM; ja >8
2593 //|.endif
2594 //| mov RB, LJ_TNUMX
2595 //|8:
2596 //| not RB
2597 //| mov TAB:RB, [DISPATCH+RB*4+DISPATCH_GL(gcroot[GCROOT_BASEMT])]
2598 //| jmp <2
2599 //|
2600 //|.ffunc_2 setmetatable
2601 dasm_put(Dst, 2084, LJ_TUDATA, LJ_TNUMX, LJ_TISNUM, LJ_TLIGHTUD, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]), 2+1);
2602#line 1443 "vm_x86.dasc"
2603 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2604 //| // Fast path: no mt for table yet and not clearing the mt.
2605 //| mov TAB:RB, [BASE]
2606 //| cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
2607 //| cmp dword [BASE+12], LJ_TTAB; jne ->fff_fallback
2608 //| mov TAB:RC, [BASE+8]
2609 //| mov TAB:RB->metatable, TAB:RC
2610 //| mov PC, [BASE-4]
2611 //| mov dword [BASE-4], LJ_TTAB // Return original table.
2612 //| mov [BASE-8], TAB:RB
2613 //| test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
2614 //| jz >1
2615 //| // Possible write barrier. Table is black, but skip iswhite(mt) check.
2616 //| barrierback TAB:RB, RC
2617 dasm_put(Dst, 2140, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain));
2618#line 1457 "vm_x86.dasc"
2619 //|1:
2620 //| jmp ->fff_res1
2621 //|
2622 //|.ffunc_2 rawget
2623 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2624 //|.if X64WIN
2625 //| mov RB, BASE // Save BASE.
2626 //| lea CARG3d, [BASE+8]
2627 //| mov CARG2d, [BASE] // Caveat: CARG2d == BASE.
2628 //| mov CARG1d, SAVE_L
2629 //|.elif X64
2630 //| mov RB, BASE // Save BASE.
2631 //| mov CARG2d, [BASE]
2632 //| lea CARG3d, [BASE+8] // Caveat: CARG3d == BASE.
2633 //| mov CARG1d, SAVE_L
2634 //|.else
2635 //| mov TAB:RD, [BASE]
2636 //| mov L:RB, SAVE_L
2637 //| mov ARG2, TAB:RD
2638 //| mov ARG1, L:RB
2639 //| mov RB, BASE // Save BASE.
2640 //| add BASE, 8
2641 //| mov ARG3, BASE
2642 //|.endif
2643 //| call extern lj_tab_get // (lua_State *L, GCtab *t, cTValue *key)
2644 //| // cTValue * returned in eax (RD).
2645 //| mov BASE, RB // Restore BASE.
2646 //| // Copy table slot.
2647 //|.if X64
2648 //| mov RBa, [RD]
2649 //| mov PC, [BASE-4]
2650 //| mov [BASE-8], RBa
2651 //|.else
2652 //| mov RB, [RD]
2653 //| mov RD, [RD+4]
2654 //| mov PC, [BASE-4]
2655 //| mov [BASE-8], RB
2656 //| mov [BASE-4], RD
2657 //|.endif
2658 //| jmp ->fff_res1
2659 //|
2660 //|//-- Base library: conversions ------------------------------------------
2661 //|
2662 //|.ffunc tonumber
2663 //| // Only handles the number case inline (without a base argument).
2664 //| cmp NARGS:RD, 1+1; jne ->fff_fallback // Exactly one argument.
2665 //| cmp dword [BASE+4], LJ_TISNUM
2666 //|.if DUALNUM
2667 //| jne >1
2668 //| mov RB, dword [BASE]; jmp ->fff_resi
2669 //|1:
2670 //| ja ->fff_fallback
2671 //|.else
2672 //| jae ->fff_fallback
2673 //|.endif
2674 //|.if SSE
2675 //| movsd xmm0, qword [BASE]; jmp ->fff_resxmm0
2676 dasm_put(Dst, 2209, DISPATCH_GL(gc.grayagain), Dt6(->gclist), 2+1, LJ_TTAB, 1+1, LJ_TISNUM);
2677#line 1514 "vm_x86.dasc"
2678 //|.else
2679 //| fld qword [BASE]; jmp ->fff_resn
2680 //|.endif
2681 //|
2682 //|.ffunc_1 tostring
2683 //| // Only handles the string or number case inline.
2684 //| mov PC, [BASE-4]
2685 //| cmp dword [BASE+4], LJ_TSTR; jne >3
2686 //| // A __tostring method in the string base metatable is ignored.
2687 //| mov STR:RD, [BASE]
2688 //|2:
2689 //| mov dword [BASE-4], LJ_TSTR
2690 //| mov [BASE-8], STR:RD
2691 //| jmp ->fff_res1
2692 //|3: // Handle numbers inline, unless a number base metatable is present.
2693 //| cmp dword [BASE+4], LJ_TISNUM; ja ->fff_fallback
2694 //| cmp dword [DISPATCH+DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM])], 0
2695 //| jne ->fff_fallback
2696 //| ffgccheck // Caveat: uses label 1.
2697 dasm_put(Dst, 2295, 1+1, LJ_TSTR, LJ_TSTR, LJ_TISNUM, DISPATCH_GL(gcroot[GCROOT_BASEMT_NUM]));
2698#line 1533 "vm_x86.dasc"
2699 //| mov L:RB, SAVE_L
2700 //| mov L:RB->base, BASE // Add frame since C call can throw.
2701 //| mov SAVE_PC, PC // Redundant (but a defined value).
2702 //|.if X64 and not X64WIN
2703 //| mov FCARG2, BASE // Otherwise: FCARG2 == BASE
2704 //|.endif
2705 //| mov L:FCARG1, L:RB
2706 //|.if DUALNUM
2707 //| call extern lj_str_fromnumber@8 // (lua_State *L, cTValue *o)
2708 //|.else
2709 //| call extern lj_str_fromnum@8 // (lua_State *L, lua_Number *np)
2710 //|.endif
2711 //| // GCstr returned in eax (RD).
2712 //| mov BASE, L:RB->base
2713 //| jmp <2
2714 //|
2715 //|//-- Base library: iterators -------------------------------------------
2716 //|
2717 //|.ffunc_1 next
2718 //| je >2 // Missing 2nd arg?
2719 //|1:
2720 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2721 //| mov L:RB, SAVE_L
2722 dasm_put(Dst, 2365, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), 1+1, LJ_TTAB);
2723#line 1556 "vm_x86.dasc"
2724 //| mov L:RB->base, BASE // Add frame since C call can throw.
2725 //| mov L:RB->top, BASE // Dummy frame length is ok.
2726 //| mov PC, [BASE-4]
2727 //|.if X64WIN
2728 //| lea CARG3d, [BASE+8]
2729 //| mov CARG2d, [BASE] // Caveat: CARG2d == BASE.
2730 //| mov CARG1d, L:RB
2731 //|.elif X64
2732 //| mov CARG2d, [BASE]
2733 //| lea CARG3d, [BASE+8] // Caveat: CARG3d == BASE.
2734 //| mov CARG1d, L:RB
2735 //|.else
2736 //| mov TAB:RD, [BASE]
2737 //| mov ARG2, TAB:RD
2738 //| mov ARG1, L:RB
2739 //| add BASE, 8
2740 //| mov ARG3, BASE
2741 //|.endif
2742 //| mov SAVE_PC, PC // Needed for ITERN fallback.
2743 //| call extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
2744 //| // Flag returned in eax (RD).
2745 //| mov BASE, L:RB->base
2746 //| test RD, RD; jz >3 // End of traversal?
2747 //| // Copy key and value to results.
2748 //|.if X64
2749 //| mov RBa, [BASE+8]
2750 //| mov RDa, [BASE+16]
2751 //| mov [BASE-8], RBa
2752 //| mov [BASE], RDa
2753 //|.else
2754 //| mov RB, [BASE+8]
2755 //| mov RD, [BASE+12]
2756 //| mov [BASE-8], RB
2757 //| mov [BASE-4], RD
2758 //| mov RB, [BASE+16]
2759 //| mov RD, [BASE+20]
2760 //| mov [BASE], RB
2761 //| mov [BASE+4], RD
2762 //|.endif
2763 //|->fff_res2:
2764 //| mov RD, 1+2
2765 //| jmp ->fff_res
2766 //|2: // Set missing 2nd arg to nil.
2767 //| mov dword [BASE+12], LJ_TNIL
2768 //| jmp <1
2769 //|3: // End of traversal: return nil.
2770 //| mov dword [BASE-4], LJ_TNIL
2771 //| jmp ->fff_res1
2772 //|
2773 //|.ffunc_1 pairs
2774 //| mov TAB:RB, [BASE]
2775 dasm_put(Dst, 2435, Dt1(->base), Dt1(->top), Dt1(->base), 1+2, LJ_TNIL, LJ_TNIL, 1+1);
2776#line 1607 "vm_x86.dasc"
2777 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2778 dasm_put(Dst, 2530, LJ_TTAB);
2779#line 1608 "vm_x86.dasc"
2780#if LJ_52
2781 //| cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
2782 dasm_put(Dst, 2542, Dt6(->metatable));
2783#line 1610 "vm_x86.dasc"
2784#endif
2785 //| mov CFUNC:RB, [BASE-8]
2786 //| mov CFUNC:RD, CFUNC:RB->upvalue[0]
2787 //| mov PC, [BASE-4]
2788 //| mov dword [BASE-4], LJ_TFUNC
2789 //| mov [BASE-8], CFUNC:RD
2790 //| mov dword [BASE+12], LJ_TNIL
2791 //| mov RD, 1+3
2792 //| jmp ->fff_res
2793 //|
2794 //|.ffunc_1 ipairs_aux
2795 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2796 //| cmp dword [BASE+12], LJ_TISNUM
2797 //|.if DUALNUM
2798 //| jne ->fff_fallback
2799 //|.else
2800 //| jae ->fff_fallback
2801 //|.endif
2802 //| mov PC, [BASE-4]
2803 //|.if DUALNUM
2804 //| mov RD, dword [BASE+8]
2805 //| add RD, 1
2806 //| mov dword [BASE-4], LJ_TISNUM
2807 //| mov dword [BASE-8], RD
2808 //|.elif SSE
2809 //| movsd xmm0, qword [BASE+8]
2810 //| sseconst_1 xmm1, RBa
2811 //| addsd xmm0, xmm1
2812 //| cvtsd2si RD, xmm0
2813 //| movsd qword [BASE-8], xmm0
2814 //|.else
2815 //| fld qword [BASE+8]
2816 //| fld1
2817 //| faddp st1
2818 //| fist ARG1
2819 //| fstp qword [BASE-8]
2820 //| mov RD, ARG1
2821 //|.endif
2822 //| mov TAB:RB, [BASE]
2823 //| cmp RD, TAB:RB->asize; jae >2 // Not in array part?
2824 //| shl RD, 3
2825 dasm_put(Dst, 2551, Dt8(->upvalue[0]), LJ_TFUNC, LJ_TNIL, 1+3, 1+1, LJ_TTAB, LJ_TISNUM, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), Dt6(->asize));
2826#line 1651 "vm_x86.dasc"
2827 //| add RD, TAB:RB->array
2828 //|1:
2829 //| cmp dword [RD+4], LJ_TNIL; je ->fff_res0
2830 //| // Copy array slot.
2831 //|.if X64
2832 //| mov RBa, [RD]
2833 //| mov [BASE], RBa
2834 //|.else
2835 //| mov RB, [RD]
2836 //| mov RD, [RD+4]
2837 //| mov [BASE], RB
2838 //| mov [BASE+4], RD
2839 //|.endif
2840 //| jmp ->fff_res2
2841 //|2: // Check for empty hash part first. Otherwise call C function.
2842 //| cmp dword TAB:RB->hmask, 0; je ->fff_res0
2843 //| mov FCARG1, TAB:RB
2844 //| mov RB, BASE // Save BASE.
2845 //| mov FCARG2, RD // Caveat: FCARG2 == BASE
2846 //| call extern lj_tab_getinth@8 // (GCtab *t, int32_t key)
2847 //| // cTValue * or NULL returned in eax (RD).
2848 //| mov BASE, RB
2849 //| test RD, RD
2850 //| jnz <1
2851 //|->fff_res0:
2852 //| mov RD, 1+0
2853 //| jmp ->fff_res
2854 //|
2855 //|.ffunc_1 ipairs
2856 //| mov TAB:RB, [BASE]
2857 dasm_put(Dst, 2655, Dt6(->array), LJ_TNIL, Dt6(->hmask), 1+0, 1+1);
2858#line 1681 "vm_x86.dasc"
2859 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
2860 dasm_put(Dst, 2530, LJ_TTAB);
2861#line 1682 "vm_x86.dasc"
2862#if LJ_52
2863 //| cmp dword TAB:RB->metatable, 0; jne ->fff_fallback
2864 dasm_put(Dst, 2542, Dt6(->metatable));
2865#line 1684 "vm_x86.dasc"
2866#endif
2867 //| mov CFUNC:RB, [BASE-8]
2868 //| mov CFUNC:RD, CFUNC:RB->upvalue[0]
2869 //| mov PC, [BASE-4]
2870 //| mov dword [BASE-4], LJ_TFUNC
2871 //| mov [BASE-8], CFUNC:RD
2872 //|.if DUALNUM
2873 //| mov dword [BASE+12], LJ_TISNUM
2874 //| mov dword [BASE+8], 0
2875 //|.elif SSE
2876 //| xorps xmm0, xmm0
2877 //| movsd qword [BASE+8], xmm0
2878 //|.else
2879 //| fldz
2880 //| fstp qword [BASE+8]
2881 //|.endif
2882 //| mov RD, 1+3
2883 //| jmp ->fff_res
2884 //|
2885 //|//-- Base library: catch errors ----------------------------------------
2886 //|
2887 //|.ffunc_1 pcall
2888 //| lea RA, [BASE+8]
2889 //| sub NARGS:RD, 1
2890 //| mov PC, 8+FRAME_PCALL
2891 //|1:
2892 //| movzx RB, byte [DISPATCH+DISPATCH_GL(hookmask)]
2893 //| shr RB, HOOK_ACTIVE_SHIFT
2894 //| and RB, 1
2895 //| add PC, RB // Remember active hook before pcall.
2896 //| jmp ->vm_call_dispatch
2897 //|
2898 //|.ffunc_2 xpcall
2899 //| cmp dword [BASE+12], LJ_TFUNC; jne ->fff_fallback
2900 dasm_put(Dst, 2731, Dt8(->upvalue[0]), LJ_TFUNC, 1+3, 1+1, 8+FRAME_PCALL, DISPATCH_GL(hookmask), HOOK_ACTIVE_SHIFT, 2+1, LJ_TFUNC);
2901#line 1718 "vm_x86.dasc"
2902 //| mov RB, [BASE+4] // Swap function and traceback.
2903 //| mov [BASE+12], RB
2904 //| mov dword [BASE+4], LJ_TFUNC
2905 //| mov LFUNC:RB, [BASE]
2906 //| mov PC, [BASE+8]
2907 //| mov [BASE+8], LFUNC:RB
2908 //| mov [BASE], PC
2909 //| lea RA, [BASE+16]
2910 //| sub NARGS:RD, 2
2911 //| mov PC, 16+FRAME_PCALL
2912 //| jmp <1
2913 //|
2914 //|//-- Coroutine library --------------------------------------------------
2915 //|
2916 //|.macro coroutine_resume_wrap, resume
2917 //|.if resume
2918 //|.ffunc_1 coroutine_resume
2919 //| mov L:RB, [BASE]
2920 //|.else
2921 //|.ffunc coroutine_wrap_aux
2922 //| mov CFUNC:RB, [BASE-8]
2923 //| mov L:RB, CFUNC:RB->upvalue[0].gcr
2924 //|.endif
2925 //| mov PC, [BASE-4]
2926 //| mov SAVE_PC, PC
2927 //|.if X64
2928 //| mov TMP1, L:RB
2929 //|.else
2930 //| mov ARG1, L:RB
2931 //|.endif
2932 //|.if resume
2933 //| cmp dword [BASE+4], LJ_TTHREAD; jne ->fff_fallback
2934 //|.endif
2935 //| cmp aword L:RB->cframe, 0; jne ->fff_fallback
2936 //| cmp byte L:RB->status, LUA_YIELD; ja ->fff_fallback
2937 //| mov RA, L:RB->top
2938 //| je >1 // Status != LUA_YIELD (i.e. 0)?
2939 //| cmp RA, L:RB->base // Check for presence of initial func.
2940 //| je ->fff_fallback
2941 //|1:
2942 //|.if resume
2943 //| lea PC, [RA+NARGS:RD*8-16] // Check stack space (-1-thread).
2944 //|.else
2945 //| lea PC, [RA+NARGS:RD*8-8] // Check stack space (-1).
2946 //|.endif
2947 //| cmp PC, L:RB->maxstack; ja ->fff_fallback
2948 //| mov L:RB->top, PC
2949 //|
2950 //| mov L:RB, SAVE_L
2951 //| mov L:RB->base, BASE
2952 //|.if resume
2953 //| add BASE, 8 // Keep resumed thread in stack for GC.
2954 //|.endif
2955 //| mov L:RB->top, BASE
2956 //|.if resume
2957 //| lea RB, [BASE+NARGS:RD*8-24] // RB = end of source for stack move.
2958 //|.else
2959 //| lea RB, [BASE+NARGS:RD*8-16] // RB = end of source for stack move.
2960 //|.endif
2961 //| sub RBa, PCa // Relative to PC.
2962 //|
2963 //| cmp PC, RA
2964 //| je >3
2965 //|2: // Move args to coroutine.
2966 //|.if X64
2967 //| mov RCa, [PC+RB]
2968 //| mov [PC-8], RCa
2969 //|.else
2970 //| mov RC, [PC+RB+4]
2971 //| mov [PC-4], RC
2972 //| mov RC, [PC+RB]
2973 //| mov [PC-8], RC
2974 //|.endif
2975 //| sub PC, 8
2976 //| cmp PC, RA
2977 //| jne <2
2978 //|3:
2979 //|.if X64
2980 //| mov CARG2d, RA
2981 //| mov CARG1d, TMP1
2982 //|.else
2983 //| mov ARG2, RA
2984 //| xor RA, RA
2985 //| mov ARG4, RA
2986 //| mov ARG3, RA
2987 //|.endif
2988 //| call ->vm_resume // (lua_State *L, TValue *base, 0, 0)
2989 //| set_vmstate INTERP
2990 //|
2991 //| mov L:RB, SAVE_L
2992 //|.if X64
2993 //| mov L:PC, TMP1
2994 //|.else
2995 //| mov L:PC, ARG1 // The callee doesn't modify SAVE_L.
2996 //|.endif
2997 //| mov BASE, L:RB->base
2998 //| cmp eax, LUA_YIELD
2999 //| ja >8
3000 //|4:
3001 //| mov RA, L:PC->base
3002 //| mov KBASE, L:PC->top
3003 //| mov L:PC->top, RA // Clear coroutine stack.
3004 //| mov PC, KBASE
3005 //| sub PC, RA
3006 //| je >6 // No results?
3007 //| lea RD, [BASE+PC]
3008 //| shr PC, 3
3009 //| cmp RD, L:RB->maxstack
3010 //| ja >9 // Need to grow stack?
3011 //|
3012 //| mov RB, BASE
3013 //| sub RBa, RAa
3014 //|5: // Move results from coroutine.
3015 //|.if X64
3016 //| mov RDa, [RA]
3017 //| mov [RA+RB], RDa
3018 //|.else
3019 //| mov RD, [RA]
3020 //| mov [RA+RB], RD
3021 //| mov RD, [RA+4]
3022 //| mov [RA+RB+4], RD
3023 //|.endif
3024 //| add RA, 8
3025 //| cmp RA, KBASE
3026 //| jne <5
3027 //|6:
3028 //|.if resume
3029 //| lea RD, [PC+2] // nresults+1 = 1 + true + results.
3030 //| mov dword [BASE-4], LJ_TTRUE // Prepend true to results.
3031 //|.else
3032 //| lea RD, [PC+1] // nresults+1 = 1 + results.
3033 //|.endif
3034 //|7:
3035 //| mov PC, SAVE_PC
3036 //| mov MULTRES, RD
3037 //|.if resume
3038 //| mov RAa, -8
3039 //|.else
3040 //| xor RA, RA
3041 //|.endif
3042 //| test PC, FRAME_TYPE
3043 //| jz ->BC_RET_Z
3044 //| jmp ->vm_return
3045 //|
3046 //|8: // Coroutine returned with error (at co->top-1).
3047 //|.if resume
3048 //| mov dword [BASE-4], LJ_TFALSE // Prepend false to results.
3049 //| mov RA, L:PC->top
3050 //| sub RA, 8
3051 //| mov L:PC->top, RA // Clear error from coroutine stack.
3052 //| // Copy error message.
3053 //|.if X64
3054 //| mov RDa, [RA]
3055 //| mov [BASE], RDa
3056 //|.else
3057 //| mov RD, [RA]
3058 //| mov [BASE], RD
3059 //| mov RD, [RA+4]
3060 //| mov [BASE+4], RD
3061 //|.endif
3062 //| mov RD, 1+2 // nresults+1 = 1 + false + error.
3063 //| jmp <7
3064 //|.else
3065 //| mov FCARG2, L:PC
3066 //| mov FCARG1, L:RB
3067 //| call extern lj_ffh_coroutine_wrap_err@8 // (lua_State *L, lua_State *co)
3068 //| // Error function does not return.
3069 //|.endif
3070 //|
3071 //|9: // Handle stack expansion on return from yield.
3072 //|.if X64
3073 //| mov L:RA, TMP1
3074 //|.else
3075 //| mov L:RA, ARG1 // The callee doesn't modify SAVE_L.
3076 //|.endif
3077 //| mov L:RA->top, KBASE // Undo coroutine stack clearing.
3078 //| mov FCARG2, PC
3079 //| mov FCARG1, L:RB
3080 //| call extern lj_state_growstack@8 // (lua_State *L, int n)
3081 //|.if X64
3082 //| mov L:PC, TMP1
3083 //|.else
3084 //| mov L:PC, ARG1
3085 //|.endif
3086 //| mov BASE, L:RB->base
3087 //| jmp <4 // Retry the stack move.
3088 //|.endmacro
3089 //|
3090 //| coroutine_resume_wrap 1 // coroutine.resume
3091 dasm_put(Dst, 2821, LJ_TFUNC, 16+FRAME_PCALL, 1+1, LJ_TTHREAD, Dt1(->cframe), Dt1(->status), LUA_YIELD);
3092 dasm_put(Dst, 2907, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top));
3093 dasm_put(Dst, 2996, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack), LJ_TTRUE);
3094#line 1907 "vm_x86.dasc"
3095 //| coroutine_resume_wrap 0 // coroutine.wrap
3096 dasm_put(Dst, 3093, FRAME_TYPE, LJ_TFALSE, Dt1(->top), Dt1(->top), 1+2, Dt1(->top), Dt1(->base), Dt8(->upvalue[0].gcr), Dt1(->cframe));
3097 dasm_put(Dst, 3207, Dt1(->status), LUA_YIELD, Dt1(->top), Dt1(->base), Dt1(->maxstack), Dt1(->top), Dt1(->base), Dt1(->top));
3098 dasm_put(Dst, 3277, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), LUA_YIELD, Dt1(->base), Dt1(->top), Dt1(->top), Dt1(->maxstack));
3099#line 1908 "vm_x86.dasc"
3100 //|
3101 //|.ffunc coroutine_yield
3102 //| mov L:RB, SAVE_L
3103 //| test aword L:RB->cframe, CFRAME_RESUME
3104 //| jz ->fff_fallback
3105 //| mov L:RB->base, BASE
3106 dasm_put(Dst, 3366, FRAME_TYPE, Dt1(->top), Dt1(->base), Dt1(->cframe), CFRAME_RESUME);
3107#line 1914 "vm_x86.dasc"
3108 //| lea RD, [BASE+NARGS:RD*8-8]
3109 //| mov L:RB->top, RD
3110 //| xor RD, RD
3111 //| mov aword L:RB->cframe, RDa
3112 //| mov al, LUA_YIELD
3113 //| mov byte L:RB->status, al
3114 //| jmp ->vm_leave_unw
3115 //|
3116 //|//-- Math library -------------------------------------------------------
3117 //|
3118 //|.if not DUALNUM
3119 //|->fff_resi: // Dummy.
3120 //|.endif
3121 //|
3122 //|.if SSE
3123 //|->fff_resn:
3124 //| mov PC, [BASE-4]
3125 //| fstp qword [BASE-8]
3126 //| jmp ->fff_res1
3127 //|.endif
3128 //|
3129 //| .ffunc_1 math_abs
3130 //|.if DUALNUM
3131 //| cmp dword [BASE+4], LJ_TISNUM; jne >2
3132 //| mov RB, dword [BASE]
3133 //| cmp RB, 0; jns ->fff_resi
3134 //| neg RB; js >1
3135 //|->fff_resbit:
3136 //|->fff_resi:
3137 //| mov PC, [BASE-4]
3138 //| mov dword [BASE-4], LJ_TISNUM
3139 //| mov dword [BASE-8], RB
3140 //| jmp ->fff_res1
3141 //|1:
3142 //| mov PC, [BASE-4]
3143 //| mov dword [BASE-4], 0x41e00000 // 2^31.
3144 //| mov dword [BASE-8], 0
3145 //| jmp ->fff_res1
3146 //|2:
3147 //| ja ->fff_fallback
3148 //|.else
3149 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
3150 //|.endif
3151 //|
3152 //|.if SSE
3153 //| movsd xmm0, qword [BASE]
3154 //| sseconst_abs xmm1, RDa
3155 dasm_put(Dst, 3476, Dt1(->base), Dt1(->top), Dt1(->cframe), LUA_YIELD, Dt1(->status), 1+1, LJ_TISNUM, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
3156#line 1961 "vm_x86.dasc"
3157 //| andps xmm0, xmm1
3158 //|->fff_resxmm0:
3159 //| mov PC, [BASE-4]
3160 //| movsd qword [BASE-8], xmm0
3161 //| // fallthrough
3162 //|.else
3163 //| fld qword [BASE]
3164 //| fabs
3165 //| // fallthrough
3166 //|->fff_resxmm0: // Dummy.
3167 //|->fff_resn:
3168 //| mov PC, [BASE-4]
3169 //| fstp qword [BASE-8]
3170 //|.endif
3171 //|
3172 //|->fff_res1:
3173 //| mov RD, 1+1
3174 //|->fff_res:
3175 //| mov MULTRES, RD
3176 //|->fff_res_:
3177 //| test PC, FRAME_TYPE
3178 //| jnz >7
3179 //|5:
3180 //| cmp PC_RB, RDL // More results expected?
3181 //| ja >6
3182 //| // Adjust BASE. KBASE is assumed to be set for the calling frame.
3183 //| movzx RA, PC_RA
3184 //| not RAa // Note: ~RA = -(RA+1)
3185 //| lea BASE, [BASE+RA*8] // base = base - (RA+1)*8
3186 //| ins_next
3187 //|
3188 //|6: // Fill up results with nil.
3189 //| mov dword [BASE+RD*8-12], LJ_TNIL
3190 //| add RD, 1
3191 //| jmp <5
3192 //|
3193 //|7: // Non-standard return case.
3194 //| mov RAa, -8 // Results start at BASE+RA = BASE-8.
3195 //| jmp ->vm_return
3196 //|
3197 //|.macro math_round, func
3198 //| .ffunc math_ .. func
3199 //|.if DUALNUM
3200 //| cmp dword [BASE+4], LJ_TISNUM; jne >1
3201 //| mov RB, dword [BASE]; jmp ->fff_resi
3202 //|1:
3203 //| ja ->fff_fallback
3204 //|.else
3205 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
3206 //|.endif
3207 //|.if SSE
3208 //| movsd xmm0, qword [BASE]
3209 //| call ->vm_ .. func
3210 //| .if DUALNUM
3211 //| cvtsd2si RB, xmm0
3212 //| cmp RB, 0x80000000
3213 //| jne ->fff_resi
3214 //| cvtsi2sd xmm1, RB
3215 //| ucomisd xmm0, xmm1
3216 //| jp ->fff_resxmm0
3217 //| je ->fff_resi
3218 //| .endif
3219 //| jmp ->fff_resxmm0
3220 //|.else
3221 //| fld qword [BASE]
3222 //| call ->vm_ .. func
3223 //| .if DUALNUM
3224 //| fist ARG1
3225 //| mov RB, ARG1
3226 //| cmp RB, 0x80000000; jne >2
3227 //| fdup
3228 //| fild ARG1
3229 //| fcomparepp
3230 //| jp ->fff_resn
3231 //| jne ->fff_resn
3232 //|2:
3233 //| fpop
3234 //| jmp ->fff_resi
3235 //| .else
3236 //| jmp ->fff_resn
3237 //| .endif
3238 //|.endif
3239 //|.endmacro
3240 //|
3241 //| math_round floor
3242 dasm_put(Dst, 3547, 1+1, FRAME_TYPE, LJ_TNIL, LJ_TISNUM);
3243#line 2046 "vm_x86.dasc"
3244 //| math_round ceil
3245 //|
3246 //|.if SSE
3247 //|.ffunc_nsse math_sqrt, sqrtsd; jmp ->fff_resxmm0
3248 dasm_put(Dst, 3670, LJ_TISNUM, 1+1, LJ_TISNUM);
3249#line 2050 "vm_x86.dasc"
3250 //|.else
3251 //|.ffunc_n math_sqrt; fsqrt; jmp ->fff_resn
3252 //|.endif
3253 //|
3254 //|.ffunc math_log
3255 //| cmp NARGS:RD, 1+1; jne ->fff_fallback // Exactly one argument.
3256 //| cmp dword [BASE+4], LJ_TISNUM; jae ->fff_fallback
3257 //| fldln2; fld qword [BASE]; fyl2x; jmp ->fff_resn
3258 //|
3259 //|.ffunc_n math_log10, fldlg2; fyl2x; jmp ->fff_resn
3260 //|.ffunc_n math_exp; call ->vm_exp_x87; jmp ->fff_resn
3261 dasm_put(Dst, 3729, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
3262#line 2061 "vm_x86.dasc"
3263 //|
3264 //|.ffunc_n math_sin; fsin; jmp ->fff_resn
3265 //|.ffunc_n math_cos; fcos; jmp ->fff_resn
3266 dasm_put(Dst, 3803, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
3267#line 2064 "vm_x86.dasc"
3268 //|.ffunc_n math_tan; fptan; fpop; jmp ->fff_resn
3269 //|
3270 //|.ffunc_n math_asin
3271 dasm_put(Dst, 3860, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1);
3272#line 2067 "vm_x86.dasc"
3273 //| fdup; fmul st0; fld1; fsubrp st1; fsqrt; fpatan
3274 //| jmp ->fff_resn
3275 //|.ffunc_n math_acos
3276 //| fdup; fmul st0; fld1; fsubrp st1; fsqrt; fxch; fpatan
3277 //| jmp ->fff_resn
3278 //|.ffunc_n math_atan; fld1; fpatan; jmp ->fff_resn
3279 dasm_put(Dst, 3927, LJ_TISNUM, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
3280#line 2073 "vm_x86.dasc"
3281 //|
3282 //|.macro math_extern, func
3283 //|.if SSE
3284 //| .ffunc_nsse math_ .. func
3285 //| .if not X64
3286 //| movsd FPARG1, xmm0
3287 //| .endif
3288 //|.else
3289 //| .ffunc_n math_ .. func
3290 //| fstp FPARG1
3291 //|.endif
3292 //| mov RB, BASE
3293 //| call extern lj_vm_ .. func
3294 //| mov BASE, RB
3295 //| .if X64
3296 //| jmp ->fff_resxmm0
3297 //| .else
3298 //| jmp ->fff_resn
3299 //| .endif
3300 //|.endmacro
3301 //|
3302 //| math_extern sinh
3303 //| math_extern cosh
3304 //| math_extern tanh
3305 dasm_put(Dst, 4017, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM);
3306#line 2097 "vm_x86.dasc"
3307 //|
3308 //|->ff_math_deg:
3309 //|.if SSE
3310 //|.ffunc_nsse math_rad
3311 //| mov CFUNC:RB, [BASE-8]
3312 //| mulsd xmm0, qword CFUNC:RB->upvalue[0]
3313 //| jmp ->fff_resxmm0
3314 //|.else
3315 //|.ffunc_n math_rad
3316 //| mov CFUNC:RB, [BASE-8]
3317 //| fmul qword CFUNC:RB->upvalue[0]
3318 //| jmp ->fff_resn
3319 //|.endif
3320 //|
3321 //|.ffunc_nn math_atan2; fpatan; jmp ->fff_resn
3322 dasm_put(Dst, 4105, 1+1, LJ_TISNUM, 1+1, LJ_TISNUM, Dt8(->upvalue[0]));
3323#line 2112 "vm_x86.dasc"
3324 //|.ffunc_nnr math_ldexp; fscale; fpop1; jmp ->fff_resn
3325 dasm_put(Dst, 4183, 2+1, LJ_TISNUM, LJ_TISNUM, 2+1, LJ_TISNUM, LJ_TISNUM);
3326#line 2113 "vm_x86.dasc"
3327 //|
3328 //|.ffunc_1 math_frexp
3329 //| mov RB, [BASE+4]
3330 //| cmp RB, LJ_TISNUM; jae ->fff_fallback
3331 //| mov PC, [BASE-4]
3332 //| mov RC, [BASE]
3333 //| mov [BASE-4], RB; mov [BASE-8], RC
3334 //| shl RB, 1; cmp RB, 0xffe00000; jae >3
3335 //| or RC, RB; jz >3
3336 //| mov RC, 1022
3337 //| cmp RB, 0x00200000; jb >4
3338 //|1:
3339 //| shr RB, 21; sub RB, RC // Extract and unbias exponent.
3340 //|.if SSE
3341 //| cvtsi2sd xmm0, RB
3342 //|.else
3343 //| mov TMP1, RB; fild TMP1
3344 //|.endif
3345 //| mov RB, [BASE-4]
3346 //| and RB, 0x800fffff // Mask off exponent.
3347 //| or RB, 0x3fe00000 // Put mantissa in range [0.5,1) or 0.
3348 //| mov [BASE-4], RB
3349 //|2:
3350 //|.if SSE
3351 //| movsd qword [BASE], xmm0
3352 //|.else
3353 //| fstp qword [BASE]
3354 //|.endif
3355 //| mov RD, 1+2
3356 //| jmp ->fff_res
3357 //|3: // Return +-0, +-Inf, NaN unmodified and an exponent of 0.
3358 //|.if SSE
3359 //| xorps xmm0, xmm0; jmp <2
3360 dasm_put(Dst, 4250, 1+1, LJ_TISNUM, 1+2);
3361#line 2146 "vm_x86.dasc"
3362 //|.else
3363 //| fldz; jmp <2
3364 //|.endif
3365 //|4: // Handle denormals by multiplying with 2^54 and adjusting the bias.
3366 //|.if SSE
3367 //| movsd xmm0, qword [BASE]
3368 //| sseconst_hi xmm1, RBa, 43500000 // 2^54.
3369 //| mulsd xmm0, xmm1
3370 //| movsd qword [BASE-8], xmm0
3371 //|.else
3372 //| fld qword [BASE]
3373 //| mov TMP1, 0x5a800000; fmul TMP1 // x = x*2^54
3374 //| fstp qword [BASE-8]
3375 //|.endif
3376 //| mov RB, [BASE-4]; mov RC, 1076; shl RB, 1; jmp <1
3377 //|
3378 //|.if SSE
3379 //|.ffunc_nsse math_modf
3380 //|.else
3381 //|.ffunc_n math_modf
3382 //|.endif
3383 //| mov RB, [BASE+4]
3384 //| mov PC, [BASE-4]
3385 //| shl RB, 1; cmp RB, 0xffe00000; je >4 // +-Inf?
3386 //|.if SSE
3387 //| movaps xmm4, xmm0
3388 //| call ->vm_trunc
3389 //| subsd xmm4, xmm0
3390 //|1:
3391 //| movsd qword [BASE-8], xmm0
3392 //| movsd qword [BASE], xmm4
3393 //|.else
3394 //| fdup
3395 //| call ->vm_trunc
3396 //| fsub st1, st0
3397 //|1:
3398 //| fstp qword [BASE-8]
3399 //| fstp qword [BASE]
3400 //|.endif
3401 //| mov RC, [BASE-4]; mov RB, [BASE+4]
3402 //| xor RC, RB; js >3 // Need to adjust sign?
3403 //|2:
3404 //| mov RD, 1+2
3405 dasm_put(Dst, 4387, (unsigned int)(U64x(43500000,00000000)), (unsigned int)((U64x(43500000,00000000))>>32), 1+1, LJ_TISNUM);
3406#line 2189 "vm_x86.dasc"
3407 //| jmp ->fff_res
3408 //|3:
3409 //| xor RB, 0x80000000; mov [BASE+4], RB // Flip sign of fraction.
3410 //| jmp <2
3411 //|4:
3412 //|.if SSE
3413 //| xorps xmm4, xmm4; jmp <1 // Return +-Inf and +-0.
3414 //|.else
3415 //| fldz; fxch; jmp <1 // Return +-Inf and +-0.
3416 //|.endif
3417 //|
3418 //|.ffunc_nnr math_fmod
3419 //|1: ; fprem; fnstsw ax; sahf; jp <1
3420 dasm_put(Dst, 4523, 1+2, 2+1, LJ_TISNUM, LJ_TISNUM);
3421#line 2202 "vm_x86.dasc"
3422 //| fpop1
3423 //| jmp ->fff_resn
3424 //|
3425 //|.if SSE
3426 //|.ffunc_nnsse math_pow; call ->vm_pow; jmp ->fff_resxmm0
3427 //|.else
3428 //|.ffunc_nn math_pow; call ->vm_pow; jmp ->fff_resn
3429 //|.endif
3430 //|
3431 //|.macro math_minmax, name, cmovop, fcmovop, sseop
3432 //| .ffunc name
3433 //| mov RA, 2
3434 //| cmp dword [BASE+4], LJ_TISNUM
3435 //|.if DUALNUM
3436 //| jne >4
3437 //| mov RB, dword [BASE]
3438 //|1: // Handle integers.
3439 //| cmp RA, RD; jae ->fff_resi
3440 //| cmp dword [BASE+RA*8-4], LJ_TISNUM; jne >3
3441 //| cmp RB, dword [BASE+RA*8-8]
3442 //| cmovop RB, dword [BASE+RA*8-8]
3443 //| add RA, 1
3444 //| jmp <1
3445 //|3:
3446 //| ja ->fff_fallback
3447 //| // Convert intermediate result to number and continue below.
3448 //|.if SSE
3449 //| cvtsi2sd xmm0, RB
3450 //|.else
3451 //| mov TMP1, RB
3452 //| fild TMP1
3453 //|.endif
3454 //| jmp >6
3455 //|4:
3456 //| ja ->fff_fallback
3457 //|.else
3458 //| jae ->fff_fallback
3459 //|.endif
3460 //|
3461 //|.if SSE
3462 //| movsd xmm0, qword [BASE]
3463 //|5: // Handle numbers or integers.
3464 //| cmp RA, RD; jae ->fff_resxmm0
3465 //| cmp dword [BASE+RA*8-4], LJ_TISNUM
3466 //|.if DUALNUM
3467 //| jb >6
3468 //| ja ->fff_fallback
3469 //| cvtsi2sd xmm1, dword [BASE+RA*8-8]
3470 //| jmp >7
3471 //|.else
3472 //| jae ->fff_fallback
3473 //|.endif
3474 //|6:
3475 //| movsd xmm1, qword [BASE+RA*8-8]
3476 //|7:
3477 //| sseop xmm0, xmm1
3478 //| add RA, 1
3479 //| jmp <5
3480 //|.else
3481 //| fld qword [BASE]
3482 //|5: // Handle numbers or integers.
3483 //| cmp RA, RD; jae ->fff_resn
3484 //| cmp dword [BASE+RA*8-4], LJ_TISNUM
3485 //|.if DUALNUM
3486 //| jb >6
3487 //| ja >9
3488 //| fild dword [BASE+RA*8-8]
3489 //| jmp >7
3490 //|.else
3491 //| jae >9
3492 //|.endif
3493 //|6:
3494 //| fld qword [BASE+RA*8-8]
3495 //|7:
3496 //| fucomi st1; fcmovop st1; fpop1
3497 //| add RA, 1
3498 //| jmp <5
3499 //|.endif
3500 //|.endmacro
3501 //|
3502 //| math_minmax math_min, cmovg, fcmovnbe, minsd
3503 dasm_put(Dst, 4590, 2+1, LJ_TISNUM, LJ_TISNUM, LJ_TISNUM);
3504#line 2283 "vm_x86.dasc"
3505 //| math_minmax math_max, cmovl, fcmovbe, maxsd
3506 dasm_put(Dst, 4665, LJ_TISNUM, LJ_TISNUM, LJ_TISNUM);
3507#line 2284 "vm_x86.dasc"
3508 //|.if not SSE
3509 //|9:
3510 //| fpop; jmp ->fff_fallback
3511 //|.endif
3512 //|
3513 //|//-- String library -----------------------------------------------------
3514 //|
3515 //|.ffunc_1 string_len
3516 //| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
3517 //| mov STR:RB, [BASE]
3518 //|.if DUALNUM
3519 //| mov RB, dword STR:RB->len; jmp ->fff_resi
3520 //|.elif SSE
3521 //| cvtsi2sd xmm0, dword STR:RB->len; jmp ->fff_resxmm0
3522 //|.else
3523 //| fild dword STR:RB->len; jmp ->fff_resn
3524 //|.endif
3525 //|
3526 //|.ffunc string_byte // Only handle the 1-arg case here.
3527 //| cmp NARGS:RD, 1+1; jne ->fff_fallback
3528 //| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
3529 dasm_put(Dst, 4754, 1+1, LJ_TSTR, Dt5(->len), 1+1);
3530#line 2305 "vm_x86.dasc"
3531 //| mov STR:RB, [BASE]
3532 //| mov PC, [BASE-4]
3533 //| cmp dword STR:RB->len, 1
3534 //| jb ->fff_res0 // Return no results for empty string.
3535 //| movzx RB, byte STR:RB[1]
3536 //|.if DUALNUM
3537 //| jmp ->fff_resi
3538 //|.elif SSE
3539 //| cvtsi2sd xmm0, RB; jmp ->fff_resxmm0
3540 //|.else
3541 //| mov TMP1, RB; fild TMP1; jmp ->fff_resn
3542 //|.endif
3543 //|
3544 //|.ffunc string_char // Only handle the 1-arg case here.
3545 //| ffgccheck
3546 //| cmp NARGS:RD, 1+1; jne ->fff_fallback // *Exactly* 1 arg.
3547 //| cmp dword [BASE+4], LJ_TISNUM
3548 dasm_put(Dst, 4824, LJ_TSTR, Dt5(->len), Dt5([1]), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+1);
3549#line 2322 "vm_x86.dasc"
3550 //|.if DUALNUM
3551 //| jne ->fff_fallback
3552 //| mov RB, dword [BASE]
3553 //| cmp RB, 255; ja ->fff_fallback
3554 //| mov TMP2, RB
3555 //|.elif SSE
3556 //| jae ->fff_fallback
3557 //| cvttsd2si RB, qword [BASE]
3558 //| cmp RB, 255; ja ->fff_fallback
3559 //| mov TMP2, RB
3560 //|.else
3561 //| jae ->fff_fallback
3562 //| fld qword [BASE]
3563 //| fistp TMP2
3564 //| cmp TMP2, 255; ja ->fff_fallback
3565 //|.endif
3566 //|.if X64
3567 //| mov TMP3, 1
3568 //|.else
3569 //| mov ARG3, 1
3570 //|.endif
3571 //| lea RDa, TMP2 // Points to stack. Little-endian.
3572 //|->fff_newstr:
3573 //| mov L:RB, SAVE_L
3574 //| mov L:RB->base, BASE
3575 //|.if X64
3576 //| mov CARG3d, TMP3 // Zero-extended to size_t.
3577 //| mov CARG2, RDa // May be 64 bit ptr to stack.
3578 //| mov CARG1d, L:RB
3579 //|.else
3580 //| mov ARG2, RD
3581 //| mov ARG1, L:RB
3582 //|.endif
3583 //| mov SAVE_PC, PC
3584 //| call extern lj_str_new // (lua_State *L, char *str, size_t l)
3585 //| // GCstr * returned in eax (RD).
3586 //| mov BASE, L:RB->base
3587 //| mov PC, [BASE-4]
3588 //| mov dword [BASE-4], LJ_TSTR
3589 //| mov [BASE-8], STR:RD
3590 //| jmp ->fff_res1
3591 //|
3592 //|.ffunc string_sub
3593 //| ffgccheck
3594 //| mov TMP2, -1
3595 //| cmp NARGS:RD, 1+2; jb ->fff_fallback
3596 dasm_put(Dst, 4888, LJ_TISNUM, Dt1(->base), Dt1(->base), LJ_TSTR, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 1+2);
3597#line 2368 "vm_x86.dasc"
3598 //| jna >1
3599 //| cmp dword [BASE+20], LJ_TISNUM
3600 //|.if DUALNUM
3601 //| jne ->fff_fallback
3602 //| mov RB, dword [BASE+16]
3603 //| mov TMP2, RB
3604 //|.elif SSE
3605 //| jae ->fff_fallback
3606 //| cvttsd2si RB, qword [BASE+16]
3607 //| mov TMP2, RB
3608 //|.else
3609 //| jae ->fff_fallback
3610 //| fld qword [BASE+16]
3611 //| fistp TMP2
3612 //|.endif
3613 //|1:
3614 //| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
3615 //| cmp dword [BASE+12], LJ_TISNUM
3616 //|.if DUALNUM
3617 //| jne ->fff_fallback
3618 //|.else
3619 //| jae ->fff_fallback
3620 //|.endif
3621 //| mov STR:RB, [BASE]
3622 //| mov TMP3, STR:RB
3623 //| mov RB, STR:RB->len
3624 //|.if DUALNUM
3625 //| mov RA, dword [BASE+8]
3626 //|.elif SSE
3627 //| cvttsd2si RA, qword [BASE+8]
3628 //|.else
3629 //| fld qword [BASE+8]
3630 //| fistp ARG3
3631 //| mov RA, ARG3
3632 //|.endif
3633 //| mov RC, TMP2
3634 //| cmp RB, RC // len < end? (unsigned compare)
3635 //| jb >5
3636 //|2:
3637 //| test RA, RA // start <= 0?
3638 //| jle >7
3639 //|3:
3640 //| mov STR:RB, TMP3
3641 dasm_put(Dst, 5014, LJ_TISNUM, LJ_TSTR, LJ_TISNUM, Dt5(->len));
3642#line 2411 "vm_x86.dasc"
3643 //| sub RC, RA // start > end?
3644 //| jl ->fff_emptystr
3645 //| lea RB, [STR:RB+RA+#STR-1]
3646 //| add RC, 1
3647 //|4:
3648 //|.if X64
3649 //| mov TMP3, RC
3650 //|.else
3651 //| mov ARG3, RC
3652 //|.endif
3653 //| mov RD, RB
3654 //| jmp ->fff_newstr
3655 //|
3656 //|5: // Negative end or overflow.
3657 //| jl >6
3658 //| lea RC, [RC+RB+1] // end = end+(len+1)
3659 //| jmp <2
3660 //|6: // Overflow.
3661 //| mov RC, RB // end = len
3662 //| jmp <2
3663 //|
3664 //|7: // Negative start or underflow.
3665 //| je >8
3666 //| add RA, RB // start = start+(len+1)
3667 //| add RA, 1
3668 //| jg <3 // start > 0?
3669 //|8: // Underflow.
3670 //| mov RA, 1 // start = 1
3671 dasm_put(Dst, 5097, sizeof(GCstr)-1);
3672#line 2439 "vm_x86.dasc"
3673 //| jmp <3
3674 //|
3675 //|->fff_emptystr: // Range underflow.
3676 //| xor RC, RC // Zero length. Any ptr in RB is ok.
3677 //| jmp <4
3678 //|
3679 //|.ffunc string_rep // Only handle the 1-char case inline.
3680 //| ffgccheck
3681 //| cmp NARGS:RD, 2+1; jne ->fff_fallback // Exactly 2 arguments.
3682 //| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
3683 //| cmp dword [BASE+12], LJ_TISNUM
3684 //| mov STR:RB, [BASE]
3685 dasm_put(Dst, 5168, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), 2+1, LJ_TSTR, LJ_TISNUM);
3686#line 2451 "vm_x86.dasc"
3687 //|.if DUALNUM
3688 //| jne ->fff_fallback
3689 //| mov RC, dword [BASE+8]
3690 //|.elif SSE
3691 //| jae ->fff_fallback
3692 //| cvttsd2si RC, qword [BASE+8]
3693 //|.else
3694 //| jae ->fff_fallback
3695 //| fld qword [BASE+8]
3696 //| fistp TMP2
3697 //| mov RC, TMP2
3698 //|.endif
3699 //| test RC, RC
3700 //| jle ->fff_emptystr // Count <= 0? (or non-int)
3701 //| cmp dword STR:RB->len, 1
3702 //| jb ->fff_emptystr // Zero length string?
3703 //| jne ->fff_fallback_2 // Fallback for > 1-char strings.
3704 //| cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_2
3705 //| movzx RA, byte STR:RB[1]
3706 //| mov RB, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
3707 //|.if X64
3708 //| mov TMP3, RC
3709 //|.else
3710 //| mov ARG3, RC
3711 //|.endif
3712 //|1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
3713 //| mov [RB], RAL
3714 //| add RB, 1
3715 //| sub RC, 1
3716 //| jnz <1
3717 //| mov RD, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
3718 //| jmp ->fff_newstr
3719 //|
3720 //|.ffunc_1 string_reverse
3721 dasm_put(Dst, 5227, Dt5(->len), DISPATCH_GL(tmpbuf.sz), Dt5([1]), DISPATCH_GL(tmpbuf.buf), DISPATCH_GL(tmpbuf.buf));
3722#line 2485 "vm_x86.dasc"
3723 //| ffgccheck
3724 //| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
3725 //| mov STR:RB, [BASE]
3726 //| mov RC, STR:RB->len
3727 //| test RC, RC
3728 //| jz ->fff_emptystr // Zero length string?
3729 //| cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1
3730 //| add RB, #STR
3731 //| mov TMP2, PC // Need another temp register.
3732 dasm_put(Dst, 5303, 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr));
3733#line 2494 "vm_x86.dasc"
3734 //|.if X64
3735 //| mov TMP3, RC
3736 //|.else
3737 //| mov ARG3, RC
3738 //|.endif
3739 //| mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
3740 //|1:
3741 //| movzx RA, byte [RB]
3742 //| add RB, 1
3743 //| sub RC, 1
3744 //| mov [PC+RC], RAL
3745 //| jnz <1
3746 //| mov RD, PC
3747 //| mov PC, TMP2
3748 //| jmp ->fff_newstr
3749 //|
3750 //|.macro ffstring_case, name, lo, hi
3751 //| .ffunc_1 name
3752 //| ffgccheck
3753 //| cmp dword [BASE+4], LJ_TSTR; jne ->fff_fallback
3754 //| mov STR:RB, [BASE]
3755 //| mov RC, STR:RB->len
3756 //| cmp [DISPATCH+DISPATCH_GL(tmpbuf.sz)], RC; jb ->fff_fallback_1
3757 //| add RB, #STR
3758 //| mov TMP2, PC // Need another temp register.
3759 //|.if X64
3760 //| mov TMP3, RC
3761 //|.else
3762 //| mov ARG3, RC
3763 //|.endif
3764 //| mov PC, [DISPATCH+DISPATCH_GL(tmpbuf.buf)]
3765 //| jmp >3
3766 //|1: // ASCII case conversion. Yes, this is suboptimal code (do you care?).
3767 //| movzx RA, byte [RB+RC]
3768 //| cmp RA, lo
3769 //| jb >2
3770 //| cmp RA, hi
3771 //| ja >2
3772 //| xor RA, 0x20
3773 //|2:
3774 //| mov [PC+RC], RAL
3775 //|3:
3776 //| sub RC, 1
3777 //| jns <1
3778 //| mov RD, PC
3779 //| mov PC, TMP2
3780 //| jmp ->fff_newstr
3781 //|.endmacro
3782 //|
3783 //|ffstring_case string_lower, 0x41, 0x5a
3784 dasm_put(Dst, 5360, DISPATCH_GL(tmpbuf.buf), 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR);
3785#line 2544 "vm_x86.dasc"
3786 //|ffstring_case string_upper, 0x61, 0x7a
3787 dasm_put(Dst, 5438, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
3788 dasm_put(Dst, 5524, 1+1, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), LJ_TSTR, Dt5(->len), DISPATCH_GL(tmpbuf.sz), sizeof(GCstr), DISPATCH_GL(tmpbuf.buf));
3789#line 2545 "vm_x86.dasc"
3790 //|
3791 //|//-- Table library ------------------------------------------------------
3792 //|
3793 //|.ffunc_1 table_getn
3794 //| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
3795 //| mov RB, BASE // Save BASE.
3796 //| mov TAB:FCARG1, [BASE]
3797 //| call extern lj_tab_len@4 // LJ_FASTCALL (GCtab *t)
3798 //| // Length of table returned in eax (RD).
3799 //| mov BASE, RB // Restore BASE.
3800 //|.if DUALNUM
3801 //| mov RB, RD; jmp ->fff_resi
3802 //|.elif SSE
3803 //| cvtsi2sd xmm0, RD; jmp ->fff_resxmm0
3804 //|.else
3805 //| mov ARG1, RD; fild ARG1; jmp ->fff_resn
3806 //|.endif
3807 //|
3808 //|//-- Bit library --------------------------------------------------------
3809 //|
3810 //|.define TOBIT_BIAS, 0x59c00000 // 2^52 + 2^51 (float, not double!).
3811 //|
3812 //|.macro .ffunc_bit, name, kind
3813 //| .ffunc_1 name
3814 //|.if kind == 2
3815 //|.if SSE
3816 //| sseconst_tobit xmm1, RBa
3817 //|.else
3818 //| mov TMP1, TOBIT_BIAS
3819 //|.endif
3820 //|.endif
3821 //| cmp dword [BASE+4], LJ_TISNUM
3822 //|.if DUALNUM
3823 //| jne >1
3824 //| mov RB, dword [BASE]
3825 //|.if kind > 0
3826 //| jmp >2
3827 //|.else
3828 //| jmp ->fff_resbit
3829 //|.endif
3830 //|1:
3831 //| ja ->fff_fallback
3832 //|.else
3833 //| jae ->fff_fallback
3834 //|.endif
3835 //|.if SSE
3836 //| movsd xmm0, qword [BASE]
3837 //|.if kind < 2
3838 //| sseconst_tobit xmm1, RBa
3839 //|.endif
3840 //| addsd xmm0, xmm1
3841 //| movd RB, xmm0
3842 //|.else
3843 //| fld qword [BASE]
3844 //|.if kind < 2
3845 //| mov TMP1, TOBIT_BIAS
3846 //|.endif
3847 //| fadd TMP1
3848 //| fstp FPARG1
3849 //|.if kind > 0
3850 //| mov RB, ARG1
3851 //|.endif
3852 //|.endif
3853 //|2:
3854 //|.endmacro
3855 //|
3856 //|.ffunc_bit bit_tobit, 0
3857 dasm_put(Dst, 5593, 1+1, LJ_TTAB);
3858#line 2612 "vm_x86.dasc"
3859 //|.if DUALNUM or SSE
3860 //|.if not SSE
3861 //| mov RB, ARG1
3862 //|.endif
3863 //| jmp ->fff_resbit
3864 //|.else
3865 //| fild ARG1
3866 //| jmp ->fff_resn
3867 //|.endif
3868 //|
3869 //|.macro .ffunc_bit_op, name, ins
3870 //| .ffunc_bit name, 2
3871 //| mov TMP2, NARGS:RD // Save for fallback.
3872 //| lea RD, [BASE+NARGS:RD*8-16]
3873 //|1:
3874 //| cmp RD, BASE
3875 //| jbe ->fff_resbit
3876 //| cmp dword [RD+4], LJ_TISNUM
3877 //|.if DUALNUM
3878 //| jne >2
3879 //| ins RB, dword [RD]
3880 //| sub RD, 8
3881 //| jmp <1
3882 //|2:
3883 //| ja ->fff_fallback_bit_op
3884 //|.else
3885 //| jae ->fff_fallback_bit_op
3886 //|.endif
3887 //|.if SSE
3888 //| movsd xmm0, qword [RD]
3889 //| addsd xmm0, xmm1
3890 //| movd RA, xmm0
3891 //| ins RB, RA
3892 //|.else
3893 //| fld qword [RD]
3894 //| fadd TMP1
3895 //| fstp FPARG1
3896 //| ins RB, ARG1
3897 //|.endif
3898 //| sub RD, 8
3899 //| jmp <1
3900 //|.endmacro
3901 //|
3902 //|.ffunc_bit_op bit_band, and
3903 dasm_put(Dst, 5684, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 1+1, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), LJ_TISNUM);
3904#line 2656 "vm_x86.dasc"
3905 //|.ffunc_bit_op bit_bor, or
3906 dasm_put(Dst, 5759, LJ_TISNUM, 1+1, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), LJ_TISNUM);
3907#line 2657 "vm_x86.dasc"
3908 //|.ffunc_bit_op bit_bxor, xor
3909 dasm_put(Dst, 5880, LJ_TISNUM, 1+1, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), LJ_TISNUM);
3910#line 2658 "vm_x86.dasc"
3911 //|
3912 //|.ffunc_bit bit_bswap, 1
3913 //| bswap RB
3914 //| jmp ->fff_resbit
3915 //|
3916 //|.ffunc_bit bit_bnot, 1
3917 dasm_put(Dst, 5980, LJ_TISNUM, 1+1, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 1+1);
3918#line 2664 "vm_x86.dasc"
3919 //| not RB
3920 //|.if DUALNUM
3921 //| jmp ->fff_resbit
3922 //|.elif SSE
3923 //|->fff_resbit:
3924 //| cvtsi2sd xmm0, RB
3925 //| jmp ->fff_resxmm0
3926 //|.else
3927 //|->fff_resbit:
3928 //| mov ARG1, RB
3929 //| fild ARG1
3930 //| jmp ->fff_resn
3931 //|.endif
3932 //|
3933 //|->fff_fallback_bit_op:
3934 //| mov NARGS:RD, TMP2 // Restore for fallback
3935 //| jmp ->fff_fallback
3936 //|
3937 //|.macro .ffunc_bit_sh, name, ins
3938 //|.if DUALNUM
3939 //| .ffunc_bit name, 1
3940 //| // Note: no inline conversion from number for 2nd argument!
3941 //| cmp dword [BASE+12], LJ_TISNUM; jne ->fff_fallback
3942 //| mov RA, dword [BASE+8]
3943 //|.elif SSE
3944 //| .ffunc_nnsse name
3945 //| sseconst_tobit xmm2, RBa
3946 //| addsd xmm0, xmm2
3947 //| addsd xmm1, xmm2
3948 //| movd RB, xmm0
3949 //| movd RA, xmm1
3950 //|.else
3951 //| .ffunc_nn name
3952 //| mov TMP1, TOBIT_BIAS
3953 //| fadd TMP1
3954 //| fstp FPARG3
3955 //| fadd TMP1
3956 //| fstp FPARG1
3957 //| mov RA, ARG3
3958 //| mov RB, ARG1
3959 //|.endif
3960 //| ins RB, cl // Assumes RA is ecx.
3961 //| jmp ->fff_resbit
3962 //|.endmacro
3963 //|
3964 //|.ffunc_bit_sh bit_lshift, shl
3965 dasm_put(Dst, 6073, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 2+1, LJ_TISNUM, LJ_TISNUM);
3966#line 2710 "vm_x86.dasc"
3967 //|.ffunc_bit_sh bit_rshift, shr
3968 //|.ffunc_bit_sh bit_arshift, sar
3969 dasm_put(Dst, 6156, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
3970#line 2712 "vm_x86.dasc"
3971 //|.ffunc_bit_sh bit_rol, rol
3972 dasm_put(Dst, 6280, 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 2+1, LJ_TISNUM);
3973#line 2713 "vm_x86.dasc"
3974 //|.ffunc_bit_sh bit_ror, ror
3975 //|
3976 //|//-----------------------------------------------------------------------
3977 //|
3978 //|->fff_fallback_2:
3979 //| mov NARGS:RD, 1+2 // Other args are ignored, anyway.
3980 dasm_put(Dst, 6371, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32), 2+1, LJ_TISNUM, LJ_TISNUM, (unsigned int)(U64x(43380000,00000000)), (unsigned int)((U64x(43380000,00000000))>>32));
3981#line 2719 "vm_x86.dasc"
3982 //| jmp ->fff_fallback
3983 //|->fff_fallback_1:
3984 //| mov NARGS:RD, 1+1 // Other args are ignored, anyway.
3985 //|->fff_fallback: // Call fast function fallback handler.
3986 //| // BASE = new base, RD = nargs+1
3987 //| mov L:RB, SAVE_L
3988 //| mov PC, [BASE-4] // Fallback may overwrite PC.
3989 //| mov SAVE_PC, PC // Redundant (but a defined value).
3990 //| mov L:RB->base, BASE
3991 //| lea RD, [BASE+NARGS:RD*8-8]
3992 //| lea RA, [RD+8*LUA_MINSTACK] // Ensure enough space for handler.
3993 //| mov L:RB->top, RD
3994 //| mov CFUNC:RD, [BASE-8]
3995 //| cmp RA, L:RB->maxstack
3996 //| ja >5 // Need to grow stack.
3997 //|.if X64
3998 //| mov CARG1d, L:RB
3999 //|.else
4000 //| mov ARG1, L:RB
4001 //|.endif
4002 //| call aword CFUNC:RD->f // (lua_State *L)
4003 //| mov BASE, L:RB->base
4004 //| // Either throws an error, or recovers and returns -1, 0 or nresults+1.
4005 //| test RD, RD; jg ->fff_res // Returned nresults+1?
4006 //|1:
4007 //| mov RA, L:RB->top
4008 //| sub RA, BASE
4009 //| shr RA, 3
4010 //| test RD, RD
4011 //| lea NARGS:RD, [RA+1]
4012 //| mov LFUNC:RB, [BASE-8]
4013 //| jne ->vm_call_tail // Returned -1?
4014 //| ins_callt // Returned 0: retry fast path.
4015 dasm_put(Dst, 6499, 1+2, 1+1, Dt1(->base), 8*LUA_MINSTACK, Dt1(->top), Dt1(->maxstack), Dt8(->f), Dt1(->base), Dt1(->top));
4016#line 2752 "vm_x86.dasc"
4017 //|
4018 //|// Reconstruct previous base for vmeta_call during tailcall.
4019 //|->vm_call_tail:
4020 //| mov RA, BASE
4021 //| test PC, FRAME_TYPE
4022 //| jnz >3
4023 //| movzx RB, PC_RA
4024 //| not RBa // Note: ~RB = -(RB+1)
4025 //| lea BASE, [BASE+RB*8] // base = base - (RB+1)*8
4026 //| jmp ->vm_call_dispatch // Resolve again for tailcall.
4027 //|3:
4028 //| mov RB, PC
4029 //| and RB, -8
4030 //| sub BASE, RB
4031 //| jmp ->vm_call_dispatch // Resolve again for tailcall.
4032 //|
4033 //|5: // Grow stack for fallback handler.
4034 //| mov FCARG2, LUA_MINSTACK
4035 //| mov FCARG1, L:RB
4036 //| call extern lj_state_growstack@8 // (lua_State *L, int n)
4037 //| mov BASE, L:RB->base
4038 //| xor RD, RD // Simulate a return 0.
4039 //| jmp <1 // Dumb retry (goes through ff first).
4040 //|
4041 //|->fff_gcstep: // Call GC step function.
4042 //| // BASE = new base, RD = nargs+1
4043 //| pop RBa // Must keep stack at same level.
4044 //| mov TMPa, RBa // Save return address
4045 //| mov L:RB, SAVE_L
4046 //| mov SAVE_PC, PC // Redundant (but a defined value).
4047 //| mov L:RB->base, BASE
4048 //| lea RD, [BASE+NARGS:RD*8-8]
4049 //| mov FCARG1, L:RB
4050 //| mov L:RB->top, RD
4051 //| call extern lj_gc_step@4 // (lua_State *L)
4052 //| mov BASE, L:RB->base
4053 //| mov RD, L:RB->top
4054 //| sub RD, BASE
4055 dasm_put(Dst, 6589, Dt7(->pc), FRAME_TYPE, LUA_MINSTACK, Dt1(->base), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
4056#line 2790 "vm_x86.dasc"
4057 //| shr RD, 3
4058 //| add NARGS:RD, 1
4059 //| mov RBa, TMPa
4060 //| push RBa // Restore return address.
4061 //| ret
4062 //|
4063 //|//-----------------------------------------------------------------------
4064 //|//-- Special dispatch targets -------------------------------------------
4065 //|//-----------------------------------------------------------------------
4066 //|
4067 //|->vm_record: // Dispatch target for recording phase.
4068 //|.if JIT
4069 //| movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
4070 //| test RDL, HOOK_VMEVENT // No recording while in vmevent.
4071 //| jnz >5
4072 //| // Decrement the hookcount for consistency, but always do the call.
4073 //| test RDL, HOOK_ACTIVE
4074 //| jnz >1
4075 //| test RDL, LUA_MASKLINE|LUA_MASKCOUNT
4076 //| jz >1
4077 //| dec dword [DISPATCH+DISPATCH_GL(hookcount)]
4078 //| jmp >1
4079 //|.endif
4080 //|
4081 //|->vm_rethook: // Dispatch target for return hooks.
4082 //| movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
4083 //| test RDL, HOOK_ACTIVE // Hook already active?
4084 //| jnz >5
4085 //| jmp >1
4086 //|
4087 //|->vm_inshook: // Dispatch target for instr/line hooks.
4088 //| movzx RD, byte [DISPATCH+DISPATCH_GL(hookmask)]
4089 dasm_put(Dst, 6715, DISPATCH_GL(hookmask), HOOK_VMEVENT, HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), DISPATCH_GL(hookmask), HOOK_ACTIVE);
4090#line 2822 "vm_x86.dasc"
4091 //| test RDL, HOOK_ACTIVE // Hook already active?
4092 //| jnz >5
4093 //|
4094 //| test RDL, LUA_MASKLINE|LUA_MASKCOUNT
4095 //| jz >5
4096 //| dec dword [DISPATCH+DISPATCH_GL(hookcount)]
4097 //| jz >1
4098 //| test RDL, LUA_MASKLINE
4099 //| jz >5
4100 //|1:
4101 //| mov L:RB, SAVE_L
4102 //| mov L:RB->base, BASE
4103 //| mov FCARG2, PC // Caveat: FCARG2 == BASE
4104 //| mov FCARG1, L:RB
4105 //| // SAVE_PC must hold the _previous_ PC. The callee updates it with PC.
4106 //| call extern lj_dispatch_ins@8 // (lua_State *L, BCIns *pc)
4107 //|3:
4108 //| mov BASE, L:RB->base
4109 //|4:
4110 //| movzx RA, PC_RA
4111 //|5:
4112 //| movzx OP, PC_OP
4113 //| movzx RD, PC_RD
4114 //|.if X64
4115 //| jmp aword [DISPATCH+OP*8+GG_DISP2STATIC] // Re-dispatch to static ins.
4116 //|.else
4117 //| jmp aword [DISPATCH+OP*4+GG_DISP2STATIC] // Re-dispatch to static ins.
4118 //|.endif
4119 //|
4120 //|->cont_hook: // Continue from hook yield.
4121 //| add PC, 4
4122 dasm_put(Dst, 6784, DISPATCH_GL(hookmask), HOOK_ACTIVE, LUA_MASKLINE|LUA_MASKCOUNT, DISPATCH_GL(hookcount), LUA_MASKLINE, Dt1(->base), Dt1(->base), GG_DISP2STATIC);
4123#line 2853 "vm_x86.dasc"
4124 //| mov RA, [RB-24]
4125 //| mov MULTRES, RA // Restore MULTRES for *M ins.
4126 //| jmp <4
4127 //|
4128 //|->vm_hotloop: // Hot loop counter underflow.
4129 //|.if JIT
4130 //| mov LFUNC:RB, [BASE-8] // Same as curr_topL(L).
4131 //| mov RB, LFUNC:RB->pc
4132 //| movzx RD, byte [RB+PC2PROTO(framesize)]
4133 //| lea RD, [BASE+RD*8]
4134 //| mov L:RB, SAVE_L
4135 //| mov L:RB->base, BASE
4136 //| mov L:RB->top, RD
4137 //| mov FCARG2, PC
4138 //| lea FCARG1, [DISPATCH+GG_DISP2J]
4139 //| mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
4140 //| mov SAVE_PC, PC
4141 //| call extern lj_trace_hot@8 // (jit_State *J, const BCIns *pc)
4142 //| jmp <3
4143 //|.endif
4144 //|
4145 //|->vm_callhook: // Dispatch target for call hooks.
4146 //| mov SAVE_PC, PC
4147 //|.if JIT
4148 //| jmp >1
4149 //|.endif
4150 //|
4151 //|->vm_hotcall: // Hot call counter underflow.
4152 //|.if JIT
4153 //| mov SAVE_PC, PC
4154 //| or PC, 1 // Marker for hot call.
4155 //|1:
4156 //|.endif
4157 //| lea RD, [BASE+NARGS:RD*8-8]
4158 //| mov L:RB, SAVE_L
4159 //| mov L:RB->base, BASE
4160 //| mov L:RB->top, RD
4161 //| mov FCARG2, PC
4162 //| mov FCARG1, L:RB
4163 //| call extern lj_dispatch_call@8 // (lua_State *L, const BCIns *pc)
4164 //| // ASMFunction returned in eax/rax (RDa).
4165 //| mov SAVE_PC, 0 // Invalidate for subsequent line hook.
4166 //|.if JIT
4167 //| and PC, -2
4168 //|.endif
4169 //| mov BASE, L:RB->base
4170 //| mov RAa, RDa
4171 //| mov RD, L:RB->top
4172 //| sub RD, BASE
4173 dasm_put(Dst, 6869, Dt7(->pc), PC2PROTO(framesize), Dt1(->base), Dt1(->top), GG_DISP2J, DISPATCH_J(L), Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
4174#line 2902 "vm_x86.dasc"
4175 //| mov RBa, RAa
4176 //| movzx RA, PC_RA
4177 //| shr RD, 3
4178 //| add NARGS:RD, 1
4179 //| jmp RBa
4180 //|
4181 //|//-----------------------------------------------------------------------
4182 //|//-- Trace exit handler -------------------------------------------------
4183 //|//-----------------------------------------------------------------------
4184 //|
4185 //|// Called from an exit stub with the exit number on the stack.
4186 //|// The 16 bit exit number is stored with two (sign-extended) push imm8.
4187 //|->vm_exit_handler:
4188 //|.if JIT
4189 //|.if X64
4190 //| push r13; push r12
4191 //| push r11; push r10; push r9; push r8
4192 //| push rdi; push rsi; push rbp; lea rbp, [rsp+88]; push rbp
4193 //| push rbx; push rdx; push rcx; push rax
4194 //| movzx RC, byte [rbp-8] // Reconstruct exit number.
4195 //| mov RCH, byte [rbp-16]
4196 //| mov [rbp-8], r15; mov [rbp-16], r14
4197 //|.else
4198 //| push ebp; lea ebp, [esp+12]; push ebp
4199 //| push ebx; push edx; push ecx; push eax
4200 //| movzx RC, byte [ebp-4] // Reconstruct exit number.
4201 //| mov RCH, byte [ebp-8]
4202 //| mov [ebp-4], edi; mov [ebp-8], esi
4203 //|.endif
4204 //| // Caveat: DISPATCH is ebx.
4205 //| mov DISPATCH, [ebp]
4206 //| mov RA, [DISPATCH+DISPATCH_GL(vmstate)] // Get trace number.
4207 //| set_vmstate EXIT
4208 //| mov [DISPATCH+DISPATCH_J(exitno)], RC
4209 //| mov [DISPATCH+DISPATCH_J(parent)], RA
4210 //|.if X64
4211 //|.if X64WIN
4212 //| sub rsp, 16*8+4*8 // Room for SSE regs + save area.
4213 //|.else
4214 //| sub rsp, 16*8 // Room for SSE regs.
4215 //|.endif
4216 //| add rbp, -128
4217 //| movsd qword [rbp-8], xmm15; movsd qword [rbp-16], xmm14
4218 //| movsd qword [rbp-24], xmm13; movsd qword [rbp-32], xmm12
4219 //| movsd qword [rbp-40], xmm11; movsd qword [rbp-48], xmm10
4220 //| movsd qword [rbp-56], xmm9; movsd qword [rbp-64], xmm8
4221 //| movsd qword [rbp-72], xmm7; movsd qword [rbp-80], xmm6
4222 //| movsd qword [rbp-88], xmm5; movsd qword [rbp-96], xmm4
4223 //| movsd qword [rbp-104], xmm3; movsd qword [rbp-112], xmm2
4224 //| movsd qword [rbp-120], xmm1; movsd qword [rbp-128], xmm0
4225 //|.else
4226 //| sub esp, 8*8+16 // Room for SSE regs + args.
4227 //| movsd qword [ebp-40], xmm7; movsd qword [ebp-48], xmm6
4228 //| movsd qword [ebp-56], xmm5; movsd qword [ebp-64], xmm4
4229 //| movsd qword [ebp-72], xmm3; movsd qword [ebp-80], xmm2
4230 //| movsd qword [ebp-88], xmm1; movsd qword [ebp-96], xmm0
4231 //|.endif
4232 //| // Caveat: RB is ebp.
4233 //| mov L:RB, [DISPATCH+DISPATCH_GL(jit_L)]
4234 //| mov BASE, [DISPATCH+DISPATCH_GL(jit_base)]
4235 //| mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
4236 //| mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0
4237 //| mov L:RB->base, BASE
4238 //|.if X64WIN
4239 //| lea CARG2, [rsp+4*8]
4240 //|.elif X64
4241 //| mov CARG2, rsp
4242 //|.else
4243 //| lea FCARG2, [esp+16]
4244 //|.endif
4245 //| lea FCARG1, [DISPATCH+GG_DISP2J]
4246 //| call extern lj_trace_exit@8 // (jit_State *J, ExitState *ex)
4247 //| // MULTRES or negated error code returned in eax (RD).
4248 //| mov RAa, L:RB->cframe
4249 //| and RAa, CFRAME_RAWMASK
4250 //|.if X64WIN
4251 //| // Reposition stack later.
4252 //|.elif X64
4253 //| mov rsp, RAa // Reposition stack to C frame.
4254 //|.else
4255 //| mov esp, RAa // Reposition stack to C frame.
4256 //|.endif
4257 //| mov [RAa+CFRAME_OFS_L], L:RB // Set SAVE_L (on-trace resume/yield).
4258 //| mov BASE, L:RB->base
4259 //| mov PC, [RAa+CFRAME_OFS_PC] // Get SAVE_PC.
4260 //|.if X64
4261 //| jmp >1
4262 //|.endif
4263 //|.endif
4264 //|->vm_exit_interp:
4265 //| // RD = MULTRES or negated error code, BASE, PC and DISPATCH set.
4266 //|.if JIT
4267 //|.if X64
4268 //| // Restore additional callee-save registers only used in compiled code.
4269 //|.if X64WIN
4270 //| lea RAa, [rsp+9*16+4*8]
4271 //|1:
4272 //| movdqa xmm15, [RAa-9*16]
4273 //| movdqa xmm14, [RAa-8*16]
4274 //| movdqa xmm13, [RAa-7*16]
4275 //| movdqa xmm12, [RAa-6*16]
4276 //| movdqa xmm11, [RAa-5*16]
4277 //| movdqa xmm10, [RAa-4*16]
4278 //| movdqa xmm9, [RAa-3*16]
4279 //| movdqa xmm8, [RAa-2*16]
4280 //| movdqa xmm7, [RAa-1*16]
4281 //| mov rsp, RAa // Reposition stack to C frame.
4282 //| movdqa xmm6, [RAa]
4283 //| mov r15, CSAVE_3
4284 //| mov r14, CSAVE_4
4285 //|.else
4286 //| add rsp, 16 // Reposition stack to C frame.
4287 dasm_put(Dst, 6998, DISPATCH_GL(vmstate), DISPATCH_GL(vmstate), ~LJ_VMST_EXIT, DISPATCH_J(exitno), DISPATCH_J(parent), 16*8, DISPATCH_GL(jit_L), DISPATCH_GL(jit_base), DISPATCH_J(L), DISPATCH_GL(jit_L), Dt1(->base), GG_DISP2J, Dt1(->cframe), CFRAME_RAWMASK, CFRAME_OFS_L, Dt1(->base), CFRAME_OFS_PC);
4288#line 3014 "vm_x86.dasc"
4289 //|1:
4290 //|.endif
4291 //| mov r13, TMPa
4292 //| mov r12, TMPQ
4293 //|.endif
4294 //| test RD, RD; js >3 // Check for error from exit.
4295 //| mov MULTRES, RD
4296 //| mov LFUNC:KBASE, [BASE-8]
4297 //| mov KBASE, LFUNC:KBASE->pc
4298 //| mov KBASE, [KBASE+PC2PROTO(k)]
4299 //| mov dword [DISPATCH+DISPATCH_GL(jit_L)], 0
4300 //| set_vmstate INTERP
4301 //| // Modified copy of ins_next which handles function header dispatch, too.
4302 //| mov RC, [PC]
4303 //| movzx RA, RCH
4304 //| movzx OP, RCL
4305 //| add PC, 4
4306 //| shr RC, 16
4307 //| cmp OP, BC_FUNCF // Function header?
4308 //| jb >2
4309 //| mov RC, MULTRES // RC/RD holds nres+1.
4310 //|2:
4311 //|.if X64
4312 //| jmp aword [DISPATCH+OP*8]
4313 //|.else
4314 //| jmp aword [DISPATCH+OP*4]
4315 //|.endif
4316 //|
4317 //|3: // Rethrow error from the right C frame.
4318 //| neg RD
4319 //| mov FCARG1, L:RB
4320 //| mov FCARG2, RD
4321 //| call extern lj_err_throw@8 // (lua_State *L, int errcode)
4322 //|.endif
4323 //|
4324 //|//-----------------------------------------------------------------------
4325 //|//-- Math helper functions ----------------------------------------------
4326 //|//-----------------------------------------------------------------------
4327 //|
4328 //|// FP value rounding. Called by math.floor/math.ceil fast functions
4329 //|// and from JIT code.
4330 //|
4331 //|// x87 variant: Arg/ret on x87 stack. No int/xmm registers modified.
4332 //|.macro vm_round_x87, mode1, mode2
4333 //| fnstcw word [esp+4] // Caveat: overwrites ARG1 and ARG2.
4334 //| mov [esp+8], eax
4335 //| mov ax, mode1
4336 //| or ax, [esp+4]
4337 //|.if mode2 ~= 0xffff
4338 //| and ax, mode2
4339 //|.endif
4340 //| mov [esp+6], ax
4341 //| fldcw word [esp+6]
4342 //| frndint
4343 //| fldcw word [esp+4]
4344 //| mov eax, [esp+8]
4345 //| ret
4346 //|.endmacro
4347 //|
4348 //|// SSE variant: arg/ret is xmm0. xmm0-xmm3 and RD (eax) modified.
4349 //|.macro vm_round_sse, mode
4350 //| sseconst_abs xmm2, RDa
4351 //| sseconst_2p52 xmm3, RDa
4352 //| movaps xmm1, xmm0
4353 //| andpd xmm1, xmm2 // |x|
4354 //| ucomisd xmm3, xmm1 // No truncation if 2^52 <= |x|.
4355 //| jbe >1
4356 //| andnpd xmm2, xmm0 // Isolate sign bit.
4357 //|.if mode == 2 // trunc(x)?
4358 //| movaps xmm0, xmm1
4359 //| addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
4360 //| subsd xmm1, xmm3
4361 //| sseconst_1 xmm3, RDa
4362 //| cmpsd xmm0, xmm1, 1 // |x| < result?
4363 //| andpd xmm0, xmm3
4364 //| subsd xmm1, xmm0 // If yes, subtract -1.
4365 //| orpd xmm1, xmm2 // Merge sign bit back in.
4366 //|.else
4367 //| addsd xmm1, xmm3 // (|x| + 2^52) - 2^52
4368 //| subsd xmm1, xmm3
4369 //| orpd xmm1, xmm2 // Merge sign bit back in.
4370 //| .if mode == 1 // ceil(x)?
4371 //| sseconst_m1 xmm2, RDa // Must subtract -1 to preserve -0.
4372 //| cmpsd xmm0, xmm1, 6 // x > result?
4373 //| .else // floor(x)?
4374 //| sseconst_1 xmm2, RDa
4375 //| cmpsd xmm0, xmm1, 1 // x < result?
4376 //| .endif
4377 //| andpd xmm0, xmm2
4378 //| subsd xmm1, xmm0 // If yes, subtract +-1.
4379 //|.endif
4380 //| movaps xmm0, xmm1
4381 //|1:
4382 //| ret
4383 //|.endmacro
4384 //|
4385 //|.macro vm_round, name, ssemode, mode1, mode2
4386 //|->name:
4387 //|.if not SSE
4388 //| vm_round_x87 mode1, mode2
4389 //|.endif
4390 //|->name .. _sse:
4391 //| vm_round_sse ssemode
4392 //|.endmacro
4393 //|
4394 //| vm_round vm_floor, 0, 0x0400, 0xf7ff
4395 dasm_put(Dst, 7260, Dt7(->pc), PC2PROTO(k), DISPATCH_GL(jit_L), DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, BC_FUNCF, (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32));
4396#line 3120 "vm_x86.dasc"
4397 //| vm_round vm_ceil, 1, 0x0800, 0xfbff
4398 //| vm_round vm_trunc, 2, 0x0c00, 0xffff
4399 dasm_put(Dst, 7397, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(bff00000,00000000)), (unsigned int)((U64x(bff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32));
4400#line 3122 "vm_x86.dasc"
4401 //|
4402 //|// FP modulo x%y. Called by BC_MOD* and vm_arith.
4403 //|->vm_mod:
4404 //|.if SSE
4405 //|// Args in xmm0/xmm1, return value in xmm0.
4406 //|// Caveat: xmm0-xmm5 and RC (eax) modified!
4407 //| movaps xmm5, xmm0
4408 //| divsd xmm0, xmm1
4409 //| sseconst_abs xmm2, RDa
4410 //| sseconst_2p52 xmm3, RDa
4411 //| movaps xmm4, xmm0
4412 //| andpd xmm4, xmm2 // |x/y|
4413 //| ucomisd xmm3, xmm4 // No truncation if 2^52 <= |x/y|.
4414 //| jbe >1
4415 //| andnpd xmm2, xmm0 // Isolate sign bit.
4416 //| addsd xmm4, xmm3 // (|x/y| + 2^52) - 2^52
4417 //| subsd xmm4, xmm3
4418 //| orpd xmm4, xmm2 // Merge sign bit back in.
4419 //| sseconst_1 xmm2, RDa
4420 //| cmpsd xmm0, xmm4, 1 // x/y < result?
4421 //| andpd xmm0, xmm2
4422 //| subsd xmm4, xmm0 // If yes, subtract 1.0.
4423 //| movaps xmm0, xmm5
4424 //| mulsd xmm1, xmm4
4425 //| subsd xmm0, xmm1
4426 //| ret
4427 //|1:
4428 //| mulsd xmm1, xmm0
4429 //| movaps xmm0, xmm5
4430 //| subsd xmm0, xmm1
4431 //| ret
4432 //|.else
4433 //|// Args/ret on x87 stack (y on top). No xmm registers modified.
4434 //|// Caveat: needs 3 slots on x87 stack! RC (eax) modified!
4435 //| fld st1
4436 //| fdiv st1
4437 //| fnstcw word [esp+4]
4438 //| mov ax, 0x0400
4439 //| or ax, [esp+4]
4440 //| and ax, 0xf7ff
4441 //| mov [esp+6], ax
4442 //| fldcw word [esp+6]
4443 //| frndint
4444 //| fldcw word [esp+4]
4445 //| fmulp st1
4446 //| fsubp st1
4447 //| ret
4448 //|.endif
4449 //|
4450 //|// FP log2(x). Called by math.log(x, base).
4451 //|->vm_log2:
4452 //|.if X64WIN
4453 //| movsd qword [rsp+8], xmm0 // Use scratch area.
4454 //| fld1
4455 //| fld qword [rsp+8]
4456 //| fyl2x
4457 //| fstp qword [rsp+8]
4458 //| movsd xmm0, qword [rsp+8]
4459 //|.elif X64
4460 //| movsd qword [rsp-8], xmm0 // Use red zone.
4461 //| fld1
4462 //| fld qword [rsp-8]
4463 //| fyl2x
4464 //| fstp qword [rsp-8]
4465 //| movsd xmm0, qword [rsp-8]
4466 //|.else
4467 //| fld1
4468 //| fld qword [esp+4]
4469 //| fyl2x
4470 //|.endif
4471 //| ret
4472 //|
4473 //|// FP exponentiation e^x and 2^x. Called by math.exp fast function and
4474 //|// from JIT code. Arg/ret on x87 stack. No int/xmm regs modified.
4475 //|// Caveat: needs 3 slots on x87 stack!
4476 //|->vm_exp_x87:
4477 //| fldl2e; fmulp st1 // e^x ==> 2^(x*log2(e))
4478 //|->vm_exp2_x87:
4479 //| .if X64WIN
4480 //| .define expscratch, dword [rsp+8] // Use scratch area.
4481 //| .elif X64
4482 //| .define expscratch, dword [rsp-8] // Use red zone.
4483 //| .else
4484 //| .define expscratch, dword [esp+4] // Needs 4 byte scratch area.
4485 //| .endif
4486 //| fst expscratch // Caveat: overwrites ARG1.
4487 //| cmp expscratch, 0x7f800000; je >1 // Special case: e^+Inf = +Inf
4488 //| cmp expscratch, 0xff800000; je >2 // Special case: e^-Inf = 0
4489 dasm_put(Dst, 7548, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(43300000,00000000)), (unsigned int)((U64x(43300000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
4490#line 3210 "vm_x86.dasc"
4491 //|->vm_exp2raw: // Entry point for vm_pow. Without +-Inf check.
4492 //| fdup; frndint; fsub st1, st0; fxch // Split into frac/int part.
4493 //| f2xm1; fld1; faddp st1; fscale; fpop1 // ==> (2^frac-1 +1) << int
4494 //|1:
4495 //| ret
4496 //|2:
4497 //| fpop; fldz; ret
4498 //|
4499 //|// Generic power function x^y. Called by BC_POW, math.pow fast function,
4500 //|// and vm_arith.
4501 //|// Args/ret on x87 stack (y on top). RC (eax) modified.
4502 //|// Caveat: needs 3 slots on x87 stack!
4503 //|->vm_pow:
4504 //|.if not SSE
4505 //| fist dword [esp+4] // Store/reload int before comparison.
4506 //| fild dword [esp+4] // Integral exponent used in vm_powi.
4507 //| fucomip st1
4508 //| jnz >8 // Branch for FP exponents.
4509 //| jp >9 // Branch for NaN exponent.
4510 //| fpop // Pop y and fallthrough to vm_powi.
4511 //|
4512 //|// FP/int power function x^i. Arg1/ret on x87 stack.
4513 //|// Arg2 (int) on C stack. RC (eax) modified.
4514 //|// Caveat: needs 2 slots on x87 stack!
4515 //| mov eax, [esp+4]
4516 //| cmp eax, 1; jle >6 // i<=1?
4517 //| // Now 1 < (unsigned)i <= 0x80000000.
4518 //|1: // Handle leading zeros.
4519 //| test eax, 1; jnz >2
4520 //| fmul st0
4521 //| shr eax, 1
4522 //| jmp <1
4523 //|2:
4524 //| shr eax, 1; jz >5
4525 //| fdup
4526 //|3: // Handle trailing bits.
4527 //| fmul st0
4528 //| shr eax, 1; jz >4
4529 //| jnc <3
4530 //| fmul st1, st0
4531 //| jmp <3
4532 //|4:
4533 //| fmulp st1
4534 //|5:
4535 //| ret
4536 //|6:
4537 //| je <5 // x^1 ==> x
4538 //| jb >7
4539 //| fld1; fdivrp st1
4540 //| neg eax
4541 //| cmp eax, 1; je <5 // x^-1 ==> 1/x
4542 //| jmp <1 // x^-i ==> (1/x)^i
4543 //|7:
4544 //| fpop; fld1 // x^0 ==> 1
4545 //| ret
4546 //|
4547 //|8: // FP/FP power function x^y.
4548 //| fst dword [esp+4]
4549 //| fxch
4550 //| fst dword [esp+8]
4551 //| mov eax, [esp+4]; shl eax, 1
4552 //| cmp eax, 0xff000000; je >2 // x^+-Inf?
4553 //| mov eax, [esp+8]; shl eax, 1; je >4 // +-0^y?
4554 //| cmp eax, 0xff000000; je >4 // +-Inf^y?
4555 //| fyl2x
4556 //| jmp ->vm_exp2raw
4557 //|
4558 //|9: // Handle x^NaN.
4559 //| fld1
4560 //| fucomip st2
4561 //| je >1 // 1^NaN ==> 1
4562 //| fxch // x^NaN ==> NaN
4563 //|1:
4564 //| fpop
4565 //| ret
4566 //|
4567 //|2: // Handle x^+-Inf.
4568 //| fabs
4569 //| fld1
4570 //| fucomip st1
4571 //| je >3 // +-1^+-Inf ==> 1
4572 //| fpop; fabs; fldz; mov eax, 0; setc al
4573 //| ror eax, 1; xor eax, [esp+4]; jns >3 // |x|<>1, x^+-Inf ==> +Inf/0
4574 //| fxch
4575 //|3:
4576 //| fpop1; fabs
4577 //| ret
4578 //|
4579 //|4: // Handle +-0^y or +-Inf^y.
4580 //| cmp dword [esp+4], 0; jge <3 // y >= 0, x^y ==> |x|
4581 //| fpop; fpop
4582 //| test eax, eax; jz >5 // y < 0, +-0^y ==> +Inf
4583 //| fldz // y < 0, +-Inf^y ==> 0
4584 //| ret
4585 //|5:
4586 //| mov dword [esp+4], 0x7f800000 // Return +Inf.
4587 //| fld dword [esp+4]
4588 //| ret
4589 //|.endif
4590 //|
4591 //|// Args in xmm0/xmm1. Ret in xmm0. xmm0-xmm2 and RC (eax) modified.
4592 //|// Needs 16 byte scratch area for x86. Also called from JIT code.
4593 //|->vm_pow_sse:
4594 //| cvtsd2si eax, xmm1
4595 //| cvtsi2sd xmm2, eax
4596 //| ucomisd xmm1, xmm2
4597 //| jnz >8 // Branch for FP exponents.
4598 //| jp >9 // Branch for NaN exponent.
4599 //| // Fallthrough to vm_powi_sse.
4600 //|
4601 //|// Args in xmm0/eax. Ret in xmm0. xmm0-xmm1 and eax modified.
4602 //|->vm_powi_sse:
4603 //| cmp eax, 1; jle >6 // i<=1?
4604 //| // Now 1 < (unsigned)i <= 0x80000000.
4605 //|1: // Handle leading zeros.
4606 //| test eax, 1; jnz >2
4607 //| mulsd xmm0, xmm0
4608 //| shr eax, 1
4609 //| jmp <1
4610 //|2:
4611 //| shr eax, 1; jz >5
4612 dasm_put(Dst, 7796);
4613#line 3331 "vm_x86.dasc"
4614 //| movaps xmm1, xmm0
4615 //|3: // Handle trailing bits.
4616 //| mulsd xmm0, xmm0
4617 //| shr eax, 1; jz >4
4618 //| jnc <3
4619 //| mulsd xmm1, xmm0
4620 //| jmp <3
4621 //|4:
4622 //| mulsd xmm0, xmm1
4623 //|5:
4624 //| ret
4625 //|6:
4626 //| je <5 // x^1 ==> x
4627 //| jb >7 // x^0 ==> 1
4628 //| neg eax
4629 //| call <1
4630 //| sseconst_1 xmm1, RDa
4631 dasm_put(Dst, 7906, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
4632#line 3348 "vm_x86.dasc"
4633 //| divsd xmm1, xmm0
4634 //| movaps xmm0, xmm1
4635 //| ret
4636 //|7:
4637 //| sseconst_1 xmm0, RDa
4638 //| ret
4639 //|
4640 //|8: // FP/FP power function x^y.
4641 //|.if X64
4642 //| movd rax, xmm1; shl rax, 1
4643 //| rol rax, 12; cmp rax, 0xffe; je >2 // x^+-Inf?
4644 //| movd rax, xmm0; shl rax, 1; je >4 // +-0^y?
4645 //| rol rax, 12; cmp rax, 0xffe; je >5 // +-Inf^y?
4646 //| .if X64WIN
4647 //| movsd qword [rsp+16], xmm1 // Use scratch area.
4648 //| movsd qword [rsp+8], xmm0
4649 //| fld qword [rsp+16]
4650 //| fld qword [rsp+8]
4651 //| .else
4652 //| movsd qword [rsp-16], xmm1 // Use red zone.
4653 //| movsd qword [rsp-8], xmm0
4654 //| fld qword [rsp-16]
4655 //| fld qword [rsp-8]
4656 //| .endif
4657 //|.else
4658 //| movsd qword [esp+12], xmm1 // Needs 16 byte scratch area.
4659 //| movsd qword [esp+4], xmm0
4660 //| cmp dword [esp+12], 0; jne >1
4661 //| mov eax, [esp+16]; shl eax, 1
4662 //| cmp eax, 0xffe00000; je >2 // x^+-Inf?
4663 //|1:
4664 //| cmp dword [esp+4], 0; jne >1
4665 //| mov eax, [esp+8]; shl eax, 1; je >4 // +-0^y?
4666 //| cmp eax, 0xffe00000; je >5 // +-Inf^y?
4667 //|1:
4668 //| fld qword [esp+12]
4669 //| fld qword [esp+4]
4670 //|.endif
4671 //| fyl2x // y*log2(x)
4672 //| fdup; frndint; fsub st1, st0; fxch // Split into frac/int part.
4673 //| f2xm1; fld1; faddp st1; fscale; fpop1 // ==> (2^frac-1 +1) << int
4674 //|.if X64WIN
4675 //| fstp qword [rsp+8] // Use scratch area.
4676 //| movsd xmm0, qword [rsp+8]
4677 //|.elif X64
4678 //| fstp qword [rsp-8] // Use red zone.
4679 //| movsd xmm0, qword [rsp-8]
4680 //|.else
4681 //| fstp qword [esp+4] // Needs 8 byte scratch area.
4682 //| movsd xmm0, qword [esp+4]
4683 //|.endif
4684 //| ret
4685 //|
4686 //|9: // Handle x^NaN.
4687 //| sseconst_1 xmm2, RDa
4688 //| ucomisd xmm0, xmm2; je >1 // 1^NaN ==> 1
4689 //| movaps xmm0, xmm1 // x^NaN ==> NaN
4690 //|1:
4691 //| ret
4692 //|
4693 //|2: // Handle x^+-Inf.
4694 //| sseconst_abs xmm2, RDa
4695 //| andpd xmm0, xmm2 // |x|
4696 //| sseconst_1 xmm2, RDa
4697 dasm_put(Dst, 7972, (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32), (unsigned int)(U64x(3ff00000,00000000)), (unsigned int)((U64x(3ff00000,00000000))>>32));
4698#line 3412 "vm_x86.dasc"
4699 //| ucomisd xmm0, xmm2; je <1 // +-1^+-Inf ==> 1
4700 //| movmskpd eax, xmm1
4701 //| xorps xmm0, xmm0
4702 //| mov ah, al; setc al; xor al, ah; jne <1 // |x|<>1, x^+-Inf ==> +Inf/0
4703 //|3:
4704 //| sseconst_hi xmm0, RDa, 7ff00000 // +Inf
4705 //| ret
4706 //|
4707 //|4: // Handle +-0^y.
4708 //| movmskpd eax, xmm1; test eax, eax; jnz <3 // y < 0, +-0^y ==> +Inf
4709 //| xorps xmm0, xmm0 // y >= 0, +-0^y ==> 0
4710 //| ret
4711 //|
4712 //|5: // Handle +-Inf^y.
4713 //| movmskpd eax, xmm1; test eax, eax; jz <3 // y >= 0, +-Inf^y ==> +Inf
4714 //| xorps xmm0, xmm0 // y < 0, +-Inf^y ==> 0
4715 //| ret
4716 //|
4717 //|// Callable from C: double lj_vm_foldfpm(double x, int fpm)
4718 //|// Computes fpm(x) for extended math functions. ORDER FPM.
4719 //|->vm_foldfpm:
4720 //|.if JIT
4721 //|.if X64
4722 //| .if X64WIN
4723 //| .define fpmop, CARG2d
4724 //| .else
4725 //| .define fpmop, CARG1d
4726 //| .endif
4727 //| cmp fpmop, 1; jb ->vm_floor; je ->vm_ceil
4728 //| cmp fpmop, 3; jb ->vm_trunc; ja >2
4729 dasm_put(Dst, 8160, (unsigned int)(U64x(7ff00000,00000000)), (unsigned int)((U64x(7ff00000,00000000))>>32));
4730#line 3442 "vm_x86.dasc"
4731 //| sqrtsd xmm0, xmm0; ret
4732 //|2:
4733 //| .if X64WIN
4734 //| movsd qword [rsp+8], xmm0 // Use scratch area.
4735 //| fld qword [rsp+8]
4736 //| .else
4737 //| movsd qword [rsp-8], xmm0 // Use red zone.
4738 //| fld qword [rsp-8]
4739 //| .endif
4740 //| cmp fpmop, 5; ja >2
4741 //| .if X64WIN; pop rax; .endif
4742 //| je >1
4743 //| call ->vm_exp_x87
4744 //| .if X64WIN; push rax; .endif
4745 //| jmp >7
4746 //|1:
4747 //| call ->vm_exp2_x87
4748 //| .if X64WIN; push rax; .endif
4749 //| jmp >7
4750 //|2: ; cmp fpmop, 7; je >1; ja >2
4751 //| fldln2; fxch; fyl2x; jmp >7
4752 dasm_put(Dst, 8258);
4753#line 3463 "vm_x86.dasc"
4754 //|1: ; fld1; fxch; fyl2x; jmp >7
4755 //|2: ; cmp fpmop, 9; je >1; ja >2
4756 //| fldlg2; fxch; fyl2x; jmp >7
4757 //|1: ; fsin; jmp >7
4758 //|2: ; cmp fpmop, 11; je >1; ja >9
4759 //| fcos; jmp >7
4760 dasm_put(Dst, 8326);
4761#line 3469 "vm_x86.dasc"
4762 //|1: ; fptan; fpop
4763 //|7:
4764 //| .if X64WIN
4765 //| fstp qword [rsp+8] // Use scratch area.
4766 //| movsd xmm0, qword [rsp+8]
4767 //| .else
4768 //| fstp qword [rsp-8] // Use red zone.
4769 //| movsd xmm0, qword [rsp-8]
4770 //| .endif
4771 //| ret
4772 //|.else // x86 calling convention.
4773 //| .define fpmop, eax
4774 //|.if SSE
4775 //| mov fpmop, [esp+12]
4776 //| movsd xmm0, qword [esp+4]
4777 //| cmp fpmop, 1; je >1; ja >2
4778 //| call ->vm_floor; jmp >7
4779 //|1: ; call ->vm_ceil; jmp >7
4780 //|2: ; cmp fpmop, 3; je >1; ja >2
4781 //| call ->vm_trunc; jmp >7
4782 //|1:
4783 //| sqrtsd xmm0, xmm0
4784 //|7:
4785 //| movsd qword [esp+4], xmm0 // Overwrite callee-owned args.
4786 //| fld qword [esp+4]
4787 //| ret
4788 //|2: ; fld qword [esp+4]
4789 //| cmp fpmop, 5; jb ->vm_exp_x87; je ->vm_exp2_x87
4790 //|2: ; cmp fpmop, 7; je >1; ja >2
4791 //| fldln2; fxch; fyl2x; ret
4792 //|1: ; fld1; fxch; fyl2x; ret
4793 //|2: ; cmp fpmop, 9; je >1; ja >2
4794 //| fldlg2; fxch; fyl2x; ret
4795 //|1: ; fsin; ret
4796 //|2: ; cmp fpmop, 11; je >1; ja >9
4797 //| fcos; ret
4798 //|1: ; fptan; fpop; ret
4799 //|.else
4800 //| mov fpmop, [esp+12]
4801 //| fld qword [esp+4]
4802 //| cmp fpmop, 1; jb ->vm_floor; je ->vm_ceil
4803 //| cmp fpmop, 3; jb ->vm_trunc; ja >2
4804 //| fsqrt; ret
4805 //|2: ; cmp fpmop, 5; jb ->vm_exp_x87; je ->vm_exp2_x87
4806 //| cmp fpmop, 7; je >1; ja >2
4807 //| fldln2; fxch; fyl2x; ret
4808 //|1: ; fld1; fxch; fyl2x; ret
4809 //|2: ; cmp fpmop, 9; je >1; ja >2
4810 //| fldlg2; fxch; fyl2x; ret
4811 //|1: ; fsin; ret
4812 //|2: ; cmp fpmop, 11; je >1; ja >9
4813 //| fcos; ret
4814 //|1: ; fptan; fpop; ret
4815 //|.endif
4816 //|.endif
4817 //|9: ; int3 // Bad fpm.
4818 //|.endif
4819 //|
4820 //|// Callable from C: double lj_vm_foldarith(double x, double y, int op)
4821 //|// Compute x op y for basic arithmetic operators (+ - * / % ^ and unary -)
4822 //|// and basic math functions. ORDER ARITH
4823 //|->vm_foldarith:
4824 //|.if X64
4825 //|
4826 //| .if X64WIN
4827 //| .define foldop, CARG3d
4828 //| .else
4829 //| .define foldop, CARG1d
4830 //| .endif
4831 //| cmp foldop, 1; je >1; ja >2
4832 //| addsd xmm0, xmm1; ret
4833 //|1: ; subsd xmm0, xmm1; ret
4834 //|2: ; cmp foldop, 3; je >1; ja >2
4835 //| mulsd xmm0, xmm1; ret
4836 //|1: ; divsd xmm0, xmm1; ret
4837 //|2: ; cmp foldop, 5; jb ->vm_mod; je ->vm_pow
4838 dasm_put(Dst, 8401);
4839#line 3545 "vm_x86.dasc"
4840 //| cmp foldop, 7; je >1; ja >2
4841 //| sseconst_sign xmm1, RDa; xorps xmm0, xmm1; ret
4842 //|1: ; sseconst_abs xmm1, RDa; andps xmm0, xmm1; ret
4843 //|2: ; cmp foldop, 9; ja >2
4844 //|.if X64WIN
4845 //| movsd qword [rsp+8], xmm0 // Use scratch area.
4846 //| movsd qword [rsp+16], xmm1
4847 //| fld qword [rsp+8]
4848 //| fld qword [rsp+16]
4849 //|.else
4850 //| movsd qword [rsp-8], xmm0 // Use red zone.
4851 //| movsd qword [rsp-16], xmm1
4852 //| fld qword [rsp-8]
4853 //| fld qword [rsp-16]
4854 //|.endif
4855 //| je >1
4856 //| fpatan
4857 //|7:
4858 //|.if X64WIN
4859 //| fstp qword [rsp+8] // Use scratch area.
4860 //| movsd xmm0, qword [rsp+8]
4861 //|.else
4862 //| fstp qword [rsp-8] // Use red zone.
4863 //| movsd xmm0, qword [rsp-8]
4864 //|.endif
4865 //| ret
4866 //|1: ; fxch; fscale; fpop1; jmp <7
4867 //|2: ; cmp foldop, 11; je >1; ja >9
4868 dasm_put(Dst, 8501, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32), (unsigned int)(U64x(7fffffff,ffffffff)), (unsigned int)((U64x(7fffffff,ffffffff))>>32));
4869#line 3573 "vm_x86.dasc"
4870 //| minsd xmm0, xmm1; ret
4871 //|1: ; maxsd xmm0, xmm1; ret
4872 //|9: ; int3 // Bad op.
4873 //|
4874 //|.elif SSE // x86 calling convention with SSE ops.
4875 //|
4876 //| .define foldop, eax
4877 //| mov foldop, [esp+20]
4878 //| movsd xmm0, qword [esp+4]
4879 //| movsd xmm1, qword [esp+12]
4880 //| cmp foldop, 1; je >1; ja >2
4881 //| addsd xmm0, xmm1
4882 //|7:
4883 //| movsd qword [esp+4], xmm0 // Overwrite callee-owned args.
4884 //| fld qword [esp+4]
4885 //| ret
4886 //|1: ; subsd xmm0, xmm1; jmp <7
4887 //|2: ; cmp foldop, 3; je >1; ja >2
4888 //| mulsd xmm0, xmm1; jmp <7
4889 //|1: ; divsd xmm0, xmm1; jmp <7
4890 //|2: ; cmp foldop, 5
4891 //| je >1; ja >2
4892 //| call ->vm_mod; jmp <7
4893 //|1: ; pop edx; call ->vm_pow; push edx; jmp <7 // Writes to scratch area.
4894 //|2: ; cmp foldop, 7; je >1; ja >2
4895 //| sseconst_sign xmm1, RDa; xorps xmm0, xmm1; jmp <7
4896 //|1: ; sseconst_abs xmm1, RDa; andps xmm0, xmm1; jmp <7
4897 //|2: ; cmp foldop, 9; ja >2
4898 //| fld qword [esp+4] // Reload from stack
4899 //| fld qword [esp+12]
4900 //| je >1
4901 //| fpatan; ret
4902 //|1: ; fxch; fscale; fpop1; ret
4903 //|2: ; cmp foldop, 11; je >1; ja >9
4904 //| minsd xmm0, xmm1; jmp <7
4905 //|1: ; maxsd xmm0, xmm1; jmp <7
4906 //|9: ; int3 // Bad op.
4907 //|
4908 //|.else // x86 calling convention with x87 ops.
4909 //|
4910 //| mov eax, [esp+20]
4911 //| fld qword [esp+4]
4912 //| fld qword [esp+12]
4913 //| cmp eax, 1; je >1; ja >2
4914 //| faddp st1; ret
4915 //|1: ; fsubp st1; ret
4916 //|2: ; cmp eax, 3; je >1; ja >2
4917 //| fmulp st1; ret
4918 //|1: ; fdivp st1; ret
4919 //|2: ; cmp eax, 5; jb ->vm_mod; je ->vm_pow
4920 //| cmp eax, 7; je >1; ja >2
4921 //| fpop; fchs; ret
4922 //|1: ; fpop; fabs; ret
4923 //|2: ; cmp eax, 9; je >1; ja >2
4924 //| fpatan; ret
4925 //|1: ; fxch; fscale; fpop1; ret
4926 //|2: ; cmp eax, 11; je >1; ja >9
4927 //| fucomi st1; fcmovnbe st1; fpop1; ret
4928 //|1: ; fucomi st1; fcmovbe st1; fpop1; ret
4929 //|9: ; int3 // Bad op.
4930 //|
4931 //|.endif
4932 //|
4933 //|//-----------------------------------------------------------------------
4934 //|//-- Miscellaneous functions --------------------------------------------
4935 //|//-----------------------------------------------------------------------
4936 //|
4937 //|// int lj_vm_cpuid(uint32_t f, uint32_t res[4])
4938 //|->vm_cpuid:
4939 //|.if X64
4940 //| mov eax, CARG1d
4941 //| .if X64WIN; push rsi; mov rsi, CARG2; .endif
4942 //| push rbx
4943 //| cpuid
4944 //| mov [rsi], eax
4945 //| mov [rsi+4], ebx
4946 //| mov [rsi+8], ecx
4947 //| mov [rsi+12], edx
4948 //| pop rbx
4949 //| .if X64WIN; pop rsi; .endif
4950 //| ret
4951 //|.else
4952 //| pushfd
4953 //| pop edx
4954 //| mov ecx, edx
4955 //| xor edx, 0x00200000 // Toggle ID bit in flags.
4956 //| push edx
4957 //| popfd
4958 //| pushfd
4959 //| pop edx
4960 //| xor eax, eax // Zero means no features supported.
4961 //| cmp ecx, edx
4962 //| jz >1 // No ID toggle means no CPUID support.
4963 //| mov eax, [esp+4] // Argument 1 is function number.
4964 //| push edi
4965 //| push ebx
4966 //| cpuid
4967 //| mov edi, [esp+16] // Argument 2 is result area.
4968 //| mov [edi], eax
4969 //| mov [edi+4], ebx
4970 //| mov [edi+8], ecx
4971 //| mov [edi+12], edx
4972 //| pop ebx
4973 //| pop edi
4974 //|1:
4975 //| ret
4976 //|.endif
4977 //|
4978 //|//-----------------------------------------------------------------------
4979 //|//-- Assertions ---------------------------------------------------------
4980 //|//-----------------------------------------------------------------------
4981 //|
4982 //|->assert_bad_for_arg_type:
4983 dasm_put(Dst, 8620);
4984#line 3686 "vm_x86.dasc"
4985#ifdef LUA_USE_ASSERT
4986 //| int3
4987 dasm_put(Dst, 8673);
4988#line 3688 "vm_x86.dasc"
4989#endif
4990 //| int3
4991 //|
4992 //|//-----------------------------------------------------------------------
4993 //|//-- FFI helper functions -----------------------------------------------
4994 //|//-----------------------------------------------------------------------
4995 //|
4996 //|// Handler for callback functions. Callback slot number in ah/al.
4997 //|->vm_ffi_callback:
4998 //|.if FFI
4999 //|.type CTSTATE, CTState, PC
5000#define DtE(_V) (int)(ptrdiff_t)&(((CTState *)0)_V)
5001#line 3699 "vm_x86.dasc"
5002 //|.if not X64
5003 //| sub esp, 16 // Leave room for SAVE_ERRF etc.
5004 //|.endif
5005 //| saveregs_ // ebp/rbp already saved. ebp now holds global_State *.
5006 //| lea DISPATCH, [ebp+GG_G2DISP]
5007 //| mov CTSTATE, GL:ebp->ctype_state
5008 //| movzx eax, ax
5009 //| mov CTSTATE->cb.slot, eax
5010 //|.if X64
5011 //| mov CTSTATE->cb.gpr[0], CARG1
5012 //| mov CTSTATE->cb.gpr[1], CARG2
5013 //| mov CTSTATE->cb.gpr[2], CARG3
5014 //| mov CTSTATE->cb.gpr[3], CARG4
5015 //| movsd qword CTSTATE->cb.fpr[0], xmm0
5016 //| movsd qword CTSTATE->cb.fpr[1], xmm1
5017 //| movsd qword CTSTATE->cb.fpr[2], xmm2
5018 //| movsd qword CTSTATE->cb.fpr[3], xmm3
5019 //|.if X64WIN
5020 //| lea rax, [rsp+CFRAME_SIZE+4*8]
5021 //|.else
5022 //| lea rax, [rsp+CFRAME_SIZE]
5023 //| mov CTSTATE->cb.gpr[4], CARG5
5024 //| mov CTSTATE->cb.gpr[5], CARG6
5025 //| movsd qword CTSTATE->cb.fpr[4], xmm4
5026 //| movsd qword CTSTATE->cb.fpr[5], xmm5
5027 //| movsd qword CTSTATE->cb.fpr[6], xmm6
5028 //| movsd qword CTSTATE->cb.fpr[7], xmm7
5029 //|.endif
5030 //| mov CTSTATE->cb.stack, rax
5031 //| mov CARG2, rsp
5032 dasm_put(Dst, 8675, GG_G2DISP, Dt2(->ctype_state), DtE(->cb.slot), DtE(->cb.gpr[0]), DtE(->cb.gpr[1]), DtE(->cb.gpr[2]), DtE(->cb.gpr[3]), DtE(->cb.fpr[0]), DtE(->cb.fpr[1]), DtE(->cb.fpr[2]), DtE(->cb.fpr[3]), CFRAME_SIZE, DtE(->cb.gpr[4]), DtE(->cb.gpr[5]), DtE(->cb.fpr[4]), DtE(->cb.fpr[5]), DtE(->cb.fpr[6]), DtE(->cb.fpr[7]), DtE(->cb.stack));
5033#line 3729 "vm_x86.dasc"
5034 //|.else
5035 //| lea eax, [esp+CFRAME_SIZE+16]
5036 //| mov CTSTATE->cb.gpr[0], FCARG1
5037 //| mov CTSTATE->cb.gpr[1], FCARG2
5038 //| mov CTSTATE->cb.stack, eax
5039 //| mov FCARG1, [esp+CFRAME_SIZE+12] // Move around misplaced retaddr/ebp.
5040 //| mov FCARG2, [esp+CFRAME_SIZE+8]
5041 //| mov SAVE_RET, FCARG1
5042 //| mov SAVE_R4, FCARG2
5043 //| mov FCARG2, esp
5044 //|.endif
5045 //| mov SAVE_PC, CTSTATE // Any value outside of bytecode is ok.
5046 //| mov FCARG1, CTSTATE
5047 //| call extern lj_ccallback_enter@8 // (CTState *cts, void *cf)
5048 //| // lua_State * returned in eax (RD).
5049 //| set_vmstate INTERP
5050 //| mov BASE, L:RD->base
5051 //| mov RD, L:RD->top
5052 //| sub RD, BASE
5053 //| mov LFUNC:RB, [BASE-8]
5054 //| shr RD, 3
5055 //| add RD, 1
5056 //| ins_callt
5057 //|.endif
5058 //|
5059 //|->cont_ffi_callback: // Return from FFI callback.
5060 //|.if FFI
5061 //| mov L:RA, SAVE_L
5062 //| mov CTSTATE, [DISPATCH+DISPATCH_GL(ctype_state)]
5063 //| mov aword CTSTATE->L, L:RAa
5064 //| mov L:RA->base, BASE
5065 //| mov L:RA->top, RB
5066 //| mov FCARG1, CTSTATE
5067 //| mov FCARG2, RC
5068 //| call extern lj_ccallback_leave@8 // (CTState *cts, TValue *o)
5069 //|.if X64
5070 //| mov rax, CTSTATE->cb.gpr[0]
5071 //| movsd xmm0, qword CTSTATE->cb.fpr[0]
5072 //| jmp ->vm_leave_unw
5073 //|.else
5074 //| mov L:RB, SAVE_L
5075 //| mov eax, CTSTATE->cb.gpr[0]
5076 //| mov edx, CTSTATE->cb.gpr[1]
5077 //| cmp dword CTSTATE->cb.gpr[2], 1
5078 //| jb >7
5079 //| je >6
5080 //| fld qword CTSTATE->cb.fpr[0].d
5081 //| jmp >7
5082 //|6:
5083 //| fld dword CTSTATE->cb.fpr[0].f
5084 //|7:
5085 //| mov ecx, L:RB->top
5086 //| movzx ecx, word [ecx+6] // Get stack adjustment and copy up.
5087 //| mov SAVE_L, ecx // Must be one slot above SAVE_RET
5088 //| restoreregs
5089 //| pop ecx // Move return addr from SAVE_RET.
5090 //| add esp, [esp] // Adjust stack.
5091 //| add esp, 16
5092 //| push ecx
5093 //| ret
5094 //|.endif
5095 //|.endif
5096 //|
5097 //|->vm_ffi_call@4: // Call C function via FFI.
5098 //| // Caveat: needs special frame unwinding, see below.
5099 //|.if FFI
5100 //|.if X64
5101 //| .type CCSTATE, CCallState, rbx
5102#define DtF(_V) (int)(ptrdiff_t)&(((CCallState *)0)_V)
5103#line 3797 "vm_x86.dasc"
5104 //| push rbp; mov rbp, rsp; push rbx; mov CCSTATE, CARG1
5105 //|.else
5106 //| .type CCSTATE, CCallState, ebx
5107 //| push ebp; mov ebp, esp; push ebx; mov CCSTATE, FCARG1
5108 //|.endif
5109 //|
5110 //| // Readjust stack.
5111 //|.if X64
5112 //| mov eax, CCSTATE->spadj
5113 //| sub rsp, rax
5114 //|.else
5115 //| sub esp, CCSTATE->spadj
5116 //|.if WIN
5117 //| mov CCSTATE->spadj, esp
5118 //|.endif
5119 //|.endif
5120 //|
5121 //| // Copy stack slots.
5122 //| movzx ecx, byte CCSTATE->nsp
5123 //| sub ecx, 1
5124 //| js >2
5125 //|1:
5126 //|.if X64
5127 //| mov rax, [CCSTATE+rcx*8+offsetof(CCallState, stack)]
5128 dasm_put(Dst, 8784, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top), Dt7(->pc), DISPATCH_GL(ctype_state), DtE(->L), Dt1(->base), Dt1(->top), DtE(->cb.gpr[0]), DtE(->cb.fpr[0]), DtF(->spadj), DtF(->nsp));
5129#line 3821 "vm_x86.dasc"
5130 //| mov [rsp+rcx*8+CCALL_SPS_EXTRA*8], rax
5131 //|.else
5132 //| mov eax, [CCSTATE+ecx*4+offsetof(CCallState, stack)]
5133 //| mov [esp+ecx*4], eax
5134 //|.endif
5135 //| sub ecx, 1
5136 //| jns <1
5137 //|2:
5138 //|
5139 //|.if X64
5140 //| movzx eax, byte CCSTATE->nfpr
5141 //| mov CARG1, CCSTATE->gpr[0]
5142 //| mov CARG2, CCSTATE->gpr[1]
5143 //| mov CARG3, CCSTATE->gpr[2]
5144 //| mov CARG4, CCSTATE->gpr[3]
5145 //|.if not X64WIN
5146 //| mov CARG5, CCSTATE->gpr[4]
5147 //| mov CARG6, CCSTATE->gpr[5]
5148 //|.endif
5149 //| test eax, eax; jz >5
5150 //| movaps xmm0, CCSTATE->fpr[0]
5151 //| movaps xmm1, CCSTATE->fpr[1]
5152 //| movaps xmm2, CCSTATE->fpr[2]
5153 //| movaps xmm3, CCSTATE->fpr[3]
5154 //|.if not X64WIN
5155 //| cmp eax, 4; jbe >5
5156 //| movaps xmm4, CCSTATE->fpr[4]
5157 dasm_put(Dst, 8915, offsetof(CCallState, stack), CCALL_SPS_EXTRA*8, DtF(->nfpr), DtF(->gpr[0]), DtF(->gpr[1]), DtF(->gpr[2]), DtF(->gpr[3]), DtF(->gpr[4]), DtF(->gpr[5]), DtF(->fpr[0]), DtF(->fpr[1]), DtF(->fpr[2]), DtF(->fpr[3]));
5158#line 3848 "vm_x86.dasc"
5159 //| movaps xmm5, CCSTATE->fpr[5]
5160 //| movaps xmm6, CCSTATE->fpr[6]
5161 //| movaps xmm7, CCSTATE->fpr[7]
5162 //|.endif
5163 //|5:
5164 //|.else
5165 //| mov FCARG1, CCSTATE->gpr[0]
5166 //| mov FCARG2, CCSTATE->gpr[1]
5167 //|.endif
5168 //|
5169 //| call aword CCSTATE->func
5170 //|
5171 //|.if X64
5172 //| mov CCSTATE->gpr[0], rax
5173 //| movaps CCSTATE->fpr[0], xmm0
5174 //|.if not X64WIN
5175 //| mov CCSTATE->gpr[1], rdx
5176 //| movaps CCSTATE->fpr[1], xmm1
5177 //|.endif
5178 //|.else
5179 //| mov CCSTATE->gpr[0], eax
5180 //| mov CCSTATE->gpr[1], edx
5181 //| cmp byte CCSTATE->resx87, 1
5182 //| jb >7
5183 //| je >6
5184 //| fstp qword CCSTATE->fpr[0].d[0]
5185 //| jmp >7
5186 //|6:
5187 //| fstp dword CCSTATE->fpr[0].f[0]
5188 //|7:
5189 //|.if WIN
5190 //| sub CCSTATE->spadj, esp
5191 //|.endif
5192 //|.endif
5193 //|
5194 //|.if X64
5195 //| mov rbx, [rbp-8]; leave; ret
5196 //|.else
5197 //| mov ebx, [ebp-4]; leave; ret
5198 //|.endif
5199 //|.endif
5200 //|// Note: vm_ffi_call must be the last function in this object file!
5201 //|
5202 //|//-----------------------------------------------------------------------
5203 dasm_put(Dst, 8996, DtF(->fpr[4]), DtF(->fpr[5]), DtF(->fpr[6]), DtF(->fpr[7]), DtF(->func), DtF(->gpr[0]), DtF(->fpr[0]), DtF(->gpr[1]), DtF(->fpr[1]));
5204#line 3892 "vm_x86.dasc"
5205}
5206
5207/* Generate the code for a single instruction. */
5208static void build_ins(BuildCtx *ctx, BCOp op, int defop)
5209{
5210 int vk = 0;
5211 //|// Note: aligning all instructions does not pay off.
5212 //|=>defop:
5213 dasm_put(Dst, 522, defop);
5214#line 3900 "vm_x86.dasc"
5215
5216 switch (op) {
5217
5218 /* -- Comparison ops ---------------------------------------------------- */
5219
5220 /* Remember: all ops branch for a true comparison, fall through otherwise. */
5221
5222 //|.macro jmp_comp, lt, ge, le, gt, target
5223 //||switch (op) {
5224 //||case BC_ISLT:
5225 //| lt target
5226 //||break;
5227 //||case BC_ISGE:
5228 //| ge target
5229 //||break;
5230 //||case BC_ISLE:
5231 //| le target
5232 //||break;
5233 //||case BC_ISGT:
5234 //| gt target
5235 //||break;
5236 //||default: break; /* Shut up GCC. */
5237 //||}
5238 //|.endmacro
5239
5240 case BC_ISLT: case BC_ISGE: case BC_ISLE: case BC_ISGT:
5241 //| // RA = src1, RD = src2, JMP with RD = target
5242 //| ins_AD
5243 //|.if DUALNUM
5244 //| checkint RA, >7
5245 //| checkint RD, >8
5246 //| mov RB, dword [BASE+RA*8]
5247 //| add PC, 4
5248 //| cmp RB, dword [BASE+RD*8]
5249 //| jmp_comp jge, jl, jg, jle, >9
5250 //|6:
5251 //| movzx RD, PC_RD
5252 //| branchPC RD
5253 //|9:
5254 //| ins_next
5255 //|
5256 //|7: // RA is not an integer.
5257 //| ja ->vmeta_comp
5258 //| // RA is a number.
5259 //| cmp dword [BASE+RD*8+4], LJ_TISNUM; jb >1; jne ->vmeta_comp
5260 //| // RA is a number, RD is an integer.
5261 //|.if SSE
5262 //| cvtsi2sd xmm0, dword [BASE+RD*8]
5263 //| jmp >2
5264 //|.else
5265 //| fld qword [BASE+RA*8]
5266 //| fild dword [BASE+RD*8]
5267 //| jmp >3
5268 //|.endif
5269 //|
5270 //|8: // RA is an integer, RD is not an integer.
5271 //| ja ->vmeta_comp
5272 //| // RA is an integer, RD is a number.
5273 //|.if SSE
5274 //| cvtsi2sd xmm1, dword [BASE+RA*8]
5275 //| movsd xmm0, qword [BASE+RD*8]
5276 //| add PC, 4
5277 //| ucomisd xmm0, xmm1
5278 //| jmp_comp jbe, ja, jb, jae, <9
5279 //| jmp <6
5280 //|.else
5281 //| fild dword [BASE+RA*8]
5282 //| jmp >2
5283 //|.endif
5284 //|.else
5285 //| checknum RA, ->vmeta_comp
5286 //| checknum RD, ->vmeta_comp
5287 //|.endif
5288 //|.if SSE
5289 //|1:
5290 //| movsd xmm0, qword [BASE+RD*8]
5291 //|2:
5292 //| add PC, 4
5293 //| ucomisd xmm0, qword [BASE+RA*8]
5294 //|3:
5295 //|.else
5296 //|1:
5297 //| fld qword [BASE+RA*8] // Reverse order, i.e like cmp D, A.
5298 //|2:
5299 //| fld qword [BASE+RD*8]
5300 //|3:
5301 //| add PC, 4
5302 //| fcomparepp
5303 //|.endif
5304 //| // Unordered: all of ZF CF PF set, ordered: PF clear.
5305 //| // To preserve NaN semantics GE/GT branch on unordered, but LT/LE don't.
5306 //|.if DUALNUM
5307 //| jmp_comp jbe, ja, jb, jae, <9
5308 //| jmp <6
5309 //|.else
5310 //| jmp_comp jbe, ja, jb, jae, >1
5311 dasm_put(Dst, 9042, LJ_TISNUM, LJ_TISNUM);
5312 switch (op) {
5313 case BC_ISLT:
5314 dasm_put(Dst, 7392);
5315 break;
5316 case BC_ISGE:
5317 dasm_put(Dst, 9083);
5318 break;
5319 case BC_ISLE:
5320 dasm_put(Dst, 9088);
5321 break;
5322 case BC_ISGT:
5323 dasm_put(Dst, 9093);
5324 break;
5325 default: break; /* Shut up GCC. */
5326 }
5327#line 3996 "vm_x86.dasc"
5328 //| movzx RD, PC_RD
5329 //| branchPC RD
5330 //|1:
5331 //| ins_next
5332 //|.endif
5333 dasm_put(Dst, 9098, -BCBIAS_J*4);
5334#line 4001 "vm_x86.dasc"
5335 break;
5336
5337 case BC_ISEQV: case BC_ISNEV:
5338 vk = op == BC_ISEQV;
5339 //| ins_AD // RA = src1, RD = src2, JMP with RD = target
5340 //| mov RB, [BASE+RD*8+4]
5341 //| add PC, 4
5342 //|.if DUALNUM
5343 //| cmp RB, LJ_TISNUM; jne >7
5344 //| checkint RA, >8
5345 //| mov RB, dword [BASE+RD*8]
5346 //| cmp RB, dword [BASE+RA*8]
5347 dasm_put(Dst, 9131);
5348#line 4013 "vm_x86.dasc"
5349 if (vk) {
5350 //| jne >9
5351 } else {
5352 //| je >9
5353 }
5354 //| movzx RD, PC_RD
5355 //| branchPC RD
5356 //|9:
5357 //| ins_next
5358 //|
5359 //|7: // RD is not an integer.
5360 //| ja >5
5361 //| // RD is a number.
5362 //| cmp dword [BASE+RA*8+4], LJ_TISNUM; jb >1; jne >5
5363 //| // RD is a number, RA is an integer.
5364 //|.if SSE
5365 //| cvtsi2sd xmm0, dword [BASE+RA*8]
5366 //|.else
5367 //| fild dword [BASE+RA*8]
5368 //|.endif
5369 //| jmp >2
5370 //|
5371 //|8: // RD is an integer, RA is not an integer.
5372 //| ja >5
5373 //| // RD is an integer, RA is a number.
5374 //|.if SSE
5375 //| cvtsi2sd xmm0, dword [BASE+RD*8]
5376 //| ucomisd xmm0, qword [BASE+RA*8]
5377 //|.else
5378 //| fild dword [BASE+RD*8]
5379 //| fld qword [BASE+RA*8]
5380 //|.endif
5381 //| jmp >4
5382 //|
5383 //|.else
5384 //| cmp RB, LJ_TISNUM; jae >5
5385 //| checknum RA, >5
5386 //|.endif
5387 //|.if SSE
5388 //|1:
5389 //| movsd xmm0, qword [BASE+RA*8]
5390 //|2:
5391 //| ucomisd xmm0, qword [BASE+RD*8]
5392 //|4:
5393 //|.else
5394 //|1:
5395 //| fld qword [BASE+RA*8]
5396 //|2:
5397 //| fld qword [BASE+RD*8]
5398 //|4:
5399 //| fcomparepp
5400 //|.endif
5401 dasm_put(Dst, 9139, LJ_TISNUM, LJ_TISNUM);
5402#line 4065 "vm_x86.dasc"
5403 iseqne_fp:
5404 if (vk) {
5405 //| jp >2 // Unordered means not equal.
5406 //| jne >2
5407 dasm_put(Dst, 9175);
5408#line 4069 "vm_x86.dasc"
5409 } else {
5410 //| jp >2 // Unordered means not equal.
5411 //| je >1
5412 dasm_put(Dst, 9184);
5413#line 4072 "vm_x86.dasc"
5414 }
5415 iseqne_end:
5416 if (vk) {
5417 //|1: // EQ: Branch to the target.
5418 //| movzx RD, PC_RD
5419 //| branchPC RD
5420 //|2: // NE: Fallthrough to next instruction.
5421 //|.if not FFI
5422 //|3:
5423 //|.endif
5424 dasm_put(Dst, 9193, -BCBIAS_J*4);
5425#line 4082 "vm_x86.dasc"
5426 } else {
5427 //|.if not FFI
5428 //|3:
5429 //|.endif
5430 //|2: // NE: Branch to the target.
5431 //| movzx RD, PC_RD
5432 //| branchPC RD
5433 //|1: // EQ: Fallthrough to next instruction.
5434 dasm_put(Dst, 9208, -BCBIAS_J*4);
5435#line 4090 "vm_x86.dasc"
5436 }
5437 if (LJ_DUALNUM && (op == BC_ISEQV || op == BC_ISNEV ||
5438 op == BC_ISEQN || op == BC_ISNEN)) {
5439 //| jmp <9
5440 dasm_put(Dst, 9223);
5441#line 4094 "vm_x86.dasc"
5442 } else {
5443 //| ins_next
5444 dasm_put(Dst, 9110);
5445#line 4096 "vm_x86.dasc"
5446 }
5447 //|
5448 if (op == BC_ISEQV || op == BC_ISNEV) {
5449 //|5: // Either or both types are not numbers.
5450 //|.if FFI
5451 //| cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
5452 //| checktp RA, LJ_TCDATA; je ->vmeta_equal_cd
5453 //|.endif
5454 //| checktp RA, RB // Compare types.
5455 //| jne <2 // Not the same type?
5456 //| cmp RB, LJ_TISPRI
5457 //| jae <1 // Same type and primitive type?
5458 //|
5459 //| // Same types and not a primitive type. Compare GCobj or pvalue.
5460 //| mov RA, [BASE+RA*8]
5461 //| mov RD, [BASE+RD*8]
5462 //| cmp RA, RD
5463 //| je <1 // Same GCobjs or pvalues?
5464 //| cmp RB, LJ_TISTABUD
5465 //| ja <2 // Different objects and not table/ud?
5466 //|.if X64
5467 //| cmp RB, LJ_TUDATA // And not 64 bit lightuserdata.
5468 //| jb <2
5469 //|.endif
5470 //|
5471 //| // Different tables or userdatas. Need to check __eq metamethod.
5472 //| // Field metatable must be at same offset for GCtab and GCudata!
5473 //| mov TAB:RB, TAB:RA->metatable
5474 dasm_put(Dst, 9228, LJ_TCDATA, LJ_TCDATA, LJ_TISPRI, LJ_TISTABUD, LJ_TUDATA);
5475#line 4124 "vm_x86.dasc"
5476 //| test TAB:RB, TAB:RB
5477 //| jz <2 // No metatable?
5478 //| test byte TAB:RB->nomm, 1<<MM_eq
5479 //| jnz <2 // Or 'no __eq' flag set?
5480 dasm_put(Dst, 9293, Dt6(->metatable), Dt6(->nomm), 1<<MM_eq);
5481#line 4128 "vm_x86.dasc"
5482 if (vk) {
5483 //| xor RB, RB // ne = 0
5484 dasm_put(Dst, 9313);
5485#line 4130 "vm_x86.dasc"
5486 } else {
5487 //| mov RB, 1 // ne = 1
5488 dasm_put(Dst, 9317);
5489#line 4132 "vm_x86.dasc"
5490 }
5491 //| jmp ->vmeta_equal // Handle __eq metamethod.
5492 dasm_put(Dst, 9323);
5493#line 4134 "vm_x86.dasc"
5494 } else {
5495 //|.if FFI
5496 //|3:
5497 //| cmp RB, LJ_TCDATA
5498 dasm_put(Dst, 9328, LJ_TCDATA);
5499#line 4138 "vm_x86.dasc"
5500 if (LJ_DUALNUM && vk) {
5501 //| jne <9
5502 dasm_put(Dst, 9335);
5503#line 4140 "vm_x86.dasc"
5504 } else {
5505 //| jne <2
5506 dasm_put(Dst, 9308);
5507#line 4142 "vm_x86.dasc"
5508 }
5509 //| jmp ->vmeta_equal_cd
5510 //|.endif
5511 dasm_put(Dst, 9340);
5512#line 4145 "vm_x86.dasc"
5513 }
5514 break;
5515 case BC_ISEQS: case BC_ISNES:
5516 vk = op == BC_ISEQS;
5517 //| ins_AND // RA = src, RD = str const, JMP with RD = target
5518 //| mov RB, [BASE+RA*8+4]
5519 //| add PC, 4
5520 //| cmp RB, LJ_TSTR; jne >3
5521 //| mov RA, [BASE+RA*8]
5522 //| cmp RA, [KBASE+RD*4]
5523 dasm_put(Dst, 9345, LJ_TSTR);
5524#line 4155 "vm_x86.dasc"
5525 iseqne_test:
5526 if (vk) {
5527 //| jne >2
5528 dasm_put(Dst, 9179);
5529#line 4158 "vm_x86.dasc"
5530 } else {
5531 //| je >1
5532 dasm_put(Dst, 7791);
5533#line 4160 "vm_x86.dasc"
5534 }
5535 goto iseqne_end;
5536 case BC_ISEQN: case BC_ISNEN:
5537 vk = op == BC_ISEQN;
5538 //| ins_AD // RA = src, RD = num const, JMP with RD = target
5539 //| mov RB, [BASE+RA*8+4]
5540 //| add PC, 4
5541 //|.if DUALNUM
5542 //| cmp RB, LJ_TISNUM; jne >7
5543 //| cmp dword [KBASE+RD*8+4], LJ_TISNUM; jne >8
5544 //| mov RB, dword [KBASE+RD*8]
5545 //| cmp RB, dword [BASE+RA*8]
5546 dasm_put(Dst, 9372);
5547#line 4172 "vm_x86.dasc"
5548 if (vk) {
5549 //| jne >9
5550 } else {
5551 //| je >9
5552 }
5553 //| movzx RD, PC_RD
5554 //| branchPC RD
5555 //|9:
5556 //| ins_next
5557 //|
5558 //|7: // RA is not an integer.
5559 //| ja >3
5560 //| // RA is a number.
5561 //| cmp dword [KBASE+RD*8+4], LJ_TISNUM; jb >1
5562 //| // RA is a number, RD is an integer.
5563 //|.if SSE
5564 //| cvtsi2sd xmm0, dword [KBASE+RD*8]
5565 //|.else
5566 //| fild dword [KBASE+RD*8]
5567 //|.endif
5568 //| jmp >2
5569 //|
5570 //|8: // RA is an integer, RD is a number.
5571 //|.if SSE
5572 //| cvtsi2sd xmm0, dword [BASE+RA*8]
5573 //| ucomisd xmm0, qword [KBASE+RD*8]
5574 //|.else
5575 //| fild dword [BASE+RA*8]
5576 //| fld qword [KBASE+RD*8]
5577 //|.endif
5578 //| jmp >4
5579 //|.else
5580 //| cmp RB, LJ_TISNUM; jae >3
5581 //|.endif
5582 //|.if SSE
5583 //|1:
5584 //| movsd xmm0, qword [KBASE+RD*8]
5585 //|2:
5586 //| ucomisd xmm0, qword [BASE+RA*8]
5587 //|4:
5588 //|.else
5589 //|1:
5590 //| fld qword [KBASE+RD*8]
5591 //|2:
5592 //| fld qword [BASE+RA*8]
5593 //|4:
5594 //| fcomparepp
5595 //|.endif
5596 dasm_put(Dst, 9380, LJ_TISNUM);
5597#line 4220 "vm_x86.dasc"
5598 goto iseqne_fp;
5599 case BC_ISEQP: case BC_ISNEP:
5600 vk = op == BC_ISEQP;
5601 //| ins_AND // RA = src, RD = primitive type (~), JMP with RD = target
5602 //| mov RB, [BASE+RA*8+4]
5603 //| add PC, 4
5604 //| cmp RB, RD
5605 dasm_put(Dst, 9407);
5606#line 4227 "vm_x86.dasc"
5607 if (!LJ_HASFFI) goto iseqne_test;
5608 if (vk) {
5609 //| jne >3
5610 //| movzx RD, PC_RD
5611 //| branchPC RD
5612 //|2:
5613 //| ins_next
5614 //|3:
5615 //| cmp RB, LJ_TCDATA; jne <2
5616 //| jmp ->vmeta_equal_cd
5617 dasm_put(Dst, 9421, -BCBIAS_J*4, LJ_TCDATA);
5618#line 4237 "vm_x86.dasc"
5619 } else {
5620 //| je >2
5621 //| cmp RB, LJ_TCDATA; je ->vmeta_equal_cd
5622 //| movzx RD, PC_RD
5623 //| branchPC RD
5624 //|2:
5625 //| ins_next
5626 dasm_put(Dst, 9472, LJ_TCDATA, -BCBIAS_J*4);
5627#line 4244 "vm_x86.dasc"
5628 }
5629 break;
5630
5631 /* -- Unary test and copy ops ------------------------------------------- */
5632
5633 case BC_ISTC: case BC_ISFC: case BC_IST: case BC_ISF:
5634 //| ins_AD // RA = dst or unused, RD = src, JMP with RD = target
5635 //| mov RB, [BASE+RD*8+4]
5636 //| add PC, 4
5637 //| cmp RB, LJ_TISTRUECOND
5638 dasm_put(Dst, 9517, LJ_TISTRUECOND);
5639#line 4254 "vm_x86.dasc"
5640 if (op == BC_IST || op == BC_ISTC) {
5641 //| jae >1
5642 dasm_put(Dst, 9093);
5643#line 4256 "vm_x86.dasc"
5644 } else {
5645 //| jb >1
5646 dasm_put(Dst, 9088);
5647#line 4258 "vm_x86.dasc"
5648 }
5649 if (op == BC_ISTC || op == BC_ISFC) {
5650 //| mov [BASE+RA*8+4], RB
5651 //| mov RB, [BASE+RD*8]
5652 //| mov [BASE+RA*8], RB
5653 dasm_put(Dst, 9529);
5654#line 4263 "vm_x86.dasc"
5655 }
5656 //| movzx RD, PC_RD
5657 //| branchPC RD
5658 //|1: // Fallthrough to the next instruction.
5659 //| ins_next
5660 dasm_put(Dst, 9098, -BCBIAS_J*4);
5661#line 4268 "vm_x86.dasc"
5662 break;
5663
5664 /* -- Unary ops --------------------------------------------------------- */
5665
5666 case BC_MOV:
5667 //| ins_AD // RA = dst, RD = src
5668 //|.if X64
5669 //| mov RBa, [BASE+RD*8]
5670 //| mov [BASE+RA*8], RBa
5671 //|.else
5672 //| mov RB, [BASE+RD*8+4]
5673 //| mov RD, [BASE+RD*8]
5674 //| mov [BASE+RA*8+4], RB
5675 //| mov [BASE+RA*8], RD
5676 //|.endif
5677 //| ins_next_
5678 dasm_put(Dst, 9540);
5679#line 4284 "vm_x86.dasc"
5680 break;
5681 case BC_NOT:
5682 //| ins_AD // RA = dst, RD = src
5683 //| xor RB, RB
5684 //| checktp RD, LJ_TISTRUECOND
5685 //| adc RB, LJ_TTRUE
5686 //| mov [BASE+RA*8+4], RB
5687 //| ins_next
5688 dasm_put(Dst, 9569, LJ_TISTRUECOND, LJ_TTRUE);
5689#line 4292 "vm_x86.dasc"
5690 break;
5691 case BC_UNM:
5692 //| ins_AD // RA = dst, RD = src
5693 //|.if DUALNUM
5694 //| checkint RD, >5
5695 //| mov RB, [BASE+RD*8]
5696 //| neg RB
5697 //| jo >4
5698 //| mov dword [BASE+RA*8+4], LJ_TISNUM
5699 //| mov dword [BASE+RA*8], RB
5700 //|9:
5701 //| ins_next
5702 //|4:
5703 //| mov dword [BASE+RA*8+4], 0x41e00000 // 2^31.
5704 //| mov dword [BASE+RA*8], 0
5705 //| jmp <9
5706 //|5:
5707 //| ja ->vmeta_unm
5708 //|.else
5709 //| checknum RD, ->vmeta_unm
5710 //|.endif
5711 //|.if SSE
5712 //| movsd xmm0, qword [BASE+RD*8]
5713 //| sseconst_sign xmm1, RDa
5714 //| xorps xmm0, xmm1
5715 //| movsd qword [BASE+RA*8], xmm0
5716 //|.else
5717 //| fld qword [BASE+RD*8]
5718 //| fchs
5719 //| fstp qword [BASE+RA*8]
5720 //|.endif
5721 //|.if DUALNUM
5722 //| jmp <9
5723 //|.else
5724 //| ins_next
5725 //|.endif
5726 dasm_put(Dst, 9606, LJ_TISNUM, (unsigned int)(U64x(80000000,00000000)), (unsigned int)((U64x(80000000,00000000))>>32));
5727#line 4328 "vm_x86.dasc"
5728 break;
5729 case BC_LEN:
5730 //| ins_AD // RA = dst, RD = src
5731 //| checkstr RD, >2
5732 //| mov STR:RD, [BASE+RD*8]
5733 //|.if DUALNUM
5734 //| mov RD, dword STR:RD->len
5735 //|1:
5736 //| mov dword [BASE+RA*8+4], LJ_TISNUM
5737 //| mov dword [BASE+RA*8], RD
5738 //|.elif SSE
5739 //| xorps xmm0, xmm0
5740 //| cvtsi2sd xmm0, dword STR:RD->len
5741 //|1:
5742 //| movsd qword [BASE+RA*8], xmm0
5743 //|.else
5744 //| fild dword STR:RD->len
5745 //|1:
5746 //| fstp qword [BASE+RA*8]
5747 //|.endif
5748 //| ins_next
5749 //|2:
5750 //| checktab RD, ->vmeta_len
5751 //| mov TAB:FCARG1, [BASE+RD*8]
5752 dasm_put(Dst, 9661, LJ_TSTR, Dt5(->len), LJ_TTAB);
5753#line 4352 "vm_x86.dasc"
5754#if LJ_52
5755 //| mov TAB:RB, TAB:FCARG1->metatable
5756 //| cmp TAB:RB, 0
5757 //| jnz >9
5758 //|3:
5759 dasm_put(Dst, 9727, Dt6(->metatable));
5760#line 4357 "vm_x86.dasc"
5761#endif
5762 //|->BC_LEN_Z:
5763 //| mov RB, BASE // Save BASE.
5764 //| call extern lj_tab_len@4 // (GCtab *t)
5765 //| // Length of table returned in eax (RD).
5766 //|.if DUALNUM
5767 //| // Nothing to do.
5768 //|.elif SSE
5769 //| cvtsi2sd xmm0, RD
5770 //|.else
5771 //| mov ARG1, RD
5772 //| fild ARG1
5773 //|.endif
5774 //| mov BASE, RB // Restore BASE.
5775 //| movzx RA, PC_RA
5776 //| jmp <1
5777 dasm_put(Dst, 9741);
5778#line 4373 "vm_x86.dasc"
5779#if LJ_52
5780 //|9: // Check for __len.
5781 //| test byte TAB:RB->nomm, 1<<MM_len
5782 //| jnz <3
5783 //| jmp ->vmeta_len // 'no __len' flag NOT set: check.
5784 dasm_put(Dst, 9767, Dt6(->nomm), 1<<MM_len);
5785#line 4378 "vm_x86.dasc"
5786#endif
5787 break;
5788
5789 /* -- Binary ops -------------------------------------------------------- */
5790
5791 //|.macro ins_arithpre, x87ins, sseins, ssereg
5792 //| ins_ABC
5793 //||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5794 //||switch (vk) {
5795 //||case 0:
5796 //| checknum RB, ->vmeta_arith_vn
5797 //| .if DUALNUM
5798 //| cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_vn
5799 //| .endif
5800 //| .if SSE
5801 //| movsd xmm0, qword [BASE+RB*8]
5802 //| sseins ssereg, qword [KBASE+RC*8]
5803 //| .else
5804 //| fld qword [BASE+RB*8]
5805 //| x87ins qword [KBASE+RC*8]
5806 //| .endif
5807 //|| break;
5808 //||case 1:
5809 //| checknum RB, ->vmeta_arith_nv
5810 //| .if DUALNUM
5811 //| cmp dword [KBASE+RC*8+4], LJ_TISNUM; jae ->vmeta_arith_nv
5812 //| .endif
5813 //| .if SSE
5814 //| movsd xmm0, qword [KBASE+RC*8]
5815 //| sseins ssereg, qword [BASE+RB*8]
5816 //| .else
5817 //| fld qword [KBASE+RC*8]
5818 //| x87ins qword [BASE+RB*8]
5819 //| .endif
5820 //|| break;
5821 //||default:
5822 //| checknum RB, ->vmeta_arith_vv
5823 //| checknum RC, ->vmeta_arith_vv
5824 //| .if SSE
5825 //| movsd xmm0, qword [BASE+RB*8]
5826 //| sseins ssereg, qword [BASE+RC*8]
5827 //| .else
5828 //| fld qword [BASE+RB*8]
5829 //| x87ins qword [BASE+RC*8]
5830 //| .endif
5831 //|| break;
5832 //||}
5833 //|.endmacro
5834 //|
5835 //|.macro ins_arithdn, intins
5836 //| ins_ABC
5837 //||vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5838 //||switch (vk) {
5839 //||case 0:
5840 //| checkint RB, ->vmeta_arith_vn
5841 //| cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_vn
5842 //| mov RB, [BASE+RB*8]
5843 //| intins RB, [KBASE+RC*8]; jo ->vmeta_arith_vno
5844 //|| break;
5845 //||case 1:
5846 //| checkint RB, ->vmeta_arith_nv
5847 //| cmp dword [KBASE+RC*8+4], LJ_TISNUM; jne ->vmeta_arith_nv
5848 //| mov RC, [KBASE+RC*8]
5849 //| intins RC, [BASE+RB*8]; jo ->vmeta_arith_nvo
5850 //|| break;
5851 //||default:
5852 //| checkint RB, ->vmeta_arith_vv
5853 //| checkint RC, ->vmeta_arith_vv
5854 //| mov RB, [BASE+RB*8]
5855 //| intins RB, [BASE+RC*8]; jo ->vmeta_arith_vvo
5856 //|| break;
5857 //||}
5858 //| mov dword [BASE+RA*8+4], LJ_TISNUM
5859 //||if (vk == 1) {
5860 //| mov dword [BASE+RA*8], RC
5861 //||} else {
5862 //| mov dword [BASE+RA*8], RB
5863 //||}
5864 //| ins_next
5865 //|.endmacro
5866 //|
5867 //|.macro ins_arithpost
5868 //|.if SSE
5869 //| movsd qword [BASE+RA*8], xmm0
5870 //|.else
5871 //| fstp qword [BASE+RA*8]
5872 //|.endif
5873 //|.endmacro
5874 //|
5875 //|.macro ins_arith, x87ins, sseins
5876 //| ins_arithpre x87ins, sseins, xmm0
5877 //| ins_arithpost
5878 //| ins_next
5879 //|.endmacro
5880 //|
5881 //|.macro ins_arith, intins, x87ins, sseins
5882 //|.if DUALNUM
5883 //| ins_arithdn intins
5884 //|.else
5885 //| ins_arith, x87ins, sseins
5886 //|.endif
5887 //|.endmacro
5888
5889 //| // RA = dst, RB = src1 or num const, RC = src2 or num const
5890 case BC_ADDVN: case BC_ADDNV: case BC_ADDVV:
5891 //| ins_arith add, fadd, addsd
5892 dasm_put(Dst, 9783);
5893 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5894 switch (vk) {
5895 case 0:
5896 dasm_put(Dst, 9791, LJ_TISNUM);
5897 break;
5898 case 1:
5899 dasm_put(Dst, 9817, LJ_TISNUM);
5900 break;
5901 default:
5902 dasm_put(Dst, 9843, LJ_TISNUM, LJ_TISNUM);
5903 break;
5904 }
5905 dasm_put(Dst, 9634);
5906#line 4484 "vm_x86.dasc"
5907 break;
5908 case BC_SUBVN: case BC_SUBNV: case BC_SUBVV:
5909 //| ins_arith sub, fsub, subsd
5910 dasm_put(Dst, 9783);
5911 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5912 switch (vk) {
5913 case 0:
5914 dasm_put(Dst, 9878, LJ_TISNUM);
5915 break;
5916 case 1:
5917 dasm_put(Dst, 9904, LJ_TISNUM);
5918 break;
5919 default:
5920 dasm_put(Dst, 9930, LJ_TISNUM, LJ_TISNUM);
5921 break;
5922 }
5923 dasm_put(Dst, 9634);
5924#line 4487 "vm_x86.dasc"
5925 break;
5926 case BC_MULVN: case BC_MULNV: case BC_MULVV:
5927 //| ins_arith imul, fmul, mulsd
5928 dasm_put(Dst, 9783);
5929 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5930 switch (vk) {
5931 case 0:
5932 dasm_put(Dst, 9965, LJ_TISNUM);
5933 break;
5934 case 1:
5935 dasm_put(Dst, 9991, LJ_TISNUM);
5936 break;
5937 default:
5938 dasm_put(Dst, 10017, LJ_TISNUM, LJ_TISNUM);
5939 break;
5940 }
5941 dasm_put(Dst, 9634);
5942#line 4490 "vm_x86.dasc"
5943 break;
5944 case BC_DIVVN: case BC_DIVNV: case BC_DIVVV:
5945 //| ins_arith fdiv, divsd
5946 dasm_put(Dst, 9783);
5947 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5948 switch (vk) {
5949 case 0:
5950 dasm_put(Dst, 10052, LJ_TISNUM);
5951 break;
5952 case 1:
5953 dasm_put(Dst, 10078, LJ_TISNUM);
5954 break;
5955 default:
5956 dasm_put(Dst, 10104, LJ_TISNUM, LJ_TISNUM);
5957 break;
5958 }
5959 dasm_put(Dst, 9634);
5960#line 4493 "vm_x86.dasc"
5961 break;
5962 case BC_MODVN:
5963 //| ins_arithpre fld, movsd, xmm1
5964 dasm_put(Dst, 9783);
5965 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5966 switch (vk) {
5967 case 0:
5968 dasm_put(Dst, 10139, LJ_TISNUM);
5969 break;
5970 case 1:
5971 dasm_put(Dst, 10165, LJ_TISNUM);
5972 break;
5973 default:
5974 dasm_put(Dst, 10191, LJ_TISNUM, LJ_TISNUM);
5975 break;
5976 }
5977#line 4496 "vm_x86.dasc"
5978 //|->BC_MODVN_Z:
5979 //| call ->vm_mod
5980 //| ins_arithpost
5981 //| ins_next
5982 dasm_put(Dst, 10226);
5983#line 4500 "vm_x86.dasc"
5984 break;
5985 case BC_MODNV: case BC_MODVV:
5986 //| ins_arithpre fld, movsd, xmm1
5987 dasm_put(Dst, 9783);
5988 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
5989 switch (vk) {
5990 case 0:
5991 dasm_put(Dst, 10139, LJ_TISNUM);
5992 break;
5993 case 1:
5994 dasm_put(Dst, 10165, LJ_TISNUM);
5995 break;
5996 default:
5997 dasm_put(Dst, 10191, LJ_TISNUM, LJ_TISNUM);
5998 break;
5999 }
6000#line 4503 "vm_x86.dasc"
6001 //| jmp ->BC_MODVN_Z // Avoid 3 copies. It's slow anyway.
6002 dasm_put(Dst, 10258);
6003#line 4504 "vm_x86.dasc"
6004 break;
6005 case BC_POW:
6006 //| ins_arithpre fld, movsd, xmm1
6007 dasm_put(Dst, 9783);
6008 vk = ((int)op - BC_ADDVN) / (BC_ADDNV-BC_ADDVN);
6009 switch (vk) {
6010 case 0:
6011 dasm_put(Dst, 10139, LJ_TISNUM);
6012 break;
6013 case 1:
6014 dasm_put(Dst, 10165, LJ_TISNUM);
6015 break;
6016 default:
6017 dasm_put(Dst, 10191, LJ_TISNUM, LJ_TISNUM);
6018 break;
6019 }
6020#line 4507 "vm_x86.dasc"
6021 //| call ->vm_pow
6022 //| ins_arithpost
6023 //| ins_next
6024 dasm_put(Dst, 10263);
6025#line 4510 "vm_x86.dasc"
6026 break;
6027
6028 case BC_CAT:
6029 //| ins_ABC // RA = dst, RB = src_start, RC = src_end
6030 //|.if X64
6031 //| mov L:CARG1d, SAVE_L
6032 //| mov L:CARG1d->base, BASE
6033 //| lea CARG2d, [BASE+RC*8]
6034 //| mov CARG3d, RC
6035 //| sub CARG3d, RB
6036 //|->BC_CAT_Z:
6037 //| mov L:RB, L:CARG1d
6038 //|.else
6039 //| lea RA, [BASE+RC*8]
6040 //| sub RC, RB
6041 //| mov ARG2, RA
6042 //| mov ARG3, RC
6043 //|->BC_CAT_Z:
6044 //| mov L:RB, SAVE_L
6045 //| mov ARG1, L:RB
6046 //| mov L:RB->base, BASE
6047 //|.endif
6048 //| mov SAVE_PC, PC
6049 //| call extern lj_meta_cat // (lua_State *L, TValue *top, int left)
6050 //| // NULL (finished) or TValue * (metamethod) returned in eax (RC).
6051 //| mov BASE, L:RB->base
6052 //| test RC, RC
6053 //| jnz ->vmeta_binop
6054 //| movzx RB, PC_RB // Copy result to Stk[RA] from Stk[RB].
6055 //| movzx RA, PC_RA
6056 //|.if X64
6057 //| mov RCa, [BASE+RB*8]
6058 //| mov [BASE+RA*8], RCa
6059 //|.else
6060 //| mov RC, [BASE+RB*8+4]
6061 //| mov RB, [BASE+RB*8]
6062 //| mov [BASE+RA*8+4], RC
6063 //| mov [BASE+RA*8], RB
6064 //|.endif
6065 //| ins_next
6066 dasm_put(Dst, 10293, Dt1(->base), Dt1(->base));
6067#line 4550 "vm_x86.dasc"
6068 break;
6069
6070 /* -- Constant ops ------------------------------------------------------ */
6071
6072 case BC_KSTR:
6073 //| ins_AND // RA = dst, RD = str const (~)
6074 //| mov RD, [KBASE+RD*4]
6075 //| mov dword [BASE+RA*8+4], LJ_TSTR
6076 //| mov [BASE+RA*8], RD
6077 //| ins_next
6078 dasm_put(Dst, 10377, LJ_TSTR);
6079#line 4560 "vm_x86.dasc"
6080 break;
6081 case BC_KCDATA:
6082 //|.if FFI
6083 //| ins_AND // RA = dst, RD = cdata const (~)
6084 //| mov RD, [KBASE+RD*4]
6085 //| mov dword [BASE+RA*8+4], LJ_TCDATA
6086 //| mov [BASE+RA*8], RD
6087 //| ins_next
6088 //|.endif
6089 dasm_put(Dst, 10377, LJ_TCDATA);
6090#line 4569 "vm_x86.dasc"
6091 break;
6092 case BC_KSHORT:
6093 //| ins_AD // RA = dst, RD = signed int16 literal
6094 //|.if DUALNUM
6095 //| movsx RD, RDW
6096 //| mov dword [BASE+RA*8+4], LJ_TISNUM
6097 //| mov dword [BASE+RA*8], RD
6098 //|.elif SSE
6099 //| movsx RD, RDW // Sign-extend literal.
6100 //| cvtsi2sd xmm0, RD
6101 //| movsd qword [BASE+RA*8], xmm0
6102 //|.else
6103 //| fild PC_RD // Refetch signed RD from instruction.
6104 //| fstp qword [BASE+RA*8]
6105 //|.endif
6106 //| ins_next
6107 dasm_put(Dst, 10414);
6108#line 4585 "vm_x86.dasc"
6109 break;
6110 case BC_KNUM:
6111 //| ins_AD // RA = dst, RD = num const
6112 //|.if SSE
6113 //| movsd xmm0, qword [KBASE+RD*8]
6114 //| movsd qword [BASE+RA*8], xmm0
6115 //|.else
6116 //| fld qword [KBASE+RD*8]
6117 //| fstp qword [BASE+RA*8]
6118 //|.endif
6119 //| ins_next
6120 dasm_put(Dst, 10449);
6121#line 4596 "vm_x86.dasc"
6122 break;
6123 case BC_KPRI:
6124 //| ins_AND // RA = dst, RD = primitive type (~)
6125 //| mov [BASE+RA*8+4], RD
6126 //| ins_next
6127 dasm_put(Dst, 10483);
6128#line 4601 "vm_x86.dasc"
6129 break;
6130 case BC_KNIL:
6131 //| ins_AD // RA = dst_start, RD = dst_end
6132 //| lea RA, [BASE+RA*8+12]
6133 //| lea RD, [BASE+RD*8+4]
6134 //| mov RB, LJ_TNIL
6135 //| mov [RA-8], RB // Sets minimum 2 slots.
6136 //|1:
6137 //| mov [RA], RB
6138 //| add RA, 8
6139 //| cmp RA, RD
6140 //| jbe <1
6141 //| ins_next
6142 dasm_put(Dst, 10512, LJ_TNIL);
6143#line 4614 "vm_x86.dasc"
6144 break;
6145
6146 /* -- Upvalue and function ops ------------------------------------------ */
6147
6148 case BC_UGET:
6149 //| ins_AD // RA = dst, RD = upvalue #
6150 //| mov LFUNC:RB, [BASE-8]
6151 //| mov UPVAL:RB, [LFUNC:RB+RD*4+offsetof(GCfuncL, uvptr)]
6152 //| mov RB, UPVAL:RB->v
6153 //|.if X64
6154 //| mov RDa, [RB]
6155 //| mov [BASE+RA*8], RDa
6156 //|.else
6157 //| mov RD, [RB+4]
6158 //| mov RB, [RB]
6159 //| mov [BASE+RA*8+4], RD
6160 //| mov [BASE+RA*8], RB
6161 //|.endif
6162 //| ins_next
6163 dasm_put(Dst, 10560, offsetof(GCfuncL, uvptr), DtA(->v));
6164#line 4633 "vm_x86.dasc"
6165 break;
6166 case BC_USETV:
6167#define TV2MARKOFS \
6168 ((int32_t)offsetof(GCupval, marked)-(int32_t)offsetof(GCupval, tv))
6169 //| ins_AD // RA = upvalue #, RD = src
6170 //| mov LFUNC:RB, [BASE-8]
6171 //| mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
6172 //| cmp byte UPVAL:RB->closed, 0
6173 //| mov RB, UPVAL:RB->v
6174 //| mov RA, [BASE+RD*8]
6175 //| mov RD, [BASE+RD*8+4]
6176 //| mov [RB], RA
6177 //| mov [RB+4], RD
6178 //| jz >1
6179 //| // Check barrier for closed upvalue.
6180 //| test byte [RB+TV2MARKOFS], LJ_GC_BLACK // isblack(uv)
6181 //| jnz >2
6182 //|1:
6183 //| ins_next
6184 //|
6185 //|2: // Upvalue is black. Check if new value is collectable and white.
6186 //| sub RD, LJ_TISGCV
6187 //| cmp RD, LJ_TNUMX - LJ_TISGCV // tvisgcv(v)
6188 //| jbe <1
6189 //| test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(v)
6190 //| jz <1
6191 //| // Crossed a write barrier. Move the barrier forward.
6192 //|.if X64 and not X64WIN
6193 //| mov FCARG2, RB
6194 //| mov RB, BASE // Save BASE.
6195 //|.else
6196 //| xchg FCARG2, RB // Save BASE (FCARG2 == BASE).
6197 //|.endif
6198 //| lea GL:FCARG1, [DISPATCH+GG_DISP2G]
6199 //| call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
6200 dasm_put(Dst, 10601, offsetof(GCfuncL, uvptr), DtA(->closed), DtA(->v), TV2MARKOFS, LJ_GC_BLACK, LJ_TISGCV, LJ_TNUMX - LJ_TISGCV, Dt4(->gch.marked), LJ_GC_WHITES, GG_DISP2G);
6201#line 4668 "vm_x86.dasc"
6202 //| mov BASE, RB // Restore BASE.
6203 //| jmp <1
6204 dasm_put(Dst, 10697);
6205#line 4670 "vm_x86.dasc"
6206 break;
6207#undef TV2MARKOFS
6208 case BC_USETS:
6209 //| ins_AND // RA = upvalue #, RD = str const (~)
6210 //| mov LFUNC:RB, [BASE-8]
6211 //| mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
6212 //| mov GCOBJ:RA, [KBASE+RD*4]
6213 //| mov RD, UPVAL:RB->v
6214 //| mov [RD], GCOBJ:RA
6215 //| mov dword [RD+4], LJ_TSTR
6216 //| test byte UPVAL:RB->marked, LJ_GC_BLACK // isblack(uv)
6217 //| jnz >2
6218 //|1:
6219 //| ins_next
6220 //|
6221 //|2: // Check if string is white and ensure upvalue is closed.
6222 //| test byte GCOBJ:RA->gch.marked, LJ_GC_WHITES // iswhite(str)
6223 //| jz <1
6224 //| cmp byte UPVAL:RB->closed, 0
6225 //| jz <1
6226 //| // Crossed a write barrier. Move the barrier forward.
6227 //| mov RB, BASE // Save BASE (FCARG2 == BASE).
6228 //| mov FCARG2, RD
6229 //| lea GL:FCARG1, [DISPATCH+GG_DISP2G]
6230 //| call extern lj_gc_barrieruv@8 // (global_State *g, TValue *tv)
6231 //| mov BASE, RB // Restore BASE.
6232 //| jmp <1
6233 dasm_put(Dst, 10709, offsetof(GCfuncL, uvptr), DtA(->v), LJ_TSTR, DtA(->marked), LJ_GC_BLACK, Dt4(->gch.marked), LJ_GC_WHITES, DtA(->closed), GG_DISP2G);
6234#line 4697 "vm_x86.dasc"
6235 break;
6236 case BC_USETN:
6237 //| ins_AD // RA = upvalue #, RD = num const
6238 //| mov LFUNC:RB, [BASE-8]
6239 //|.if SSE
6240 //| movsd xmm0, qword [KBASE+RD*8]
6241 //|.else
6242 //| fld qword [KBASE+RD*8]
6243 //|.endif
6244 //| mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
6245 //| mov RA, UPVAL:RB->v
6246 //|.if SSE
6247 //| movsd qword [RA], xmm0
6248 //|.else
6249 //| fstp qword [RA]
6250 //|.endif
6251 //| ins_next
6252 dasm_put(Dst, 10805, offsetof(GCfuncL, uvptr), DtA(->v));
6253#line 4714 "vm_x86.dasc"
6254 break;
6255 case BC_USETP:
6256 //| ins_AND // RA = upvalue #, RD = primitive type (~)
6257 //| mov LFUNC:RB, [BASE-8]
6258 //| mov UPVAL:RB, [LFUNC:RB+RA*4+offsetof(GCfuncL, uvptr)]
6259 //| mov RA, UPVAL:RB->v
6260 //| mov [RA+4], RD
6261 //| ins_next
6262 dasm_put(Dst, 10850, offsetof(GCfuncL, uvptr), DtA(->v));
6263#line 4722 "vm_x86.dasc"
6264 break;
6265 case BC_UCLO:
6266 //| ins_AD // RA = level, RD = target
6267 //| branchPC RD // Do this first to free RD.
6268 //| mov L:RB, SAVE_L
6269 //| cmp dword L:RB->openupval, 0
6270 //| je >1
6271 //| mov L:RB->base, BASE
6272 //| lea FCARG2, [BASE+RA*8] // Caveat: FCARG2 == BASE
6273 //| mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
6274 //| call extern lj_func_closeuv@8 // (lua_State *L, TValue *level)
6275 //| mov BASE, L:RB->base
6276 //|1:
6277 //| ins_next
6278 dasm_put(Dst, 10890, -BCBIAS_J*4, Dt1(->openupval), Dt1(->base), Dt1(->base));
6279#line 4736 "vm_x86.dasc"
6280 break;
6281
6282 case BC_FNEW:
6283 //| ins_AND // RA = dst, RD = proto const (~) (holding function prototype)
6284 //|.if X64
6285 //| mov L:RB, SAVE_L
6286 //| mov L:RB->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
6287 //| mov CARG3d, [BASE-8]
6288 //| mov CARG2d, [KBASE+RD*4] // Fetch GCproto *.
6289 //| mov CARG1d, L:RB
6290 //|.else
6291 //| mov LFUNC:RA, [BASE-8]
6292 //| mov PROTO:RD, [KBASE+RD*4] // Fetch GCproto *.
6293 //| mov L:RB, SAVE_L
6294 //| mov ARG3, LFUNC:RA
6295 //| mov ARG2, PROTO:RD
6296 //| mov ARG1, L:RB
6297 //| mov L:RB->base, BASE
6298 //|.endif
6299 //| mov SAVE_PC, PC
6300 //| // (lua_State *L, GCproto *pt, GCfuncL *parent)
6301 //| call extern lj_func_newL_gc
6302 //| // GCfuncL * returned in eax (RC).
6303 //| mov BASE, L:RB->base
6304 //| movzx RA, PC_RA
6305 //| mov [BASE+RA*8], LFUNC:RC
6306 //| mov dword [BASE+RA*8+4], LJ_TFUNC
6307 //| ins_next
6308 dasm_put(Dst, 10946, Dt1(->base), Dt1(->base), LJ_TFUNC);
6309#line 4764 "vm_x86.dasc"
6310 break;
6311
6312 /* -- Table ops --------------------------------------------------------- */
6313
6314 case BC_TNEW:
6315 //| ins_AD // RA = dst, RD = hbits|asize
6316 //| mov L:RB, SAVE_L
6317 //| mov L:RB->base, BASE
6318 //| mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
6319 //| cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
6320 //| mov SAVE_PC, PC
6321 //| jae >5
6322 //|1:
6323 //|.if X64
6324 //| mov CARG3d, RD
6325 //| and RD, 0x7ff
6326 //| shr CARG3d, 11
6327 //|.else
6328 //| mov RA, RD
6329 //| and RD, 0x7ff
6330 //| shr RA, 11
6331 //| mov ARG3, RA
6332 //|.endif
6333 //| cmp RD, 0x7ff
6334 //| je >3
6335 //|2:
6336 //|.if X64
6337 //| mov L:CARG1d, L:RB
6338 //| mov CARG2d, RD
6339 //|.else
6340 //| mov ARG1, L:RB
6341 //| mov ARG2, RD
6342 //|.endif
6343 //| call extern lj_tab_new // (lua_State *L, int32_t asize, uint32_t hbits)
6344 //| // Table * returned in eax (RC).
6345 //| mov BASE, L:RB->base
6346 //| movzx RA, PC_RA
6347 //| mov [BASE+RA*8], TAB:RC
6348 //| mov dword [BASE+RA*8+4], LJ_TTAB
6349 //| ins_next
6350 //|3: // Turn 0x7ff into 0x801.
6351 //| mov RD, 0x801
6352 //| jmp <2
6353 //|5:
6354 //| mov L:FCARG1, L:RB
6355 //| call extern lj_gc_step_fixtop@4 // (lua_State *L)
6356 //| movzx RD, PC_RD
6357 //| jmp <1
6358 dasm_put(Dst, 11013, Dt1(->base), DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), LJ_TTAB);
6359#line 4812 "vm_x86.dasc"
6360 break;
6361 case BC_TDUP:
6362 //| ins_AND // RA = dst, RD = table const (~) (holding template table)
6363 //| mov L:RB, SAVE_L
6364 //| mov RA, [DISPATCH+DISPATCH_GL(gc.total)]
6365 //| mov SAVE_PC, PC
6366 //| cmp RA, [DISPATCH+DISPATCH_GL(gc.threshold)]
6367 //| mov L:RB->base, BASE
6368 //| jae >3
6369 //|2:
6370 //| mov TAB:FCARG2, [KBASE+RD*4] // Caveat: FCARG2 == BASE
6371 //| mov L:FCARG1, L:RB // Caveat: FCARG1 == RA
6372 //| call extern lj_tab_dup@8 // (lua_State *L, Table *kt)
6373 //| // Table * returned in eax (RC).
6374 //| mov BASE, L:RB->base
6375 //| movzx RA, PC_RA
6376 //| mov [BASE+RA*8], TAB:RC
6377 //| mov dword [BASE+RA*8+4], LJ_TTAB
6378 //| ins_next
6379 //|3:
6380 //| mov L:FCARG1, L:RB
6381 //| call extern lj_gc_step_fixtop@4 // (lua_State *L)
6382 //| movzx RD, PC_RD // Need to reload RD.
6383 //| not RDa
6384 //| jmp <2
6385 dasm_put(Dst, 11137, DISPATCH_GL(gc.total), DISPATCH_GL(gc.threshold), Dt1(->base), Dt1(->base), LJ_TTAB);
6386#line 4837 "vm_x86.dasc"
6387 break;
6388
6389 case BC_GGET:
6390 //| ins_AND // RA = dst, RD = str const (~)
6391 //| mov LFUNC:RB, [BASE-8]
6392 //| mov TAB:RB, LFUNC:RB->env
6393 //| mov STR:RC, [KBASE+RD*4]
6394 //| jmp ->BC_TGETS_Z
6395 dasm_put(Dst, 11236, Dt7(->env));
6396#line 4845 "vm_x86.dasc"
6397 break;
6398 case BC_GSET:
6399 //| ins_AND // RA = src, RD = str const (~)
6400 //| mov LFUNC:RB, [BASE-8]
6401 //| mov TAB:RB, LFUNC:RB->env
6402 //| mov STR:RC, [KBASE+RD*4]
6403 //| jmp ->BC_TSETS_Z
6404 dasm_put(Dst, 11256, Dt7(->env));
6405#line 4852 "vm_x86.dasc"
6406 break;
6407
6408 case BC_TGETV:
6409 //| ins_ABC // RA = dst, RB = table, RC = key
6410 //| checktab RB, ->vmeta_tgetv
6411 //| mov TAB:RB, [BASE+RB*8]
6412 //|
6413 //| // Integer key?
6414 //|.if DUALNUM
6415 //| checkint RC, >5
6416 //| mov RC, dword [BASE+RC*8]
6417 //|.else
6418 //| // Convert number to int and back and compare.
6419 //| checknum RC, >5
6420 //|.if SSE
6421 //| movsd xmm0, qword [BASE+RC*8]
6422 //| cvtsd2si RC, xmm0
6423 //| cvtsi2sd xmm1, RC
6424 //| ucomisd xmm0, xmm1
6425 //|.else
6426 //| fld qword [BASE+RC*8]
6427 //| fist ARG1
6428 //| fild ARG1
6429 //| fcomparepp
6430 //| mov RC, ARG1
6431 //|.endif
6432 //| jne ->vmeta_tgetv // Generic numeric key? Use fallback.
6433 //|.endif
6434 //| cmp RC, TAB:RB->asize // Takes care of unordered, too.
6435 //| jae ->vmeta_tgetv // Not in array part? Use fallback.
6436 //| shl RC, 3
6437 //| add RC, TAB:RB->array
6438 //| cmp dword [RC+4], LJ_TNIL // Avoid overwriting RB in fastpath.
6439 //| je >2
6440 //| // Get array slot.
6441 //|.if X64
6442 //| mov RBa, [RC]
6443 //| mov [BASE+RA*8], RBa
6444 //|.else
6445 //| mov RB, [RC]
6446 //| mov RC, [RC+4]
6447 //| mov [BASE+RA*8], RB
6448 //| mov [BASE+RA*8+4], RC
6449 //|.endif
6450 //|1:
6451 //| ins_next
6452 //|
6453 //|2: // Check for __index if table value is nil.
6454 //| cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
6455 //| jz >3
6456 //| mov TAB:RA, TAB:RB->metatable
6457 dasm_put(Dst, 11276, LJ_TTAB, LJ_TISNUM, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable));
6458#line 4903 "vm_x86.dasc"
6459 //| test byte TAB:RA->nomm, 1<<MM_index
6460 //| jz ->vmeta_tgetv // 'no __index' flag NOT set: check.
6461 //| movzx RA, PC_RA // Restore RA.
6462 //|3:
6463 //| mov dword [BASE+RA*8+4], LJ_TNIL
6464 //| jmp <1
6465 //|
6466 //|5: // String key?
6467 //| checkstr RC, ->vmeta_tgetv
6468 //| mov STR:RC, [BASE+RC*8]
6469 //| jmp ->BC_TGETS_Z
6470 dasm_put(Dst, 11394, Dt6(->metatable), Dt6(->nomm), 1<<MM_index, LJ_TNIL, LJ_TSTR);
6471#line 4914 "vm_x86.dasc"
6472 break;
6473 case BC_TGETS:
6474 //| ins_ABC // RA = dst, RB = table, RC = str const (~)
6475 //| not RCa
6476 //| mov STR:RC, [KBASE+RC*4]
6477 //| checktab RB, ->vmeta_tgets
6478 //| mov TAB:RB, [BASE+RB*8]
6479 //|->BC_TGETS_Z: // RB = GCtab *, RC = GCstr *, refetches PC_RA.
6480 //| mov RA, TAB:RB->hmask
6481 //| and RA, STR:RC->hash
6482 //| imul RA, #NODE
6483 //| add NODE:RA, TAB:RB->node
6484 //|1:
6485 //| cmp dword NODE:RA->key.it, LJ_TSTR
6486 //| jne >4
6487 //| cmp dword NODE:RA->key.gcr, STR:RC
6488 //| jne >4
6489 //| // Ok, key found. Assumes: offsetof(Node, val) == 0
6490 //| cmp dword [RA+4], LJ_TNIL // Avoid overwriting RB in fastpath.
6491 //| je >5 // Key found, but nil value?
6492 //| movzx RC, PC_RA
6493 //| // Get node value.
6494 //|.if X64
6495 //| mov RBa, [RA]
6496 //| mov [BASE+RC*8], RBa
6497 //|.else
6498 //| mov RB, [RA]
6499 //| mov RA, [RA+4]
6500 //| mov [BASE+RC*8], RB
6501 //| mov [BASE+RC*8+4], RA
6502 //|.endif
6503 //|2:
6504 //| ins_next
6505 dasm_put(Dst, 11442, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
6506#line 4947 "vm_x86.dasc"
6507 //|
6508 //|3:
6509 //| movzx RC, PC_RA
6510 //| mov dword [BASE+RC*8+4], LJ_TNIL
6511 //| jmp <2
6512 //|
6513 //|4: // Follow hash chain.
6514 //| mov NODE:RA, NODE:RA->next
6515 //| test NODE:RA, NODE:RA
6516 //| jnz <1
6517 //| // End of hash chain: key not found, nil result.
6518 //|
6519 //|5: // Check for __index if table value is nil.
6520 //| mov TAB:RA, TAB:RB->metatable
6521 //| test TAB:RA, TAB:RA
6522 //| jz <3 // No metatable: done.
6523 //| test byte TAB:RA->nomm, 1<<MM_index
6524 //| jnz <3 // 'no __index' flag set: done.
6525 //| jmp ->vmeta_tgets // Caveat: preserve STR:RC.
6526 dasm_put(Dst, 11527, LJ_TNIL, DtB(->next), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
6527#line 4966 "vm_x86.dasc"
6528 break;
6529 case BC_TGETB:
6530 //| ins_ABC // RA = dst, RB = table, RC = byte literal
6531 //| checktab RB, ->vmeta_tgetb
6532 //| mov TAB:RB, [BASE+RB*8]
6533 //| cmp RC, TAB:RB->asize
6534 //| jae ->vmeta_tgetb
6535 //| shl RC, 3
6536 //| add RC, TAB:RB->array
6537 //| cmp dword [RC+4], LJ_TNIL // Avoid overwriting RB in fastpath.
6538 //| je >2
6539 //| // Get array slot.
6540 //|.if X64
6541 //| mov RBa, [RC]
6542 //| mov [BASE+RA*8], RBa
6543 //|.else
6544 //| mov RB, [RC]
6545 //| mov RC, [RC+4]
6546 //| mov [BASE+RA*8], RB
6547 //| mov [BASE+RA*8+4], RC
6548 //|.endif
6549 //|1:
6550 //| ins_next
6551 //|
6552 //|2: // Check for __index if table value is nil.
6553 //| cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
6554 //| jz >3
6555 //| mov TAB:RA, TAB:RB->metatable
6556 //| test byte TAB:RA->nomm, 1<<MM_index
6557 //| jz ->vmeta_tgetb // 'no __index' flag NOT set: check.
6558 //| movzx RA, PC_RA // Restore RA.
6559 dasm_put(Dst, 11599, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_index);
6560#line 4997 "vm_x86.dasc"
6561 //|3:
6562 //| mov dword [BASE+RA*8+4], LJ_TNIL
6563 //| jmp <1
6564 dasm_put(Dst, 11695, LJ_TNIL);
6565#line 5000 "vm_x86.dasc"
6566 break;
6567
6568 case BC_TSETV:
6569 //| ins_ABC // RA = src, RB = table, RC = key
6570 //| checktab RB, ->vmeta_tsetv
6571 //| mov TAB:RB, [BASE+RB*8]
6572 //|
6573 //| // Integer key?
6574 //|.if DUALNUM
6575 //| checkint RC, >5
6576 //| mov RC, dword [BASE+RC*8]
6577 //|.else
6578 //| // Convert number to int and back and compare.
6579 //| checknum RC, >5
6580 //|.if SSE
6581 //| movsd xmm0, qword [BASE+RC*8]
6582 //| cvtsd2si RC, xmm0
6583 //| cvtsi2sd xmm1, RC
6584 //| ucomisd xmm0, xmm1
6585 //|.else
6586 //| fld qword [BASE+RC*8]
6587 //| fist ARG1
6588 //| fild ARG1
6589 //| fcomparepp
6590 //| mov RC, ARG1
6591 //|.endif
6592 //| jne ->vmeta_tsetv // Generic numeric key? Use fallback.
6593 //|.endif
6594 //| cmp RC, TAB:RB->asize // Takes care of unordered, too.
6595 //| jae ->vmeta_tsetv
6596 //| shl RC, 3
6597 //| add RC, TAB:RB->array
6598 //| cmp dword [RC+4], LJ_TNIL
6599 //| je >3 // Previous value is nil?
6600 //|1:
6601 //| test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
6602 //| jnz >7
6603 //|2: // Set array slot.
6604 //|.if X64
6605 //| mov RBa, [BASE+RA*8]
6606 dasm_put(Dst, 11712, LJ_TTAB, LJ_TISNUM, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK);
6607#line 5040 "vm_x86.dasc"
6608 //| mov [RC], RBa
6609 //|.else
6610 //| mov RB, [BASE+RA*8+4]
6611 //| mov RA, [BASE+RA*8]
6612 //| mov [RC+4], RB
6613 //| mov [RC], RA
6614 //|.endif
6615 //| ins_next
6616 //|
6617 //|3: // Check for __newindex if previous value is nil.
6618 //| cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
6619 //| jz <1
6620 //| mov TAB:RA, TAB:RB->metatable
6621 //| test byte TAB:RA->nomm, 1<<MM_newindex
6622 //| jz ->vmeta_tsetv // 'no __newindex' flag NOT set: check.
6623 //| movzx RA, PC_RA // Restore RA.
6624 //| jmp <1
6625 //|
6626 //|5: // String key?
6627 //| checkstr RC, ->vmeta_tsetv
6628 //| mov STR:RC, [BASE+RC*8]
6629 //| jmp ->BC_TSETS_Z
6630 //|
6631 //|7: // Possible table write barrier for the value. Skip valiswhite check.
6632 //| barrierback TAB:RB, RA
6633 dasm_put(Dst, 11804, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt6(->marked), (uint8_t)~LJ_GC_BLACK);
6634#line 5065 "vm_x86.dasc"
6635 //| movzx RA, PC_RA // Restore RA.
6636 //| jmp <2
6637 dasm_put(Dst, 11888, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
6638#line 5067 "vm_x86.dasc"
6639 break;
6640 case BC_TSETS:
6641 //| ins_ABC // RA = src, RB = table, RC = str const (~)
6642 //| not RCa
6643 //| mov STR:RC, [KBASE+RC*4]
6644 //| checktab RB, ->vmeta_tsets
6645 //| mov TAB:RB, [BASE+RB*8]
6646 //|->BC_TSETS_Z: // RB = GCtab *, RC = GCstr *, refetches PC_RA.
6647 //| mov RA, TAB:RB->hmask
6648 //| and RA, STR:RC->hash
6649 //| imul RA, #NODE
6650 //| mov byte TAB:RB->nomm, 0 // Clear metamethod cache.
6651 //| add NODE:RA, TAB:RB->node
6652 //|1:
6653 //| cmp dword NODE:RA->key.it, LJ_TSTR
6654 //| jne >5
6655 //| cmp dword NODE:RA->key.gcr, STR:RC
6656 //| jne >5
6657 //| // Ok, key found. Assumes: offsetof(Node, val) == 0
6658 //| cmp dword [RA+4], LJ_TNIL
6659 //| je >4 // Previous value is nil?
6660 //|2:
6661 //| test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
6662 dasm_put(Dst, 11909, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->nomm), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), LJ_TNIL);
6663#line 5090 "vm_x86.dasc"
6664 //| jnz >7
6665 //|3: // Set node value.
6666 //| movzx RC, PC_RA
6667 //|.if X64
6668 //| mov RBa, [BASE+RC*8]
6669 //| mov [RA], RBa
6670 //|.else
6671 //| mov RB, [BASE+RC*8+4]
6672 //| mov RC, [BASE+RC*8]
6673 //| mov [RA+4], RB
6674 //| mov [RA], RC
6675 //|.endif
6676 //| ins_next
6677 //|
6678 //|4: // Check for __newindex if previous value is nil.
6679 //| cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
6680 //| jz <2
6681 //| mov TMP1, RA // Save RA.
6682 //| mov TAB:RA, TAB:RB->metatable
6683 //| test byte TAB:RA->nomm, 1<<MM_newindex
6684 //| jz ->vmeta_tsets // 'no __newindex' flag NOT set: check.
6685 //| mov RA, TMP1 // Restore RA.
6686 //| jmp <2
6687 //|
6688 //|5: // Follow hash chain.
6689 //| mov NODE:RA, NODE:RA->next
6690 //| test NODE:RA, NODE:RA
6691 //| jnz <1
6692 //| // End of hash chain: key not found, add a new one.
6693 //|
6694 //| // But check for __newindex first.
6695 //| mov TAB:RA, TAB:RB->metatable
6696 dasm_put(Dst, 11986, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable), Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, DtB(->next));
6697#line 5122 "vm_x86.dasc"
6698 //| test TAB:RA, TAB:RA
6699 //| jz >6 // No metatable: continue.
6700 //| test byte TAB:RA->nomm, 1<<MM_newindex
6701 //| jz ->vmeta_tsets // 'no __newindex' flag NOT set: check.
6702 //|6:
6703 //| mov TMP1, STR:RC
6704 //| mov TMP2, LJ_TSTR
6705 //| mov TMP3, TAB:RB // Save TAB:RB for us.
6706 //|.if X64
6707 //| mov L:CARG1d, SAVE_L
6708 //| mov L:CARG1d->base, BASE
6709 //| lea CARG3, TMP1
6710 //| mov CARG2d, TAB:RB
6711 //| mov L:RB, L:CARG1d
6712 //|.else
6713 //| lea RC, TMP1 // Store temp. TValue in TMP1/TMP2.
6714 //| mov ARG2, TAB:RB
6715 //| mov L:RB, SAVE_L
6716 //| mov ARG3, RC
6717 //| mov ARG1, L:RB
6718 //| mov L:RB->base, BASE
6719 //|.endif
6720 //| mov SAVE_PC, PC
6721 //| call extern lj_tab_newkey // (lua_State *L, GCtab *t, TValue *k)
6722 //| // Handles write barrier for the new key. TValue * returned in eax (RC).
6723 //| mov BASE, L:RB->base
6724 //| mov TAB:RB, TMP3 // Need TAB:RB for barrier.
6725 //| mov RA, eax
6726 //| jmp <2 // Must check write barrier for value.
6727 //|
6728 //|7: // Possible table write barrier for the value. Skip valiswhite check.
6729 //| barrierback TAB:RB, RC // Destroys STR:RC.
6730 //| jmp <3
6731 dasm_put(Dst, 12073, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, LJ_TSTR, Dt1(->base), Dt1(->base), Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
6732#line 5155 "vm_x86.dasc"
6733 break;
6734 case BC_TSETB:
6735 //| ins_ABC // RA = src, RB = table, RC = byte literal
6736 //| checktab RB, ->vmeta_tsetb
6737 //| mov TAB:RB, [BASE+RB*8]
6738 //| cmp RC, TAB:RB->asize
6739 //| jae ->vmeta_tsetb
6740 //| shl RC, 3
6741 //| add RC, TAB:RB->array
6742 //| cmp dword [RC+4], LJ_TNIL
6743 //| je >3 // Previous value is nil?
6744 //|1:
6745 //| test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
6746 //| jnz >7
6747 //|2: // Set array slot.
6748 //|.if X64
6749 //| mov RAa, [BASE+RA*8]
6750 //| mov [RC], RAa
6751 //|.else
6752 //| mov RB, [BASE+RA*8+4]
6753 //| mov RA, [BASE+RA*8]
6754 //| mov [RC+4], RB
6755 //| mov [RC], RA
6756 //|.endif
6757 //| ins_next
6758 //|
6759 //|3: // Check for __newindex if previous value is nil.
6760 //| cmp dword TAB:RB->metatable, 0 // Shouldn't overwrite RA for fastpath.
6761 //| jz <1
6762 //| mov TAB:RA, TAB:RB->metatable
6763 dasm_put(Dst, 12165, LJ_TTAB, Dt6(->asize), Dt6(->array), LJ_TNIL, Dt6(->marked), LJ_GC_BLACK, Dt6(->metatable));
6764#line 5185 "vm_x86.dasc"
6765 //| test byte TAB:RA->nomm, 1<<MM_newindex
6766 //| jz ->vmeta_tsetb // 'no __newindex' flag NOT set: check.
6767 //| movzx RA, PC_RA // Restore RA.
6768 //| jmp <1
6769 //|
6770 //|7: // Possible table write barrier for the value. Skip valiswhite check.
6771 //| barrierback TAB:RB, RA
6772 //| movzx RA, PC_RA // Restore RA.
6773 //| jmp <2
6774 dasm_put(Dst, 12260, Dt6(->metatable), Dt6(->nomm), 1<<MM_newindex, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
6775#line 5194 "vm_x86.dasc"
6776 break;
6777
6778 case BC_TSETM:
6779 //| ins_AD // RA = base (table at base-1), RD = num const (start index)
6780 //| mov TMP1, KBASE // Need one more free register.
6781 //| mov KBASE, dword [KBASE+RD*8] // Integer constant is in lo-word.
6782 //|1:
6783 //| lea RA, [BASE+RA*8]
6784 //| mov TAB:RB, [RA-8] // Guaranteed to be a table.
6785 //| test byte TAB:RB->marked, LJ_GC_BLACK // isblack(table)
6786 //| jnz >7
6787 //|2:
6788 //| mov RD, MULTRES
6789 //| sub RD, 1
6790 //| jz >4 // Nothing to copy?
6791 //| add RD, KBASE // Compute needed size.
6792 //| cmp RD, TAB:RB->asize
6793 //| ja >5 // Doesn't fit into array part?
6794 //| sub RD, KBASE
6795 //| shl KBASE, 3
6796 //| add KBASE, TAB:RB->array
6797 //|3: // Copy result slots to table.
6798 //|.if X64
6799 //| mov RBa, [RA]
6800 //| add RA, 8
6801 //| mov [KBASE], RBa
6802 //|.else
6803 //| mov RB, [RA]
6804 //| mov [KBASE], RB
6805 //| mov RB, [RA+4]
6806 //| add RA, 8
6807 //| mov [KBASE+4], RB
6808 //|.endif
6809 //| add KBASE, 8
6810 //| sub RD, 1
6811 //| jnz <3
6812 //|4:
6813 //| mov KBASE, TMP1
6814 //| ins_next
6815 //|
6816 //|5: // Need to resize array part.
6817 //|.if X64
6818 //| mov L:CARG1d, SAVE_L
6819 //| mov L:CARG1d->base, BASE // Caveat: CARG2d/CARG3d may be BASE.
6820 //| mov CARG2d, TAB:RB
6821 //| mov CARG3d, RD
6822 //| mov L:RB, L:CARG1d
6823 //|.else
6824 //| mov ARG2, TAB:RB
6825 //| mov L:RB, SAVE_L
6826 //| mov L:RB->base, BASE
6827 //| mov ARG3, RD
6828 //| mov ARG1, L:RB
6829 //|.endif
6830 //| mov SAVE_PC, PC
6831 //| call extern lj_tab_reasize // (lua_State *L, GCtab *t, int nasize)
6832 //| mov BASE, L:RB->base
6833 //| movzx RA, PC_RA // Restore RA.
6834 //| jmp <1 // Retry.
6835 //|
6836 //|7: // Possible table write barrier for any value. Skip valiswhite check.
6837 //| barrierback TAB:RB, RD
6838 dasm_put(Dst, 12308, Dt6(->marked), LJ_GC_BLACK, Dt6(->asize), Dt6(->array), Dt1(->base), Dt1(->base));
6839#line 5256 "vm_x86.dasc"
6840 //| jmp <2
6841 dasm_put(Dst, 12458, Dt6(->marked), (uint8_t)~LJ_GC_BLACK, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist));
6842#line 5257 "vm_x86.dasc"
6843 break;
6844
6845 /* -- Calls and vararg handling ----------------------------------------- */
6846
6847 case BC_CALL: case BC_CALLM:
6848 //| ins_A_C // RA = base, (RB = nresults+1,) RC = nargs+1 | extra_nargs
6849 dasm_put(Dst, 9787);
6850#line 5263 "vm_x86.dasc"
6851 if (op == BC_CALLM) {
6852 //| add NARGS:RD, MULTRES
6853 dasm_put(Dst, 12478);
6854#line 5265 "vm_x86.dasc"
6855 }
6856 //| cmp dword [BASE+RA*8+4], LJ_TFUNC
6857 //| mov LFUNC:RB, [BASE+RA*8]
6858 //| jne ->vmeta_call_ra
6859 //| lea BASE, [BASE+RA*8+8]
6860 //| ins_call
6861 dasm_put(Dst, 12483, LJ_TFUNC, Dt7(->pc));
6862#line 5271 "vm_x86.dasc"
6863 break;
6864
6865 case BC_CALLMT:
6866 //| ins_AD // RA = base, RD = extra_nargs
6867 //| add NARGS:RD, MULTRES
6868 //| // Fall through. Assumes BC_CALLT follows and ins_AD is a no-op.
6869 dasm_put(Dst, 12478);
6870#line 5277 "vm_x86.dasc"
6871 break;
6872 case BC_CALLT:
6873 //| ins_AD // RA = base, RD = nargs+1
6874 //| lea RA, [BASE+RA*8+8]
6875 //| mov KBASE, BASE // Use KBASE for move + vmeta_call hint.
6876 //| mov LFUNC:RB, [RA-8]
6877 //| cmp dword [RA-4], LJ_TFUNC
6878 //| jne ->vmeta_call
6879 //|->BC_CALLT_Z:
6880 //| mov PC, [BASE-4]
6881 //| test PC, FRAME_TYPE
6882 //| jnz >7
6883 //|1:
6884 //| mov [BASE-8], LFUNC:RB // Copy function down, reloaded below.
6885 //| mov MULTRES, NARGS:RD
6886 //| sub NARGS:RD, 1
6887 //| jz >3
6888 //|2: // Move args down.
6889 //|.if X64
6890 //| mov RBa, [RA]
6891 //| add RA, 8
6892 //| mov [KBASE], RBa
6893 //|.else
6894 //| mov RB, [RA]
6895 //| mov [KBASE], RB
6896 //| mov RB, [RA+4]
6897 //| add RA, 8
6898 //| mov [KBASE+4], RB
6899 //|.endif
6900 //| add KBASE, 8
6901 //| sub NARGS:RD, 1
6902 //| jnz <2
6903 //|
6904 //| mov LFUNC:RB, [BASE-8]
6905 //|3:
6906 //| mov NARGS:RD, MULTRES
6907 //| cmp byte LFUNC:RB->ffid, 1 // (> FF_C) Calling a fast function?
6908 //| ja >5
6909 //|4:
6910 //| ins_callt
6911 //|
6912 //|5: // Tailcall to a fast function.
6913 //| test PC, FRAME_TYPE // Lua frame below?
6914 dasm_put(Dst, 12526, LJ_TFUNC, FRAME_TYPE, Dt7(->ffid), Dt7(->pc));
6915#line 5320 "vm_x86.dasc"
6916 //| jnz <4
6917 //| movzx RA, PC_RA
6918 //| not RAa
6919 //| lea RA, [BASE+RA*8]
6920 //| mov LFUNC:KBASE, [RA-8] // Need to prepare KBASE.
6921 //| mov KBASE, LFUNC:KBASE->pc
6922 //| mov KBASE, [KBASE+PC2PROTO(k)]
6923 //| jmp <4
6924 //|
6925 //|7: // Tailcall from a vararg function.
6926 //| sub PC, FRAME_VARG
6927 //| test PC, FRAME_TYPEP
6928 //| jnz >8 // Vararg frame below?
6929 //| sub BASE, PC // Need to relocate BASE/KBASE down.
6930 //| mov KBASE, BASE
6931 //| mov PC, [BASE-4]
6932 //| jmp <1
6933 //|8:
6934 //| add PC, FRAME_VARG
6935 //| jmp <1
6936 dasm_put(Dst, 12644, FRAME_TYPE, Dt7(->pc), PC2PROTO(k), FRAME_VARG, FRAME_TYPEP, FRAME_VARG);
6937#line 5340 "vm_x86.dasc"
6938 break;
6939
6940 case BC_ITERC:
6941 //| ins_A // RA = base, (RB = nresults+1,) RC = nargs+1 (2+1)
6942 //| lea RA, [BASE+RA*8+8] // fb = base+1
6943 //|.if X64
6944 //| mov RBa, [RA-24] // Copy state. fb[0] = fb[-3].
6945 //| mov RCa, [RA-16] // Copy control var. fb[1] = fb[-2].
6946 //| mov [RA], RBa
6947 //| mov [RA+8], RCa
6948 //|.else
6949 //| mov RB, [RA-24] // Copy state. fb[0] = fb[-3].
6950 //| mov RC, [RA-20]
6951 //| mov [RA], RB
6952 //| mov [RA+4], RC
6953 //| mov RB, [RA-16] // Copy control var. fb[1] = fb[-2].
6954 //| mov RC, [RA-12]
6955 //| mov [RA+8], RB
6956 //| mov [RA+12], RC
6957 //|.endif
6958 //| mov LFUNC:RB, [RA-32] // Copy callable. fb[-1] = fb[-4]
6959 //| mov RC, [RA-28]
6960 //| mov [RA-8], LFUNC:RB
6961 //| mov [RA-4], RC
6962 //| cmp RC, LJ_TFUNC // Handle like a regular 2-arg call.
6963 //| mov NARGS:RD, 2+1
6964 //| jne ->vmeta_call
6965 //| mov BASE, RA
6966 //| ins_call
6967 dasm_put(Dst, 12718, LJ_TFUNC, 2+1, Dt7(->pc));
6968#line 5369 "vm_x86.dasc"
6969 break;
6970
6971 case BC_ITERN:
6972 //| ins_A // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
6973 //|.if JIT
6974 //| // NYI: add hotloop, record BC_ITERN.
6975 //|.endif
6976 //| mov TMP1, KBASE // Need two more free registers.
6977 //| mov TMP2, DISPATCH
6978 //| mov TAB:RB, [BASE+RA*8-16]
6979 //| mov RC, [BASE+RA*8-8] // Get index from control var.
6980 //| mov DISPATCH, TAB:RB->asize
6981 //| add PC, 4
6982 //| mov KBASE, TAB:RB->array
6983 //|1: // Traverse array part.
6984 //| cmp RC, DISPATCH; jae >5 // Index points after array part?
6985 //| cmp dword [KBASE+RC*8+4], LJ_TNIL; je >4
6986 //|.if DUALNUM
6987 //| mov dword [BASE+RA*8+4], LJ_TISNUM
6988 //| mov dword [BASE+RA*8], RC
6989 //|.elif SSE
6990 //| cvtsi2sd xmm0, RC
6991 //|.else
6992 //| fild dword [BASE+RA*8-8]
6993 //|.endif
6994 //| // Copy array slot to returned value.
6995 //|.if X64
6996 //| mov RBa, [KBASE+RC*8]
6997 //| mov [BASE+RA*8+8], RBa
6998 //|.else
6999 //| mov RB, [KBASE+RC*8+4]
7000 //| mov [BASE+RA*8+12], RB
7001 //| mov RB, [KBASE+RC*8]
7002 //| mov [BASE+RA*8+8], RB
7003 //|.endif
7004 //| add RC, 1
7005 //| // Return array index as a numeric key.
7006 //|.if DUALNUM
7007 //| // See above.
7008 //|.elif SSE
7009 //| movsd qword [BASE+RA*8], xmm0
7010 //|.else
7011 //| fstp qword [BASE+RA*8]
7012 //|.endif
7013 //| mov [BASE+RA*8-8], RC // Update control var.
7014 //|2:
7015 //| movzx RD, PC_RD // Get target from ITERL.
7016 //| branchPC RD
7017 //|3:
7018 //| mov DISPATCH, TMP2
7019 //| mov KBASE, TMP1
7020 //| ins_next
7021 //|
7022 //|4: // Skip holes in array part.
7023 //| add RC, 1
7024 //|.if not (DUALNUM or SSE)
7025 //| mov [BASE+RA*8-8], RC
7026 //|.endif
7027 //| jmp <1
7028 //|
7029 //|5: // Traverse hash part.
7030 //| sub RC, DISPATCH
7031 //|6:
7032 //| cmp RC, TAB:RB->hmask; ja <3 // End of iteration? Branch to ITERL+1.
7033 //| imul KBASE, RC, #NODE
7034 //| add NODE:KBASE, TAB:RB->node
7035 dasm_put(Dst, 12790, Dt6(->asize), Dt6(->array), LJ_TNIL, -BCBIAS_J*4, Dt6(->hmask), sizeof(Node));
7036#line 5435 "vm_x86.dasc"
7037 //| cmp dword NODE:KBASE->val.it, LJ_TNIL; je >7
7038 //| lea DISPATCH, [RC+DISPATCH+1]
7039 //| // Copy key and value from hash slot.
7040 //|.if X64
7041 //| mov RBa, NODE:KBASE->key
7042 //| mov RCa, NODE:KBASE->val
7043 //| mov [BASE+RA*8], RBa
7044 //| mov [BASE+RA*8+8], RCa
7045 //|.else
7046 //| mov RB, NODE:KBASE->key.gcr
7047 //| mov RC, NODE:KBASE->key.it
7048 //| mov [BASE+RA*8], RB
7049 //| mov [BASE+RA*8+4], RC
7050 //| mov RB, NODE:KBASE->val.gcr
7051 //| mov RC, NODE:KBASE->val.it
7052 //| mov [BASE+RA*8+8], RB
7053 //| mov [BASE+RA*8+12], RC
7054 //|.endif
7055 //| mov [BASE+RA*8-8], DISPATCH
7056 //| jmp <2
7057 //|
7058 //|7: // Skip holes in hash part.
7059 //| add RC, 1
7060 //| jmp <6
7061 dasm_put(Dst, 12942, Dt6(->node), DtB(->val.it), LJ_TNIL, DtB(->key), DtB(->val));
7062#line 5459 "vm_x86.dasc"
7063 break;
7064
7065 case BC_ISNEXT:
7066 //| ins_AD // RA = base, RD = target (points to ITERN)
7067 //| cmp dword [BASE+RA*8-20], LJ_TFUNC; jne >5
7068 //| mov CFUNC:RB, [BASE+RA*8-24]
7069 //| cmp dword [BASE+RA*8-12], LJ_TTAB; jne >5
7070 //| cmp dword [BASE+RA*8-4], LJ_TNIL; jne >5
7071 //| cmp byte CFUNC:RB->ffid, FF_next_N; jne >5
7072 //| branchPC RD
7073 //| mov dword [BASE+RA*8-8], 0 // Initialize control var.
7074 //| mov dword [BASE+RA*8-4], 0xfffe7fff
7075 //|1:
7076 //| ins_next
7077 //|5: // Despecialize bytecode if any of the checks fail.
7078 //| mov PC_OP, BC_JMP
7079 //| branchPC RD
7080 //| mov byte [PC], BC_ITERC
7081 //| jmp <1
7082 dasm_put(Dst, 12997, LJ_TFUNC, LJ_TTAB, LJ_TNIL, Dt8(->ffid), FF_next_N, -BCBIAS_J*4, BC_JMP, -BCBIAS_J*4, BC_ITERC);
7083#line 5478 "vm_x86.dasc"
7084 break;
7085
7086 case BC_VARG:
7087 //| ins_ABC // RA = base, RB = nresults+1, RC = numparams
7088 //| mov TMP1, KBASE // Need one more free register.
7089 //| lea KBASE, [BASE+RC*8+(8+FRAME_VARG)]
7090 //| lea RA, [BASE+RA*8]
7091 //| sub KBASE, [BASE-4]
7092 //| // Note: KBASE may now be even _above_ BASE if nargs was < numparams.
7093 //| test RB, RB
7094 //| jz >5 // Copy all varargs?
7095 //| lea RB, [RA+RB*8-8]
7096 //| cmp KBASE, BASE // No vararg slots?
7097 //| jnb >2
7098 //|1: // Copy vararg slots to destination slots.
7099 //|.if X64
7100 //| mov RCa, [KBASE-8]
7101 //| add KBASE, 8
7102 //| mov [RA], RCa
7103 //|.else
7104 //| mov RC, [KBASE-8]
7105 //| mov [RA], RC
7106 //| mov RC, [KBASE-4]
7107 //| add KBASE, 8
7108 //| mov [RA+4], RC
7109 //|.endif
7110 //| add RA, 8
7111 //| cmp RA, RB // All destination slots filled?
7112 //| jnb >3
7113 //| cmp KBASE, BASE // No more vararg slots?
7114 //| jb <1
7115 //|2: // Fill up remainder with nil.
7116 //| mov dword [RA+4], LJ_TNIL
7117 //| add RA, 8
7118 //| cmp RA, RB
7119 //| jb <2
7120 //|3:
7121 //| mov KBASE, TMP1
7122 //| ins_next
7123 //|
7124 //|5: // Copy all varargs.
7125 //| mov MULTRES, 1 // MULTRES = 0+1
7126 //| mov RC, BASE
7127 //| sub RC, KBASE
7128 //| jbe <3 // No vararg slots?
7129 //| mov RB, RC
7130 //| shr RB, 3
7131 //| add RB, 1
7132 //| mov MULTRES, RB // MULTRES = #varargs+1
7133 //| mov L:RB, SAVE_L
7134 //| add RC, RA
7135 //| cmp RC, L:RB->maxstack
7136 //| ja >7 // Need to grow stack?
7137 //|6: // Copy all vararg slots.
7138 //|.if X64
7139 //| mov RCa, [KBASE-8]
7140 dasm_put(Dst, 13110, (8+FRAME_VARG), LJ_TNIL, Dt1(->maxstack));
7141#line 5534 "vm_x86.dasc"
7142 //| add KBASE, 8
7143 //| mov [RA], RCa
7144 //|.else
7145 //| mov RC, [KBASE-8]
7146 //| mov [RA], RC
7147 //| mov RC, [KBASE-4]
7148 //| add KBASE, 8
7149 //| mov [RA+4], RC
7150 //|.endif
7151 //| add RA, 8
7152 //| cmp KBASE, BASE // No more vararg slots?
7153 //| jb <6
7154 //| jmp <3
7155 //|
7156 //|7: // Grow stack for varargs.
7157 //| mov L:RB->base, BASE
7158 //| mov L:RB->top, RA
7159 //| mov SAVE_PC, PC
7160 //| sub KBASE, BASE // Need delta, because BASE may change.
7161 //| mov FCARG2, MULTRES
7162 //| sub FCARG2, 1
7163 //| mov FCARG1, L:RB
7164 //| call extern lj_state_growstack@8 // (lua_State *L, int n)
7165 //| mov BASE, L:RB->base
7166 //| mov RA, L:RB->top
7167 //| add KBASE, BASE
7168 //| jmp <6
7169 dasm_put(Dst, 13277, Dt1(->base), Dt1(->top), Dt1(->base), Dt1(->top));
7170#line 5561 "vm_x86.dasc"
7171 break;
7172
7173 /* -- Returns ----------------------------------------------------------- */
7174
7175 case BC_RETM:
7176 //| ins_AD // RA = results, RD = extra_nresults
7177 //| add RD, MULTRES // MULTRES >=1, so RD >=1.
7178 //| // Fall through. Assumes BC_RET follows and ins_AD is a no-op.
7179 dasm_put(Dst, 12478);
7180#line 5569 "vm_x86.dasc"
7181 break;
7182
7183 case BC_RET: case BC_RET0: case BC_RET1:
7184 //| ins_AD // RA = results, RD = nresults+1
7185 if (op != BC_RET0) {
7186 //| shl RA, 3
7187 dasm_put(Dst, 13347);
7188#line 5575 "vm_x86.dasc"
7189 }
7190 //|1:
7191 //| mov PC, [BASE-4]
7192 //| mov MULTRES, RD // Save nresults+1.
7193 //| test PC, FRAME_TYPE // Check frame type marker.
7194 //| jnz >7 // Not returning to a fixarg Lua func?
7195 dasm_put(Dst, 13351, FRAME_TYPE);
7196#line 5581 "vm_x86.dasc"
7197 switch (op) {
7198 case BC_RET:
7199 //|->BC_RET_Z:
7200 //| mov KBASE, BASE // Use KBASE for result move.
7201 //| sub RD, 1
7202 //| jz >3
7203 //|2: // Move results down.
7204 //|.if X64
7205 //| mov RBa, [KBASE+RA]
7206 //| mov [KBASE-8], RBa
7207 //|.else
7208 //| mov RB, [KBASE+RA]
7209 //| mov [KBASE-8], RB
7210 //| mov RB, [KBASE+RA+4]
7211 //| mov [KBASE-4], RB
7212 //|.endif
7213 //| add KBASE, 8
7214 //| sub RD, 1
7215 //| jnz <2
7216 //|3:
7217 //| mov RD, MULTRES // Note: MULTRES may be >255.
7218 //| movzx RB, PC_RB // So cannot compare with RDL!
7219 //|5:
7220 //| cmp RB, RD // More results expected?
7221 //| ja >6
7222 dasm_put(Dst, 13370);
7223#line 5606 "vm_x86.dasc"
7224 break;
7225 case BC_RET1:
7226 //|.if X64
7227 //| mov RBa, [BASE+RA]
7228 //| mov [BASE-8], RBa
7229 //|.else
7230 //| mov RB, [BASE+RA+4]
7231 //| mov [BASE-4], RB
7232 //| mov RB, [BASE+RA]
7233 //| mov [BASE-8], RB
7234 //|.endif
7235 dasm_put(Dst, 13424);
7236#line 5617 "vm_x86.dasc"
7237 /* fallthrough */
7238 case BC_RET0:
7239 //|5:
7240 //| cmp PC_RB, RDL // More results expected?
7241 //| ja >6
7242 dasm_put(Dst, 13434);
7243#line 5622 "vm_x86.dasc"
7244 default:
7245 break;
7246 }
7247 //| movzx RA, PC_RA
7248 //| not RAa // Note: ~RA = -(RA+1)
7249 //| lea BASE, [BASE+RA*8] // base = base - (RA+1)*8
7250 //| mov LFUNC:KBASE, [BASE-8]
7251 //| mov KBASE, LFUNC:KBASE->pc
7252 //| mov KBASE, [KBASE+PC2PROTO(k)]
7253 //| ins_next
7254 //|
7255 //|6: // Fill up results with nil.
7256 dasm_put(Dst, 13445, Dt7(->pc), PC2PROTO(k));
7257#line 5634 "vm_x86.dasc"
7258 if (op == BC_RET) {
7259 //| mov dword [KBASE-4], LJ_TNIL // Note: relies on shifted base.
7260 //| add KBASE, 8
7261 dasm_put(Dst, 13493, LJ_TNIL);
7262#line 5637 "vm_x86.dasc"
7263 } else {
7264 //| mov dword [BASE+RD*8-12], LJ_TNIL
7265 dasm_put(Dst, 13504, LJ_TNIL);
7266#line 5639 "vm_x86.dasc"
7267 }
7268 //| add RD, 1
7269 //| jmp <5
7270 //|
7271 //|7: // Non-standard return case.
7272 //| lea RB, [PC-FRAME_VARG]
7273 //| test RB, FRAME_TYPEP
7274 //| jnz ->vm_return
7275 //| // Return from vararg function: relocate BASE down and RA up.
7276 //| sub BASE, RB
7277 dasm_put(Dst, 13511, -FRAME_VARG, FRAME_TYPEP);
7278#line 5649 "vm_x86.dasc"
7279 if (op != BC_RET0) {
7280 //| add RA, RB
7281 dasm_put(Dst, 13535);
7282#line 5651 "vm_x86.dasc"
7283 }
7284 //| jmp <1
7285 dasm_put(Dst, 9762);
7286#line 5653 "vm_x86.dasc"
7287 break;
7288
7289 /* -- Loops and branches ------------------------------------------------ */
7290
7291 //|.define FOR_IDX, [RA]; .define FOR_TIDX, dword [RA+4]
7292 //|.define FOR_STOP, [RA+8]; .define FOR_TSTOP, dword [RA+12]
7293 //|.define FOR_STEP, [RA+16]; .define FOR_TSTEP, dword [RA+20]
7294 //|.define FOR_EXT, [RA+24]; .define FOR_TEXT, dword [RA+28]
7295
7296 case BC_FORL:
7297 //|.if JIT
7298 //| hotloop RB
7299 //|.endif
7300 //| // Fall through. Assumes BC_IFORL follows and ins_AJ is a no-op.
7301 dasm_put(Dst, 13539, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
7302#line 5667 "vm_x86.dasc"
7303 break;
7304
7305 case BC_JFORI:
7306 case BC_JFORL:
7307#if !LJ_HASJIT
7308 break;
7309#endif
7310 case BC_FORI:
7311 case BC_IFORL:
7312 vk = (op == BC_IFORL || op == BC_JFORL);
7313 //| ins_AJ // RA = base, RD = target (after end of loop or start of loop)
7314 //| lea RA, [BASE+RA*8]
7315 dasm_put(Dst, 13560);
7316#line 5679 "vm_x86.dasc"
7317 if (LJ_DUALNUM) {
7318 //| cmp FOR_TIDX, LJ_TISNUM; jne >9
7319 dasm_put(Dst, 13564, LJ_TISNUM);
7320#line 5681 "vm_x86.dasc"
7321 if (!vk) {
7322 //| cmp FOR_TSTOP, LJ_TISNUM; jne ->vmeta_for
7323 //| cmp FOR_TSTEP, LJ_TISNUM; jne ->vmeta_for
7324 //| mov RB, dword FOR_IDX
7325 //| cmp dword FOR_STEP, 0; jl >5
7326 dasm_put(Dst, 13574, LJ_TISNUM, LJ_TISNUM);
7327#line 5686 "vm_x86.dasc"
7328 } else {
7329#ifdef LUA_USE_ASSERT
7330 //| cmp FOR_TSTOP, LJ_TISNUM; jne ->assert_bad_for_arg_type
7331 //| cmp FOR_TSTEP, LJ_TISNUM; jne ->assert_bad_for_arg_type
7332 dasm_put(Dst, 13603, LJ_TISNUM, LJ_TISNUM);
7333#line 5690 "vm_x86.dasc"
7334#endif
7335 //| mov RB, dword FOR_STEP
7336 //| test RB, RB; js >5
7337 //| add RB, dword FOR_IDX; jo >1
7338 //| mov dword FOR_IDX, RB
7339 dasm_put(Dst, 13622);
7340#line 5695 "vm_x86.dasc"
7341 }
7342 //| cmp RB, dword FOR_STOP
7343 //| mov FOR_TEXT, LJ_TISNUM
7344 //| mov dword FOR_EXT, RB
7345 dasm_put(Dst, 13641, LJ_TISNUM);
7346#line 5699 "vm_x86.dasc"
7347 if (op == BC_FORI) {
7348 //| jle >7
7349 //|1:
7350 //|6:
7351 //| branchPC RD
7352 dasm_put(Dst, 13652, -BCBIAS_J*4);
7353#line 5704 "vm_x86.dasc"
7354 } else if (op == BC_JFORI) {
7355 //| branchPC RD
7356 //| movzx RD, PC_RD
7357 //| jle =>BC_JLOOP
7358 //|1:
7359 //|6:
7360 dasm_put(Dst, 13666, -BCBIAS_J*4, BC_JLOOP);
7361#line 5710 "vm_x86.dasc"
7362 } else if (op == BC_IFORL) {
7363 //| jg >7
7364 //|6:
7365 //| branchPC RD
7366 //|1:
7367 dasm_put(Dst, 13684, -BCBIAS_J*4);
7368#line 5715 "vm_x86.dasc"
7369 } else {
7370 //| jle =>BC_JLOOP
7371 //|1:
7372 //|6:
7373 dasm_put(Dst, 13676, BC_JLOOP);
7374#line 5719 "vm_x86.dasc"
7375 }
7376 //|7:
7377 //| ins_next
7378 //|
7379 //|5: // Invert check for negative step.
7380 dasm_put(Dst, 13698);
7381#line 5724 "vm_x86.dasc"
7382 if (vk) {
7383 //| add RB, dword FOR_IDX; jo <1
7384 //| mov dword FOR_IDX, RB
7385 dasm_put(Dst, 13723);
7386#line 5727 "vm_x86.dasc"
7387 }
7388 //| cmp RB, dword FOR_STOP
7389 //| mov FOR_TEXT, LJ_TISNUM
7390 //| mov dword FOR_EXT, RB
7391 dasm_put(Dst, 13641, LJ_TISNUM);
7392#line 5731 "vm_x86.dasc"
7393 if (op == BC_FORI) {
7394 //| jge <7
7395 dasm_put(Dst, 13732);
7396#line 5733 "vm_x86.dasc"
7397 } else if (op == BC_JFORI) {
7398 //| branchPC RD
7399 //| movzx RD, PC_RD
7400 //| jge =>BC_JLOOP
7401 dasm_put(Dst, 13737, -BCBIAS_J*4, BC_JLOOP);
7402#line 5737 "vm_x86.dasc"
7403 } else if (op == BC_IFORL) {
7404 //| jl <7
7405 dasm_put(Dst, 13751);
7406#line 5739 "vm_x86.dasc"
7407 } else {
7408 //| jge =>BC_JLOOP
7409 dasm_put(Dst, 13747, BC_JLOOP);
7410#line 5741 "vm_x86.dasc"
7411 }
7412 //| jmp <6
7413 //|9: // Fallback to FP variant.
7414 dasm_put(Dst, 13756);
7415#line 5744 "vm_x86.dasc"
7416 } else if (!vk) {
7417 //| cmp FOR_TIDX, LJ_TISNUM
7418 dasm_put(Dst, 13763, LJ_TISNUM);
7419#line 5746 "vm_x86.dasc"
7420 }
7421 if (!vk) {
7422 //| jae ->vmeta_for
7423 //| cmp FOR_TSTOP, LJ_TISNUM; jae ->vmeta_for
7424 dasm_put(Dst, 13769, LJ_TISNUM);
7425#line 5750 "vm_x86.dasc"
7426 } else {
7427#ifdef LUA_USE_ASSERT
7428 //| cmp FOR_TSTOP, LJ_TISNUM; jae ->assert_bad_for_arg_type
7429 //| cmp FOR_TSTEP, LJ_TISNUM; jae ->assert_bad_for_arg_type
7430 dasm_put(Dst, 13783, LJ_TISNUM, LJ_TISNUM);
7431#line 5754 "vm_x86.dasc"
7432#endif
7433 }
7434 //| mov RB, FOR_TSTEP // Load type/hiword of for step.
7435 dasm_put(Dst, 13802);
7436#line 5757 "vm_x86.dasc"
7437 if (!vk) {
7438 //| cmp RB, LJ_TISNUM; jae ->vmeta_for
7439 dasm_put(Dst, 13806, LJ_TISNUM);
7440#line 5759 "vm_x86.dasc"
7441 }
7442 //|.if SSE
7443 //| movsd xmm0, qword FOR_IDX
7444 //| movsd xmm1, qword FOR_STOP
7445 dasm_put(Dst, 13815);
7446#line 5763 "vm_x86.dasc"
7447 if (vk) {
7448 //| addsd xmm0, qword FOR_STEP
7449 //| movsd qword FOR_IDX, xmm0
7450 //| test RB, RB; js >3
7451 dasm_put(Dst, 13827);
7452#line 5767 "vm_x86.dasc"
7453 } else {
7454 //| jl >3
7455 dasm_put(Dst, 13846);
7456#line 5769 "vm_x86.dasc"
7457 }
7458 //| ucomisd xmm1, xmm0
7459 //|1:
7460 //| movsd qword FOR_EXT, xmm0
7461 //|.else
7462 //| fld qword FOR_STOP
7463 //| fld qword FOR_IDX
7464 dasm_put(Dst, 13851);
7465#line 5776 "vm_x86.dasc"
7466 if (vk) {
7467 //| fadd qword FOR_STEP // nidx = idx + step
7468 //| fst qword FOR_IDX
7469 //| fst qword FOR_EXT
7470 //| test RB, RB; js >1
7471 } else {
7472 //| fst qword FOR_EXT
7473 //| jl >1
7474 }
7475 //| fxch // Swap lim/(n)idx if step non-negative.
7476 //|1:
7477 //| fcomparepp
7478 //|.endif
7479 if (op == BC_FORI) {
7480 //|.if DUALNUM
7481 //| jnb <7
7482 //|.else
7483 //| jnb >2
7484 //| branchPC RD
7485 //|.endif
7486 dasm_put(Dst, 13864, -BCBIAS_J*4);
7487#line 5796 "vm_x86.dasc"
7488 } else if (op == BC_JFORI) {
7489 //| branchPC RD
7490 //| movzx RD, PC_RD
7491 //| jnb =>BC_JLOOP
7492 dasm_put(Dst, 13874, -BCBIAS_J*4, BC_JLOOP);
7493#line 5800 "vm_x86.dasc"
7494 } else if (op == BC_IFORL) {
7495 //|.if DUALNUM
7496 //| jb <7
7497 //|.else
7498 //| jb >2
7499 //| branchPC RD
7500 //|.endif
7501 dasm_put(Dst, 13888, -BCBIAS_J*4);
7502#line 5807 "vm_x86.dasc"
7503 } else {
7504 //| jnb =>BC_JLOOP
7505 dasm_put(Dst, 13884, BC_JLOOP);
7506#line 5809 "vm_x86.dasc"
7507 }
7508 //|.if DUALNUM
7509 //| jmp <6
7510 //|.else
7511 //|2:
7512 //| ins_next
7513 //|.endif
7514 //|.if SSE
7515 //|3: // Invert comparison if step is negative.
7516 //| ucomisd xmm0, xmm1
7517 //| jmp <1
7518 //|.endif
7519 dasm_put(Dst, 13898);
7520#line 5821 "vm_x86.dasc"
7521 break;
7522
7523 case BC_ITERL:
7524 //|.if JIT
7525 //| hotloop RB
7526 //|.endif
7527 //| // Fall through. Assumes BC_IITERL follows and ins_AJ is a no-op.
7528 dasm_put(Dst, 13539, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
7529#line 5828 "vm_x86.dasc"
7530 break;
7531
7532 case BC_JITERL:
7533#if !LJ_HASJIT
7534 break;
7535#endif
7536 case BC_IITERL:
7537 //| ins_AJ // RA = base, RD = target
7538 //| lea RA, [BASE+RA*8]
7539 //| mov RB, [RA+4]
7540 //| cmp RB, LJ_TNIL; je >1 // Stop if iterator returned nil.
7541 dasm_put(Dst, 13931, LJ_TNIL);
7542#line 5839 "vm_x86.dasc"
7543 if (op == BC_JITERL) {
7544 //| mov [RA-4], RB
7545 //| mov RB, [RA]
7546 //| mov [RA-8], RB
7547 //| jmp =>BC_JLOOP
7548 dasm_put(Dst, 13946, BC_JLOOP);
7549#line 5844 "vm_x86.dasc"
7550 } else {
7551 //| branchPC RD // Otherwise save control var + branch.
7552 //| mov RD, [RA]
7553 //| mov [RA-4], RB
7554 //| mov [RA-8], RD
7555 dasm_put(Dst, 13960, -BCBIAS_J*4);
7556#line 5849 "vm_x86.dasc"
7557 }
7558 //|1:
7559 //| ins_next
7560 dasm_put(Dst, 9108);
7561#line 5852 "vm_x86.dasc"
7562 break;
7563
7564 case BC_LOOP:
7565 //| ins_A // RA = base, RD = target (loop extent)
7566 //| // Note: RA/RD is only used by trace recorder to determine scope/extent
7567 //| // This opcode does NOT jump, it's only purpose is to detect a hot loop.
7568 //|.if JIT
7569 //| hotloop RB
7570 //|.endif
7571 //| // Fall through. Assumes BC_ILOOP follows and ins_A is a no-op.
7572 dasm_put(Dst, 13539, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_LOOP);
7573#line 5862 "vm_x86.dasc"
7574 break;
7575
7576 case BC_ILOOP:
7577 //| ins_A // RA = base, RD = target (loop extent)
7578 //| ins_next
7579 dasm_put(Dst, 9110);
7580#line 5867 "vm_x86.dasc"
7581 break;
7582
7583 case BC_JLOOP:
7584 //|.if JIT
7585 //| ins_AD // RA = base (ignored), RD = traceno
7586 //| mov RA, [DISPATCH+DISPATCH_J(trace)]
7587 //| mov TRACE:RD, [RA+RD*4]
7588 //| mov RDa, TRACE:RD->mcode
7589 //| mov L:RB, SAVE_L
7590 //| mov [DISPATCH+DISPATCH_GL(jit_base)], BASE
7591 //| mov [DISPATCH+DISPATCH_GL(jit_L)], L:RB
7592 //| // Save additional callee-save registers only used in compiled code.
7593 //|.if X64WIN
7594 //| mov TMPQ, r12
7595 //| mov TMPa, r13
7596 //| mov CSAVE_4, r14
7597 //| mov CSAVE_3, r15
7598 //| mov RAa, rsp
7599 //| sub rsp, 9*16+4*8
7600 //| movdqa [RAa], xmm6
7601 //| movdqa [RAa-1*16], xmm7
7602 //| movdqa [RAa-2*16], xmm8
7603 //| movdqa [RAa-3*16], xmm9
7604 //| movdqa [RAa-4*16], xmm10
7605 //| movdqa [RAa-5*16], xmm11
7606 //| movdqa [RAa-6*16], xmm12
7607 //| movdqa [RAa-7*16], xmm13
7608 //| movdqa [RAa-8*16], xmm14
7609 //| movdqa [RAa-9*16], xmm15
7610 //|.elif X64
7611 //| mov TMPQ, r12
7612 //| mov TMPa, r13
7613 //| sub rsp, 16
7614 //|.endif
7615 //| jmp RDa
7616 //|.endif
7617 dasm_put(Dst, 13976, DISPATCH_J(trace), DtD(->mcode), DISPATCH_GL(jit_base), DISPATCH_GL(jit_L));
7618#line 5903 "vm_x86.dasc"
7619 break;
7620
7621 case BC_JMP:
7622 //| ins_AJ // RA = unused, RD = target
7623 //| branchPC RD
7624 //| ins_next
7625 dasm_put(Dst, 14017, -BCBIAS_J*4);
7626#line 5909 "vm_x86.dasc"
7627 break;
7628
7629 /* -- Function headers -------------------------------------------------- */
7630
7631 /*
7632 ** Reminder: A function may be called with func/args above L->maxstack,
7633 ** i.e. occupying EXTRA_STACK slots. And vmeta_call may add one extra slot,
7634 ** too. This means all FUNC* ops (including fast functions) must check
7635 ** for stack overflow _before_ adding more slots!
7636 */
7637
7638 case BC_FUNCF:
7639 //|.if JIT
7640 //| hotcall RB
7641 //|.endif
7642 dasm_put(Dst, 14043, HOTCOUNT_PCMASK, GG_DISP2HOT, HOTCOUNT_CALL);
7643#line 5924 "vm_x86.dasc"
7644 case BC_FUNCV: /* NYI: compiled vararg functions. */
7645 //| // Fall through. Assumes BC_IFUNCF/BC_IFUNCV follow and ins_AD is a no-op.
7646 break;
7647
7648 case BC_JFUNCF:
7649#if !LJ_HASJIT
7650 break;
7651#endif
7652 case BC_IFUNCF:
7653 //| ins_AD // BASE = new base, RA = framesize, RD = nargs+1
7654 //| mov KBASE, [PC-4+PC2PROTO(k)]
7655 //| mov L:RB, SAVE_L
7656 //| lea RA, [BASE+RA*8] // Top of frame.
7657 //| cmp RA, L:RB->maxstack
7658 //| ja ->vm_growstack_f
7659 //| movzx RA, byte [PC-4+PC2PROTO(numparams)]
7660 //| cmp NARGS:RD, RA // Check for missing parameters.
7661 //| jbe >3
7662 //|2:
7663 dasm_put(Dst, 14064, -4+PC2PROTO(k), Dt1(->maxstack), -4+PC2PROTO(numparams));
7664#line 5943 "vm_x86.dasc"
7665 if (op == BC_JFUNCF) {
7666 //| movzx RD, PC_RD
7667 //| jmp =>BC_JLOOP
7668 dasm_put(Dst, 14095, BC_JLOOP);
7669#line 5946 "vm_x86.dasc"
7670 } else {
7671 //| ins_next
7672 dasm_put(Dst, 9110);
7673#line 5948 "vm_x86.dasc"
7674 }
7675 //|
7676 //|3: // Clear missing parameters.
7677 //| mov dword [BASE+NARGS:RD*8-4], LJ_TNIL
7678 //| add NARGS:RD, 1
7679 //| cmp NARGS:RD, RA
7680 //| jbe <3
7681 //| jmp <2
7682 dasm_put(Dst, 14104, LJ_TNIL);
7683#line 5956 "vm_x86.dasc"
7684 break;
7685
7686 case BC_JFUNCV:
7687#if !LJ_HASJIT
7688 break;
7689#endif
7690 //| int3 // NYI: compiled vararg functions
7691 dasm_put(Dst, 8673);
7692#line 5963 "vm_x86.dasc"
7693 break; /* NYI: compiled vararg functions. */
7694
7695 case BC_IFUNCV:
7696 //| ins_AD // BASE = new base, RA = framesize, RD = nargs+1
7697 //| lea RB, [NARGS:RD*8+FRAME_VARG]
7698 //| lea RD, [BASE+NARGS:RD*8]
7699 //| mov LFUNC:KBASE, [BASE-8]
7700 //| mov [RD-4], RB // Store delta + FRAME_VARG.
7701 //| mov [RD-8], LFUNC:KBASE // Store copy of LFUNC.
7702 //| mov L:RB, SAVE_L
7703 //| lea RA, [RD+RA*8]
7704 //| cmp RA, L:RB->maxstack
7705 //| ja ->vm_growstack_v // Need to grow stack.
7706 //| mov RA, BASE
7707 //| mov BASE, RD
7708 //| movzx RB, byte [PC-4+PC2PROTO(numparams)]
7709 //| test RB, RB
7710 //| jz >2
7711 //|1: // Copy fixarg slots up to new frame.
7712 //| add RA, 8
7713 //| cmp RA, BASE
7714 //| jnb >3 // Less args than parameters?
7715 //| mov KBASE, [RA-8]
7716 //| mov [RD], KBASE
7717 //| mov KBASE, [RA-4]
7718 //| mov [RD+4], KBASE
7719 //| add RD, 8
7720 //| mov dword [RA-4], LJ_TNIL // Clear old fixarg slot (help the GC).
7721 //| sub RB, 1
7722 //| jnz <1
7723 //|2:
7724 dasm_put(Dst, 14126, FRAME_VARG, Dt1(->maxstack), -4+PC2PROTO(numparams), LJ_TNIL);
7725#line 5994 "vm_x86.dasc"
7726 if (op == BC_JFUNCV) {
7727 //| movzx RD, PC_RD
7728 //| jmp =>BC_JLOOP
7729 dasm_put(Dst, 14095, BC_JLOOP);
7730#line 5997 "vm_x86.dasc"
7731 } else {
7732 //| mov KBASE, [PC-4+PC2PROTO(k)]
7733 //| ins_next
7734 dasm_put(Dst, 14223, -4+PC2PROTO(k));
7735#line 6000 "vm_x86.dasc"
7736 }
7737 //|
7738 //|3: // Clear missing parameters.
7739 //| mov dword [RD+4], LJ_TNIL
7740 //| add RD, 8
7741 //| sub RB, 1
7742 //| jnz <3
7743 //| jmp <2
7744 dasm_put(Dst, 14248, LJ_TNIL);
7745#line 6008 "vm_x86.dasc"
7746 break;
7747
7748 case BC_FUNCC:
7749 case BC_FUNCCW:
7750 //| ins_AD // BASE = new base, RA = ins RA|RD (unused), RD = nargs+1
7751 //| mov CFUNC:RB, [BASE-8]
7752 //| mov KBASEa, CFUNC:RB->f
7753 //| mov L:RB, SAVE_L
7754 //| lea RD, [BASE+NARGS:RD*8-8]
7755 //| mov L:RB->base, BASE
7756 //| lea RA, [RD+8*LUA_MINSTACK]
7757 //| cmp RA, L:RB->maxstack
7758 //| mov L:RB->top, RD
7759 dasm_put(Dst, 14270, Dt8(->f), Dt1(->base), 8*LUA_MINSTACK, Dt1(->maxstack), Dt1(->top));
7760#line 6021 "vm_x86.dasc"
7761 if (op == BC_FUNCC) {
7762 //|.if X64
7763 //| mov CARG1d, L:RB // Caveat: CARG1d may be RA.
7764 //|.else
7765 //| mov ARG1, L:RB
7766 //|.endif
7767 dasm_put(Dst, 14300);
7768#line 6027 "vm_x86.dasc"
7769 } else {
7770 //|.if X64
7771 //| mov CARG2, KBASEa
7772 //| mov CARG1d, L:RB // Caveat: CARG1d may be RA.
7773 //|.else
7774 //| mov ARG2, KBASEa
7775 //| mov ARG1, L:RB
7776 //|.endif
7777 dasm_put(Dst, 14304);
7778#line 6035 "vm_x86.dasc"
7779 }
7780 //| ja ->vm_growstack_c // Need to grow stack.
7781 //| set_vmstate C
7782 dasm_put(Dst, 14312, DISPATCH_GL(vmstate), ~LJ_VMST_C);
7783#line 6038 "vm_x86.dasc"
7784 if (op == BC_FUNCC) {
7785 //| call KBASEa // (lua_State *L)
7786 dasm_put(Dst, 14322);
7787#line 6040 "vm_x86.dasc"
7788 } else {
7789 //| // (lua_State *L, lua_CFunction f)
7790 //| call aword [DISPATCH+DISPATCH_GL(wrapf)]
7791 dasm_put(Dst, 14327, DISPATCH_GL(wrapf));
7792#line 6043 "vm_x86.dasc"
7793 }
7794 //| set_vmstate INTERP
7795 //| // nresults returned in eax (RD).
7796 //| mov BASE, L:RB->base
7797 //| lea RA, [BASE+RD*8]
7798 //| neg RA
7799 //| add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8
7800 //| mov PC, [BASE-4] // Fetch PC of caller.
7801 //| jmp ->vm_returnc
7802 dasm_put(Dst, 14333, DISPATCH_GL(vmstate), ~LJ_VMST_INTERP, Dt1(->base), Dt1(->top));
7803#line 6052 "vm_x86.dasc"
7804 break;
7805
7806 /* ---------------------------------------------------------------------- */
7807
7808 default:
7809 fprintf(stderr, "Error: undefined opcode BC_%s\n", bc_names[op]);
7810 exit(2);
7811 break;
7812 }
7813}
7814
7815static int build_backend(BuildCtx *ctx)
7816{
7817 int op;
7818 dasm_growpc(Dst, BC__MAX);
7819 build_subroutines(ctx);
7820 //|.code_op
7821 dasm_put(Dst, 14359);
7822#line 6069 "vm_x86.dasc"
7823 for (op = 0; op < BC__MAX; op++)
7824 build_ins(ctx, (BCOp)op, op);
7825 return BC__MAX;
7826}
7827
7828/* Emit pseudo frame-info for all assembler functions. */
7829static void emit_asm_debug(BuildCtx *ctx)
7830{
7831 int fcofs = (int)((uint8_t *)ctx->glob[GLOB_vm_ffi_call] - ctx->code);
7832#if LJ_64
7833#define SZPTR "8"
7834#define BSZPTR "3"
7835#define REG_SP "0x7"
7836#define REG_RA "0x10"
7837#else
7838#define SZPTR "4"
7839#define BSZPTR "2"
7840#define REG_SP "0x4"
7841#define REG_RA "0x8"
7842#endif
7843 switch (ctx->mode) {
7844 case BUILD_elfasm:
7845 fprintf(ctx->fp, "\t.section .debug_frame,\"\",@progbits\n");
7846 fprintf(ctx->fp,
7847 ".Lframe0:\n"
7848 "\t.long .LECIE0-.LSCIE0\n"
7849 ".LSCIE0:\n"
7850 "\t.long 0xffffffff\n"
7851 "\t.byte 0x1\n"
7852 "\t.string \"\"\n"
7853 "\t.uleb128 0x1\n"
7854 "\t.sleb128 -" SZPTR "\n"
7855 "\t.byte " REG_RA "\n"
7856 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
7857 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
7858 "\t.align " SZPTR "\n"
7859 ".LECIE0:\n\n");
7860 fprintf(ctx->fp,
7861 ".LSFDE0:\n"
7862 "\t.long .LEFDE0-.LASFDE0\n"
7863 ".LASFDE0:\n"
7864 "\t.long .Lframe0\n"
7865#if LJ_64
7866 "\t.quad .Lbegin\n"
7867 "\t.quad %d\n"
7868 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
7869 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
7870 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
7871 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
7872 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
7873#else
7874 "\t.long .Lbegin\n"
7875 "\t.long %d\n"
7876 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
7877 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
7878 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
7879 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
7880 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
7881#endif
7882 "\t.align " SZPTR "\n"
7883 ".LEFDE0:\n\n", fcofs, CFRAME_SIZE);
7884#if LJ_HASFFI
7885 fprintf(ctx->fp,
7886 ".LSFDE1:\n"
7887 "\t.long .LEFDE1-.LASFDE1\n"
7888 ".LASFDE1:\n"
7889 "\t.long .Lframe0\n"
7890#if LJ_64
7891 "\t.quad lj_vm_ffi_call\n"
7892 "\t.quad %d\n"
7893 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
7894 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
7895 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
7896 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
7897#else
7898 "\t.long lj_vm_ffi_call\n"
7899 "\t.long %d\n"
7900 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
7901 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
7902 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
7903 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
7904#endif
7905 "\t.align " SZPTR "\n"
7906 ".LEFDE1:\n\n", (int)ctx->codesz - fcofs);
7907#endif
7908#if (defined(__sun__) && defined(__svr4__))
7909#if LJ_64
7910 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@unwind\n");
7911#else
7912 fprintf(ctx->fp, "\t.section .eh_frame,\"aw\",@progbits\n");
7913#endif
7914#else
7915 fprintf(ctx->fp, "\t.section .eh_frame,\"a\",@progbits\n");
7916#endif
7917 fprintf(ctx->fp,
7918 ".Lframe1:\n"
7919 "\t.long .LECIE1-.LSCIE1\n"
7920 ".LSCIE1:\n"
7921 "\t.long 0\n"
7922 "\t.byte 0x1\n"
7923 "\t.string \"zPR\"\n"
7924 "\t.uleb128 0x1\n"
7925 "\t.sleb128 -" SZPTR "\n"
7926 "\t.byte " REG_RA "\n"
7927 "\t.uleb128 6\n" /* augmentation length */
7928 "\t.byte 0x1b\n" /* pcrel|sdata4 */
7929 "\t.long lj_err_unwind_dwarf-.\n"
7930 "\t.byte 0x1b\n" /* pcrel|sdata4 */
7931 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
7932 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
7933 "\t.align " SZPTR "\n"
7934 ".LECIE1:\n\n");
7935 fprintf(ctx->fp,
7936 ".LSFDE2:\n"
7937 "\t.long .LEFDE2-.LASFDE2\n"
7938 ".LASFDE2:\n"
7939 "\t.long .LASFDE2-.Lframe1\n"
7940 "\t.long .Lbegin-.\n"
7941 "\t.long %d\n"
7942 "\t.uleb128 0\n" /* augmentation length */
7943 "\t.byte 0xe\n\t.uleb128 %d\n" /* def_cfa_offset */
7944#if LJ_64
7945 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
7946 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
7947 "\t.byte 0x8f\n\t.uleb128 0x4\n" /* offset r15 */
7948 "\t.byte 0x8e\n\t.uleb128 0x5\n" /* offset r14 */
7949#else
7950 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
7951 "\t.byte 0x87\n\t.uleb128 0x3\n" /* offset edi */
7952 "\t.byte 0x86\n\t.uleb128 0x4\n" /* offset esi */
7953 "\t.byte 0x83\n\t.uleb128 0x5\n" /* offset ebx */
7954#endif
7955 "\t.align " SZPTR "\n"
7956 ".LEFDE2:\n\n", fcofs, CFRAME_SIZE);
7957#if LJ_HASFFI
7958 fprintf(ctx->fp,
7959 ".Lframe2:\n"
7960 "\t.long .LECIE2-.LSCIE2\n"
7961 ".LSCIE2:\n"
7962 "\t.long 0\n"
7963 "\t.byte 0x1\n"
7964 "\t.string \"zR\"\n"
7965 "\t.uleb128 0x1\n"
7966 "\t.sleb128 -" SZPTR "\n"
7967 "\t.byte " REG_RA "\n"
7968 "\t.uleb128 1\n" /* augmentation length */
7969 "\t.byte 0x1b\n" /* pcrel|sdata4 */
7970 "\t.byte 0xc\n\t.uleb128 " REG_SP "\n\t.uleb128 " SZPTR "\n"
7971 "\t.byte 0x80+" REG_RA "\n\t.uleb128 0x1\n"
7972 "\t.align " SZPTR "\n"
7973 ".LECIE2:\n\n");
7974 fprintf(ctx->fp,
7975 ".LSFDE3:\n"
7976 "\t.long .LEFDE3-.LASFDE3\n"
7977 ".LASFDE3:\n"
7978 "\t.long .LASFDE3-.Lframe2\n"
7979 "\t.long lj_vm_ffi_call-.\n"
7980 "\t.long %d\n"
7981 "\t.uleb128 0\n" /* augmentation length */
7982#if LJ_64
7983 "\t.byte 0xe\n\t.uleb128 16\n" /* def_cfa_offset */
7984 "\t.byte 0x86\n\t.uleb128 0x2\n" /* offset rbp */
7985 "\t.byte 0xd\n\t.uleb128 0x6\n" /* def_cfa_register rbp */
7986 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset rbx */
7987#else
7988 "\t.byte 0xe\n\t.uleb128 8\n" /* def_cfa_offset */
7989 "\t.byte 0x85\n\t.uleb128 0x2\n" /* offset ebp */
7990 "\t.byte 0xd\n\t.uleb128 0x5\n" /* def_cfa_register ebp */
7991 "\t.byte 0x83\n\t.uleb128 0x3\n" /* offset ebx */
7992#endif
7993 "\t.align " SZPTR "\n"
7994 ".LEFDE3:\n\n", (int)ctx->codesz - fcofs);
7995#endif
7996 break;
7997 /* Mental note: never let Apple design an assembler.
7998 ** Or a linker. Or a plastic case. But I digress.
7999 */
8000 case BUILD_machasm: {
8001#if LJ_HASFFI
8002 int fcsize = 0;
8003#endif
8004 int i;
8005 fprintf(ctx->fp, "\t.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support\n");
8006 fprintf(ctx->fp,
8007 "EH_frame1:\n"
8008 "\t.set L$set$x,LECIEX-LSCIEX\n"
8009 "\t.long L$set$x\n"
8010 "LSCIEX:\n"
8011 "\t.long 0\n"
8012 "\t.byte 0x1\n"
8013 "\t.ascii \"zPR\\0\"\n"
8014 "\t.byte 0x1\n"
8015 "\t.byte 128-" SZPTR "\n"
8016 "\t.byte " REG_RA "\n"
8017 "\t.byte 6\n" /* augmentation length */
8018 "\t.byte 0x9b\n" /* indirect|pcrel|sdata4 */
8019#if LJ_64
8020 "\t.long _lj_err_unwind_dwarf+4@GOTPCREL\n"
8021 "\t.byte 0x1b\n" /* pcrel|sdata4 */
8022 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
8023#else
8024 "\t.long L_lj_err_unwind_dwarf$non_lazy_ptr-.\n"
8025 "\t.byte 0x1b\n" /* pcrel|sdata4 */
8026 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH-O. */
8027#endif
8028 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
8029 "\t.align " BSZPTR "\n"
8030 "LECIEX:\n\n");
8031 for (i = 0; i < ctx->nsym; i++) {
8032 const char *name = ctx->sym[i].name;
8033 int32_t size = ctx->sym[i+1].ofs - ctx->sym[i].ofs;
8034 if (size == 0) continue;
8035#if LJ_HASFFI
8036 if (!strcmp(name, "_lj_vm_ffi_call")) { fcsize = size; continue; }
8037#endif
8038 fprintf(ctx->fp,
8039 "%s.eh:\n"
8040 "LSFDE%d:\n"
8041 "\t.set L$set$%d,LEFDE%d-LASFDE%d\n"
8042 "\t.long L$set$%d\n"
8043 "LASFDE%d:\n"
8044 "\t.long LASFDE%d-EH_frame1\n"
8045 "\t.long %s-.\n"
8046 "\t.long %d\n"
8047 "\t.byte 0\n" /* augmentation length */
8048 "\t.byte 0xe\n\t.byte %d\n" /* def_cfa_offset */
8049#if LJ_64
8050 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
8051 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
8052 "\t.byte 0x8f\n\t.byte 0x4\n" /* offset r15 */
8053 "\t.byte 0x8e\n\t.byte 0x5\n" /* offset r14 */
8054#else
8055 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
8056 "\t.byte 0x87\n\t.byte 0x3\n" /* offset edi */
8057 "\t.byte 0x86\n\t.byte 0x4\n" /* offset esi */
8058 "\t.byte 0x83\n\t.byte 0x5\n" /* offset ebx */
8059#endif
8060 "\t.align " BSZPTR "\n"
8061 "LEFDE%d:\n\n",
8062 name, i, i, i, i, i, i, i, name, size, CFRAME_SIZE, i);
8063 }
8064#if LJ_HASFFI
8065 if (fcsize) {
8066 fprintf(ctx->fp,
8067 "EH_frame2:\n"
8068 "\t.set L$set$y,LECIEY-LSCIEY\n"
8069 "\t.long L$set$y\n"
8070 "LSCIEY:\n"
8071 "\t.long 0\n"
8072 "\t.byte 0x1\n"
8073 "\t.ascii \"zR\\0\"\n"
8074 "\t.byte 0x1\n"
8075 "\t.byte 128-" SZPTR "\n"
8076 "\t.byte " REG_RA "\n"
8077 "\t.byte 1\n" /* augmentation length */
8078#if LJ_64
8079 "\t.byte 0x1b\n" /* pcrel|sdata4 */
8080 "\t.byte 0xc\n\t.byte " REG_SP "\n\t.byte " SZPTR "\n"
8081#else
8082 "\t.byte 0x1b\n" /* pcrel|sdata4 */
8083 "\t.byte 0xc\n\t.byte 0x5\n\t.byte 0x4\n" /* esp=5 on 32 bit MACH. */
8084#endif
8085 "\t.byte 0x80+" REG_RA "\n\t.byte 0x1\n"
8086 "\t.align " BSZPTR "\n"
8087 "LECIEY:\n\n");
8088 fprintf(ctx->fp,
8089 "_lj_vm_ffi_call.eh:\n"
8090 "LSFDEY:\n"
8091 "\t.set L$set$yy,LEFDEY-LASFDEY\n"
8092 "\t.long L$set$yy\n"
8093 "LASFDEY:\n"
8094 "\t.long LASFDEY-EH_frame2\n"
8095 "\t.long _lj_vm_ffi_call-.\n"
8096 "\t.long %d\n"
8097 "\t.byte 0\n" /* augmentation length */
8098#if LJ_64
8099 "\t.byte 0xe\n\t.byte 16\n" /* def_cfa_offset */
8100 "\t.byte 0x86\n\t.byte 0x2\n" /* offset rbp */
8101 "\t.byte 0xd\n\t.byte 0x6\n" /* def_cfa_register rbp */
8102 "\t.byte 0x83\n\t.byte 0x3\n" /* offset rbx */
8103#else
8104 "\t.byte 0xe\n\t.byte 8\n" /* def_cfa_offset */
8105 "\t.byte 0x84\n\t.byte 0x2\n" /* offset ebp (4 for MACH-O)*/
8106 "\t.byte 0xd\n\t.byte 0x4\n" /* def_cfa_register ebp */
8107 "\t.byte 0x83\n\t.byte 0x3\n" /* offset ebx */
8108#endif
8109 "\t.align " BSZPTR "\n"
8110 "LEFDEY:\n\n", fcsize);
8111 }
8112#endif
8113#if LJ_64
8114 fprintf(ctx->fp, "\t.subsections_via_symbols\n");
8115#else
8116 fprintf(ctx->fp,
8117 "\t.non_lazy_symbol_pointer\n"
8118 "L_lj_err_unwind_dwarf$non_lazy_ptr:\n"
8119 ".indirect_symbol _lj_err_unwind_dwarf\n"
8120 ".long 0\n");
8121#endif
8122 }
8123 break;
8124 default: /* Difficult for other modes. */
8125 break;
8126 }
8127}
8128
8129