blob: e550488a0307d98da464f6cd538fa5c788b70dbd [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,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700178#ifdef TARGET_REX_SUPPORT
179 fr8 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 8,
180 fr9 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 9,
181 fr10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
182 fr11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
183 fr12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
184 fr13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
185 fr14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
186 fr15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
187#endif
buzbee091cc402014-03-31 10:14:40 -0700188
Mark Mendellfe945782014-05-22 09:52:36 -0400189 // xmm registers, double precision aliases.
buzbee091cc402014-03-31 10:14:40 -0700190 dr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 0,
191 dr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 1,
192 dr2 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 2,
193 dr3 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 3,
194 dr4 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 4,
195 dr5 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 5,
196 dr6 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 6,
197 dr7 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 7,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700198#ifdef TARGET_REX_SUPPORT
199 dr8 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 8,
200 dr9 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 9,
201 dr10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
202 dr11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
203 dr12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
204 dr13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
205 dr14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
206 dr15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
207#endif
buzbee091cc402014-03-31 10:14:40 -0700208
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700209 // xmm registers, quad precision aliases
Mark Mendellfe945782014-05-22 09:52:36 -0400210 xr0 = RegStorage::k128BitSolo | 0,
211 xr1 = RegStorage::k128BitSolo | 1,
212 xr2 = RegStorage::k128BitSolo | 2,
213 xr3 = RegStorage::k128BitSolo | 3,
214 xr4 = RegStorage::k128BitSolo | 4,
215 xr5 = RegStorage::k128BitSolo | 5,
216 xr6 = RegStorage::k128BitSolo | 6,
217 xr7 = RegStorage::k128BitSolo | 7,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700218#ifdef TARGET_REX_SUPPORT
219 xr8 = RegStorage::k128BitSolo | 8,
220 xr9 = RegStorage::k128BitSolo | 9,
221 xr10 = RegStorage::k128BitSolo | 10,
222 xr11 = RegStorage::k128BitSolo | 11,
223 xr12 = RegStorage::k128BitSolo | 12,
224 xr13 = RegStorage::k128BitSolo | 13,
225 xr14 = RegStorage::k128BitSolo | 14,
226 xr15 = RegStorage::k128BitSolo | 15,
227#endif
buzbee091cc402014-03-31 10:14:40 -0700228
229 // TODO: as needed, add 256, 512 and 1024-bit xmm views.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700230};
231
buzbee091cc402014-03-31 10:14:40 -0700232constexpr RegStorage rs_r0(RegStorage::kValid | r0);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700233constexpr RegStorage rs_r0q(RegStorage::kValid | r0q);
buzbee091cc402014-03-31 10:14:40 -0700234constexpr RegStorage rs_rAX = rs_r0;
235constexpr RegStorage rs_r1(RegStorage::kValid | r1);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700236constexpr RegStorage rs_r1q(RegStorage::kValid | r1q);
buzbee091cc402014-03-31 10:14:40 -0700237constexpr RegStorage rs_rCX = rs_r1;
238constexpr RegStorage rs_r2(RegStorage::kValid | r2);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700239constexpr RegStorage rs_r2q(RegStorage::kValid | r2q);
buzbee091cc402014-03-31 10:14:40 -0700240constexpr RegStorage rs_rDX = rs_r2;
241constexpr RegStorage rs_r3(RegStorage::kValid | r3);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700242constexpr RegStorage rs_r3q(RegStorage::kValid | r3q);
buzbee091cc402014-03-31 10:14:40 -0700243constexpr RegStorage rs_rBX = rs_r3;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700244constexpr RegStorage rs_rX86_SP_64(RegStorage::kValid | r4sp_64);
245constexpr RegStorage rs_rX86_SP_32(RegStorage::kValid | r4sp_32);
246extern RegStorage rs_rX86_SP;
buzbee091cc402014-03-31 10:14:40 -0700247constexpr RegStorage rs_r5(RegStorage::kValid | r5);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700248constexpr RegStorage rs_r5q(RegStorage::kValid | r5q);
buzbee091cc402014-03-31 10:14:40 -0700249constexpr RegStorage rs_rBP = rs_r5;
250constexpr RegStorage rs_r6(RegStorage::kValid | r6);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700251constexpr RegStorage rs_r6q(RegStorage::kValid | r6q);
buzbee091cc402014-03-31 10:14:40 -0700252constexpr RegStorage rs_rSI = rs_r6;
253constexpr RegStorage rs_r7(RegStorage::kValid | r7);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700254constexpr RegStorage rs_r7q(RegStorage::kValid | r7q);
buzbee091cc402014-03-31 10:14:40 -0700255constexpr RegStorage rs_rDI = rs_r7;
256constexpr RegStorage rs_rRET(RegStorage::kValid | rRET);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700257#ifdef TARGET_REX_SUPPORT
258constexpr RegStorage rs_r8(RegStorage::kValid | r8);
259constexpr RegStorage rs_r8q(RegStorage::kValid | r8q);
260constexpr RegStorage rs_r9(RegStorage::kValid | r9);
261constexpr RegStorage rs_r9q(RegStorage::kValid | r9q);
262constexpr RegStorage rs_r10(RegStorage::kValid | r10);
263constexpr RegStorage rs_r10q(RegStorage::kValid | r10q);
264constexpr RegStorage rs_r11(RegStorage::kValid | r11);
265constexpr RegStorage rs_r11q(RegStorage::kValid | r11q);
266constexpr RegStorage rs_r12(RegStorage::kValid | r12);
267constexpr RegStorage rs_r12q(RegStorage::kValid | r12q);
268constexpr RegStorage rs_r13(RegStorage::kValid | r13);
269constexpr RegStorage rs_r13q(RegStorage::kValid | r13q);
270constexpr RegStorage rs_r14(RegStorage::kValid | r14);
271constexpr RegStorage rs_r14q(RegStorage::kValid | r14q);
272constexpr RegStorage rs_r15(RegStorage::kValid | r15);
273constexpr RegStorage rs_r15q(RegStorage::kValid | r15q);
274#endif
buzbee091cc402014-03-31 10:14:40 -0700275
276constexpr RegStorage rs_fr0(RegStorage::kValid | fr0);
277constexpr RegStorage rs_fr1(RegStorage::kValid | fr1);
278constexpr RegStorage rs_fr2(RegStorage::kValid | fr2);
279constexpr RegStorage rs_fr3(RegStorage::kValid | fr3);
280constexpr RegStorage rs_fr4(RegStorage::kValid | fr4);
281constexpr RegStorage rs_fr5(RegStorage::kValid | fr5);
282constexpr RegStorage rs_fr6(RegStorage::kValid | fr6);
283constexpr RegStorage rs_fr7(RegStorage::kValid | fr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700284#ifdef TARGET_REX_SUPPORT
285constexpr RegStorage rs_fr8(RegStorage::kValid | fr8);
286constexpr RegStorage rs_fr9(RegStorage::kValid | fr9);
287constexpr RegStorage rs_fr10(RegStorage::kValid | fr10);
288constexpr RegStorage rs_fr11(RegStorage::kValid | fr11);
289constexpr RegStorage rs_fr12(RegStorage::kValid | fr12);
290constexpr RegStorage rs_fr13(RegStorage::kValid | fr13);
291constexpr RegStorage rs_fr14(RegStorage::kValid | fr14);
292constexpr RegStorage rs_fr15(RegStorage::kValid | fr15);
293#endif
buzbee091cc402014-03-31 10:14:40 -0700294
295constexpr RegStorage rs_dr0(RegStorage::kValid | dr0);
296constexpr RegStorage rs_dr1(RegStorage::kValid | dr1);
297constexpr RegStorage rs_dr2(RegStorage::kValid | dr2);
298constexpr RegStorage rs_dr3(RegStorage::kValid | dr3);
299constexpr RegStorage rs_dr4(RegStorage::kValid | dr4);
300constexpr RegStorage rs_dr5(RegStorage::kValid | dr5);
301constexpr RegStorage rs_dr6(RegStorage::kValid | dr6);
302constexpr RegStorage rs_dr7(RegStorage::kValid | dr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700303#ifdef TARGET_REX_SUPPORT
304constexpr RegStorage rs_dr8(RegStorage::kValid | dr8);
305constexpr RegStorage rs_dr9(RegStorage::kValid | dr9);
306constexpr RegStorage rs_dr10(RegStorage::kValid | dr10);
307constexpr RegStorage rs_dr11(RegStorage::kValid | dr11);
308constexpr RegStorage rs_dr12(RegStorage::kValid | dr12);
309constexpr RegStorage rs_dr13(RegStorage::kValid | dr13);
310constexpr RegStorage rs_dr14(RegStorage::kValid | dr14);
311constexpr RegStorage rs_dr15(RegStorage::kValid | dr15);
312#endif
buzbee091cc402014-03-31 10:14:40 -0700313
Mark Mendellfe945782014-05-22 09:52:36 -0400314constexpr RegStorage rs_xr0(RegStorage::kValid | xr0);
315constexpr RegStorage rs_xr1(RegStorage::kValid | xr1);
316constexpr RegStorage rs_xr2(RegStorage::kValid | xr2);
317constexpr RegStorage rs_xr3(RegStorage::kValid | xr3);
318constexpr RegStorage rs_xr4(RegStorage::kValid | xr4);
319constexpr RegStorage rs_xr5(RegStorage::kValid | xr5);
320constexpr RegStorage rs_xr6(RegStorage::kValid | xr6);
321constexpr RegStorage rs_xr7(RegStorage::kValid | xr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700322#ifdef TARGET_REX_SUPPORT
323constexpr RegStorage rs_xr8(RegStorage::kValid | xr8);
324constexpr RegStorage rs_xr9(RegStorage::kValid | xr9);
325constexpr RegStorage rs_xr10(RegStorage::kValid | xr10);
326constexpr RegStorage rs_xr11(RegStorage::kValid | xr11);
327constexpr RegStorage rs_xr12(RegStorage::kValid | xr12);
328constexpr RegStorage rs_xr13(RegStorage::kValid | xr13);
329constexpr RegStorage rs_xr14(RegStorage::kValid | xr14);
330constexpr RegStorage rs_xr15(RegStorage::kValid | xr15);
331#endif
buzbee2700f7e2014-03-07 09:46:20 -0800332
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700333extern X86NativeRegisterPool rX86_ARG0;
334extern X86NativeRegisterPool rX86_ARG1;
335extern X86NativeRegisterPool rX86_ARG2;
336extern X86NativeRegisterPool rX86_ARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700337#ifdef TARGET_REX_SUPPORT
338extern X86NativeRegisterPool rX86_ARG4;
339extern X86NativeRegisterPool rX86_ARG5;
340#endif
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700341extern X86NativeRegisterPool rX86_FARG0;
342extern X86NativeRegisterPool rX86_FARG1;
343extern X86NativeRegisterPool rX86_FARG2;
344extern X86NativeRegisterPool rX86_FARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700345extern X86NativeRegisterPool rX86_FARG4;
346extern X86NativeRegisterPool rX86_FARG5;
347extern X86NativeRegisterPool rX86_FARG6;
348extern X86NativeRegisterPool rX86_FARG7;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700349extern X86NativeRegisterPool rX86_RET0;
350extern X86NativeRegisterPool rX86_RET1;
351extern X86NativeRegisterPool rX86_INVOKE_TGT;
352extern X86NativeRegisterPool rX86_COUNT;
353
354extern RegStorage rs_rX86_ARG0;
355extern RegStorage rs_rX86_ARG1;
356extern RegStorage rs_rX86_ARG2;
357extern RegStorage rs_rX86_ARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700358extern RegStorage rs_rX86_ARG4;
359extern RegStorage rs_rX86_ARG5;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700360extern RegStorage rs_rX86_FARG0;
361extern RegStorage rs_rX86_FARG1;
362extern RegStorage rs_rX86_FARG2;
363extern RegStorage rs_rX86_FARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700364extern RegStorage rs_rX86_FARG4;
365extern RegStorage rs_rX86_FARG5;
366extern RegStorage rs_rX86_FARG6;
367extern RegStorage rs_rX86_FARG7;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700368extern RegStorage rs_rX86_RET0;
369extern RegStorage rs_rX86_RET1;
370extern RegStorage rs_rX86_INVOKE_TGT;
371extern RegStorage rs_rX86_COUNT;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700372
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000373// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
374const RegLocation x86_loc_c_return
buzbee091cc402014-03-31 10:14:40 -0700375 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000376 RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
377const RegLocation x86_loc_c_return_wide
buzbee091cc402014-03-31 10:14:40 -0700378 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000379 RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700380const RegLocation x86_64_loc_c_return_wide
381 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
382 RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000383const RegLocation x86_loc_c_return_float
buzbee091cc402014-03-31 10:14:40 -0700384 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000385 RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000386const RegLocation x86_loc_c_return_double
buzbee091cc402014-03-31 10:14:40 -0700387 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
388 RegStorage(RegStorage::k64BitSolo, dr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000389
Brian Carlstrom7940e442013-07-12 13:46:57 -0700390/*
391 * The following enum defines the list of supported X86 instructions by the
392 * assembler. Their corresponding EncodingMap positions will be defined in
393 * Assemble.cc.
394 */
395enum X86OpCode {
396 kX86First = 0,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700397 kX8632BitData = kX86First, // data [31..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700398 kX86Bkpt,
399 kX86Nop,
400 // Define groups of binary operations
401 // MR - Memory Register - opcode [base + disp], reg
402 // - lir operands - 0: base, 1: disp, 2: reg
403 // AR - Array Register - opcode [base + index * scale + disp], reg
404 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
405 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
406 // - lir operands - 0: disp, 1: reg
407 // RR - Register Register - opcode reg1, reg2
408 // - lir operands - 0: reg1, 1: reg2
409 // RM - Register Memory - opcode reg, [base + disp]
410 // - lir operands - 0: reg, 1: base, 2: disp
411 // RA - Register Array - opcode reg, [base + index * scale + disp]
412 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
413 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
414 // - lir operands - 0: reg, 1: disp
415 // RI - Register Immediate - opcode reg, #immediate
416 // - lir operands - 0: reg, 1: immediate
417 // MI - Memory Immediate - opcode [base + disp], #immediate
418 // - lir operands - 0: base, 1: disp, 2: immediate
419 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
420 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
Vladimir Markoe6ed00b2013-10-24 14:52:37 +0100421 // TI - Thread Immediate - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
Brian Carlstrom7940e442013-07-12 13:46:57 -0700422 // - lir operands - 0: disp, 1: imm
423#define BinaryOpCode(opcode) \
424 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
425 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
426 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
427 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
428 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
429 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
430 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700431 opcode ## 32MR, opcode ## 32AR, opcode ## 32TR, \
432 opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
433 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
434 opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8, \
435 opcode ## 64MR, opcode ## 64AR, opcode ## 64TR, \
436 opcode ## 64RR, opcode ## 64RM, opcode ## 64RA, opcode ## 64RT, \
437 opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, opcode ## 64TI, \
438 opcode ## 64RI8, opcode ## 64MI8, opcode ## 64AI8, opcode ## 64TI8
Brian Carlstrom7940e442013-07-12 13:46:57 -0700439 BinaryOpCode(kX86Add),
440 BinaryOpCode(kX86Or),
441 BinaryOpCode(kX86Adc),
442 BinaryOpCode(kX86Sbb),
443 BinaryOpCode(kX86And),
444 BinaryOpCode(kX86Sub),
445 BinaryOpCode(kX86Xor),
446 BinaryOpCode(kX86Cmp),
447#undef BinaryOpCode
448 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
449 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
450 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700451 kX86Imul64RRI, kX86Imul64RMI, kX86Imul64RAI,
452 kX86Imul64RRI8, kX86Imul64RMI8, kX86Imul64RAI8,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700453 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
454 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
455 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
456 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
457 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
458 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700459 kX86Mov32MR, kX86Mov32AR, kX86Mov32TR,
460 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
461 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
Mark Mendell4028a6c2014-02-19 20:06:20 -0800462 kX86Lea32RM,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700463 kX86Lea32RA,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700464 kX86Mov64MR, kX86Mov64AR, kX86Mov64TR,
465 kX86Mov64RR, kX86Mov64RM, kX86Mov64RA, kX86Mov64RT,
466 kX86Mov64RI, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI,
467 kX86Lea64RM,
468 kX86Lea64RA,
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800469 // RRC - Register Register ConditionCode - cond_opcode reg1, reg2
470 // - lir operands - 0: reg1, 1: reg2, 2: CC
471 kX86Cmov32RRC,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700472 kX86Cmov64RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400473 // RMC - Register Memory ConditionCode - cond_opcode reg1, [base + disp]
474 // - lir operands - 0: reg1, 1: base, 2: disp 3: CC
475 kX86Cmov32RMC,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700476 kX86Cmov64RMC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400477
Brian Carlstrom7940e442013-07-12 13:46:57 -0700478 // RC - Register CL - opcode reg, CL
479 // - lir operands - 0: reg, 1: CL
480 // MC - Memory CL - opcode [base + disp], CL
481 // - lir operands - 0: base, 1: disp, 2: CL
482 // AC - Array CL - opcode [base + index * scale + disp], CL
483 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
484#define BinaryShiftOpCode(opcode) \
485 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
486 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
487 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
488 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
489 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700490 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC, \
491 opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, \
492 opcode ## 64RC, opcode ## 64MC, opcode ## 64AC
Brian Carlstrom7940e442013-07-12 13:46:57 -0700493 BinaryShiftOpCode(kX86Rol),
494 BinaryShiftOpCode(kX86Ror),
495 BinaryShiftOpCode(kX86Rcl),
496 BinaryShiftOpCode(kX86Rcr),
497 BinaryShiftOpCode(kX86Sal),
498 BinaryShiftOpCode(kX86Shr),
499 BinaryShiftOpCode(kX86Sar),
500#undef BinaryShiftOpcode
501 kX86Cmc,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800502 kX86Shld32RRI,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400503 kX86Shld32MRI,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800504 kX86Shrd32RRI,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400505 kX86Shrd32MRI,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700506 kX86Shld64RRI,
507 kX86Shld64MRI,
508 kX86Shrd64RRI,
509 kX86Shrd64MRI,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700510#define UnaryOpcode(opcode, reg, mem, array) \
511 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
512 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700513 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array, \
514 opcode ## 64 ## reg, opcode ## 64 ## mem, opcode ## 64 ## array
Brian Carlstrom7940e442013-07-12 13:46:57 -0700515 UnaryOpcode(kX86Test, RI, MI, AI),
516 kX86Test32RR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700517 kX86Test64RR,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700518 UnaryOpcode(kX86Not, R, M, A),
519 UnaryOpcode(kX86Neg, R, M, A),
520 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
521 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
522 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
523 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
Mark Mendell2bf31e62014-01-23 12:13:40 -0800524 kx86Cdq32Da,
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700525 kx86Cqo64Da,
Vladimir Markoa8b4caf2013-10-24 15:08:57 +0100526 kX86Bswap32R,
Vladimir Marko70b797d2013-12-03 15:25:24 +0000527 kX86Push32R, kX86Pop32R,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700528#undef UnaryOpcode
529#define Binary0fOpCode(opcode) \
530 opcode ## RR, opcode ## RM, opcode ## RA
531 Binary0fOpCode(kX86Movsd),
532 kX86MovsdMR,
533 kX86MovsdAR,
534 Binary0fOpCode(kX86Movss),
535 kX86MovssMR,
536 kX86MovssAR,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700537 Binary0fOpCode(kX86Cvtsi2sd), // int to double
538 Binary0fOpCode(kX86Cvtsi2ss), // int to float
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700539 Binary0fOpCode(kX86Cvtsqi2sd), // long to double
540 Binary0fOpCode(kX86Cvtsqi2ss), // long to float
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700541 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int
542 Binary0fOpCode(kX86Cvttss2si), // truncating float to int
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700543 Binary0fOpCode(kX86Cvttsd2sqi), // truncating double to long
544 Binary0fOpCode(kX86Cvttss2sqi), // truncating float to long
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700545 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
546 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
Brian Carlstrom7940e442013-07-12 13:46:57 -0700547 Binary0fOpCode(kX86Ucomisd), // unordered double compare
548 Binary0fOpCode(kX86Ucomiss), // unordered float compare
549 Binary0fOpCode(kX86Comisd), // double compare
550 Binary0fOpCode(kX86Comiss), // float compare
551 Binary0fOpCode(kX86Orps), // or of floating point registers
552 Binary0fOpCode(kX86Xorps), // xor of floating point registers
553 Binary0fOpCode(kX86Addsd), // double add
554 Binary0fOpCode(kX86Addss), // float add
555 Binary0fOpCode(kX86Mulsd), // double multiply
556 Binary0fOpCode(kX86Mulss), // float multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700557 Binary0fOpCode(kX86Cvtsd2ss), // double to float
558 Binary0fOpCode(kX86Cvtss2sd), // float to double
Brian Carlstrom7940e442013-07-12 13:46:57 -0700559 Binary0fOpCode(kX86Subsd), // double subtract
560 Binary0fOpCode(kX86Subss), // float subtract
561 Binary0fOpCode(kX86Divsd), // double divide
562 Binary0fOpCode(kX86Divss), // float divide
Razvan A Lupusorud3266bc2014-01-24 12:55:31 -0800563 Binary0fOpCode(kX86Punpckldq), // Interleave low-order double words
Mark Mendellfe945782014-05-22 09:52:36 -0400564 Binary0fOpCode(kX86Sqrtsd), // square root
565 Binary0fOpCode(kX86Pmulld), // parallel integer multiply 32 bits x 4
566 Binary0fOpCode(kX86Pmullw), // parallel integer multiply 16 bits x 8
567 Binary0fOpCode(kX86Mulps), // parallel FP multiply 32 bits x 4
568 Binary0fOpCode(kX86Mulpd), // parallel FP multiply 64 bits x 2
569 Binary0fOpCode(kX86Paddb), // parallel integer addition 8 bits x 16
570 Binary0fOpCode(kX86Paddw), // parallel integer addition 16 bits x 8
571 Binary0fOpCode(kX86Paddd), // parallel integer addition 32 bits x 4
572 Binary0fOpCode(kX86Addps), // parallel FP addition 32 bits x 4
573 Binary0fOpCode(kX86Addpd), // parallel FP addition 64 bits x 2
574 Binary0fOpCode(kX86Psubb), // parallel integer subtraction 8 bits x 16
575 Binary0fOpCode(kX86Psubw), // parallel integer subtraction 16 bits x 8
576 Binary0fOpCode(kX86Psubd), // parallel integer subtraction 32 bits x 4
577 Binary0fOpCode(kX86Subps), // parallel FP subtraction 32 bits x 4
578 Binary0fOpCode(kX86Subpd), // parallel FP subtraction 64 bits x 2
579 Binary0fOpCode(kX86Pand), // parallel AND 128 bits x 1
580 Binary0fOpCode(kX86Por), // parallel OR 128 bits x 1
581 Binary0fOpCode(kX86Pxor), // parallel XOR 128 bits x 1
582 Binary0fOpCode(kX86Phaddw), // parallel horizontal addition 16 bits x 8
583 Binary0fOpCode(kX86Phaddd), // parallel horizontal addition 32 bits x 4
584 kX86PextrbRRI, // Extract 8 bits from XMM into GPR
585 kX86PextrwRRI, // Extract 16 bits from XMM into GPR
586 kX86PextrdRRI, // Extract 32 bits from XMM into GPR
587 kX86PshuflwRRI, // Shuffle 16 bits in lower 64 bits of XMM.
588 kX86PshufdRRI, // Shuffle 32 bits in XMM.
589 kX86PsrawRI, // signed right shift of floating point registers 16 bits x 8
590 kX86PsradRI, // signed right shift of floating point registers 32 bits x 4
591 kX86PsrlwRI, // logical right shift of floating point registers 16 bits x 8
592 kX86PsrldRI, // logical right shift of floating point registers 32 bits x 4
593 kX86PsrlqRI, // logical right shift of floating point registers 64 bits x 2
594 kX86PsllwRI, // left shift of floating point registers 16 bits x 8
595 kX86PslldRI, // left shift of floating point registers 32 bits x 4
596 kX86PsllqRI, // left shift of floating point registers 64 bits x 2
Razvan A Lupusoru614c2b42014-01-28 17:05:21 -0800597 kX86Fild32M, // push 32-bit integer on x87 stack
598 kX86Fild64M, // push 64-bit integer on x87 stack
599 kX86Fstp32M, // pop top x87 fp stack and do 32-bit store
600 kX86Fstp64M, // pop top x87 fp stack and do 64-bit store
Mark Mendelld65c51a2014-04-29 16:55:20 -0400601 Binary0fOpCode(kX86Mova128), // move 128 bits aligned
602 kX86Mova128MR, kX86Mova128AR, // store 128 bit aligned from xmm1 to m128
Razvan A Lupusoru2c498d12014-01-29 16:02:57 -0800603 Binary0fOpCode(kX86Movups), // load unaligned packed single FP values from xmm2/m128 to xmm1
604 kX86MovupsMR, kX86MovupsAR, // store unaligned packed single FP values from xmm1 to m128
605 Binary0fOpCode(kX86Movaps), // load aligned packed single FP values from xmm2/m128 to xmm1
606 kX86MovapsMR, kX86MovapsAR, // store aligned packed single FP values from xmm1 to m128
607 kX86MovlpsRM, kX86MovlpsRA, // load packed single FP values from m64 to low quadword of xmm
608 kX86MovlpsMR, kX86MovlpsAR, // store packed single FP values from low quadword of xmm to m64
609 kX86MovhpsRM, kX86MovhpsRA, // load packed single FP values from m64 to high quadword of xmm
610 kX86MovhpsMR, kX86MovhpsAR, // store packed single FP values from high quadword of xmm to m64
Brian Carlstrom7940e442013-07-12 13:46:57 -0700611 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700612 Binary0fOpCode(kX86Movqxr), // move into xmm from 64 bit gpr
613 kX86MovqrxRR, kX86MovqrxMR, kX86MovqrxAR, // move into 64 bit reg from xmm
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700614 kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR, // move into reg from xmm
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700615 kX86MovsxdRR, kX86MovsxdRM, kX86MovsxdRA, // move 32 bit to 64 bit with sign extension
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700616 kX86Set8R, kX86Set8M, kX86Set8A, // set byte depending on condition operand
Brian Carlstrom7940e442013-07-12 13:46:57 -0700617 kX86Mfence, // memory barrier
618 Binary0fOpCode(kX86Imul16), // 16bit multiply
619 Binary0fOpCode(kX86Imul32), // 32bit multiply
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700620 Binary0fOpCode(kX86Imul64), // 64bit multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700621 kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR, // compare and exchange
Vladimir Markoc29bb612013-11-27 16:47:25 +0000622 kX86LockCmpxchgMR, kX86LockCmpxchgAR, // locked compare and exchange
Vladimir Marko70b797d2013-12-03 15:25:24 +0000623 kX86LockCmpxchg8bM, kX86LockCmpxchg8bA, // locked compare and exchange
Razvan A Lupusoru99ad7232014-02-25 17:41:08 -0800624 kX86XchgMR, // exchange memory with register (automatically locked)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700625 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
626 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
627 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
628 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
629#undef Binary0fOpCode
630 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
631 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned
632 kX86JmpR, // jmp reg; lir operands - 0: reg
Mark Mendell4028a6c2014-02-19 20:06:20 -0800633 kX86Jecxz8, // jcexz rel8; jump relative if ECX is zero.
Brian Carlstrom60d7a652014-03-13 18:10:08 -0700634 kX86JmpT, // jmp fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
635
Brian Carlstrom7940e442013-07-12 13:46:57 -0700636 kX86CallR, // call reg; lir operands - 0: reg
637 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
638 kX86CallA, // call [base + index * scale + disp]
639 // lir operands - 0: base, 1: index, 2: scale, 3: disp
640 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
Mark Mendell55d0eac2014-02-06 11:02:52 -0800641 kX86CallI, // call <relative> - 0: disp; Used for core.oat linking only
Brian Carlstrom7940e442013-07-12 13:46:57 -0700642 kX86Ret, // ret; no lir operands
643 kX86StartOfMethod, // call 0; pop reg; sub reg, # - generate start of method into reg
644 // lir operands - 0: reg
645 kX86PcRelLoadRA, // mov reg, [base + index * scale + PC relative displacement]
646 // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
647 kX86PcRelAdr, // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
Mark Mendell4028a6c2014-02-19 20:06:20 -0800648 kX86RepneScasw, // repne scasw
Brian Carlstrom7940e442013-07-12 13:46:57 -0700649 kX86Last
650};
651
652/* Instruction assembly field_loc kind */
653enum X86EncodingKind {
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700654 kData, // Special case for raw data.
655 kNop, // Special case for variable length nop.
656 kNullary, // Opcode that takes no arguments.
657 kPrefix2Nullary, // Opcode that takes no arguments, but 2 prefixes.
658 kRegOpcode, // Shorter form of R instruction kind (opcode+rd)
659 kReg, kMem, kArray, // R, M and A instruction kinds.
660 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds.
661 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds.
662 kRegRegStore, // RR following the store modrm reg-reg encoding rather than the load.
663 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
664 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
665 kMovRegImm, // Shorter form move RI.
666 kRegRegImmRev, // RRI with first reg in r/m
667 kMemRegImm, // MRI instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700668 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
669 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
670 kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
671 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800672 kRegRegCond, // RR instruction kind followed by a condition.
Mark Mendell2637f2e2014-04-30 10:10:47 -0400673 kRegMemCond, // RM instruction kind followed by a condition.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700674 kJmp, kJcc, kCall, // Branch instruction kinds.
675 kPcRel, // Operation with displacement that is PC relative
676 kMacro, // An instruction composing multiple others
677 kUnimplemented // Encoding used when an instruction isn't yet implemented.
678};
679
680/* Struct used to define the EncodingMap positions for each X86 opcode */
681struct X86EncodingMap {
682 X86OpCode opcode; // e.g. kOpAddRI
683 X86EncodingKind kind; // Used to discriminate in the union below
684 uint64_t flags;
685 struct {
686 uint8_t prefix1; // non-zero => a prefix byte
687 uint8_t prefix2; // non-zero => a second prefix byte
688 uint8_t opcode; // 1 byte opcode
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700689 uint8_t extra_opcode1; // possible extra opcode byte
690 uint8_t extra_opcode2; // possible second extra opcode byte
Brian Carlstrom7940e442013-07-12 13:46:57 -0700691 // 3bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
692 // encoding kind
693 uint8_t modrm_opcode;
694 uint8_t ax_opcode; // non-zero => shorter encoding for AX as a destination
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700695 uint8_t immediate_bytes; // number of bytes of immediate
Brian Carlstrom7940e442013-07-12 13:46:57 -0700696 } skeleton;
697 const char *name;
698 const char* fmt;
699};
700
701
702// FIXME: mem barrier type - what do we do for x86?
703#define kSY 0
704#define kST 0
705
706// Offsets of high and low halves of a 64bit value.
707#define LOWORD_OFFSET 0
708#define HIWORD_OFFSET 4
709
710// Segment override instruction prefix used for quick TLS access to Thread::Current().
711#define THREAD_PREFIX 0x64
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700712#define THREAD_PREFIX_GS 0x65
713
714// 64 Bit Operand Size
715#define REX_W 0x48
716// Extension of the ModR/M reg field
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700717#define REX_R 0x44
718// Extension of the SIB index field
719#define REX_X 0x42
720// Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
721#define REX_B 0x41
722// Mask extracting the least 3 bits of r0..r15
723#define kRegNumMask32 0x07
724// Value indicating that base or reg is not used
725#define NO_REG 0
Brian Carlstrom7940e442013-07-12 13:46:57 -0700726
727#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
728#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
729
730extern X86EncodingMap EncodingMap[kX86Last];
731extern X86ConditionCode X86ConditionEncoding(ConditionCode cond);
732
733} // namespace art
734
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700735#endif // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_