blob: d6a6a60d3d953124b680460789999328b6c67d41 [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
Andreas Gampe0b9203e2015-01-22 20:39:27 -080020#include "dex/reg_location.h"
21#include "dex/reg_storage.h"
Brian Carlstrom7940e442013-07-12 13:46:57 -070022
23namespace art {
24
25/*
Ian Rogers0177e532014-02-11 16:30:46 -080026 * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64). The ABI
27 * has different conventions and we capture those here. Changing something that is callee save and
28 * making it caller save places a burden on up-calls to save/restore the callee save register,
29 * however, there are few registers that are callee save in the ABI. Changing something that is
30 * caller save and making it callee save places a burden on down-calls to save/restore the callee
31 * save register. For these reasons we aim to match native conventions for caller and callee save.
32 * On x86 only the first 4 registers can be used for byte operations, for this reason they are
33 * preferred for temporary scratch registers.
Brian Carlstrom7940e442013-07-12 13:46:57 -070034 *
35 * General Purpose Register:
Ian Rogers0177e532014-02-11 16:30:46 -080036 * Native: x86 | x86-64 / x32 | ART x86 | ART x86-64
37 * r0/eax: caller | caller | caller, Method*, scratch, return value | caller, scratch, return value
38 * r1/ecx: caller | caller, arg4 | caller, arg1, scratch | caller, arg3, scratch
39 * r2/edx: caller | caller, arg3 | caller, arg2, scratch, high half of long return | caller, arg2, scratch
40 * r3/ebx: callEE | callEE | callER, arg3, scratch | callee, promotable
Brian Carlstrom7940e442013-07-12 13:46:57 -070041 * r4/esp: stack pointer
Ian Rogers0177e532014-02-11 16:30:46 -080042 * r5/ebp: callee | callee | callee, promotable | callee, promotable
43 * r6/esi: callEE | callER, arg2 | callee, promotable | caller, arg1, scratch
44 * r7/edi: callEE | callER, arg1 | callee, promotable | caller, Method*, scratch
Brian Carlstrom7940e442013-07-12 13:46:57 -070045 * --- x86-64/x32 registers
46 * Native: x86-64 / x32 | ART
Ian Rogers0177e532014-02-11 16:30:46 -080047 * r8: caller save, arg5 | caller, arg4, scratch
48 * r9: caller save, arg6 | caller, arg5, scratch
Brian Carlstrom7940e442013-07-12 13:46:57 -070049 * r10: caller save | caller, scratch
50 * r11: caller save | caller, scratch
Ian Rogers0177e532014-02-11 16:30:46 -080051 * r12: callee save | callee, available for register promotion (promotable)
52 * r13: callee save | callee, available for register promotion (promotable)
53 * r14: callee save | callee, available for register promotion (promotable)
54 * r15: callee save | callee, available for register promotion (promotable)
Brian Carlstrom7940e442013-07-12 13:46:57 -070055 *
56 * There is no rSELF, instead on x86 fs: has a base address of Thread::Current, whereas on
57 * x86-64/x32 gs: holds it.
58 *
59 * For floating point we don't support CPUs without SSE2 support (ie newer than PIII):
Mark P Mendell966c3ae2015-01-27 15:45:27 +000060 * Native: x86 | x86-64 / x32 | ART x86 | ART x86-64
61 * XMM0: caller | caller, arg1 | caller, arg1, float return value | caller, arg1, float return value
62 * XMM1: caller | caller, arg2 | caller, arg2, scratch | caller, arg2, scratch
63 * XMM2: caller | caller, arg3 | caller, arg3, scratch | caller, arg3, scratch
64 * XMM3: caller | caller, arg4 | caller, arg4, scratch | caller, arg4, scratch
65 * XMM4: caller | caller, arg5 | caller, scratch | caller, arg5, scratch
66 * XMM5: caller | caller, arg6 | caller, scratch | caller, arg6, scratch
67 * XMM6: caller | caller, arg7 | caller, scratch | caller, arg7, scratch
68 * XMM7: caller | caller, arg8 | caller, scratch | caller, arg8, scratch
Brian Carlstrom7940e442013-07-12 13:46:57 -070069 * --- x86-64/x32 registers
Serguei Katkovc3801912014-07-08 17:21:53 +070070 * XMM8 .. 11: caller save available as scratch registers for ART.
71 * XMM12 .. 15: callee save available as promoted registers for ART.
72 * This change (XMM12..15) is for QCG only, for others they are caller save.
Brian Carlstrom7940e442013-07-12 13:46:57 -070073 *
Ian Rogers0177e532014-02-11 16:30:46 -080074 * X87 is a necessary evil outside of ART code for x86:
Brian Carlstrom7940e442013-07-12 13:46:57 -070075 * ST0: x86 float/double native return value, caller save
76 * ST1 .. ST7: caller save
77 *
78 * Stack frame diagram (stack grows down, higher addresses at top):
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -070079 * For a more detailed view of each region see stack.h.
Brian Carlstrom7940e442013-07-12 13:46:57 -070080 *
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -070081 * +---------------------------+
82 * | IN[ins-1] | {Note: resides in caller's frame}
83 * | . |
84 * | IN[0] |
Mathieu Chartiere401d142015-04-22 13:56:20 -070085 * | caller's ArtMethod* |
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -070086 * +===========================+ {Note: start of callee's frame}
87 * | return address | {pushed by call}
88 * | spill region | {variable sized}
89 * +---------------------------+
90 * | ...filler 4-bytes... | {Note: used as 2nd word of V[locals-1] if long]
91 * +---------------------------+
92 * | V[locals-1] |
93 * | V[locals-2] |
94 * | . |
95 * | . |
96 * | V[1] |
97 * | V[0] |
98 * +---------------------------+
99 * | 0 to 12-bytes padding |
100 * +---------------------------+
101 * | compiler temp region |
102 * +---------------------------+
103 * | OUT[outs-1] |
104 * | OUT[outs-2] |
105 * | . |
106 * | OUT[0] |
Mathieu Chartiere401d142015-04-22 13:56:20 -0700107 * | ArtMethod* | <<== sp w/ 16-byte alignment
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -0700108 * +===========================+
Brian Carlstrom7940e442013-07-12 13:46:57 -0700109 */
110
Brian Carlstrom7940e442013-07-12 13:46:57 -0700111enum X86ResourceEncodingPos {
112 kX86GPReg0 = 0,
113 kX86RegSP = 4,
114 kX86FPReg0 = 16, // xmm0 .. xmm7/xmm15.
Serguei Katkove90501d2014-03-12 15:56:54 +0700115 kX86FPRegEnd = 32,
116 kX86FPStack = 33,
117 kX86RegEnd = kX86FPStack,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700118};
119
buzbee091cc402014-03-31 10:14:40 -0700120// FIXME: for 64-bit, perhaps add an X86_64NativeRegisterPool enum?
Brian Carlstrom7940e442013-07-12 13:46:57 -0700121enum X86NativeRegisterPool {
buzbee091cc402014-03-31 10:14:40 -0700122 r0 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 0,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700123 r0q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 0,
buzbee091cc402014-03-31 10:14:40 -0700124 rAX = r0,
125 r1 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 1,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700126 r1q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 1,
buzbee091cc402014-03-31 10:14:40 -0700127 rCX = r1,
128 r2 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 2,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700129 r2q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 2,
buzbee091cc402014-03-31 10:14:40 -0700130 rDX = r2,
131 r3 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 3,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700132 r3q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 3,
buzbee091cc402014-03-31 10:14:40 -0700133 rBX = r3,
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700134 r4sp_32 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 4,
135 rX86_SP_32 = r4sp_32,
136 r4sp_64 = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 4,
137 rX86_SP_64 = r4sp_64,
buzbee091cc402014-03-31 10:14:40 -0700138 r5 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 5,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700139 r5q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 5,
buzbee091cc402014-03-31 10:14:40 -0700140 rBP = r5,
141 r5sib_no_base = r5,
142 r6 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 6,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700143 r6q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 6,
buzbee091cc402014-03-31 10:14:40 -0700144 rSI = r6,
145 r7 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 7,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700146 r7q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 7,
buzbee091cc402014-03-31 10:14:40 -0700147 rDI = r7,
buzbee091cc402014-03-31 10:14:40 -0700148 r8 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 8,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700149 r8q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 8,
buzbee091cc402014-03-31 10:14:40 -0700150 r9 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 9,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700151 r9q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 9,
buzbee091cc402014-03-31 10:14:40 -0700152 r10 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 10,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700153 r10q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 10,
buzbee091cc402014-03-31 10:14:40 -0700154 r11 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 11,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700155 r11q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 11,
buzbee091cc402014-03-31 10:14:40 -0700156 r12 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 12,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700157 r12q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 12,
buzbee091cc402014-03-31 10:14:40 -0700158 r13 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 13,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700159 r13q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 13,
buzbee091cc402014-03-31 10:14:40 -0700160 r14 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 14,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700161 r14q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 14,
buzbee091cc402014-03-31 10:14:40 -0700162 r15 = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 15,
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700163 r15q = RegStorage::k64BitSolo | RegStorage::kCoreRegister | 15,
buzbee091cc402014-03-31 10:14:40 -0700164 // fake return address register for core spill mask.
165 rRET = RegStorage::k32BitSolo | RegStorage::kCoreRegister | 16,
buzbee091cc402014-03-31 10:14:40 -0700166
Mark Mendellfe945782014-05-22 09:52:36 -0400167 // xmm registers, single precision view.
buzbee091cc402014-03-31 10:14:40 -0700168 fr0 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 0,
169 fr1 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 1,
170 fr2 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 2,
171 fr3 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 3,
172 fr4 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 4,
173 fr5 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 5,
174 fr6 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 6,
175 fr7 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 7,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700176 fr8 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 8,
177 fr9 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 9,
178 fr10 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 10,
179 fr11 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 11,
180 fr12 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 12,
181 fr13 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 13,
182 fr14 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 14,
183 fr15 = RegStorage::k32BitSolo | RegStorage::kFloatingPoint | 15,
buzbee091cc402014-03-31 10:14:40 -0700184
Mark Mendellfe945782014-05-22 09:52:36 -0400185 // xmm registers, double precision aliases.
buzbee091cc402014-03-31 10:14:40 -0700186 dr0 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 0,
187 dr1 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 1,
188 dr2 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 2,
189 dr3 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 3,
190 dr4 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 4,
191 dr5 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 5,
192 dr6 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 6,
193 dr7 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 7,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700194 dr8 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 8,
195 dr9 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 9,
196 dr10 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 10,
197 dr11 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 11,
198 dr12 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 12,
199 dr13 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 13,
200 dr14 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 14,
201 dr15 = RegStorage::k64BitSolo | RegStorage::kFloatingPoint | 15,
buzbee091cc402014-03-31 10:14:40 -0700202
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700203 // xmm registers, quad precision aliases
Mark Mendellfe945782014-05-22 09:52:36 -0400204 xr0 = RegStorage::k128BitSolo | 0,
205 xr1 = RegStorage::k128BitSolo | 1,
206 xr2 = RegStorage::k128BitSolo | 2,
207 xr3 = RegStorage::k128BitSolo | 3,
208 xr4 = RegStorage::k128BitSolo | 4,
209 xr5 = RegStorage::k128BitSolo | 5,
210 xr6 = RegStorage::k128BitSolo | 6,
211 xr7 = RegStorage::k128BitSolo | 7,
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700212 xr8 = RegStorage::k128BitSolo | 8,
213 xr9 = RegStorage::k128BitSolo | 9,
214 xr10 = RegStorage::k128BitSolo | 10,
215 xr11 = RegStorage::k128BitSolo | 11,
216 xr12 = RegStorage::k128BitSolo | 12,
217 xr13 = RegStorage::k128BitSolo | 13,
218 xr14 = RegStorage::k128BitSolo | 14,
219 xr15 = RegStorage::k128BitSolo | 15,
buzbee091cc402014-03-31 10:14:40 -0700220
Mark Mendell27dee8b2014-12-01 19:06:12 -0500221 // Special value for RIP 64 bit addressing.
222 kRIPReg = 255,
223
buzbee091cc402014-03-31 10:14:40 -0700224 // TODO: as needed, add 256, 512 and 1024-bit xmm views.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700225};
226
buzbee091cc402014-03-31 10:14:40 -0700227constexpr RegStorage rs_r0(RegStorage::kValid | r0);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700228constexpr RegStorage rs_r0q(RegStorage::kValid | r0q);
buzbee091cc402014-03-31 10:14:40 -0700229constexpr RegStorage rs_rAX = rs_r0;
230constexpr RegStorage rs_r1(RegStorage::kValid | r1);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700231constexpr RegStorage rs_r1q(RegStorage::kValid | r1q);
buzbee091cc402014-03-31 10:14:40 -0700232constexpr RegStorage rs_rCX = rs_r1;
233constexpr RegStorage rs_r2(RegStorage::kValid | r2);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700234constexpr RegStorage rs_r2q(RegStorage::kValid | r2q);
buzbee091cc402014-03-31 10:14:40 -0700235constexpr RegStorage rs_rDX = rs_r2;
236constexpr RegStorage rs_r3(RegStorage::kValid | r3);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700237constexpr RegStorage rs_r3q(RegStorage::kValid | r3q);
buzbee091cc402014-03-31 10:14:40 -0700238constexpr RegStorage rs_rBX = rs_r3;
Dmitry Petrochenko9ee801f2014-05-12 11:31:37 +0700239constexpr RegStorage rs_rX86_SP_64(RegStorage::kValid | r4sp_64);
240constexpr RegStorage rs_rX86_SP_32(RegStorage::kValid | r4sp_32);
Ian Rogersb28c1c02014-11-08 11:21:21 -0800241static_assert(rs_rX86_SP_64.GetRegNum() == rs_rX86_SP_32.GetRegNum(), "Unexpected mismatch");
buzbee091cc402014-03-31 10:14:40 -0700242constexpr RegStorage rs_r5(RegStorage::kValid | r5);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700243constexpr RegStorage rs_r5q(RegStorage::kValid | r5q);
buzbee091cc402014-03-31 10:14:40 -0700244constexpr RegStorage rs_rBP = rs_r5;
245constexpr RegStorage rs_r6(RegStorage::kValid | r6);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700246constexpr RegStorage rs_r6q(RegStorage::kValid | r6q);
buzbee091cc402014-03-31 10:14:40 -0700247constexpr RegStorage rs_rSI = rs_r6;
248constexpr RegStorage rs_r7(RegStorage::kValid | r7);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700249constexpr RegStorage rs_r7q(RegStorage::kValid | r7q);
buzbee091cc402014-03-31 10:14:40 -0700250constexpr RegStorage rs_rDI = rs_r7;
251constexpr RegStorage rs_rRET(RegStorage::kValid | rRET);
Dmitry Petrochenko0999a6f2014-05-22 12:26:50 +0700252constexpr RegStorage rs_r8(RegStorage::kValid | r8);
253constexpr RegStorage rs_r8q(RegStorage::kValid | r8q);
254constexpr RegStorage rs_r9(RegStorage::kValid | r9);
255constexpr RegStorage rs_r9q(RegStorage::kValid | r9q);
256constexpr RegStorage rs_r10(RegStorage::kValid | r10);
257constexpr RegStorage rs_r10q(RegStorage::kValid | r10q);
258constexpr RegStorage rs_r11(RegStorage::kValid | r11);
259constexpr RegStorage rs_r11q(RegStorage::kValid | r11q);
260constexpr RegStorage rs_r12(RegStorage::kValid | r12);
261constexpr RegStorage rs_r12q(RegStorage::kValid | r12q);
262constexpr RegStorage rs_r13(RegStorage::kValid | r13);
263constexpr RegStorage rs_r13q(RegStorage::kValid | r13q);
264constexpr RegStorage rs_r14(RegStorage::kValid | r14);
265constexpr RegStorage rs_r14q(RegStorage::kValid | r14q);
266constexpr RegStorage rs_r15(RegStorage::kValid | r15);
267constexpr RegStorage rs_r15q(RegStorage::kValid | r15q);
buzbee091cc402014-03-31 10:14:40 -0700268
269constexpr RegStorage rs_fr0(RegStorage::kValid | fr0);
270constexpr RegStorage rs_fr1(RegStorage::kValid | fr1);
271constexpr RegStorage rs_fr2(RegStorage::kValid | fr2);
272constexpr RegStorage rs_fr3(RegStorage::kValid | fr3);
273constexpr RegStorage rs_fr4(RegStorage::kValid | fr4);
274constexpr RegStorage rs_fr5(RegStorage::kValid | fr5);
275constexpr RegStorage rs_fr6(RegStorage::kValid | fr6);
276constexpr RegStorage rs_fr7(RegStorage::kValid | fr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700277constexpr RegStorage rs_fr8(RegStorage::kValid | fr8);
278constexpr RegStorage rs_fr9(RegStorage::kValid | fr9);
279constexpr RegStorage rs_fr10(RegStorage::kValid | fr10);
280constexpr RegStorage rs_fr11(RegStorage::kValid | fr11);
281constexpr RegStorage rs_fr12(RegStorage::kValid | fr12);
282constexpr RegStorage rs_fr13(RegStorage::kValid | fr13);
283constexpr RegStorage rs_fr14(RegStorage::kValid | fr14);
284constexpr RegStorage rs_fr15(RegStorage::kValid | fr15);
buzbee091cc402014-03-31 10:14:40 -0700285
286constexpr RegStorage rs_dr0(RegStorage::kValid | dr0);
287constexpr RegStorage rs_dr1(RegStorage::kValid | dr1);
288constexpr RegStorage rs_dr2(RegStorage::kValid | dr2);
289constexpr RegStorage rs_dr3(RegStorage::kValid | dr3);
290constexpr RegStorage rs_dr4(RegStorage::kValid | dr4);
291constexpr RegStorage rs_dr5(RegStorage::kValid | dr5);
292constexpr RegStorage rs_dr6(RegStorage::kValid | dr6);
293constexpr RegStorage rs_dr7(RegStorage::kValid | dr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700294constexpr RegStorage rs_dr8(RegStorage::kValid | dr8);
295constexpr RegStorage rs_dr9(RegStorage::kValid | dr9);
296constexpr RegStorage rs_dr10(RegStorage::kValid | dr10);
297constexpr RegStorage rs_dr11(RegStorage::kValid | dr11);
298constexpr RegStorage rs_dr12(RegStorage::kValid | dr12);
299constexpr RegStorage rs_dr13(RegStorage::kValid | dr13);
300constexpr RegStorage rs_dr14(RegStorage::kValid | dr14);
301constexpr RegStorage rs_dr15(RegStorage::kValid | dr15);
buzbee091cc402014-03-31 10:14:40 -0700302
Mark Mendellfe945782014-05-22 09:52:36 -0400303constexpr RegStorage rs_xr0(RegStorage::kValid | xr0);
304constexpr RegStorage rs_xr1(RegStorage::kValid | xr1);
305constexpr RegStorage rs_xr2(RegStorage::kValid | xr2);
306constexpr RegStorage rs_xr3(RegStorage::kValid | xr3);
307constexpr RegStorage rs_xr4(RegStorage::kValid | xr4);
308constexpr RegStorage rs_xr5(RegStorage::kValid | xr5);
309constexpr RegStorage rs_xr6(RegStorage::kValid | xr6);
310constexpr RegStorage rs_xr7(RegStorage::kValid | xr7);
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700311constexpr RegStorage rs_xr8(RegStorage::kValid | xr8);
312constexpr RegStorage rs_xr9(RegStorage::kValid | xr9);
313constexpr RegStorage rs_xr10(RegStorage::kValid | xr10);
314constexpr RegStorage rs_xr11(RegStorage::kValid | xr11);
315constexpr RegStorage rs_xr12(RegStorage::kValid | xr12);
316constexpr RegStorage rs_xr13(RegStorage::kValid | xr13);
317constexpr RegStorage rs_xr14(RegStorage::kValid | xr14);
318constexpr RegStorage rs_xr15(RegStorage::kValid | xr15);
buzbee2700f7e2014-03-07 09:46:20 -0800319
Ian Rogersb28c1c02014-11-08 11:21:21 -0800320constexpr RegStorage rs_rX86_RET0 = rs_rAX;
321constexpr RegStorage rs_rX86_RET1 = rs_rDX;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700322
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000323// RegisterLocation templates return values (r_V0, or r_V0/r_V1).
324const RegLocation x86_loc_c_return
buzbee091cc402014-03-31 10:14:40 -0700325 {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000326 RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
327const RegLocation x86_loc_c_return_wide
buzbee091cc402014-03-31 10:14:40 -0700328 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000329 RegStorage(RegStorage::k64BitPair, rAX, rDX), INVALID_SREG, INVALID_SREG};
Chao-ying Fua77ee512014-07-01 17:43:41 -0700330const RegLocation x86_loc_c_return_ref
331 {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
332 RegStorage(RegStorage::k32BitSolo, rAX), INVALID_SREG, INVALID_SREG};
333const RegLocation x86_64_loc_c_return_ref
334 {kLocPhysReg, 0, 0, 0, 0, 0, 1, 0, 1,
335 RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700336const RegLocation x86_64_loc_c_return_wide
337 {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1,
338 RegStorage(RegStorage::k64BitSolo, rAX), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000339const RegLocation x86_loc_c_return_float
buzbee091cc402014-03-31 10:14:40 -0700340 {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1,
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000341 RegStorage(RegStorage::k32BitSolo, fr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000342const RegLocation x86_loc_c_return_double
buzbee091cc402014-03-31 10:14:40 -0700343 {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1,
344 RegStorage(RegStorage::k64BitSolo, dr0), INVALID_SREG, INVALID_SREG};
Bill Buzbee00e1ec62014-02-27 23:44:13 +0000345
Brian Carlstrom7940e442013-07-12 13:46:57 -0700346/*
347 * The following enum defines the list of supported X86 instructions by the
348 * assembler. Their corresponding EncodingMap positions will be defined in
349 * Assemble.cc.
350 */
351enum X86OpCode {
352 kX86First = 0,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700353 kX8632BitData = kX86First, // data [31..0].
Brian Carlstrom7940e442013-07-12 13:46:57 -0700354 kX86Bkpt,
355 kX86Nop,
356 // Define groups of binary operations
357 // MR - Memory Register - opcode [base + disp], reg
358 // - lir operands - 0: base, 1: disp, 2: reg
359 // AR - Array Register - opcode [base + index * scale + disp], reg
360 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
361 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
362 // - lir operands - 0: disp, 1: reg
363 // RR - Register Register - opcode reg1, reg2
364 // - lir operands - 0: reg1, 1: reg2
365 // RM - Register Memory - opcode reg, [base + disp]
366 // - lir operands - 0: reg, 1: base, 2: disp
367 // RA - Register Array - opcode reg, [base + index * scale + disp]
368 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
369 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
370 // - lir operands - 0: reg, 1: disp
371 // RI - Register Immediate - opcode reg, #immediate
372 // - lir operands - 0: reg, 1: immediate
373 // MI - Memory Immediate - opcode [base + disp], #immediate
374 // - lir operands - 0: base, 1: disp, 2: immediate
375 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
376 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
Vladimir Markoe6ed00b2013-10-24 14:52:37 +0100377 // TI - Thread Immediate - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
Brian Carlstrom7940e442013-07-12 13:46:57 -0700378 // - lir operands - 0: disp, 1: imm
379#define BinaryOpCode(opcode) \
380 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
381 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
382 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
383 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
384 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
385 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
386 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700387 opcode ## 32MR, opcode ## 32AR, opcode ## 32TR, \
388 opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
389 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
390 opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8, \
391 opcode ## 64MR, opcode ## 64AR, opcode ## 64TR, \
392 opcode ## 64RR, opcode ## 64RM, opcode ## 64RA, opcode ## 64RT, \
393 opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, opcode ## 64TI, \
394 opcode ## 64RI8, opcode ## 64MI8, opcode ## 64AI8, opcode ## 64TI8
Brian Carlstrom7940e442013-07-12 13:46:57 -0700395 BinaryOpCode(kX86Add),
396 BinaryOpCode(kX86Or),
397 BinaryOpCode(kX86Adc),
398 BinaryOpCode(kX86Sbb),
399 BinaryOpCode(kX86And),
400 BinaryOpCode(kX86Sub),
401 BinaryOpCode(kX86Xor),
402 BinaryOpCode(kX86Cmp),
403#undef BinaryOpCode
404 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
405 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
406 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700407 kX86Imul64RRI, kX86Imul64RMI, kX86Imul64RAI,
408 kX86Imul64RRI8, kX86Imul64RMI8, kX86Imul64RAI8,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700409 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
410 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
411 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
412 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
413 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
414 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700415 kX86Mov32MR, kX86Mov32AR, kX86Movnti32MR, kX86Movnti32AR, kX86Mov32TR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700416 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
417 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
Mark Mendell4028a6c2014-02-19 20:06:20 -0800418 kX86Lea32RM,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700419 kX86Lea32RA,
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700420 kX86Mov64MR, kX86Mov64AR, kX86Movnti64MR, kX86Movnti64AR, kX86Mov64TR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700421 kX86Mov64RR, kX86Mov64RM, kX86Mov64RA, kX86Mov64RT,
Yixin Shou5192cbb2014-07-01 13:48:17 -0400422 kX86Mov64RI32, kX86Mov64RI64, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700423 kX86Lea64RM,
424 kX86Lea64RA,
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800425 // RRC - Register Register ConditionCode - cond_opcode reg1, reg2
426 // - lir operands - 0: reg1, 1: reg2, 2: CC
427 kX86Cmov32RRC,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700428 kX86Cmov64RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400429 // RMC - Register Memory ConditionCode - cond_opcode reg1, [base + disp]
430 // - lir operands - 0: reg1, 1: base, 2: disp 3: CC
431 kX86Cmov32RMC,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700432 kX86Cmov64RMC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400433
Brian Carlstrom7940e442013-07-12 13:46:57 -0700434 // RC - Register CL - opcode reg, CL
435 // - lir operands - 0: reg, 1: CL
436 // MC - Memory CL - opcode [base + disp], CL
437 // - lir operands - 0: base, 1: disp, 2: CL
438 // AC - Array CL - opcode [base + index * scale + disp], CL
439 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
440#define BinaryShiftOpCode(opcode) \
441 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
442 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
443 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
444 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
445 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700446 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC, \
447 opcode ## 64RI, opcode ## 64MI, opcode ## 64AI, \
448 opcode ## 64RC, opcode ## 64MC, opcode ## 64AC
Brian Carlstrom7940e442013-07-12 13:46:57 -0700449 BinaryShiftOpCode(kX86Rol),
450 BinaryShiftOpCode(kX86Ror),
451 BinaryShiftOpCode(kX86Rcl),
452 BinaryShiftOpCode(kX86Rcr),
453 BinaryShiftOpCode(kX86Sal),
454 BinaryShiftOpCode(kX86Shr),
455 BinaryShiftOpCode(kX86Sar),
456#undef BinaryShiftOpcode
457 kX86Cmc,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800458 kX86Shld32RRI,
Yixin Shouf40f8902014-08-14 14:10:32 -0400459 kX86Shld32RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400460 kX86Shld32MRI,
Mark Mendell4708dcd2014-01-22 09:05:18 -0800461 kX86Shrd32RRI,
Yixin Shouf40f8902014-08-14 14:10:32 -0400462 kX86Shrd32RRC,
Mark Mendell2637f2e2014-04-30 10:10:47 -0400463 kX86Shrd32MRI,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700464 kX86Shld64RRI,
465 kX86Shld64MRI,
466 kX86Shrd64RRI,
467 kX86Shrd64MRI,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700468#define UnaryOpcode(opcode, reg, mem, array) \
469 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
470 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700471 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array, \
472 opcode ## 64 ## reg, opcode ## 64 ## mem, opcode ## 64 ## array
Brian Carlstrom7940e442013-07-12 13:46:57 -0700473 UnaryOpcode(kX86Test, RI, MI, AI),
474 kX86Test32RR,
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700475 kX86Test64RR,
Dave Allison69dfe512014-07-11 17:11:58 +0000476 kX86Test32RM,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700477 UnaryOpcode(kX86Not, R, M, A),
478 UnaryOpcode(kX86Neg, R, M, A),
479 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
480 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
481 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
482 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
Mark Mendell2bf31e62014-01-23 12:13:40 -0800483 kx86Cdq32Da,
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700484 kx86Cqo64Da,
Vladimir Markoa8b4caf2013-10-24 15:08:57 +0100485 kX86Bswap32R,
nikolay serdjukc5e4ce12014-06-10 17:07:10 +0700486 kX86Bswap64R,
Vladimir Marko70b797d2013-12-03 15:25:24 +0000487 kX86Push32R, kX86Pop32R,
Brian Carlstrom7940e442013-07-12 13:46:57 -0700488#undef UnaryOpcode
489#define Binary0fOpCode(opcode) \
490 opcode ## RR, opcode ## RM, opcode ## RA
491 Binary0fOpCode(kX86Movsd),
492 kX86MovsdMR,
493 kX86MovsdAR,
494 Binary0fOpCode(kX86Movss),
495 kX86MovssMR,
496 kX86MovssAR,
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700497 Binary0fOpCode(kX86Cvtsi2sd), // int to double
498 Binary0fOpCode(kX86Cvtsi2ss), // int to float
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700499 Binary0fOpCode(kX86Cvtsqi2sd), // long to double
500 Binary0fOpCode(kX86Cvtsqi2ss), // long to float
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700501 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int
502 Binary0fOpCode(kX86Cvttss2si), // truncating float to int
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700503 Binary0fOpCode(kX86Cvttsd2sqi), // truncating double to long
504 Binary0fOpCode(kX86Cvttss2sqi), // truncating float to long
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700505 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
506 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
Brian Carlstrom7940e442013-07-12 13:46:57 -0700507 Binary0fOpCode(kX86Ucomisd), // unordered double compare
508 Binary0fOpCode(kX86Ucomiss), // unordered float compare
509 Binary0fOpCode(kX86Comisd), // double compare
510 Binary0fOpCode(kX86Comiss), // float compare
Alexei Zavjalov1222c962014-07-16 00:54:13 +0700511 Binary0fOpCode(kX86Orpd), // double logical OR
512 Binary0fOpCode(kX86Orps), // float logical OR
513 Binary0fOpCode(kX86Andpd), // double logical AND
514 Binary0fOpCode(kX86Andps), // float logical AND
515 Binary0fOpCode(kX86Xorpd), // double logical XOR
516 Binary0fOpCode(kX86Xorps), // float logical XOR
517 Binary0fOpCode(kX86Addsd), // double ADD
518 Binary0fOpCode(kX86Addss), // float ADD
Brian Carlstrom7940e442013-07-12 13:46:57 -0700519 Binary0fOpCode(kX86Mulsd), // double multiply
520 Binary0fOpCode(kX86Mulss), // float multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700521 Binary0fOpCode(kX86Cvtsd2ss), // double to float
522 Binary0fOpCode(kX86Cvtss2sd), // float to double
Brian Carlstrom7940e442013-07-12 13:46:57 -0700523 Binary0fOpCode(kX86Subsd), // double subtract
524 Binary0fOpCode(kX86Subss), // float subtract
525 Binary0fOpCode(kX86Divsd), // double divide
526 Binary0fOpCode(kX86Divss), // float divide
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700527 Binary0fOpCode(kX86Punpcklbw), // Interleave low-order bytes
528 Binary0fOpCode(kX86Punpcklwd), // Interleave low-order single words (16-bits)
529 Binary0fOpCode(kX86Punpckldq), // Interleave low-order double words (32-bit)
530 Binary0fOpCode(kX86Punpcklqdq), // Interleave low-order quad word
Mark Mendellfe945782014-05-22 09:52:36 -0400531 Binary0fOpCode(kX86Sqrtsd), // square root
532 Binary0fOpCode(kX86Pmulld), // parallel integer multiply 32 bits x 4
533 Binary0fOpCode(kX86Pmullw), // parallel integer multiply 16 bits x 8
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700534 Binary0fOpCode(kX86Pmuludq), // parallel unsigned 32 integer and stores result as 64
Mark Mendellfe945782014-05-22 09:52:36 -0400535 Binary0fOpCode(kX86Mulps), // parallel FP multiply 32 bits x 4
536 Binary0fOpCode(kX86Mulpd), // parallel FP multiply 64 bits x 2
537 Binary0fOpCode(kX86Paddb), // parallel integer addition 8 bits x 16
538 Binary0fOpCode(kX86Paddw), // parallel integer addition 16 bits x 8
539 Binary0fOpCode(kX86Paddd), // parallel integer addition 32 bits x 4
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700540 Binary0fOpCode(kX86Paddq), // parallel integer addition 64 bits x 2
541 Binary0fOpCode(kX86Psadbw), // computes sum of absolute differences for unsigned byte integers
Mark Mendellfe945782014-05-22 09:52:36 -0400542 Binary0fOpCode(kX86Addps), // parallel FP addition 32 bits x 4
543 Binary0fOpCode(kX86Addpd), // parallel FP addition 64 bits x 2
544 Binary0fOpCode(kX86Psubb), // parallel integer subtraction 8 bits x 16
545 Binary0fOpCode(kX86Psubw), // parallel integer subtraction 16 bits x 8
546 Binary0fOpCode(kX86Psubd), // parallel integer subtraction 32 bits x 4
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700547 Binary0fOpCode(kX86Psubq), // parallel integer subtraction 32 bits x 4
Mark Mendellfe945782014-05-22 09:52:36 -0400548 Binary0fOpCode(kX86Subps), // parallel FP subtraction 32 bits x 4
549 Binary0fOpCode(kX86Subpd), // parallel FP subtraction 64 bits x 2
550 Binary0fOpCode(kX86Pand), // parallel AND 128 bits x 1
551 Binary0fOpCode(kX86Por), // parallel OR 128 bits x 1
552 Binary0fOpCode(kX86Pxor), // parallel XOR 128 bits x 1
553 Binary0fOpCode(kX86Phaddw), // parallel horizontal addition 16 bits x 8
554 Binary0fOpCode(kX86Phaddd), // parallel horizontal addition 32 bits x 4
Olivier Comefb0fecf2014-06-20 11:46:16 +0200555 Binary0fOpCode(kX86Haddpd), // parallel FP horizontal addition 64 bits x 2
556 Binary0fOpCode(kX86Haddps), // parallel FP horizontal addition 32 bits x 4
Mark Mendellfe945782014-05-22 09:52:36 -0400557 kX86PextrbRRI, // Extract 8 bits from XMM into GPR
558 kX86PextrwRRI, // Extract 16 bits from XMM into GPR
559 kX86PextrdRRI, // Extract 32 bits from XMM into GPR
Udayan Banerji60bfe7b2014-07-08 19:59:43 -0700560 kX86PextrbMRI, // Extract 8 bits from XMM into memory
561 kX86PextrwMRI, // Extract 16 bits from XMM into memory
562 kX86PextrdMRI, // Extract 32 bits from XMM into memory
Mark Mendellfe945782014-05-22 09:52:36 -0400563 kX86PshuflwRRI, // Shuffle 16 bits in lower 64 bits of XMM.
564 kX86PshufdRRI, // Shuffle 32 bits in XMM.
Olivier Comefb0fecf2014-06-20 11:46:16 +0200565 kX86ShufpsRRI, // FP Shuffle 32 bits in XMM.
566 kX86ShufpdRRI, // FP Shuffle 64 bits in XMM.
Mark Mendellfe945782014-05-22 09:52:36 -0400567 kX86PsrawRI, // signed right shift of floating point registers 16 bits x 8
568 kX86PsradRI, // signed right shift of floating point registers 32 bits x 4
569 kX86PsrlwRI, // logical right shift of floating point registers 16 bits x 8
570 kX86PsrldRI, // logical right shift of floating point registers 32 bits x 4
571 kX86PsrlqRI, // logical right shift of floating point registers 64 bits x 2
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700572 kX86PsrldqRI, // logical shift of 128-bit vector register, immediate in bytes
Mark Mendellfe945782014-05-22 09:52:36 -0400573 kX86PsllwRI, // left shift of floating point registers 16 bits x 8
574 kX86PslldRI, // left shift of floating point registers 32 bits x 4
575 kX86PsllqRI, // left shift of floating point registers 64 bits x 2
Razvan A Lupusoru614c2b42014-01-28 17:05:21 -0800576 kX86Fild32M, // push 32-bit integer on x87 stack
577 kX86Fild64M, // push 64-bit integer on x87 stack
Alexei Zavjalovbd3682e2014-06-12 03:08:01 +0700578 kX86Fld32M, // push float on x87 stack
579 kX86Fld64M, // push double on x87 stack
Razvan A Lupusoru614c2b42014-01-28 17:05:21 -0800580 kX86Fstp32M, // pop top x87 fp stack and do 32-bit store
581 kX86Fstp64M, // pop top x87 fp stack and do 64-bit store
Alexei Zavjalovbd3682e2014-06-12 03:08:01 +0700582 kX86Fst32M, // do 32-bit store
583 kX86Fst64M, // do 64-bit store
584 kX86Fprem, // remainder from dividing of two floating point values
585 kX86Fucompp, // compare floating point values and pop x87 fp stack twice
586 kX86Fstsw16R, // store FPU status word
Lupusoru, Razvan Ab3a84e22014-07-28 14:11:01 -0700587 Binary0fOpCode(kX86Movdqa), // move 128 bits aligned
588 kX86MovdqaMR, kX86MovdqaAR, // store 128 bit aligned from xmm1 to m128
Razvan A Lupusoru2c498d12014-01-29 16:02:57 -0800589 Binary0fOpCode(kX86Movups), // load unaligned packed single FP values from xmm2/m128 to xmm1
590 kX86MovupsMR, kX86MovupsAR, // store unaligned packed single FP values from xmm1 to m128
591 Binary0fOpCode(kX86Movaps), // load aligned packed single FP values from xmm2/m128 to xmm1
592 kX86MovapsMR, kX86MovapsAR, // store aligned packed single FP values from xmm1 to m128
593 kX86MovlpsRM, kX86MovlpsRA, // load packed single FP values from m64 to low quadword of xmm
594 kX86MovlpsMR, kX86MovlpsAR, // store packed single FP values from low quadword of xmm to m64
595 kX86MovhpsRM, kX86MovhpsRA, // load packed single FP values from m64 to high quadword of xmm
596 kX86MovhpsMR, kX86MovhpsAR, // store packed single FP values from high quadword of xmm to m64
Brian Carlstrom7940e442013-07-12 13:46:57 -0700597 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700598 Binary0fOpCode(kX86Movqxr), // move into xmm from 64 bit gpr
599 kX86MovqrxRR, kX86MovqrxMR, kX86MovqrxAR, // move into 64 bit reg from xmm
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700600 kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR, // move into reg from xmm
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700601 kX86MovsxdRR, kX86MovsxdRM, kX86MovsxdRA, // move 32 bit to 64 bit with sign extension
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700602 kX86Set8R, kX86Set8M, kX86Set8A, // set byte depending on condition operand
Jean Christophe Beylerb5bce7c2014-07-25 12:32:18 -0700603 kX86Lfence, // memory barrier to serialize all previous
604 // load-from-memory instructions
605 kX86Mfence, // memory barrier to serialize all previous
606 // load-from-memory and store-to-memory instructions
607 kX86Sfence, // memory barrier to serialize all previous
608 // store-to-memory instructions
Brian Carlstrom7940e442013-07-12 13:46:57 -0700609 Binary0fOpCode(kX86Imul16), // 16bit multiply
610 Binary0fOpCode(kX86Imul32), // 32bit multiply
Chao-ying Fue0ccdc02014-06-06 17:32:37 -0700611 Binary0fOpCode(kX86Imul64), // 64bit multiply
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700612 kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR, // compare and exchange
nikolay serdjukc5e4ce12014-06-10 17:07:10 +0700613 kX86LockCmpxchgMR, kX86LockCmpxchgAR, kX86LockCmpxchg64AR, // locked compare and exchange
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700614 kX86LockCmpxchg64M, kX86LockCmpxchg64A, // locked compare and exchange
Razvan A Lupusoru99ad7232014-02-25 17:41:08 -0800615 kX86XchgMR, // exchange memory with register (automatically locked)
Brian Carlstrom7940e442013-07-12 13:46:57 -0700616 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
617 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
618 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
619 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
Serguei Katkov1c557032014-06-23 13:23:38 +0700620 Binary0fOpCode(kX86Movzx8q), // zero-extend 8-bit value to quad word
621 Binary0fOpCode(kX86Movzx16q), // zero-extend 16-bit value to quad word
622 Binary0fOpCode(kX86Movsx8q), // sign-extend 8-bit value to quad word
623 Binary0fOpCode(kX86Movsx16q), // sign-extend 16-bit value to quad word
Brian Carlstrom7940e442013-07-12 13:46:57 -0700624#undef Binary0fOpCode
625 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
626 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned
627 kX86JmpR, // jmp reg; lir operands - 0: reg
Mark Mendell4028a6c2014-02-19 20:06:20 -0800628 kX86Jecxz8, // jcexz rel8; jump relative if ECX is zero.
Brian Carlstrom60d7a652014-03-13 18:10:08 -0700629 kX86JmpT, // jmp fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
630
Brian Carlstrom7940e442013-07-12 13:46:57 -0700631 kX86CallR, // call reg; lir operands - 0: reg
632 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
633 kX86CallA, // call [base + index * scale + disp]
634 // lir operands - 0: base, 1: index, 2: scale, 3: disp
635 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
Mark Mendell55d0eac2014-02-06 11:02:52 -0800636 kX86CallI, // call <relative> - 0: disp; Used for core.oat linking only
Brian Carlstrom7940e442013-07-12 13:46:57 -0700637 kX86Ret, // ret; no lir operands
Brian Carlstrom7940e442013-07-12 13:46:57 -0700638 kX86PcRelLoadRA, // mov reg, [base + index * scale + PC relative displacement]
639 // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
640 kX86PcRelAdr, // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
Mark Mendell4028a6c2014-02-19 20:06:20 -0800641 kX86RepneScasw, // repne scasw
Brian Carlstrom7940e442013-07-12 13:46:57 -0700642 kX86Last
643};
Ian Rogers6a3c1fc2014-10-31 00:33:20 -0700644std::ostream& operator<<(std::ostream& os, const X86OpCode& rhs);
Brian Carlstrom7940e442013-07-12 13:46:57 -0700645
646/* Instruction assembly field_loc kind */
647enum X86EncodingKind {
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700648 kData, // Special case for raw data.
649 kNop, // Special case for variable length nop.
650 kNullary, // Opcode that takes no arguments.
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700651 kRegOpcode, // Shorter form of R instruction kind (opcode+rd)
652 kReg, kMem, kArray, // R, M and A instruction kinds.
653 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds.
654 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds.
655 kRegRegStore, // RR following the store modrm reg-reg encoding rather than the load.
656 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
657 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
658 kMovRegImm, // Shorter form move RI.
Yixin Shou5192cbb2014-07-01 13:48:17 -0400659 kMovRegQuadImm, // 64 bit move RI
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700660 kRegRegImmStore, // RRI following the store modrm reg-reg encoding rather than the load.
Dmitry Petrochenko96992e82014-05-20 04:03:46 +0700661 kMemRegImm, // MRI instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700662 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
663 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
Yixin Shouf40f8902014-08-14 14:10:32 -0400664 kShiftRegRegCl,
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700665 // kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700666 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
Razvan A Lupusorubd288c22013-12-20 17:27:23 -0800667 kRegRegCond, // RR instruction kind followed by a condition.
Mark Mendell2637f2e2014-04-30 10:10:47 -0400668 kRegMemCond, // RM instruction kind followed by a condition.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700669 kJmp, kJcc, kCall, // Branch instruction kinds.
670 kPcRel, // Operation with displacement that is PC relative
Brian Carlstrom7940e442013-07-12 13:46:57 -0700671 kUnimplemented // Encoding used when an instruction isn't yet implemented.
672};
673
674/* Struct used to define the EncodingMap positions for each X86 opcode */
675struct X86EncodingMap {
676 X86OpCode opcode; // e.g. kOpAddRI
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700677 // The broad category the instruction conforms to, such as kRegReg. Identifies which LIR operands
678 // hold meaning for the opcode.
679 X86EncodingKind kind;
Brian Carlstrom7940e442013-07-12 13:46:57 -0700680 uint64_t flags;
681 struct {
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700682 uint8_t prefix1; // Non-zero => a prefix byte.
683 uint8_t prefix2; // Non-zero => a second prefix byte.
684 uint8_t opcode; // 1 byte opcode.
685 uint8_t extra_opcode1; // Possible extra opcode byte.
686 uint8_t extra_opcode2; // Possible second extra opcode byte.
687 // 3-bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
688 // encoding kind.
Brian Carlstrom7940e442013-07-12 13:46:57 -0700689 uint8_t modrm_opcode;
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700690 uint8_t ax_opcode; // Non-zero => shorter encoding for AX as a destination.
691 uint8_t immediate_bytes; // Number of bytes of immediate.
692 // Does the instruction address a byte register? In 32-bit mode the registers ah, bh, ch and dh
693 // are not used. In 64-bit mode the REX prefix is used to normalize and allow any byte register
694 // to be addressed.
695 bool r8_form;
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
Serguei Katkov94f3eb02014-06-24 13:23:17 +0700722// 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 +0700723#define REX 0x40
Dmitry Petrochenkoa20468c2014-04-30 13:40:19 +0700724// Mask extracting the least 3 bits of r0..r15
725#define kRegNumMask32 0x07
726// Value indicating that base or reg is not used
727#define NO_REG 0
Brian Carlstrom7940e442013-07-12 13:46:57 -0700728
729#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
730#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
Ian Rogers0f9b9c52014-06-09 01:32:12 -0700731#define IS_SIMM32(v) ((INT64_C(-2147483648) <= (v)) && ((v) <= INT64_C(2147483647)))
Brian Carlstrom7940e442013-07-12 13:46:57 -0700732
733extern X86EncodingMap EncodingMap[kX86Last];
734extern X86ConditionCode X86ConditionEncoding(ConditionCode cond);
735
736} // namespace art
737
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700738#endif // ART_COMPILER_DEX_QUICK_X86_X86_LIR_H_