blob: 964422ce4ca4b6d80e02e595f6ba751e1e696a3f [file] [log] [blame]
Brian Carlstrom7940e442013-07-12 13:46:57 -07001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
18#define ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_
Brian Carlstrom7940e442013-07-12 13:46:57 -070019
20#include "dex/compiler_internals.h"
21
22namespace art {
23
24/*
Ian Rogers0177e532014-02-11 16:30:46 -080025 * 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.
Brian Carlstrom7940e442013-07-12 13:46:57 -070033 *
34 * General Purpose Register:
Ian Rogers0177e532014-02-11 16:30:46 -080035 * 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
Brian Carlstrom7940e442013-07-12 13:46:57 -070040 * r4/esp: stack pointer
Ian Rogers0177e532014-02-11 16:30:46 -080041 * 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
Brian Carlstrom7940e442013-07-12 13:46:57 -070044 * --- x86-64/x32 registers
45 * Native: x86-64 / x32 | ART
Ian Rogers0177e532014-02-11 16:30:46 -080046 * r8: caller save, arg5 | caller, arg4, scratch
47 * r9: caller save, arg6 | caller, arg5, scratch
Brian Carlstrom7940e442013-07-12 13:46:57 -070048 * r10: caller save | caller, scratch
49 * r11: caller save | caller, scratch
Ian Rogers0177e532014-02-11 16:30:46 -080050 * 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)
Brian Carlstrom7940e442013-07-12 13:46:57 -070054 *
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):
Ian Rogers0177e532014-02-11 16:30:46 -080059 * 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
Brian Carlstrom7940e442013-07-12 13:46:57 -070068 * --- x86-64/x32 registers
Ian Rogers0177e532014-02-11 16:30:46 -080069 * XMM8 .. 15: caller save available as scratch registers for ART.
Brian Carlstrom7940e442013-07-12 13:46:57 -070070 *
Ian Rogers0177e532014-02-11 16:30:46 -080071 * X87 is a necessary evil outside of ART code for x86:
Brian Carlstrom7940e442013-07-12 13:46:57 -070072 * ST0: x86 float/double native return value, caller save
73 * ST1 .. ST7: caller save
74 *
75 * Stack frame diagram (stack grows down, higher addresses at top):
76 *
77 * +------------------------+
78 * | IN[ins-1] | {Note: resides in caller's frame}
79 * | . |
80 * | IN[0] |
81 * | caller's Method* |
82 * +========================+ {Note: start of callee's frame}
83 * | return address | {pushed by call}
84 * | spill region | {variable sized}
85 * +------------------------+
86 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
87 * +------------------------+
88 * | V[locals-1] |
89 * | V[locals-2] |
90 * | . |
91 * | . |
92 * | V[1] |
93 * | V[0] |
94 * +------------------------+
95 * | 0 to 3 words padding |
96 * +------------------------+
97 * | OUT[outs-1] |
98 * | OUT[outs-2] |
99 * | . |
100 * | OUT[0] |
101 * | cur_method* | <<== sp w/ 16-byte alignment
102 * +========================+
103 */
104
Brian Carlstrom7940e442013-07-12 13:46:57 -0700105enum X86ResourceEncodingPos {
106 kX86GPReg0 = 0,
107 kX86RegSP = 4,
108 kX86FPReg0 = 16, // xmm0 .. xmm7/xmm15.
Serguei Katkove90501d2014-03-12 15:56:54 +0700109 kX86FPRegEnd = 32,
110 kX86FPStack = 33,
111 kX86RegEnd = kX86FPStack,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700112};
113
Brian Carlstrom7940e442013-07-12 13:46:57 -0700114#define ENCODE_X86_REG_SP (1ULL << kX86RegSP)
Serguei Katkove90501d2014-03-12 15:56:54 +0700115#define ENCODE_X86_FP_STACK (1ULL << kX86FPStack)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700116
buzbee091cc402014-03-31 10:14:40 -0700117// FIXME: for 64-bit, perhaps add an X86_64NativeRegisterPool enum?
Brian Carlstrom7940e442013-07-12 13:46:57 -0700118enum X86NativeRegisterPool {
buzbee091cc402014-03-31 10:14:40 -0700119 r0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700120 r0q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 0,
buzbee091cc402014-03-31 10:14:40 -0700121 rAX = r0,
122 r1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 1,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700123 r1q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 1,
buzbee091cc402014-03-31 10:14:40 -0700124 rCX = r1,
125 r2 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 2,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700126 r2q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 2,
buzbee091cc402014-03-31 10:14:40 -0700127 rDX = r2,
128 r3 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 3,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700129 r3q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 3,
buzbee091cc402014-03-31 10:14:40 -0700130 rBX = r3,
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700131 r4sp_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 4,
132 rX86_SP_32 = r4sp_32,
133 r4sp_64 = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 4,
134 rX86_SP_64 = r4sp_64,
buzbee091cc402014-03-31 10:14:40 -0700135 r5 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 5,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700136 r5q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 5,
buzbee091cc402014-03-31 10:14:40 -0700137 rBP = r5,
138 r5sib_no_base = r5,
139 r6 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 6,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700140 r6q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 6,
buzbee091cc402014-03-31 10:14:40 -0700141 rSI = r6,
142 r7 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 7,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700143 r7q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 7,
buzbee091cc402014-03-31 10:14:40 -0700144 rDI = r7,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700145#ifndef TARGET_REX_SUPPORT
buzbee091cc402014-03-31 10:14:40 -0700146 // fake return address register for core spill mask.
147 rRET = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700148#else
buzbee091cc402014-03-31 10:14:40 -0700149 r8 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700150 r8q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 8,
buzbee091cc402014-03-31 10:14:40 -0700151 r9 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 9,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700152 r9q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 9,
buzbee091cc402014-03-31 10:14:40 -0700153 r10 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700154 r10q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
buzbee091cc402014-03-31 10:14:40 -0700155 r11 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700156 r11q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
buzbee091cc402014-03-31 10:14:40 -0700157 r12 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700158 r12q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
buzbee091cc402014-03-31 10:14:40 -0700159 r13 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700160 r13q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
buzbee091cc402014-03-31 10:14:40 -0700161 r14 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700162 r14q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
buzbee091cc402014-03-31 10:14:40 -0700163 r15 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700164 r15q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
buzbee091cc402014-03-31 10:14:40 -0700165 // fake return address register for core spill mask.
166 rRET = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700167#endif
buzbee091cc402014-03-31 10:14:40 -0700168
Mark Mendellfe945782014-05-22 09:52:36 -0400169 // xmm registers, single precision view.
buzbee091cc402014-03-31 10:14:40 -0700170 fr0 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 0,
171 fr1 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 1,
172 fr2 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 2,
173 fr3 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 3,
174 fr4 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 4,
175 fr5 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 5,
176 fr6 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 6,
177 fr7 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 7,
178
Mark Mendellfe945782014-05-22 09:52:36 -0400179 // xmm registers, double precision aliases.
buzbee091cc402014-03-31 10:14:40 -0700180 dr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 0,
181 dr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 1,
182 dr2 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 2,
183 dr3 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 3,
184 dr4 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 4,
185 dr5 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 5,
186 dr6 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 6,
187 dr7 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 7,
188
Mark Mendellfe945782014-05-22 09:52:36 -0400189 // xmm registers aliases.
190 xr0 = RegStorage::k128BitSolo | 0,
191 xr1 = RegStorage::k128BitSolo | 1,
192 xr2 = RegStorage::k128BitSolo | 2,
193 xr3 = RegStorage::k128BitSolo | 3,
194 xr4 = RegStorage::k128BitSolo | 4,
195 xr5 = RegStorage::k128BitSolo | 5,
196 xr6 = RegStorage::k128BitSolo | 6,
197 xr7 = RegStorage::k128BitSolo | 7,
buzbee091cc402014-03-31 10:14:40 -0700198
199 // TODO: as needed, add 256, 512 and 1024-bit xmm views.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700200};
201
buzbee091cc402014-03-31 10:14:40 -0700202constexpr RegStorage rs_r0(RegStorage::kValid | r0);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700203constexpr RegStorage rs_r0q(RegStorage::kValid | r0q);
buzbee091cc402014-03-31 10:14:40 -0700204constexpr RegStorage rs_rAX = rs_r0;
205constexpr RegStorage rs_r1(RegStorage::kValid | r1);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700206constexpr RegStorage rs_r1q(RegStorage::kValid | r1q);
buzbee091cc402014-03-31 10:14:40 -0700207constexpr RegStorage rs_rCX = rs_r1;
208constexpr RegStorage rs_r2(RegStorage::kValid | r2);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700209constexpr RegStorage rs_r2q(RegStorage::kValid | r2q);
buzbee091cc402014-03-31 10:14:40 -0700210constexpr RegStorage rs_rDX = rs_r2;
211constexpr RegStorage rs_r3(RegStorage::kValid | r3);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700212constexpr RegStorage rs_r3q(RegStorage::kValid | r3q);
buzbee091cc402014-03-31 10:14:40 -0700213constexpr RegStorage rs_rBX = rs_r3;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700214constexpr RegStorage rs_rX86_SP_64(RegStorage::kValid | r4sp_64);
215constexpr RegStorage rs_rX86_SP_32(RegStorage::kValid | r4sp_32);
216extern RegStorage rs_rX86_SP;
buzbee091cc402014-03-31 10:14:40 -0700217constexpr RegStorage rs_r5(RegStorage::kValid | r5);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700218constexpr RegStorage rs_r5q(RegStorage::kValid | r5q);
buzbee091cc402014-03-31 10:14:40 -0700219constexpr RegStorage rs_rBP = rs_r5;
220constexpr RegStorage rs_r6(RegStorage::kValid | r6);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700221constexpr RegStorage rs_r6q(RegStorage::kValid | r6q);
buzbee091cc402014-03-31 10:14:40 -0700222constexpr RegStorage rs_rSI = rs_r6;
223constexpr RegStorage rs_r7(RegStorage::kValid | r7);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700224constexpr RegStorage rs_r7q(RegStorage::kValid | r7q);
buzbee091cc402014-03-31 10:14:40 -0700225constexpr RegStorage rs_rDI = rs_r7;
226constexpr RegStorage rs_rRET(RegStorage::kValid | rRET);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700227#ifdef TARGET_REX_SUPPORT
228constexpr RegStorage rs_r8(RegStorage::kValid | r8);
229constexpr RegStorage rs_r8q(RegStorage::kValid | r8q);
230constexpr RegStorage rs_r9(RegStorage::kValid | r9);
231constexpr RegStorage rs_r9q(RegStorage::kValid | r9q);
232constexpr RegStorage rs_r10(RegStorage::kValid | r10);
233constexpr RegStorage rs_r10q(RegStorage::kValid | r10q);
234constexpr RegStorage rs_r11(RegStorage::kValid | r11);
235constexpr RegStorage rs_r11q(RegStorage::kValid | r11q);
236constexpr RegStorage rs_r12(RegStorage::kValid | r12);
237constexpr RegStorage rs_r12q(RegStorage::kValid | r12q);
238constexpr RegStorage rs_r13(RegStorage::kValid | r13);
239constexpr RegStorage rs_r13q(RegStorage::kValid | r13q);
240constexpr RegStorage rs_r14(RegStorage::kValid | r14);
241constexpr RegStorage rs_r14q(RegStorage::kValid | r14q);
242constexpr RegStorage rs_r15(RegStorage::kValid | r15);
243constexpr RegStorage rs_r15q(RegStorage::kValid | r15q);
244#endif
buzbee091cc402014-03-31 10:14:40 -0700245
246constexpr RegStorage rs_fr0(RegStorage::kValid | fr0);
247constexpr RegStorage rs_fr1(RegStorage::kValid | fr1);
248constexpr RegStorage rs_fr2(RegStorage::kValid | fr2);
249constexpr RegStorage rs_fr3(RegStorage::kValid | fr3);
250constexpr RegStorage rs_fr4(RegStorage::kValid | fr4);
251constexpr RegStorage rs_fr5(RegStorage::kValid | fr5);
252constexpr RegStorage rs_fr6(RegStorage::kValid | fr6);
253constexpr RegStorage rs_fr7(RegStorage::kValid | fr7);
254
255constexpr RegStorage rs_dr0(RegStorage::kValid | dr0);
256constexpr RegStorage rs_dr1(RegStorage::kValid | dr1);
257constexpr RegStorage rs_dr2(RegStorage::kValid | dr2);
258constexpr RegStorage rs_dr3(RegStorage::kValid | dr3);
259constexpr RegStorage rs_dr4(RegStorage::kValid | dr4);
260constexpr RegStorage rs_dr5(RegStorage::kValid | dr5);
261constexpr RegStorage rs_dr6(RegStorage::kValid | dr6);
262constexpr RegStorage rs_dr7(RegStorage::kValid | dr7);
263
Mark Mendellfe945782014-05-22 09:52:36 -0400264constexpr RegStorage rs_xr0(RegStorage::kValid | xr0);
265constexpr RegStorage rs_xr1(RegStorage::kValid | xr1);
266constexpr RegStorage rs_xr2(RegStorage::kValid | xr2);
267constexpr RegStorage rs_xr3(RegStorage::kValid | xr3);
268constexpr RegStorage rs_xr4(RegStorage::kValid | xr4);
269constexpr RegStorage rs_xr5(RegStorage::kValid | xr5);
270constexpr RegStorage rs_xr6(RegStorage::kValid | xr6);
271constexpr RegStorage rs_xr7(RegStorage::kValid | xr7);
buzbee2700f7e2014-03-07 09:46:20 -0800272
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700273extern X86NativeRegisterPool rX86_ARG0;
274extern X86NativeRegisterPool rX86_ARG1;
275extern X86NativeRegisterPool rX86_ARG2;
276extern X86NativeRegisterPool rX86_ARG3;
277extern X86NativeRegisterPool rX86_FARG0;
278extern X86NativeRegisterPool rX86_FARG1;
279extern X86NativeRegisterPool rX86_FARG2;
280extern X86NativeRegisterPool rX86_FARG3;
281extern X86NativeRegisterPool rX86_RET0;
282extern X86NativeRegisterPool rX86_RET1;
283extern X86NativeRegisterPool rX86_INVOKE_TGT;
284extern X86NativeRegisterPool rX86_COUNT;
285
286extern RegStorage rs_rX86_ARG0;
287extern RegStorage rs_rX86_ARG1;
288extern RegStorage rs_rX86_ARG2;
289extern RegStorage rs_rX86_ARG3;
290extern RegStorage rs_rX86_FARG0;
291extern RegStorage rs_rX86_FARG1;
292extern RegStorage rs_rX86_FARG2;
293extern RegStorage rs_rX86_FARG3;
294extern RegStorage rs_rX86_RET0;
295extern RegStorage rs_rX86_RET1;
296extern RegStorage rs_rX86_INVOKE_TGT;
297extern RegStorage rs_rX86_COUNT;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700298
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000299// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
300const RegLocation x86_loc_c_return
buzbee091cc402014-03-31 10:14:40 -0700301 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000302 RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
303const RegLocation x86_loc_c_return_wide
buzbee091cc402014-03-31 10:14:40 -0700304 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000305 RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000306const RegLocation x86_loc_c_return_float
buzbee091cc402014-03-31 10:14:40 -0700307 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000308 RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000309const RegLocation x86_loc_c_return_double
buzbee091cc402014-03-31 10:14:40 -0700310 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
311 RegStorage(RegStorage::k64BitSolo, dr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000312
Brian Carlstrom7940e442013-07-12 13:46:57 -0700313/*
314 * The following enum defines the list of supported X86 instructions by the
315 * assembler. Their corresponding EncodingMap positions will be defined in
316 * Assemble.cc.
317 */
318enum X86OpCode {
319 kX86First = 0,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700320 kX8632BitData = kX86First, // data [31..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700321 kX86Bkpt,
322 kX86Nop,
323 // Define groups of binary operations
324 // MR - Memory Register - opcode [base + disp], reg
325 // - lir operands - 0: base, 1: disp, 2: reg
326 // AR - Array Register - opcode [base + index * scale + disp], reg
327 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
328 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
329 // - lir operands - 0: disp, 1: reg
330 // RR - Register Register - opcode reg1, reg2
331 // - lir operands - 0: reg1, 1: reg2
332 // RM - Register Memory - opcode reg, [base + disp]
333 // - lir operands - 0: reg, 1: base, 2: disp
334 // RA - Register Array - opcode reg, [base + index * scale + disp]
335 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
336 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
337 // - lir operands - 0: reg, 1: disp
338 // RI - Register Immediate - opcode reg, #immediate
339 // - lir operands - 0: reg, 1: immediate
340 // MI - Memory Immediate - opcode [base + disp], #immediate
341 // - lir operands - 0: base, 1: disp, 2: immediate
342 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
343 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
Vladimir Markoe6ed00b2013-10-24 14:52:37 +0100344 // TI - Thread Immediate - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
Brian Carlstrom7940e442013-07-12 13:46:57 -0700345 // - lir operands - 0: disp, 1: imm
346#define BinaryOpCode(opcode) \
347 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
348 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
349 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
350 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
351 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
352 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
353 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700354 opcode ## 32MR, opcode ## 64MR, opcode ## 32AR, opcode ## 64AR, opcode ## 32TR, \
355 opcode ## 32RR, opcode ## 32RM, opcode ## 64RM, opcode ## 32RA, opcode ## 64RA, opcode ## 32RT, opcode ## 64RT, \
356 opcode ## 32RI, opcode ## 64RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
357 opcode ## 32RI8, opcode ## 64RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8
Brian Carlstrom7940e442013-07-12 13:46:57 -0700358 BinaryOpCode(kX86Add),
359 BinaryOpCode(kX86Or),
360 BinaryOpCode(kX86Adc),
361 BinaryOpCode(kX86Sbb),
362 BinaryOpCode(kX86And),
363 BinaryOpCode(kX86Sub),
364 BinaryOpCode(kX86Xor),
365 BinaryOpCode(kX86Cmp),
366#undef BinaryOpCode
367 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
368 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
369 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
370 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
371 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
372 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
373 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
374 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
375 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700376 kX86Mov32MR, kX86Mov64MR, kX86Mov32AR, kX86Mov64AR, kX86Mov32TR,
377 kX86Mov32RR, kX86Mov32RM, kX86Mov64RM, kX86Mov32RA, kX86Mov64RA, kX86Mov32RT, kX86Mov64RT,
378 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI, kX86Mov64TI,
Mark Mendell4028a6c2014-02-19 20:06:20 -0800379 kX86Lea32RM,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700380 kX86Lea32RA,
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800381 // RRC - Register Register ConditionCode - cond_opcode reg1, reg2
382 // - lir operands - 0: reg1, 1: reg2, 2: CC
383 kX86Cmov32RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400384 // RMC - Register Memory ConditionCode - cond_opcode reg1, [base + disp]
385 // - lir operands - 0: reg1, 1: base, 2: disp 3: CC
386 kX86Cmov32RMC,
387
Brian Carlstrom7940e442013-07-12 13:46:57 -0700388 // RC - Register CL - opcode reg, CL
389 // - lir operands - 0: reg, 1: CL
390 // MC - Memory CL - opcode [base + disp], CL
391 // - lir operands - 0: base, 1: disp, 2: CL
392 // AC - Array CL - opcode [base + index * scale + disp], CL
393 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
394#define BinaryShiftOpCode(opcode) \
395 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
396 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
397 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
398 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
399 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
400 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC
401 BinaryShiftOpCode(kX86Rol),
402 BinaryShiftOpCode(kX86Ror),
403 BinaryShiftOpCode(kX86Rcl),
404 BinaryShiftOpCode(kX86Rcr),
405 BinaryShiftOpCode(kX86Sal),
406 BinaryShiftOpCode(kX86Shr),
407 BinaryShiftOpCode(kX86Sar),
408#undef BinaryShiftOpcode
409 kX86Cmc,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800410 kX86Shld32RRI,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400411 kX86Shld32MRI,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800412 kX86Shrd32RRI,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400413 kX86Shrd32MRI,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700414#define UnaryOpcode(opcode, reg, mem, array) \
415 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
416 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
417 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array
418 UnaryOpcode(kX86Test, RI, MI, AI),
419 kX86Test32RR,
420 UnaryOpcode(kX86Not, R, M, A),
421 UnaryOpcode(kX86Neg, R, M, A),
422 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
423 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
424 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
425 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
Mark Mendell2bf31e62014-01-23 12:13:40 -0800426 kx86Cdq32Da,
Vladimir Markoa8b4caf2013-10-24 15:08:57 +0100427 kX86Bswap32R,
Vladimir Marko70b797d2013-12-03 15:25:24 +0000428 kX86Push32R, kX86Pop32R,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700429#undef UnaryOpcode
430#define Binary0fOpCode(opcode) \
431 opcode ## RR, opcode ## RM, opcode ## RA
432 Binary0fOpCode(kX86Movsd),
433 kX86MovsdMR,
434 kX86MovsdAR,
435 Binary0fOpCode(kX86Movss),
436 kX86MovssMR,
437 kX86MovssAR,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700438 Binary0fOpCode(kX86Cvtsi2sd), // int to double
439 Binary0fOpCode(kX86Cvtsi2ss), // int to float
440 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int
441 Binary0fOpCode(kX86Cvttss2si), // truncating float to int
442 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
443 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
Brian Carlstrom7940e442013-07-12 13:46:57 -0700444 Binary0fOpCode(kX86Ucomisd), // unordered double compare
445 Binary0fOpCode(kX86Ucomiss), // unordered float compare
446 Binary0fOpCode(kX86Comisd), // double compare
447 Binary0fOpCode(kX86Comiss), // float compare
448 Binary0fOpCode(kX86Orps), // or of floating point registers
449 Binary0fOpCode(kX86Xorps), // xor of floating point registers
450 Binary0fOpCode(kX86Addsd), // double add
451 Binary0fOpCode(kX86Addss), // float add
452 Binary0fOpCode(kX86Mulsd), // double multiply
453 Binary0fOpCode(kX86Mulss), // float multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700454 Binary0fOpCode(kX86Cvtsd2ss), // double to float
455 Binary0fOpCode(kX86Cvtss2sd), // float to double
Brian Carlstrom7940e442013-07-12 13:46:57 -0700456 Binary0fOpCode(kX86Subsd), // double subtract
457 Binary0fOpCode(kX86Subss), // float subtract
458 Binary0fOpCode(kX86Divsd), // double divide
459 Binary0fOpCode(kX86Divss), // float divide
Razvan A Lupusorud3266bc2014-01-24 12:55:31 -0800460 Binary0fOpCode(kX86Punpckldq), // Interleave low-order double words
Mark Mendellfe945782014-05-22 09:52:36 -0400461 Binary0fOpCode(kX86Sqrtsd), // square root
462 Binary0fOpCode(kX86Pmulld), // parallel integer multiply 32 bits x 4
463 Binary0fOpCode(kX86Pmullw), // parallel integer multiply 16 bits x 8
464 Binary0fOpCode(kX86Mulps), // parallel FP multiply 32 bits x 4
465 Binary0fOpCode(kX86Mulpd), // parallel FP multiply 64 bits x 2
466 Binary0fOpCode(kX86Paddb), // parallel integer addition 8 bits x 16
467 Binary0fOpCode(kX86Paddw), // parallel integer addition 16 bits x 8
468 Binary0fOpCode(kX86Paddd), // parallel integer addition 32 bits x 4
469 Binary0fOpCode(kX86Addps), // parallel FP addition 32 bits x 4
470 Binary0fOpCode(kX86Addpd), // parallel FP addition 64 bits x 2
471 Binary0fOpCode(kX86Psubb), // parallel integer subtraction 8 bits x 16
472 Binary0fOpCode(kX86Psubw), // parallel integer subtraction 16 bits x 8
473 Binary0fOpCode(kX86Psubd), // parallel integer subtraction 32 bits x 4
474 Binary0fOpCode(kX86Subps), // parallel FP subtraction 32 bits x 4
475 Binary0fOpCode(kX86Subpd), // parallel FP subtraction 64 bits x 2
476 Binary0fOpCode(kX86Pand), // parallel AND 128 bits x 1
477 Binary0fOpCode(kX86Por), // parallel OR 128 bits x 1
478 Binary0fOpCode(kX86Pxor), // parallel XOR 128 bits x 1
479 Binary0fOpCode(kX86Phaddw), // parallel horizontal addition 16 bits x 8
480 Binary0fOpCode(kX86Phaddd), // parallel horizontal addition 32 bits x 4
481 kX86PextrbRRI, // Extract 8 bits from XMM into GPR
482 kX86PextrwRRI, // Extract 16 bits from XMM into GPR
483 kX86PextrdRRI, // Extract 32 bits from XMM into GPR
484 kX86PshuflwRRI, // Shuffle 16 bits in lower 64 bits of XMM.
485 kX86PshufdRRI, // Shuffle 32 bits in XMM.
486 kX86PsrawRI, // signed right shift of floating point registers 16 bits x 8
487 kX86PsradRI, // signed right shift of floating point registers 32 bits x 4
488 kX86PsrlwRI, // logical right shift of floating point registers 16 bits x 8
489 kX86PsrldRI, // logical right shift of floating point registers 32 bits x 4
490 kX86PsrlqRI, // logical right shift of floating point registers 64 bits x 2
491 kX86PsllwRI, // left shift of floating point registers 16 bits x 8
492 kX86PslldRI, // left shift of floating point registers 32 bits x 4
493 kX86PsllqRI, // left shift of floating point registers 64 bits x 2
Razvan A Lupusoru614c2b42014-01-28 17:05:21 -0800494 kX86Fild32M, // push 32-bit integer on x87 stack
495 kX86Fild64M, // push 64-bit integer on x87 stack
496 kX86Fstp32M, // pop top x87 fp stack and do 32-bit store
497 kX86Fstp64M, // pop top x87 fp stack and do 64-bit store
Mark Mendelld65c51a2014-04-29 16:55:20 -0400498 Binary0fOpCode(kX86Mova128), // move 128 bits aligned
499 kX86Mova128MR, kX86Mova128AR, // store 128 bit aligned from xmm1 to m128
Razvan A Lupusoru2c498d12014-01-29 16:02:57 -0800500 Binary0fOpCode(kX86Movups), // load unaligned packed single FP values from xmm2/m128 to xmm1
501 kX86MovupsMR, kX86MovupsAR, // store unaligned packed single FP values from xmm1 to m128
502 Binary0fOpCode(kX86Movaps), // load aligned packed single FP values from xmm2/m128 to xmm1
503 kX86MovapsMR, kX86MovapsAR, // store aligned packed single FP values from xmm1 to m128
504 kX86MovlpsRM, kX86MovlpsRA, // load packed single FP values from m64 to low quadword of xmm
505 kX86MovlpsMR, kX86MovlpsAR, // store packed single FP values from low quadword of xmm to m64
506 kX86MovhpsRM, kX86MovhpsRA, // load packed single FP values from m64 to high quadword of xmm
507 kX86MovhpsMR, kX86MovhpsAR, // store packed single FP values from high quadword of xmm to m64
Brian Carlstrom7940e442013-07-12 13:46:57 -0700508 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700509 kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR, // move into reg from xmm
510 kX86Set8R, kX86Set8M, kX86Set8A, // set byte depending on condition operand
Brian Carlstrom7940e442013-07-12 13:46:57 -0700511 kX86Mfence, // memory barrier
512 Binary0fOpCode(kX86Imul16), // 16bit multiply
513 Binary0fOpCode(kX86Imul32), // 32bit multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700514 kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR, // compare and exchange
Vladimir Markoc29bb612013-11-27 16:47:25 +0000515 kX86LockCmpxchgMR, kX86LockCmpxchgAR, // locked compare and exchange
Vladimir Marko70b797d2013-12-03 15:25:24 +0000516 kX86LockCmpxchg8bM, kX86LockCmpxchg8bA, // locked compare and exchange
Razvan A Lupusoru99ad7232014-02-25 17:41:08 -0800517 kX86XchgMR, // exchange memory with register (automatically locked)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700518 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
519 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
520 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
521 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
522#undef Binary0fOpCode
523 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
524 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned
525 kX86JmpR, // jmp reg; lir operands - 0: reg
Mark Mendell4028a6c2014-02-19 20:06:20 -0800526 kX86Jecxz8, // jcexz rel8; jump relative if ECX is zero.
Brian Carlstrom60d7a652014-03-13 18:10:08 -0700527 kX86JmpT, // jmp fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
528
Brian Carlstrom7940e442013-07-12 13:46:57 -0700529 kX86CallR, // call reg; lir operands - 0: reg
530 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
531 kX86CallA, // call [base + index * scale + disp]
532 // lir operands - 0: base, 1: index, 2: scale, 3: disp
533 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
Mark Mendell55d0eac2014-02-06 11:02:52 -0800534 kX86CallI, // call <relative> - 0: disp; Used for core.oat linking only
Brian Carlstrom7940e442013-07-12 13:46:57 -0700535 kX86Ret, // ret; no lir operands
536 kX86StartOfMethod, // call 0; pop reg; sub reg, # - generate start of method into reg
537 // lir operands - 0: reg
538 kX86PcRelLoadRA, // mov reg, [base + index * scale + PC relative displacement]
539 // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
540 kX86PcRelAdr, // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
Mark Mendell4028a6c2014-02-19 20:06:20 -0800541 kX86RepneScasw, // repne scasw
Brian Carlstrom7940e442013-07-12 13:46:57 -0700542 kX86Last
543};
544
545/* Instruction assembly field_loc kind */
546enum X86EncodingKind {
547 kData, // Special case for raw data.
548 kNop, // Special case for variable length nop.
549 kNullary, // Opcode that takes no arguments.
Mark Mendell4028a6c2014-02-19 20:06:20 -0800550 kPrefix2Nullary, // Opcode that takes no arguments, but 2 prefixes.
Vladimir Markoa8b4caf2013-10-24 15:08:57 +0100551 kRegOpcode, // Shorter form of R instruction kind (opcode+rd)
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700552 kReg, kReg64, kMem, kArray, // R, M and A instruction kinds.
553 kMemReg, kMemReg64, kArrayReg, kArrayReg64, kThreadReg, // MR, AR and TR instruction kinds.
554 kRegReg, kRegMem, kRegArray, kRegThread, kReg64Thread, // RR, RM, RA and RT instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700555 kRegRegStore, // RR following the store modrm reg-reg encoding rather than the load.
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700556 kRegImm, kReg64Imm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700557 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
558 kMovRegImm, // Shorter form move RI.
Mark Mendell4708dcd2014-01-22 09:05:18 -0800559 kRegRegImmRev, // RRI with first reg in r/m
Mark Mendell2637f2e2014-04-30 10:10:47 -0400560 kMemRegImm, // MRI instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700561 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
562 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
563 kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
564 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800565 kRegRegCond, // RR instruction kind followed by a condition.
Mark Mendell2637f2e2014-04-30 10:10:47 -0400566 kRegMemCond, // RM instruction kind followed by a condition.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700567 kJmp, kJcc, kCall, // Branch instruction kinds.
568 kPcRel, // Operation with displacement that is PC relative
569 kMacro, // An instruction composing multiple others
570 kUnimplemented // Encoding used when an instruction isn't yet implemented.
571};
572
573/* Struct used to define the EncodingMap positions for each X86 opcode */
574struct X86EncodingMap {
575 X86OpCode opcode; // e.g. kOpAddRI
576 X86EncodingKind kind; // Used to discriminate in the union below
577 uint64_t flags;
578 struct {
579 uint8_t prefix1; // non-zero => a prefix byte
580 uint8_t prefix2; // non-zero => a second prefix byte
581 uint8_t opcode; // 1 byte opcode
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700582 uint8_t extra_opcode1; // possible extra opcode byte
583 uint8_t extra_opcode2; // possible second extra opcode byte
Brian Carlstrom7940e442013-07-12 13:46:57 -0700584 // 3bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
585 // encoding kind
586 uint8_t modrm_opcode;
587 uint8_t ax_opcode; // non-zero => shorter encoding for AX as a destination
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700588 uint8_t immediate_bytes; // number of bytes of immediate
Brian Carlstrom7940e442013-07-12 13:46:57 -0700589 } skeleton;
590 const char *name;
591 const char* fmt;
592};
593
594
595// FIXME: mem barrier type - what do we do for x86?
596#define kSY 0
597#define kST 0
598
599// Offsets of high and low halves of a 64bit value.
600#define LOWORD_OFFSET 0
601#define HIWORD_OFFSET 4
602
603// Segment override instruction prefix used for quick TLS access to Thread::Current().
604#define THREAD_PREFIX 0x64
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700605#define THREAD_PREFIX_GS 0x65
606
607// 64 Bit Operand Size
608#define REX_W 0x48
609// Extension of the ModR/M reg field
Brian Carlstrom7940e442013-07-12 13:46:57 -0700610
611#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
612#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
613
614extern X86EncodingMap EncodingMap[kX86Last];
615extern X86ConditionCode X86ConditionEncoding(ConditionCode cond);
616
617} // namespace art
618
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700619#endif // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_