blob: 15fe7e298f9798249e771c76e2cafda4b123f8f4 [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
Serguei Katkovc3801912014-07-08 17:21:53 +070069 * 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.
Brian Carlstrom7940e442013-07-12 13:46:57 -070072 *
Ian Rogers0177e532014-02-11 16:30:46 -080073 * X87 is a necessary evil outside of ART code for x86:
Brian Carlstrom7940e442013-07-12 13:46:57 -070074 * 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
Brian Carlstrom7940e442013-07-12 13:46:57 -0700107enum X86ResourceEncodingPos {
108 kX86GPReg0 = 0,
109 kX86RegSP = 4,
110 kX86FPReg0 = 16, // xmm0 .. xmm7/xmm15.
Serguei Katkove90501d2014-03-12 15:56:54 +0700111 kX86FPRegEnd = 32,
112 kX86FPStack = 33,
113 kX86RegEnd = kX86FPStack,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700114};
115
buzbee091cc402014-03-31 10:14:40 -0700116// FIXME: for 64-bit, perhaps add an X86_64NativeRegisterPool enum?
Brian Carlstrom7940e442013-07-12 13:46:57 -0700117enum X86NativeRegisterPool {
buzbee091cc402014-03-31 10:14:40 -0700118 r0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700119 r0q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 0,
buzbee091cc402014-03-31 10:14:40 -0700120 rAX = r0,
121 r1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 1,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700122 r1q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 1,
buzbee091cc402014-03-31 10:14:40 -0700123 rCX = r1,
124 r2 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 2,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700125 r2q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 2,
buzbee091cc402014-03-31 10:14:40 -0700126 rDX = r2,
127 r3 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 3,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700128 r3q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 3,
buzbee091cc402014-03-31 10:14:40 -0700129 rBX = r3,
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700130 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,
buzbee091cc402014-03-31 10:14:40 -0700134 r5 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 5,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700135 r5q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 5,
buzbee091cc402014-03-31 10:14:40 -0700136 rBP = r5,
137 r5sib_no_base = r5,
138 r6 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 6,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700139 r6q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 6,
buzbee091cc402014-03-31 10:14:40 -0700140 rSI = r6,
141 r7 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 7,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700142 r7q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 7,
buzbee091cc402014-03-31 10:14:40 -0700143 rDI = r7,
buzbee091cc402014-03-31 10:14:40 -0700144 r8 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700145 r8q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 8,
buzbee091cc402014-03-31 10:14:40 -0700146 r9 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 9,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700147 r9q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 9,
buzbee091cc402014-03-31 10:14:40 -0700148 r10 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700149 r10q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
buzbee091cc402014-03-31 10:14:40 -0700150 r11 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700151 r11q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
buzbee091cc402014-03-31 10:14:40 -0700152 r12 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700153 r12q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
buzbee091cc402014-03-31 10:14:40 -0700154 r13 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700155 r13q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
buzbee091cc402014-03-31 10:14:40 -0700156 r14 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700157 r14q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
buzbee091cc402014-03-31 10:14:40 -0700158 r15 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700159 r15q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
buzbee091cc402014-03-31 10:14:40 -0700160 // fake return address register for core spill mask.
161 rRET = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
buzbee091cc402014-03-31 10:14:40 -0700162
Mark Mendellfe945782014-05-22 09:52:36 -0400163 // xmm registers, single precision view.
buzbee091cc402014-03-31 10:14:40 -0700164 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,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700172 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,
buzbee091cc402014-03-31 10:14:40 -0700180
Mark Mendellfe945782014-05-22 09:52:36 -0400181 // xmm registers, double precision aliases.
buzbee091cc402014-03-31 10:14:40 -0700182 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,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700190 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,
buzbee091cc402014-03-31 10:14:40 -0700198
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700199 // xmm registers, quad precision aliases
Mark Mendellfe945782014-05-22 09:52:36 -0400200 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,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700208 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,
buzbee091cc402014-03-31 10:14:40 -0700216
217 // TODO: as needed, add 256, 512 and 1024-bit xmm views.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700218};
219
buzbee091cc402014-03-31 10:14:40 -0700220constexpr RegStorage rs_r0(RegStorage::kValid | r0);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700221constexpr RegStorage rs_r0q(RegStorage::kValid | r0q);
buzbee091cc402014-03-31 10:14:40 -0700222constexpr RegStorage rs_rAX = rs_r0;
223constexpr RegStorage rs_r1(RegStorage::kValid | r1);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700224constexpr RegStorage rs_r1q(RegStorage::kValid | r1q);
buzbee091cc402014-03-31 10:14:40 -0700225constexpr RegStorage rs_rCX = rs_r1;
226constexpr RegStorage rs_r2(RegStorage::kValid | r2);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700227constexpr RegStorage rs_r2q(RegStorage::kValid | r2q);
buzbee091cc402014-03-31 10:14:40 -0700228constexpr RegStorage rs_rDX = rs_r2;
229constexpr RegStorage rs_r3(RegStorage::kValid | r3);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700230constexpr RegStorage rs_r3q(RegStorage::kValid | r3q);
buzbee091cc402014-03-31 10:14:40 -0700231constexpr RegStorage rs_rBX = rs_r3;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700232constexpr RegStorage rs_rX86_SP_64(RegStorage::kValid | r4sp_64);
233constexpr RegStorage rs_rX86_SP_32(RegStorage::kValid | r4sp_32);
234extern RegStorage rs_rX86_SP;
buzbee091cc402014-03-31 10:14:40 -0700235constexpr RegStorage rs_r5(RegStorage::kValid | r5);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700236constexpr RegStorage rs_r5q(RegStorage::kValid | r5q);
buzbee091cc402014-03-31 10:14:40 -0700237constexpr RegStorage rs_rBP = rs_r5;
238constexpr RegStorage rs_r6(RegStorage::kValid | r6);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700239constexpr RegStorage rs_r6q(RegStorage::kValid | r6q);
buzbee091cc402014-03-31 10:14:40 -0700240constexpr RegStorage rs_rSI = rs_r6;
241constexpr RegStorage rs_r7(RegStorage::kValid | r7);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700242constexpr RegStorage rs_r7q(RegStorage::kValid | r7q);
buzbee091cc402014-03-31 10:14:40 -0700243constexpr RegStorage rs_rDI = rs_r7;
244constexpr RegStorage rs_rRET(RegStorage::kValid | rRET);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700245constexpr RegStorage rs_r8(RegStorage::kValid | r8);
246constexpr RegStorage rs_r8q(RegStorage::kValid | r8q);
247constexpr RegStorage rs_r9(RegStorage::kValid | r9);
248constexpr RegStorage rs_r9q(RegStorage::kValid | r9q);
249constexpr RegStorage rs_r10(RegStorage::kValid | r10);
250constexpr RegStorage rs_r10q(RegStorage::kValid | r10q);
251constexpr RegStorage rs_r11(RegStorage::kValid | r11);
252constexpr RegStorage rs_r11q(RegStorage::kValid | r11q);
253constexpr RegStorage rs_r12(RegStorage::kValid | r12);
254constexpr RegStorage rs_r12q(RegStorage::kValid | r12q);
255constexpr RegStorage rs_r13(RegStorage::kValid | r13);
256constexpr RegStorage rs_r13q(RegStorage::kValid | r13q);
257constexpr RegStorage rs_r14(RegStorage::kValid | r14);
258constexpr RegStorage rs_r14q(RegStorage::kValid | r14q);
259constexpr RegStorage rs_r15(RegStorage::kValid | r15);
260constexpr RegStorage rs_r15q(RegStorage::kValid | r15q);
buzbee091cc402014-03-31 10:14:40 -0700261
262constexpr RegStorage rs_fr0(RegStorage::kValid | fr0);
263constexpr RegStorage rs_fr1(RegStorage::kValid | fr1);
264constexpr RegStorage rs_fr2(RegStorage::kValid | fr2);
265constexpr RegStorage rs_fr3(RegStorage::kValid | fr3);
266constexpr RegStorage rs_fr4(RegStorage::kValid | fr4);
267constexpr RegStorage rs_fr5(RegStorage::kValid | fr5);
268constexpr RegStorage rs_fr6(RegStorage::kValid | fr6);
269constexpr RegStorage rs_fr7(RegStorage::kValid | fr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700270constexpr RegStorage rs_fr8(RegStorage::kValid | fr8);
271constexpr RegStorage rs_fr9(RegStorage::kValid | fr9);
272constexpr RegStorage rs_fr10(RegStorage::kValid | fr10);
273constexpr RegStorage rs_fr11(RegStorage::kValid | fr11);
274constexpr RegStorage rs_fr12(RegStorage::kValid | fr12);
275constexpr RegStorage rs_fr13(RegStorage::kValid | fr13);
276constexpr RegStorage rs_fr14(RegStorage::kValid | fr14);
277constexpr RegStorage rs_fr15(RegStorage::kValid | fr15);
buzbee091cc402014-03-31 10:14:40 -0700278
279constexpr RegStorage rs_dr0(RegStorage::kValid | dr0);
280constexpr RegStorage rs_dr1(RegStorage::kValid | dr1);
281constexpr RegStorage rs_dr2(RegStorage::kValid | dr2);
282constexpr RegStorage rs_dr3(RegStorage::kValid | dr3);
283constexpr RegStorage rs_dr4(RegStorage::kValid | dr4);
284constexpr RegStorage rs_dr5(RegStorage::kValid | dr5);
285constexpr RegStorage rs_dr6(RegStorage::kValid | dr6);
286constexpr RegStorage rs_dr7(RegStorage::kValid | dr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700287constexpr RegStorage rs_dr8(RegStorage::kValid | dr8);
288constexpr RegStorage rs_dr9(RegStorage::kValid | dr9);
289constexpr RegStorage rs_dr10(RegStorage::kValid | dr10);
290constexpr RegStorage rs_dr11(RegStorage::kValid | dr11);
291constexpr RegStorage rs_dr12(RegStorage::kValid | dr12);
292constexpr RegStorage rs_dr13(RegStorage::kValid | dr13);
293constexpr RegStorage rs_dr14(RegStorage::kValid | dr14);
294constexpr RegStorage rs_dr15(RegStorage::kValid | dr15);
buzbee091cc402014-03-31 10:14:40 -0700295
Mark Mendellfe945782014-05-22 09:52:36 -0400296constexpr RegStorage rs_xr0(RegStorage::kValid | xr0);
297constexpr RegStorage rs_xr1(RegStorage::kValid | xr1);
298constexpr RegStorage rs_xr2(RegStorage::kValid | xr2);
299constexpr RegStorage rs_xr3(RegStorage::kValid | xr3);
300constexpr RegStorage rs_xr4(RegStorage::kValid | xr4);
301constexpr RegStorage rs_xr5(RegStorage::kValid | xr5);
302constexpr RegStorage rs_xr6(RegStorage::kValid | xr6);
303constexpr RegStorage rs_xr7(RegStorage::kValid | xr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700304constexpr RegStorage rs_xr8(RegStorage::kValid | xr8);
305constexpr RegStorage rs_xr9(RegStorage::kValid | xr9);
306constexpr RegStorage rs_xr10(RegStorage::kValid | xr10);
307constexpr RegStorage rs_xr11(RegStorage::kValid | xr11);
308constexpr RegStorage rs_xr12(RegStorage::kValid | xr12);
309constexpr RegStorage rs_xr13(RegStorage::kValid | xr13);
310constexpr RegStorage rs_xr14(RegStorage::kValid | xr14);
311constexpr RegStorage rs_xr15(RegStorage::kValid | xr15);
buzbee2700f7e2014-03-07 09:46:20 -0800312
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700313extern X86NativeRegisterPool rX86_ARG0;
314extern X86NativeRegisterPool rX86_ARG1;
315extern X86NativeRegisterPool rX86_ARG2;
316extern X86NativeRegisterPool rX86_ARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700317extern X86NativeRegisterPool rX86_ARG4;
318extern X86NativeRegisterPool rX86_ARG5;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700319extern X86NativeRegisterPool rX86_FARG0;
320extern X86NativeRegisterPool rX86_FARG1;
321extern X86NativeRegisterPool rX86_FARG2;
322extern X86NativeRegisterPool rX86_FARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700323extern X86NativeRegisterPool rX86_FARG4;
324extern X86NativeRegisterPool rX86_FARG5;
325extern X86NativeRegisterPool rX86_FARG6;
326extern X86NativeRegisterPool rX86_FARG7;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700327extern X86NativeRegisterPool rX86_RET0;
328extern X86NativeRegisterPool rX86_RET1;
329extern X86NativeRegisterPool rX86_INVOKE_TGT;
330extern X86NativeRegisterPool rX86_COUNT;
331
332extern RegStorage rs_rX86_ARG0;
333extern RegStorage rs_rX86_ARG1;
334extern RegStorage rs_rX86_ARG2;
335extern RegStorage rs_rX86_ARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700336extern RegStorage rs_rX86_ARG4;
337extern RegStorage rs_rX86_ARG5;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700338extern RegStorage rs_rX86_FARG0;
339extern RegStorage rs_rX86_FARG1;
340extern RegStorage rs_rX86_FARG2;
341extern RegStorage rs_rX86_FARG3;
Dmitry Petrochenko58994cd2014-05-17 01:02:18 +0700342extern RegStorage rs_rX86_FARG4;
343extern RegStorage rs_rX86_FARG5;
344extern RegStorage rs_rX86_FARG6;
345extern RegStorage rs_rX86_FARG7;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700346extern RegStorage rs_rX86_RET0;
347extern RegStorage rs_rX86_RET1;
348extern RegStorage rs_rX86_INVOKE_TGT;
349extern RegStorage rs_rX86_COUNT;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700350
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000351// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
352const RegLocation x86_loc_c_return
buzbee091cc402014-03-31 10:14:40 -0700353 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000354 RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
355const RegLocation x86_loc_c_return_wide
buzbee091cc402014-03-31 10:14:40 -0700356 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000357 RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
Chao-ying Fua77ee512014-07-01 17:43:41 -0700358const 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};
361const 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};
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700364const 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};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000367const RegLocation x86_loc_c_return_float
buzbee091cc402014-03-31 10:14:40 -0700368 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000369 RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000370const RegLocation x86_loc_c_return_double
buzbee091cc402014-03-31 10:14:40 -0700371 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
372 RegStorage(RegStorage::k64BitSolo, dr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000373
Brian Carlstrom7940e442013-07-12 13:46:57 -0700374/*
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 */
379enum X86OpCode {
380 kX86First = 0,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700381 kX8632BitData = kX86First, // data [31..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700382 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
Vladimir Markoe6ed00b2013-10-24 14:52:37 +0100405 // TI - Thread Immediate - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
Brian Carlstrom7940e442013-07-12 13:46:57 -0700406 // - 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, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700415 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
Brian Carlstrom7940e442013-07-12 13:46:57 -0700423 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,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700435 kX86Imul64RRI, kX86Imul64RMI, kX86Imul64RAI,
436 kX86Imul64RRI8, kX86Imul64RMI8, kX86Imul64RAI8,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700437 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,
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700443 kX86Mov32MR, kX86Mov32AR, kX86Movnti32MR, kX86Movnti32AR, kX86Mov32TR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700444 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
445 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
Mark Mendell4028a6c2014-02-19 20:06:20 -0800446 kX86Lea32RM,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700447 kX86Lea32RA,
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700448 kX86Mov64MR, kX86Mov64AR, kX86Movnti64MR, kX86Movnti64AR, kX86Mov64TR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700449 kX86Mov64RR, kX86Mov64RM, kX86Mov64RA, kX86Mov64RT,
Yixin Shou5192cbb2014-07-01 13:48:17 -0400450 kX86Mov64RI32, kX86Mov64RI64, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700451 kX86Lea64RM,
452 kX86Lea64RA,
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800453 // RRC - Register Register ConditionCode - cond_opcode reg1, reg2
454 // - lir operands - 0: reg1, 1: reg2, 2: CC
455 kX86Cmov32RRC,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700456 kX86Cmov64RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400457 // RMC - Register Memory ConditionCode - cond_opcode reg1, [base + disp]
458 // - lir operands - 0: reg1, 1: base, 2: disp 3: CC
459 kX86Cmov32RMC,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700460 kX86Cmov64RMC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400461
Brian Carlstrom7940e442013-07-12 13:46:57 -0700462 // 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, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700474 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC, \
475 opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, \
476 opcode ## 64RC, opcode ## 64MC, opcode ## 64AC
Brian Carlstrom7940e442013-07-12 13:46:57 -0700477 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,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800486 kX86Shld32RRI,
Yixin Shouf40f8902014-08-14 14:10:32 -0400487 kX86Shld32RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400488 kX86Shld32MRI,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800489 kX86Shrd32RRI,
Yixin Shouf40f8902014-08-14 14:10:32 -0400490 kX86Shrd32RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400491 kX86Shrd32MRI,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700492 kX86Shld64RRI,
493 kX86Shld64MRI,
494 kX86Shrd64RRI,
495 kX86Shrd64MRI,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700496#define UnaryOpcode(opcode, reg, mem, array) \
497 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
498 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700499 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array, \
500 opcode ## 64 ## reg, opcode ## 64 ## mem, opcode ## 64 ## array
Brian Carlstrom7940e442013-07-12 13:46:57 -0700501 UnaryOpcode(kX86Test, RI, MI, AI),
502 kX86Test32RR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700503 kX86Test64RR,
Dave Allison69dfe512014-07-11 17:11:58 +0000504 kX86Test32RM,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700505 UnaryOpcode(kX86Not, R, M, A),
506 UnaryOpcode(kX86Neg, R, M, A),
507 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
508 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
509 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
510 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
Mark Mendell2bf31e62014-01-23 12:13:40 -0800511 kx86Cdq32Da,
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700512 kx86Cqo64Da,
Vladimir Markoa8b4caf2013-10-24 15:08:57 +0100513 kX86Bswap32R,
nikolay serdjukc5e4ce12014-06-10 17:07:10 +0700514 kX86Bswap64R,
Vladimir Marko70b797d2013-12-03 15:25:24 +0000515 kX86Push32R, kX86Pop32R,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700516#undef UnaryOpcode
517#define Binary0fOpCode(opcode) \
518 opcode ## RR, opcode ## RM, opcode ## RA
519 Binary0fOpCode(kX86Movsd),
520 kX86MovsdMR,
521 kX86MovsdAR,
522 Binary0fOpCode(kX86Movss),
523 kX86MovssMR,
524 kX86MovssAR,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700525 Binary0fOpCode(kX86Cvtsi2sd), // int to double
526 Binary0fOpCode(kX86Cvtsi2ss), // int to float
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700527 Binary0fOpCode(kX86Cvtsqi2sd), // long to double
528 Binary0fOpCode(kX86Cvtsqi2ss), // long to float
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700529 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int
530 Binary0fOpCode(kX86Cvttss2si), // truncating float to int
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700531 Binary0fOpCode(kX86Cvttsd2sqi), // truncating double to long
532 Binary0fOpCode(kX86Cvttss2sqi), // truncating float to long
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700533 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
534 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
Brian Carlstrom7940e442013-07-12 13:46:57 -0700535 Binary0fOpCode(kX86Ucomisd), // unordered double compare
536 Binary0fOpCode(kX86Ucomiss), // unordered float compare
537 Binary0fOpCode(kX86Comisd), // double compare
538 Binary0fOpCode(kX86Comiss), // float compare
Alexei Zavjalov1222c962014-07-16 00:54:13 +0700539 Binary0fOpCode(kX86Orpd), // double logical OR
540 Binary0fOpCode(kX86Orps), // float logical OR
541 Binary0fOpCode(kX86Andpd), // double logical AND
542 Binary0fOpCode(kX86Andps), // float logical AND
543 Binary0fOpCode(kX86Xorpd), // double logical XOR
544 Binary0fOpCode(kX86Xorps), // float logical XOR
545 Binary0fOpCode(kX86Addsd), // double ADD
546 Binary0fOpCode(kX86Addss), // float ADD
Brian Carlstrom7940e442013-07-12 13:46:57 -0700547 Binary0fOpCode(kX86Mulsd), // double multiply
548 Binary0fOpCode(kX86Mulss), // float multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700549 Binary0fOpCode(kX86Cvtsd2ss), // double to float
550 Binary0fOpCode(kX86Cvtss2sd), // float to double
Brian Carlstrom7940e442013-07-12 13:46:57 -0700551 Binary0fOpCode(kX86Subsd), // double subtract
552 Binary0fOpCode(kX86Subss), // float subtract
553 Binary0fOpCode(kX86Divsd), // double divide
554 Binary0fOpCode(kX86Divss), // float divide
Razvan A Lupusorud3266bc2014-01-24 12:55:31 -0800555 Binary0fOpCode(kX86Punpckldq), // Interleave low-order double words
Mark Mendellfe945782014-05-22 09:52:36 -0400556 Binary0fOpCode(kX86Sqrtsd), // square root
557 Binary0fOpCode(kX86Pmulld), // parallel integer multiply 32 bits x 4
558 Binary0fOpCode(kX86Pmullw), // parallel integer multiply 16 bits x 8
559 Binary0fOpCode(kX86Mulps), // parallel FP multiply 32 bits x 4
560 Binary0fOpCode(kX86Mulpd), // parallel FP multiply 64 bits x 2
561 Binary0fOpCode(kX86Paddb), // parallel integer addition 8 bits x 16
562 Binary0fOpCode(kX86Paddw), // parallel integer addition 16 bits x 8
563 Binary0fOpCode(kX86Paddd), // parallel integer addition 32 bits x 4
564 Binary0fOpCode(kX86Addps), // parallel FP addition 32 bits x 4
565 Binary0fOpCode(kX86Addpd), // parallel FP addition 64 bits x 2
566 Binary0fOpCode(kX86Psubb), // parallel integer subtraction 8 bits x 16
567 Binary0fOpCode(kX86Psubw), // parallel integer subtraction 16 bits x 8
568 Binary0fOpCode(kX86Psubd), // parallel integer subtraction 32 bits x 4
569 Binary0fOpCode(kX86Subps), // parallel FP subtraction 32 bits x 4
570 Binary0fOpCode(kX86Subpd), // parallel FP subtraction 64 bits x 2
571 Binary0fOpCode(kX86Pand), // parallel AND 128 bits x 1
572 Binary0fOpCode(kX86Por), // parallel OR 128 bits x 1
573 Binary0fOpCode(kX86Pxor), // parallel XOR 128 bits x 1
574 Binary0fOpCode(kX86Phaddw), // parallel horizontal addition 16 bits x 8
575 Binary0fOpCode(kX86Phaddd), // parallel horizontal addition 32 bits x 4
Olivier Comefb0fecf2014-06-20 11:46:16 +0200576 Binary0fOpCode(kX86Haddpd), // parallel FP horizontal addition 64 bits x 2
577 Binary0fOpCode(kX86Haddps), // parallel FP horizontal addition 32 bits x 4
Mark Mendellfe945782014-05-22 09:52:36 -0400578 kX86PextrbRRI, // Extract 8 bits from XMM into GPR
579 kX86PextrwRRI, // Extract 16 bits from XMM into GPR
580 kX86PextrdRRI, // Extract 32 bits from XMM into GPR
Udayan Banerji60bfe7b2014-07-08 19:59:43 -0700581 kX86PextrbMRI, // Extract 8 bits from XMM into memory
582 kX86PextrwMRI, // Extract 16 bits from XMM into memory
583 kX86PextrdMRI, // Extract 32 bits from XMM into memory
Mark Mendellfe945782014-05-22 09:52:36 -0400584 kX86PshuflwRRI, // Shuffle 16 bits in lower 64 bits of XMM.
585 kX86PshufdRRI, // Shuffle 32 bits in XMM.
Olivier Comefb0fecf2014-06-20 11:46:16 +0200586 kX86ShufpsRRI, // FP Shuffle 32 bits in XMM.
587 kX86ShufpdRRI, // FP Shuffle 64 bits in XMM.
Mark Mendellfe945782014-05-22 09:52:36 -0400588 kX86PsrawRI, // signed right shift of floating point registers 16 bits x 8
589 kX86PsradRI, // signed right shift of floating point registers 32 bits x 4
590 kX86PsrlwRI, // logical right shift of floating point registers 16 bits x 8
591 kX86PsrldRI, // logical right shift of floating point registers 32 bits x 4
592 kX86PsrlqRI, // logical right shift of floating point registers 64 bits x 2
593 kX86PsllwRI, // left shift of floating point registers 16 bits x 8
594 kX86PslldRI, // left shift of floating point registers 32 bits x 4
595 kX86PsllqRI, // left shift of floating point registers 64 bits x 2
Razvan A Lupusoru614c2b42014-01-28 17:05:21 -0800596 kX86Fild32M, // push 32-bit integer on x87 stack
597 kX86Fild64M, // push 64-bit integer on x87 stack
Alexei Zavjalovbd3682e2014-06-12 03:08:01 +0700598 kX86Fld32M, // push float on x87 stack
599 kX86Fld64M, // push double on x87 stack
Razvan A Lupusoru614c2b42014-01-28 17:05:21 -0800600 kX86Fstp32M, // pop top x87 fp stack and do 32-bit store
601 kX86Fstp64M, // pop top x87 fp stack and do 64-bit store
Alexei Zavjalovbd3682e2014-06-12 03:08:01 +0700602 kX86Fst32M, // do 32-bit store
603 kX86Fst64M, // do 64-bit store
604 kX86Fprem, // remainder from dividing of two floating point values
605 kX86Fucompp, // compare floating point values and pop x87 fp stack twice
606 kX86Fstsw16R, // store FPU status word
Mark Mendelld65c51a2014-04-29 16:55:20 -0400607 Binary0fOpCode(kX86Mova128), // move 128 bits aligned
608 kX86Mova128MR, kX86Mova128AR, // store 128 bit aligned from xmm1 to m128
Razvan A Lupusoru2c498d12014-01-29 16:02:57 -0800609 Binary0fOpCode(kX86Movups), // load unaligned packed single FP values from xmm2/m128 to xmm1
610 kX86MovupsMR, kX86MovupsAR, // store unaligned packed single FP values from xmm1 to m128
611 Binary0fOpCode(kX86Movaps), // load aligned packed single FP values from xmm2/m128 to xmm1
612 kX86MovapsMR, kX86MovapsAR, // store aligned packed single FP values from xmm1 to m128
613 kX86MovlpsRM, kX86MovlpsRA, // load packed single FP values from m64 to low quadword of xmm
614 kX86MovlpsMR, kX86MovlpsAR, // store packed single FP values from low quadword of xmm to m64
615 kX86MovhpsRM, kX86MovhpsRA, // load packed single FP values from m64 to high quadword of xmm
616 kX86MovhpsMR, kX86MovhpsAR, // store packed single FP values from high quadword of xmm to m64
Brian Carlstrom7940e442013-07-12 13:46:57 -0700617 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700618 Binary0fOpCode(kX86Movqxr), // move into xmm from 64 bit gpr
619 kX86MovqrxRR, kX86MovqrxMR, kX86MovqrxAR, // move into 64 bit reg from xmm
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700620 kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR, // move into reg from xmm
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700621 kX86MovsxdRR, kX86MovsxdRM, kX86MovsxdRA, // move 32 bit to 64 bit with sign extension
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700622 kX86Set8R, kX86Set8M, kX86Set8A, // set byte depending on condition operand
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700623 kX86Lfence, // memory barrier to serialize all previous
624 // load-from-memory instructions
625 kX86Mfence, // memory barrier to serialize all previous
626 // load-from-memory and store-to-memory instructions
627 kX86Sfence, // memory barrier to serialize all previous
628 // store-to-memory instructions
Brian Carlstrom7940e442013-07-12 13:46:57 -0700629 Binary0fOpCode(kX86Imul16), // 16bit multiply
630 Binary0fOpCode(kX86Imul32), // 32bit multiply
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700631 Binary0fOpCode(kX86Imul64), // 64bit multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700632 kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR, // compare and exchange
nikolay serdjukc5e4ce12014-06-10 17:07:10 +0700633 kX86LockCmpxchgMR, kX86LockCmpxchgAR, kX86LockCmpxchg64AR, // locked compare and exchange
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700634 kX86LockCmpxchg64M, kX86LockCmpxchg64A, // locked compare and exchange
Razvan A Lupusoru99ad7232014-02-25 17:41:08 -0800635 kX86XchgMR, // exchange memory with register (automatically locked)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700636 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
637 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
638 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
639 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
Serguei Katkov1c557032014-06-23 13:23:38 +0700640 Binary0fOpCode(kX86Movzx8q), // zero-extend 8-bit value to quad word
641 Binary0fOpCode(kX86Movzx16q), // zero-extend 16-bit value to quad word
642 Binary0fOpCode(kX86Movsx8q), // sign-extend 8-bit value to quad word
643 Binary0fOpCode(kX86Movsx16q), // sign-extend 16-bit value to quad word
Brian Carlstrom7940e442013-07-12 13:46:57 -0700644#undef Binary0fOpCode
645 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
646 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned
647 kX86JmpR, // jmp reg; lir operands - 0: reg
Mark Mendell4028a6c2014-02-19 20:06:20 -0800648 kX86Jecxz8, // jcexz rel8; jump relative if ECX is zero.
Brian Carlstrom60d7a652014-03-13 18:10:08 -0700649 kX86JmpT, // jmp fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
650
Brian Carlstrom7940e442013-07-12 13:46:57 -0700651 kX86CallR, // call reg; lir operands - 0: reg
652 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
653 kX86CallA, // call [base + index * scale + disp]
654 // lir operands - 0: base, 1: index, 2: scale, 3: disp
655 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
Mark Mendell55d0eac2014-02-06 11:02:52 -0800656 kX86CallI, // call <relative> - 0: disp; Used for core.oat linking only
Brian Carlstrom7940e442013-07-12 13:46:57 -0700657 kX86Ret, // ret; no lir operands
658 kX86StartOfMethod, // call 0; pop reg; sub reg, # - generate start of method into reg
659 // lir operands - 0: reg
660 kX86PcRelLoadRA, // mov reg, [base + index * scale + PC relative displacement]
661 // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
662 kX86PcRelAdr, // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
Mark Mendell4028a6c2014-02-19 20:06:20 -0800663 kX86RepneScasw, // repne scasw
Brian Carlstrom7940e442013-07-12 13:46:57 -0700664 kX86Last
665};
666
667/* Instruction assembly field_loc kind */
668enum X86EncodingKind {
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700669 kData, // Special case for raw data.
670 kNop, // Special case for variable length nop.
671 kNullary, // Opcode that takes no arguments.
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700672 kRegOpcode, // Shorter form of R instruction kind (opcode+rd)
673 kReg, kMem, kArray, // R, M and A instruction kinds.
674 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds.
675 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds.
676 kRegRegStore, // RR following the store modrm reg-reg encoding rather than the load.
677 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
678 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
679 kMovRegImm, // Shorter form move RI.
Yixin Shou5192cbb2014-07-01 13:48:17 -0400680 kMovRegQuadImm, // 64 bit move RI
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700681 kRegRegImmStore, // RRI following the store modrm reg-reg encoding rather than the load.
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700682 kMemRegImm, // MRI instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700683 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
684 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
Yixin Shouf40f8902014-08-14 14:10:32 -0400685 kShiftRegRegCl,
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700686 // kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700687 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800688 kRegRegCond, // RR instruction kind followed by a condition.
Mark Mendell2637f2e2014-04-30 10:10:47 -0400689 kRegMemCond, // RM instruction kind followed by a condition.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700690 kJmp, kJcc, kCall, // Branch instruction kinds.
691 kPcRel, // Operation with displacement that is PC relative
692 kMacro, // An instruction composing multiple others
693 kUnimplemented // Encoding used when an instruction isn't yet implemented.
694};
695
696/* Struct used to define the EncodingMap positions for each X86 opcode */
697struct X86EncodingMap {
698 X86OpCode opcode; // e.g. kOpAddRI
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700699 // The broad category the instruction conforms to, such as kRegReg. Identifies which LIR operands
700 // hold meaning for the opcode.
701 X86EncodingKind kind;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700702 uint64_t flags;
703 struct {
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700704 uint8_t prefix1; // Non-zero => a prefix byte.
705 uint8_t prefix2; // Non-zero => a second prefix byte.
706 uint8_t opcode; // 1 byte opcode.
707 uint8_t extra_opcode1; // Possible extra opcode byte.
708 uint8_t extra_opcode2; // Possible second extra opcode byte.
709 // 3-bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
710 // encoding kind.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700711 uint8_t modrm_opcode;
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700712 uint8_t ax_opcode; // Non-zero => shorter encoding for AX as a destination.
713 uint8_t immediate_bytes; // Number of bytes of immediate.
714 // Does the instruction address a byte register? In 32-bit mode the registers ah, bh, ch and dh
715 // are not used. In 64-bit mode the REX prefix is used to normalize and allow any byte register
716 // to be addressed.
717 bool r8_form;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700718 } skeleton;
719 const char *name;
720 const char* fmt;
721};
722
723
724// FIXME: mem barrier type - what do we do for x86?
725#define kSY 0
726#define kST 0
727
728// Offsets of high and low halves of a 64bit value.
729#define LOWORD_OFFSET 0
730#define HIWORD_OFFSET 4
731
732// Segment override instruction prefix used for quick TLS access to Thread::Current().
733#define THREAD_PREFIX 0x64
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700734#define THREAD_PREFIX_GS 0x65
735
736// 64 Bit Operand Size
737#define REX_W 0x48
738// Extension of the ModR/M reg field
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700739#define REX_R 0x44
740// Extension of the SIB index field
741#define REX_X 0x42
742// Extension of the ModR/M r/m field, SIB base field, or Opcode reg field
743#define REX_B 0x41
Serguei Katkov94f3eb02014-06-24 13:23:17 +0700744// An empty REX prefix used to normalize the byte operations so that they apply to R4 through R15
Serguei Katkov1c557032014-06-23 13:23:38 +0700745#define REX 0x40
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700746// Mask extracting the least 3 bits of r0..r15
747#define kRegNumMask32 0x07
748// Value indicating that base or reg is not used
749#define NO_REG 0
Brian Carlstrom7940e442013-07-12 13:46:57 -0700750
751#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
752#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700753#define IS_SIMM32(v) ((INT64_C(-2147483648) <= (v)) && ((v) <= INT64_C(2147483647)))
Brian Carlstrom7940e442013-07-12 13:46:57 -0700754
755extern X86EncodingMap EncodingMap[kX86Last];
756extern X86ConditionCode X86ConditionEncoding(ConditionCode cond);
757
758} // namespace art
759
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700760#endif // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_