1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
18 #define ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
19 
20 #include "dex/compiler_internals.h"
21 
22 namespace art {
23 
24 /*
25  * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64). The ABI
26  * has different conventions and we capture those here. Changing something that is callee save and
27  * making it caller save places a burden on up-calls to save/restore the callee save register,
28  * however, there are few registers that are callee save in the ABI. Changing something that is
29  * caller save and making it callee save places a burden on down-calls to save/restore the callee
30  * save register. For these reasons we aim to match native conventions for caller and callee save.
31  * On x86 only the first 4 registers can be used for byte operations, for this reason they are
32  * preferred for temporary scratch registers.
33  *
34  * General Purpose Register:
35  *  Native: x86    | x86-64 / x32 | ART x86                                         | ART x86-64
36  *  r0/eax: caller | caller       | caller, Method*, scratch, return value          | caller, scratch, return value
37  *  r1/ecx: caller | caller, arg4 | caller, arg1, scratch                           | caller, arg3, scratch
38  *  r2/edx: caller | caller, arg3 | caller, arg2, scratch, high half of long return | caller, arg2, scratch
39  *  r3/ebx: callEE | callEE       | callER, arg3, scratch                           | callee, promotable
40  *  r4/esp: stack pointer
41  *  r5/ebp: callee | callee       | callee, promotable                              | callee, promotable
42  *  r6/esi: callEE | callER, arg2 | callee, promotable                              | caller, arg1, scratch
43  *  r7/edi: callEE | callER, arg1 | callee, promotable                              | caller, Method*, scratch
44  *  ---  x86-64/x32 registers
45  *  Native: x86-64 / x32      | ART
46  *  r8:     caller save, arg5 | caller, arg4, scratch
47  *  r9:     caller save, arg6 | caller, arg5, scratch
48  *  r10:    caller save       | caller, scratch
49  *  r11:    caller save       | caller, scratch
50  *  r12:    callee save       | callee, available for register promotion (promotable)
51  *  r13:    callee save       | callee, available for register promotion (promotable)
52  *  r14:    callee save       | callee, available for register promotion (promotable)
53  *  r15:    callee save       | callee, available for register promotion (promotable)
54  *
55  * There is no rSELF, instead on x86 fs: has a base address of Thread::Current, whereas on
56  * x86-64/x32 gs: holds it.
57  *
58  * For floating point we don't support CPUs without SSE2 support (ie newer than PIII):
59  *  Native: x86  | x86-64 / x32 | ART x86                    | ART x86-64
60  *  XMM0: caller | caller, arg1 | caller, float return value | caller, arg1, float return value
61  *  XMM1: caller | caller, arg2 | caller, scratch            | caller, arg2, scratch
62  *  XMM2: caller | caller, arg3 | caller, scratch            | caller, arg3, scratch
63  *  XMM3: caller | caller, arg4 | caller, scratch            | caller, arg4, scratch
64  *  XMM4: caller | caller, arg5 | caller, scratch            | caller, arg5, scratch
65  *  XMM5: caller | caller, arg6 | caller, scratch            | caller, arg6, scratch
66  *  XMM6: caller | caller, arg7 | caller, scratch            | caller, arg7, scratch
67  *  XMM7: caller | caller, arg8 | caller, scratch            | caller, arg8, scratch
68  *  ---  x86-64/x32 registers
69  *  XMM8 .. 11: caller save available as scratch registers for ART.
70  *  XMM12 .. 15: callee save available as promoted registers for ART.
71  *  This change (XMM12..15) is for QCG only, for others they are caller save.
72  *
73  * X87 is a necessary evil outside of ART code for x86:
74  *  ST0:  x86 float/double native return value, caller save
75  *  ST1 .. ST7: caller save
76  *
77  *  Stack frame diagram (stack grows down, higher addresses at top):
78  *
79  * +------------------------+
80  * | IN[ins-1]              |  {Note: resides in caller's frame}
81  * |       .                |
82  * | IN[0]                  |
83  * | caller's Method*       |
84  * +========================+  {Note: start of callee's frame}
85  * | return address         |  {pushed by call}
86  * | spill region           |  {variable sized}
87  * +------------------------+
88  * | ...filler word...      |  {Note: used as 2nd word of V[locals-1] if long]
89  * +------------------------+
90  * | V[locals-1]            |
91  * | V[locals-2]            |
92  * |      .                 |
93  * |      .                 |
94  * | V[1]                   |
95  * | V[0]                   |
96  * +------------------------+
97  * |  0 to 3 words padding  |
98  * +------------------------+
99  * | OUT[outs-1]            |
100  * | OUT[outs-2]            |
101  * |       .                |
102  * | OUT[0]                 |
103  * | cur_method*            | <<== sp w/ 16-byte alignment
104  * +========================+
105  */
106 
107 enum X86ResourceEncodingPos {
108   kX86GPReg0   = 0,
109   kX86RegSP    = 4,
110   kX86FPReg0   = 16,  // xmm0 .. xmm7/xmm15.
111   kX86FPRegEnd = 32,
112   kX86FPStack  = 33,
113   kX86RegEnd   = kX86FPStack,
114 };
115 
116 // FIXME: for 64-bit, perhaps add an X86_64NativeRegisterPool enum?
117 enum X86NativeRegisterPool {
118   r0             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0,
119   r0q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 0,
120   rAX            = r0,
121   r1             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 1,
122   r1q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 1,
123   rCX            = r1,
124   r2             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 2,
125   r2q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 2,
126   rDX            = r2,
127   r3             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 3,
128   r3q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 3,
129   rBX            = r3,
130   r4sp_32        = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 4,
131   rX86_SP_32     = r4sp_32,
132   r4sp_64        = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 4,
133   rX86_SP_64     = r4sp_64,
134   r5             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 5,
135   r5q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 5,
136   rBP            = r5,
137   r5sib_no_base  = r5,
138   r6             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 6,
139   r6q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 6,
140   rSI            = r6,
141   r7             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 7,
142   r7q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 7,
143   rDI            = r7,
144   r8             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
145   r8q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 8,
146   r9             = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 9,
147   r9q            = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 9,
148   r10            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
149   r10q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
150   r11            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
151   r11q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
152   r12            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
153   r12q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
154   r13            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
155   r13q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
156   r14            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
157   r14q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
158   r15            = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
159   r15q           = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
160   // fake return address register for core spill mask.
161   rRET           = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
162 
163   // xmm registers, single precision view.
164   fr0  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 0,
165   fr1  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 1,
166   fr2  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 2,
167   fr3  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 3,
168   fr4  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 4,
169   fr5  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 5,
170   fr6  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 6,
171   fr7  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 7,
172   fr8  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 8,
173   fr9  = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 9,
174   fr10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
175   fr11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
176   fr12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
177   fr13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
178   fr14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
179   fr15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
180 
181   // xmm registers, double precision aliases.
182   dr0  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 0,
183   dr1  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 1,
184   dr2  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 2,
185   dr3  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 3,
186   dr4  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 4,
187   dr5  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 5,
188   dr6  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 6,
189   dr7  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 7,
190   dr8  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 8,
191   dr9  = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 9,
192   dr10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
193   dr11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
194   dr12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
195   dr13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
196   dr14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
197   dr15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
198 
199   // xmm registers, quad precision aliases
200   xr0  = RegStorage::k128BitSolo | 0,
201   xr1  = RegStorage::k128BitSolo | 1,
202   xr2  = RegStorage::k128BitSolo | 2,
203   xr3  = RegStorage::k128BitSolo | 3,
204   xr4  = RegStorage::k128BitSolo | 4,
205   xr5  = RegStorage::k128BitSolo | 5,
206   xr6  = RegStorage::k128BitSolo | 6,
207   xr7  = RegStorage::k128BitSolo | 7,
208   xr8  = RegStorage::k128BitSolo | 8,
209   xr9  = RegStorage::k128BitSolo | 9,
210   xr10 = RegStorage::k128BitSolo | 10,
211   xr11 = RegStorage::k128BitSolo | 11,
212   xr12 = RegStorage::k128BitSolo | 12,
213   xr13 = RegStorage::k128BitSolo | 13,
214   xr14 = RegStorage::k128BitSolo | 14,
215   xr15 = RegStorage::k128BitSolo | 15,
216 
217   // TODO: as needed, add 256, 512 and 1024-bit xmm views.
218 };
219 
220 constexpr RegStorage rs_r0(RegStorage::kValid | r0);
221 constexpr RegStorage rs_r0q(RegStorage::kValid | r0q);
222 constexpr RegStorage rs_rAX = rs_r0;
223 constexpr RegStorage rs_r1(RegStorage::kValid | r1);
224 constexpr RegStorage rs_r1q(RegStorage::kValid | r1q);
225 constexpr RegStorage rs_rCX = rs_r1;
226 constexpr RegStorage rs_r2(RegStorage::kValid | r2);
227 constexpr RegStorage rs_r2q(RegStorage::kValid | r2q);
228 constexpr RegStorage rs_rDX = rs_r2;
229 constexpr RegStorage rs_r3(RegStorage::kValid | r3);
230 constexpr RegStorage rs_r3q(RegStorage::kValid | r3q);
231 constexpr RegStorage rs_rBX = rs_r3;
232 constexpr RegStorage rs_rX86_SP_64(RegStorage::kValid | r4sp_64);
233 constexpr RegStorage rs_rX86_SP_32(RegStorage::kValid | r4sp_32);
234 extern RegStorage rs_rX86_SP;
235 constexpr RegStorage rs_r5(RegStorage::kValid | r5);
236 constexpr RegStorage rs_r5q(RegStorage::kValid | r5q);
237 constexpr RegStorage rs_rBP = rs_r5;
238 constexpr RegStorage rs_r6(RegStorage::kValid | r6);
239 constexpr RegStorage rs_r6q(RegStorage::kValid | r6q);
240 constexpr RegStorage rs_rSI = rs_r6;
241 constexpr RegStorage rs_r7(RegStorage::kValid | r7);
242 constexpr RegStorage rs_r7q(RegStorage::kValid | r7q);
243 constexpr RegStorage rs_rDI = rs_r7;
244 constexpr RegStorage rs_rRET(RegStorage::kValid | rRET);
245 constexpr RegStorage rs_r8(RegStorage::kValid | r8);
246 constexpr RegStorage rs_r8q(RegStorage::kValid | r8q);
247 constexpr RegStorage rs_r9(RegStorage::kValid | r9);
248 constexpr RegStorage rs_r9q(RegStorage::kValid | r9q);
249 constexpr RegStorage rs_r10(RegStorage::kValid | r10);
250 constexpr RegStorage rs_r10q(RegStorage::kValid | r10q);
251 constexpr RegStorage rs_r11(RegStorage::kValid | r11);
252 constexpr RegStorage rs_r11q(RegStorage::kValid | r11q);
253 constexpr RegStorage rs_r12(RegStorage::kValid | r12);
254 constexpr RegStorage rs_r12q(RegStorage::kValid | r12q);
255 constexpr RegStorage rs_r13(RegStorage::kValid | r13);
256 constexpr RegStorage rs_r13q(RegStorage::kValid | r13q);
257 constexpr RegStorage rs_r14(RegStorage::kValid | r14);
258 constexpr RegStorage rs_r14q(RegStorage::kValid | r14q);
259 constexpr RegStorage rs_r15(RegStorage::kValid | r15);
260 constexpr RegStorage rs_r15q(RegStorage::kValid | r15q);
261 
262 constexpr RegStorage rs_fr0(RegStorage::kValid | fr0);
263 constexpr RegStorage rs_fr1(RegStorage::kValid | fr1);
264 constexpr RegStorage rs_fr2(RegStorage::kValid | fr2);
265 constexpr RegStorage rs_fr3(RegStorage::kValid | fr3);
266 constexpr RegStorage rs_fr4(RegStorage::kValid | fr4);
267 constexpr RegStorage rs_fr5(RegStorage::kValid | fr5);
268 constexpr RegStorage rs_fr6(RegStorage::kValid | fr6);
269 constexpr RegStorage rs_fr7(RegStorage::kValid | fr7);
270 constexpr RegStorage rs_fr8(RegStorage::kValid | fr8);
271 constexpr RegStorage rs_fr9(RegStorage::kValid | fr9);
272 constexpr RegStorage rs_fr10(RegStorage::kValid | fr10);
273 constexpr RegStorage rs_fr11(RegStorage::kValid | fr11);
274 constexpr RegStorage rs_fr12(RegStorage::kValid | fr12);
275 constexpr RegStorage rs_fr13(RegStorage::kValid | fr13);
276 constexpr RegStorage rs_fr14(RegStorage::kValid | fr14);
277 constexpr RegStorage rs_fr15(RegStorage::kValid | fr15);
278 
279 constexpr RegStorage rs_dr0(RegStorage::kValid | dr0);
280 constexpr RegStorage rs_dr1(RegStorage::kValid | dr1);
281 constexpr RegStorage rs_dr2(RegStorage::kValid | dr2);
282 constexpr RegStorage rs_dr3(RegStorage::kValid | dr3);
283 constexpr RegStorage rs_dr4(RegStorage::kValid | dr4);
284 constexpr RegStorage rs_dr5(RegStorage::kValid | dr5);
285 constexpr RegStorage rs_dr6(RegStorage::kValid | dr6);
286 constexpr RegStorage rs_dr7(RegStorage::kValid | dr7);
287 constexpr RegStorage rs_dr8(RegStorage::kValid | dr8);
288 constexpr RegStorage rs_dr9(RegStorage::kValid | dr9);
289 constexpr RegStorage rs_dr10(RegStorage::kValid | dr10);
290 constexpr RegStorage rs_dr11(RegStorage::kValid | dr11);
291 constexpr RegStorage rs_dr12(RegStorage::kValid | dr12);
292 constexpr RegStorage rs_dr13(RegStorage::kValid | dr13);
293 constexpr RegStorage rs_dr14(RegStorage::kValid | dr14);
294 constexpr RegStorage rs_dr15(RegStorage::kValid | dr15);
295 
296 constexpr RegStorage rs_xr0(RegStorage::kValid | xr0);
297 constexpr RegStorage rs_xr1(RegStorage::kValid | xr1);
298 constexpr RegStorage rs_xr2(RegStorage::kValid | xr2);
299 constexpr RegStorage rs_xr3(RegStorage::kValid | xr3);
300 constexpr RegStorage rs_xr4(RegStorage::kValid | xr4);
301 constexpr RegStorage rs_xr5(RegStorage::kValid | xr5);
302 constexpr RegStorage rs_xr6(RegStorage::kValid | xr6);
303 constexpr RegStorage rs_xr7(RegStorage::kValid | xr7);
304 constexpr RegStorage rs_xr8(RegStorage::kValid | xr8);
305 constexpr RegStorage rs_xr9(RegStorage::kValid | xr9);
306 constexpr RegStorage rs_xr10(RegStorage::kValid | xr10);
307 constexpr RegStorage rs_xr11(RegStorage::kValid | xr11);
308 constexpr RegStorage rs_xr12(RegStorage::kValid | xr12);
309 constexpr RegStorage rs_xr13(RegStorage::kValid | xr13);
310 constexpr RegStorage rs_xr14(RegStorage::kValid | xr14);
311 constexpr RegStorage rs_xr15(RegStorage::kValid | xr15);
312 
313 extern X86NativeRegisterPool rX86_ARG0;
314 extern X86NativeRegisterPool rX86_ARG1;
315 extern X86NativeRegisterPool rX86_ARG2;
316 extern X86NativeRegisterPool rX86_ARG3;
317 extern X86NativeRegisterPool rX86_ARG4;
318 extern X86NativeRegisterPool rX86_ARG5;
319 extern X86NativeRegisterPool rX86_FARG0;
320 extern X86NativeRegisterPool rX86_FARG1;
321 extern X86NativeRegisterPool rX86_FARG2;
322 extern X86NativeRegisterPool rX86_FARG3;
323 extern X86NativeRegisterPool rX86_FARG4;
324 extern X86NativeRegisterPool rX86_FARG5;
325 extern X86NativeRegisterPool rX86_FARG6;
326 extern X86NativeRegisterPool rX86_FARG7;
327 extern X86NativeRegisterPool rX86_RET0;
328 extern X86NativeRegisterPool rX86_RET1;
329 extern X86NativeRegisterPool rX86_INVOKE_TGT;
330 extern X86NativeRegisterPool rX86_COUNT;
331 
332 extern RegStorage rs_rX86_ARG0;
333 extern RegStorage rs_rX86_ARG1;
334 extern RegStorage rs_rX86_ARG2;
335 extern RegStorage rs_rX86_ARG3;
336 extern RegStorage rs_rX86_ARG4;
337 extern RegStorage rs_rX86_ARG5;
338 extern RegStorage rs_rX86_FARG0;
339 extern RegStorage rs_rX86_FARG1;
340 extern RegStorage rs_rX86_FARG2;
341 extern RegStorage rs_rX86_FARG3;
342 extern RegStorage rs_rX86_FARG4;
343 extern RegStorage rs_rX86_FARG5;
344 extern RegStorage rs_rX86_FARG6;
345 extern RegStorage rs_rX86_FARG7;
346 extern RegStorage rs_rX86_RET0;
347 extern RegStorage rs_rX86_RET1;
348 extern RegStorage rs_rX86_INVOKE_TGT;
349 extern RegStorage rs_rX86_COUNT;
350 
351 // RegisterLocation templates return values (r_V0, or r_V0/r_V1).
352 const RegLocation x86_loc_c_return
353     {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
354      RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
355 const RegLocation x86_loc_c_return_wide
356     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
357      RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
358 const RegLocation x86_loc_c_return_ref
359     {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
360      RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
361 const RegLocation x86_64_loc_c_return_ref
362     {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
363      RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
364 const RegLocation x86_64_loc_c_return_wide
365     {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
366      RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
367 const RegLocation x86_loc_c_return_float
368     {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
369      RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
370 const RegLocation x86_loc_c_return_double
371     {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
372      RegStorage(RegStorage::k64BitSolo, dr0), INVALID_SREG, INVALID_SREG};
373 
374 /*
375  * The following enum defines the list of supported X86 instructions by the
376  * assembler. Their corresponding EncodingMap positions will be defined in
377  * Assemble.cc.
378  */
379 enum X86OpCode {
380   kX86First = 0,
381   kX8632BitData = kX86First,  // data [31..0].
382   kX86Bkpt,
383   kX86Nop,
384   // Define groups of binary operations
385   // MR - Memory Register  - opcode [base + disp], reg
386   //             - lir operands - 0: base, 1: disp, 2: reg
387   // AR - Array Register   - opcode [base + index * scale + disp], reg
388   //             - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
389   // TR - Thread Register  - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
390   //             - lir operands - 0: disp, 1: reg
391   // RR - Register Register  - opcode reg1, reg2
392   //             - lir operands - 0: reg1, 1: reg2
393   // RM - Register Memory  - opcode reg, [base + disp]
394   //             - lir operands - 0: reg, 1: base, 2: disp
395   // RA - Register Array   - opcode reg, [base + index * scale + disp]
396   //             - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
397   // RT - Register Thread  - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
398   //             - lir operands - 0: reg, 1: disp
399   // RI - Register Immediate - opcode reg, #immediate
400   //             - lir operands - 0: reg, 1: immediate
401   // MI - Memory Immediate   - opcode [base + disp], #immediate
402   //             - lir operands - 0: base, 1: disp, 2: immediate
403   // AI - Array Immediate  - opcode [base + index * scale + disp], #immediate
404   //             - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
405   // TI - Thread Immediate  - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
406   //             - lir operands - 0: disp, 1: imm
407 #define BinaryOpCode(opcode) \
408   opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
409   opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
410   opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
411   opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
412   opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
413   opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
414   opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
415   opcode ## 32MR, opcode ## 32AR, opcode ## 32TR,  \
416   opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
417   opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
418   opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8, \
419   opcode ## 64MR, opcode ## 64AR, opcode ## 64TR,  \
420   opcode ## 64RR, opcode ## 64RM, opcode ## 64RA, opcode ## 64RT, \
421   opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, opcode ## 64TI, \
422   opcode ## 64RI8, opcode ## 64MI8, opcode ## 64AI8, opcode ## 64TI8
423   BinaryOpCode(kX86Add),
424   BinaryOpCode(kX86Or),
425   BinaryOpCode(kX86Adc),
426   BinaryOpCode(kX86Sbb),
427   BinaryOpCode(kX86And),
428   BinaryOpCode(kX86Sub),
429   BinaryOpCode(kX86Xor),
430   BinaryOpCode(kX86Cmp),
431 #undef BinaryOpCode
432   kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
433   kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
434   kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
435   kX86Imul64RRI, kX86Imul64RMI, kX86Imul64RAI,
436   kX86Imul64RRI8, kX86Imul64RMI8, kX86Imul64RAI8,
437   kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
438   kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
439   kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
440   kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
441   kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
442   kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
443   kX86Mov32MR, kX86Mov32AR, kX86Mov32TR,
444   kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
445   kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
446   kX86Lea32RM,
447   kX86Lea32RA,
448   kX86Mov64MR, kX86Mov64AR, kX86Mov64TR,
449   kX86Mov64RR, kX86Mov64RM, kX86Mov64RA, kX86Mov64RT,
450   kX86Mov64RI32, kX86Mov64RI64, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI,
451   kX86Lea64RM,
452   kX86Lea64RA,
453   // RRC - Register Register ConditionCode - cond_opcode reg1, reg2
454   //             - lir operands - 0: reg1, 1: reg2, 2: CC
455   kX86Cmov32RRC,
456   kX86Cmov64RRC,
457   // RMC - Register Memory ConditionCode - cond_opcode reg1, [base + disp]
458   //             - lir operands - 0: reg1, 1: base, 2: disp 3: CC
459   kX86Cmov32RMC,
460   kX86Cmov64RMC,
461 
462   // RC - Register CL - opcode reg, CL
463   //          - lir operands - 0: reg, 1: CL
464   // MC - Memory CL   - opcode [base + disp], CL
465   //          - lir operands - 0: base, 1: disp, 2: CL
466   // AC - Array CL  - opcode [base + index * scale + disp], CL
467   //          - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
468 #define BinaryShiftOpCode(opcode) \
469   opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
470   opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
471   opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
472   opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
473   opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
474   opcode ## 32RC, opcode ## 32MC, opcode ## 32AC, \
475   opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, \
476   opcode ## 64RC, opcode ## 64MC, opcode ## 64AC
477   BinaryShiftOpCode(kX86Rol),
478   BinaryShiftOpCode(kX86Ror),
479   BinaryShiftOpCode(kX86Rcl),
480   BinaryShiftOpCode(kX86Rcr),
481   BinaryShiftOpCode(kX86Sal),
482   BinaryShiftOpCode(kX86Shr),
483   BinaryShiftOpCode(kX86Sar),
484 #undef BinaryShiftOpcode
485   kX86Cmc,
486   kX86Shld32RRI,
487   kX86Shld32MRI,
488   kX86Shrd32RRI,
489   kX86Shrd32MRI,
490   kX86Shld64RRI,
491   kX86Shld64MRI,
492   kX86Shrd64RRI,
493   kX86Shrd64MRI,
494 #define UnaryOpcode(opcode, reg, mem, array) \
495   opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
496   opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
497   opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array, \
498   opcode ## 64 ## reg, opcode ## 64 ## mem, opcode ## 64 ## array
499   UnaryOpcode(kX86Test, RI, MI, AI),
500   kX86Test32RR,
501   kX86Test64RR,
502   kX86Test32RM,
503   UnaryOpcode(kX86Not, R, M, A),
504   UnaryOpcode(kX86Neg, R, M, A),
505   UnaryOpcode(kX86Mul,  DaR, DaM, DaA),
506   UnaryOpcode(kX86Imul, DaR, DaM, DaA),
507   UnaryOpcode(kX86Divmod,  DaR, DaM, DaA),
508   UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
509   kx86Cdq32Da,
510   kx86Cqo64Da,
511   kX86Bswap32R,
512   kX86Bswap64R,
513   kX86Push32R, kX86Pop32R,
514 #undef UnaryOpcode
515 #define Binary0fOpCode(opcode) \
516   opcode ## RR, opcode ## RM, opcode ## RA
517   Binary0fOpCode(kX86Movsd),
518   kX86MovsdMR,
519   kX86MovsdAR,
520   Binary0fOpCode(kX86Movss),
521   kX86MovssMR,
522   kX86MovssAR,
523   Binary0fOpCode(kX86Cvtsi2sd),  // int to double
524   Binary0fOpCode(kX86Cvtsi2ss),  // int to float
525   Binary0fOpCode(kX86Cvtsqi2sd),  // long to double
526   Binary0fOpCode(kX86Cvtsqi2ss),  // long to float
527   Binary0fOpCode(kX86Cvttsd2si),  // truncating double to int
528   Binary0fOpCode(kX86Cvttss2si),  // truncating float to int
529   Binary0fOpCode(kX86Cvttsd2sqi),  // truncating double to long
530   Binary0fOpCode(kX86Cvttss2sqi),  // truncating float to long
531   Binary0fOpCode(kX86Cvtsd2si),  // rounding double to int
532   Binary0fOpCode(kX86Cvtss2si),  // rounding float to int
533   Binary0fOpCode(kX86Ucomisd),  // unordered double compare
534   Binary0fOpCode(kX86Ucomiss),  // unordered float compare
535   Binary0fOpCode(kX86Comisd),   // double compare
536   Binary0fOpCode(kX86Comiss),   // float compare
537   Binary0fOpCode(kX86Orpd),     // double logical OR
538   Binary0fOpCode(kX86Orps),     // float logical OR
539   Binary0fOpCode(kX86Andpd),    // double logical AND
540   Binary0fOpCode(kX86Andps),    // float logical AND
541   Binary0fOpCode(kX86Xorpd),    // double logical XOR
542   Binary0fOpCode(kX86Xorps),    // float logical XOR
543   Binary0fOpCode(kX86Addsd),    // double ADD
544   Binary0fOpCode(kX86Addss),    // float ADD
545   Binary0fOpCode(kX86Mulsd),    // double multiply
546   Binary0fOpCode(kX86Mulss),    // float multiply
547   Binary0fOpCode(kX86Cvtsd2ss),  // double to float
548   Binary0fOpCode(kX86Cvtss2sd),  // float to double
549   Binary0fOpCode(kX86Subsd),    // double subtract
550   Binary0fOpCode(kX86Subss),    // float subtract
551   Binary0fOpCode(kX86Divsd),    // double divide
552   Binary0fOpCode(kX86Divss),    // float divide
553   Binary0fOpCode(kX86Punpckldq),  // Interleave low-order double words
554   Binary0fOpCode(kX86Sqrtsd),   // square root
555   Binary0fOpCode(kX86Pmulld),   // parallel integer multiply 32 bits x 4
556   Binary0fOpCode(kX86Pmullw),   // parallel integer multiply 16 bits x 8
557   Binary0fOpCode(kX86Mulps),    // parallel FP multiply 32 bits x 4
558   Binary0fOpCode(kX86Mulpd),    // parallel FP multiply 64 bits x 2
559   Binary0fOpCode(kX86Paddb),    // parallel integer addition 8 bits x 16
560   Binary0fOpCode(kX86Paddw),    // parallel integer addition 16 bits x 8
561   Binary0fOpCode(kX86Paddd),    // parallel integer addition 32 bits x 4
562   Binary0fOpCode(kX86Addps),    // parallel FP addition 32 bits x 4
563   Binary0fOpCode(kX86Addpd),    // parallel FP addition 64 bits x 2
564   Binary0fOpCode(kX86Psubb),    // parallel integer subtraction 8 bits x 16
565   Binary0fOpCode(kX86Psubw),    // parallel integer subtraction 16 bits x 8
566   Binary0fOpCode(kX86Psubd),    // parallel integer subtraction 32 bits x 4
567   Binary0fOpCode(kX86Subps),    // parallel FP subtraction 32 bits x 4
568   Binary0fOpCode(kX86Subpd),    // parallel FP subtraction 64 bits x 2
569   Binary0fOpCode(kX86Pand),     // parallel AND 128 bits x 1
570   Binary0fOpCode(kX86Por),      // parallel OR 128 bits x 1
571   Binary0fOpCode(kX86Pxor),     // parallel XOR 128 bits x 1
572   Binary0fOpCode(kX86Phaddw),   // parallel horizontal addition 16 bits x 8
573   Binary0fOpCode(kX86Phaddd),   // parallel horizontal addition 32 bits x 4
574   Binary0fOpCode(kX86Haddpd),   // parallel FP horizontal addition 64 bits x 2
575   Binary0fOpCode(kX86Haddps),   // parallel FP horizontal addition 32 bits x 4
576   kX86PextrbRRI,                // Extract 8 bits from XMM into GPR
577   kX86PextrwRRI,                // Extract 16 bits from XMM into GPR
578   kX86PextrdRRI,                // Extract 32 bits from XMM into GPR
579   kX86PextrbMRI,                // Extract 8 bits from XMM into memory
580   kX86PextrwMRI,                // Extract 16 bits from XMM into memory
581   kX86PextrdMRI,                // Extract 32 bits from XMM into memory
582   kX86PshuflwRRI,               // Shuffle 16 bits in lower 64 bits of XMM.
583   kX86PshufdRRI,                // Shuffle 32 bits in XMM.
584   kX86ShufpsRRI,                // FP Shuffle 32 bits in XMM.
585   kX86ShufpdRRI,                // FP Shuffle 64 bits in XMM.
586   kX86PsrawRI,                  // signed right shift of floating point registers 16 bits x 8
587   kX86PsradRI,                  // signed right shift of floating point registers 32 bits x 4
588   kX86PsrlwRI,                  // logical right shift of floating point registers 16 bits x 8
589   kX86PsrldRI,                  // logical right shift of floating point registers 32 bits x 4
590   kX86PsrlqRI,                  // logical right shift of floating point registers 64 bits x 2
591   kX86PsllwRI,                  // left shift of floating point registers 16 bits x 8
592   kX86PslldRI,                  // left shift of floating point registers 32 bits x 4
593   kX86PsllqRI,                  // left shift of floating point registers 64 bits x 2
594   kX86Fild32M,                  // push 32-bit integer on x87 stack
595   kX86Fild64M,                  // push 64-bit integer on x87 stack
596   kX86Fld32M,                   // push float on x87 stack
597   kX86Fld64M,                   // push double on x87 stack
598   kX86Fstp32M,                  // pop top x87 fp stack and do 32-bit store
599   kX86Fstp64M,                  // pop top x87 fp stack and do 64-bit store
600   kX86Fst32M,                   // do 32-bit store
601   kX86Fst64M,                   // do 64-bit store
602   kX86Fprem,                    // remainder from dividing of two floating point values
603   kX86Fucompp,                  // compare floating point values and pop x87 fp stack twice
604   kX86Fstsw16R,                 // store FPU status word
605   Binary0fOpCode(kX86Mova128),  // move 128 bits aligned
606   kX86Mova128MR, kX86Mova128AR,  // store 128 bit aligned from xmm1 to m128
607   Binary0fOpCode(kX86Movups),   // load unaligned packed single FP values from xmm2/m128 to xmm1
608   kX86MovupsMR, kX86MovupsAR,   // store unaligned packed single FP values from xmm1 to m128
609   Binary0fOpCode(kX86Movaps),   // load aligned packed single FP values from xmm2/m128 to xmm1
610   kX86MovapsMR, kX86MovapsAR,   // store aligned packed single FP values from xmm1 to m128
611   kX86MovlpsRM, kX86MovlpsRA,   // load packed single FP values from m64 to low quadword of xmm
612   kX86MovlpsMR, kX86MovlpsAR,   // store packed single FP values from low quadword of xmm to m64
613   kX86MovhpsRM, kX86MovhpsRA,   // load packed single FP values from m64 to high quadword of xmm
614   kX86MovhpsMR, kX86MovhpsAR,   // store packed single FP values from high quadword of xmm to m64
615   Binary0fOpCode(kX86Movdxr),   // move into xmm from gpr
616   Binary0fOpCode(kX86Movqxr),   // move into xmm from 64 bit gpr
617   kX86MovqrxRR, kX86MovqrxMR, kX86MovqrxAR,  // move into 64 bit reg from xmm
618   kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR,  // move into reg from xmm
619   kX86MovsxdRR, kX86MovsxdRM, kX86MovsxdRA,  // move 32 bit to 64 bit with sign extension
620   kX86Set8R, kX86Set8M, kX86Set8A,  // set byte depending on condition operand
621   kX86Mfence,                   // memory barrier
622   Binary0fOpCode(kX86Imul16),   // 16bit multiply
623   Binary0fOpCode(kX86Imul32),   // 32bit multiply
624   Binary0fOpCode(kX86Imul64),   // 64bit multiply
625   kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR,  // compare and exchange
626   kX86LockCmpxchgMR, kX86LockCmpxchgAR, kX86LockCmpxchg64AR,  // locked compare and exchange
627   kX86LockCmpxchg64M, kX86LockCmpxchg64A,  // locked compare and exchange
628   kX86XchgMR,  // exchange memory with register (automatically locked)
629   Binary0fOpCode(kX86Movzx8),   // zero-extend 8-bit value
630   Binary0fOpCode(kX86Movzx16),  // zero-extend 16-bit value
631   Binary0fOpCode(kX86Movsx8),   // sign-extend 8-bit value
632   Binary0fOpCode(kX86Movsx16),  // sign-extend 16-bit value
633   Binary0fOpCode(kX86Movzx8q),   // zero-extend 8-bit value to quad word
634   Binary0fOpCode(kX86Movzx16q),  // zero-extend 16-bit value to quad word
635   Binary0fOpCode(kX86Movsx8q),   // sign-extend 8-bit value to quad word
636   Binary0fOpCode(kX86Movsx16q),  // sign-extend 16-bit value to quad word
637 #undef Binary0fOpCode
638   kX86Jcc8, kX86Jcc32,  // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
639   kX86Jmp8, kX86Jmp32,  // jmp rel8/32; lir operands - 0: rel, target assigned
640   kX86JmpR,             // jmp reg; lir operands - 0: reg
641   kX86Jecxz8,           // jcexz rel8; jump relative if ECX is zero.
642   kX86JmpT,             // jmp fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
643 
644   kX86CallR,            // call reg; lir operands - 0: reg
645   kX86CallM,            // call [base + disp]; lir operands - 0: base, 1: disp
646   kX86CallA,            // call [base + index * scale + disp]
647                         // lir operands - 0: base, 1: index, 2: scale, 3: disp
648   kX86CallT,            // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
649   kX86CallI,            // call <relative> - 0: disp; Used for core.oat linking only
650   kX86Ret,              // ret; no lir operands
651   kX86StartOfMethod,    // call 0; pop reg; sub reg, # - generate start of method into reg
652                         // lir operands - 0: reg
653   kX86PcRelLoadRA,      // mov reg, [base + index * scale + PC relative displacement]
654                         // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
655   kX86PcRelAdr,         // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
656   kX86RepneScasw,       // repne scasw
657   kX86Last
658 };
659 
660 /* Instruction assembly field_loc kind */
661 enum X86EncodingKind {
662   kData,                                    // Special case for raw data.
663   kNop,                                     // Special case for variable length nop.
664   kNullary,                                 // Opcode that takes no arguments.
665   kRegOpcode,                               // Shorter form of R instruction kind (opcode+rd)
666   kReg, kMem, kArray,                       // R, M and A instruction kinds.
667   kMemReg, kArrayReg, kThreadReg,           // MR, AR and TR instruction kinds.
668   kRegReg, kRegMem, kRegArray, kRegThread,  // RR, RM, RA and RT instruction kinds.
669   kRegRegStore,                             // RR following the store modrm reg-reg encoding rather than the load.
670   kRegImm, kMemImm, kArrayImm, kThreadImm,  // RI, MI, AI and TI instruction kinds.
671   kRegRegImm, kRegMemImm, kRegArrayImm,     // RRI, RMI and RAI instruction kinds.
672   kMovRegImm,                               // Shorter form move RI.
673   kMovRegQuadImm,                           // 64 bit move RI
674   kRegRegImmStore,                          // RRI following the store modrm reg-reg encoding rather than the load.
675   kMemRegImm,                               // MRI instruction kinds.
676   kShiftRegImm, kShiftMemImm, kShiftArrayImm,  // Shift opcode with immediate.
677   kShiftRegCl, kShiftMemCl, kShiftArrayCl,     // Shift opcode with register CL.
678   // kRegRegReg, kRegRegMem, kRegRegArray,    // RRR, RRM, RRA instruction kinds.
679   kRegCond, kMemCond, kArrayCond,          // R, M, A instruction kinds following by a condition.
680   kRegRegCond,                             // RR instruction kind followed by a condition.
681   kRegMemCond,                             // RM instruction kind followed by a condition.
682   kJmp, kJcc, kCall,                       // Branch instruction kinds.
683   kPcRel,                                  // Operation with displacement that is PC relative
684   kMacro,                                  // An instruction composing multiple others
685   kUnimplemented                           // Encoding used when an instruction isn't yet implemented.
686 };
687 
688 /* Struct used to define the EncodingMap positions for each X86 opcode */
689 struct X86EncodingMap {
690   X86OpCode opcode;      // e.g. kOpAddRI
691   // The broad category the instruction conforms to, such as kRegReg. Identifies which LIR operands
692   // hold meaning for the opcode.
693   X86EncodingKind kind;
694   uint64_t flags;
695   struct {
696   uint8_t prefix1;       // Non-zero => a prefix byte.
697   uint8_t prefix2;       // Non-zero => a second prefix byte.
698   uint8_t opcode;        // 1 byte opcode.
699   uint8_t extra_opcode1;  // Possible extra opcode byte.
700   uint8_t extra_opcode2;  // Possible second extra opcode byte.
701   // 3-bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
702   // encoding kind.
703   uint8_t modrm_opcode;
704   uint8_t ax_opcode;  // Non-zero => shorter encoding for AX as a destination.
705   uint8_t immediate_bytes;  // Number of bytes of immediate.
706   // Does the instruction address a byte register? In 32-bit mode the registers ah, bh, ch and dh
707   // are not used. In 64-bit mode the REX prefix is used to normalize and allow any byte register
708   // to be addressed.
709   bool r8_form;
710   } skeleton;
711   const char *name;
712   const char* fmt;
713 };
714 
715 
716 // FIXME: mem barrier type - what do we do for x86?
717 #define kSY 0
718 #define kST 0
719 
720 // Offsets of high and low halves of a 64bit value.
721 #define LOWORD_OFFSET 0
722 #define HIWORD_OFFSET 4
723 
724 // Segment override instruction prefix used for quick TLS access to Thread::Current().
725 #define THREAD_PREFIX 0x64
726 #define THREAD_PREFIX_GS 0x65
727 
728 // 64 Bit Operand Size
729 #define REX_W 0x48
730 // Extension of the ModR/M reg field
731 #define REX_R 0x44
732 // Extension of the SIB index field
733 #define REX_X 0x42
734 // Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
735 #define REX_B 0x41
736 // An empty REX prefix used to normalize the byte operations so that they apply to R4 through R15
737 #define REX 0x40
738 // Mask extracting the least 3 bits of r0..r15
739 #define kRegNumMask32 0x07
740 // Value indicating that base or reg is not used
741 #define NO_REG 0
742 
743 #define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
744 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
745 #define IS_SIMM32(v) ((INT64_C(-2147483648) <= (v)) && ((v) <= INT64_C(2147483647)))
746 
747 extern X86EncodingMap EncodingMap[kX86Last];
748 extern X86ConditionCode X86ConditionEncoding(ConditionCode cond);
749 
750 }  // namespace art
751 
752 #endif  // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
753