blob: 59b18591348dbce23c053b275a86a2c032b22db8 [file] [log] [blame]
Ian Rogerse32ca232012-03-05 10:20:23 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_
18#define ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_
19
20#include "../../Dalvik.h"
21#include "../../CompilerInternals.h"
22
23namespace art {
24
Ian Rogerse32ca232012-03-05 10:20:23 -080025/*
26 * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64), although
27 * we currently only target x86. The ABI has different conventions and we hope to have a single
28 * convention to simplify code generation. Changing something that is callee save and making it
29 * caller save places a burden on up-calls to save/restore the callee save register, however, there
30 * are few registers that are callee save in the ABI. Changing something that is caller save and
31 * making it callee save places a burden on down-calls to save/restore the callee save register.
Ian Rogersb41b33b2012-03-20 14:22:54 -070032 * For these reasons we aim to match native conventions for caller and callee save. The first 4
33 * registers can be used for byte operations, for this reason they are preferred for temporary
34 * scratch registers.
Ian Rogerse32ca232012-03-05 10:20:23 -080035 *
36 * General Purpose Register:
37 * Native: x86 | x86-64 / x32 | ART
38 * r0/eax: caller save | caller save | caller, Method*, scratch, return value
Ian Rogersb41b33b2012-03-20 14:22:54 -070039 * r1/ecx: caller save | caller save, arg4 | caller, arg1, scratch
40 * r2/edx: caller save | caller save, arg3 | caller, arg2, scratch, high half of long return
41 * r3/ebx: callEE save | callEE save | callER, arg3, scratch
Ian Rogerse32ca232012-03-05 10:20:23 -080042 * r4/esp: stack pointer
43 * r5/ebp: callee save | callee save | callee, available for dalvik register promotion
44 * r6/esi: callEE save | callER save, arg2 | callee, available for dalvik register promotion
45 * r7/edi: callEE save | callER save, arg1 | callee, available for dalvik register promotion
46 * --- x86-64/x32 registers
47 * Native: x86-64 / x32 | ART
48 * r8: caller save, arg5 | caller, scratch
49 * r9: caller save, arg6 | caller, scratch
50 * r10: caller save | caller, scratch
51 * r11: caller save | caller, scratch
52 * r12: callee save | callee, available for dalvik register promotion
53 * r13: callee save | callee, available for dalvik register promotion
54 * r14: callee save | callee, available for dalvik register promotion
55 * r15: callee save | callee, available for dalvik register promotion
56 *
57 * There is no rSELF, instead on x86 fs: has a base address of Thread::Current, whereas on
58 * x86-64/x32 gs: holds it.
59 *
60 * For floating point we don't support CPUs without SSE2 support (ie newer than PIII):
61 * Native: x86 | x86-64 / x32 | ART
62 * XMM0: caller save |caller save, arg1 | caller, float/double return value (except for native x86 code)
63 * XMM1: caller save |caller save, arg2 | caller, scratch
64 * XMM2: caller save |caller save, arg3 | caller, scratch
65 * XMM3: caller save |caller save, arg4 | caller, scratch
66 * XMM4: caller save |caller save, arg5 | caller, scratch
67 * XMM5: caller save |caller save, arg6 | caller, scratch
68 * XMM6: caller save |caller save, arg7 | caller, scratch
69 * XMM7: caller save |caller save, arg8 | caller, scratch
70 * --- x86-64/x32 registers
71 * XMM8 .. 15: caller save
72 *
73 * X87 is a necessary evil outside of ART code:
74 * ST0: x86 float/double native return value, caller save
75 * ST1 .. ST7: caller save
76 *
77 * Stack frame diagram (stack grows down, higher addresses at top):
78 *
79 * +------------------------+
80 * | IN[ins-1] | {Note: resides in caller's frame}
81 * | . |
82 * | IN[0] |
83 * | caller's Method* |
84 * +========================+ {Note: start of callee's frame}
85 * | return address | {pushed by call}
86 * | spill region | {variable sized}
87 * +------------------------+
88 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
89 * +------------------------+
90 * | V[locals-1] |
91 * | V[locals-2] |
92 * | . |
93 * | . |
94 * | V[1] |
95 * | V[0] |
96 * +------------------------+
97 * | 0 to 3 words padding |
98 * +------------------------+
99 * | OUT[outs-1] |
100 * | OUT[outs-2] |
101 * | . |
102 * | OUT[0] |
103 * | curMethod* | <<== sp w/ 16-byte alignment
104 * +========================+
105 */
106
107/* Offset to distingish FP regs */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700108#define FP_REG_OFFSET 32
Ian Rogerse32ca232012-03-05 10:20:23 -0800109/* Offset to distinguish DP FP regs */
jeffhaofdffdf82012-07-11 16:08:43 -0700110#define FP_DOUBLE (FP_REG_OFFSET + 16)
Ian Rogerse32ca232012-03-05 10:20:23 -0800111/* Offset to distingish the extra regs */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700112#define EXTRA_REG_OFFSET (FP_DOUBLE + 16)
Ian Rogerse32ca232012-03-05 10:20:23 -0800113/* Reg types */
114#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
115#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
116#define EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET)
117#define LOWREG(x) ((x & 0x1f) == x)
118#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
119#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
Ian Rogersb5d09b22012-03-06 22:14:17 -0800120
Ian Rogerse32ca232012-03-05 10:20:23 -0800121/*
122 * Note: the low register of a floating point pair is sufficient to
123 * create the name of a double, but require both names to be passed to
124 * allow for asserts to verify that the pair is consecutive if significant
125 * rework is done in this area. Also, it is a good reminder in the calling
126 * code that reg locations always describe doubles as a pair of singles.
127 */
128#define S2D(x,y) ((x) | FP_DOUBLE)
129/* Mask to strip off fp flags */
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700130#define FP_REG_MASK 0xF
Ian Rogerse32ca232012-03-05 10:20:23 -0800131/* non-existent Dalvik register */
132#define vNone (-1)
133/* non-existant physical register */
134#define rNone (-1)
135
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700136/* RegisterLocation templates return values (rAX, rAX/rDX or XMM0) */
buzbee2cfc6392012-05-07 14:51:40 -0700137// location, wide, defined, const, fp, core, ref, highWord, home, lowReg, highReg, sRegLow
138#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 0, 0, 1, rAX, INVALID_REG, INVALID_SREG, INVALID_SREG}
139#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, rAX, rDX, INVALID_SREG, INVALID_SREG}
140#define LOC_C_RETURN_FLOAT {kLocPhysReg, 0, 0, 0, 1, 0, 0, 0, 1, fr0, INVALID_REG, INVALID_SREG, INVALID_SREG}
141#define LOC_C_RETURN_WIDE_DOUBLE {kLocPhysReg, 1, 0, 0, 1, 0, 0, 0, 1, fr0, fr1, INVALID_SREG, INVALID_SREG}
Ian Rogerse32ca232012-03-05 10:20:23 -0800142
buzbeeec137432012-11-13 12:13:16 -0800143enum X86ResourceEncodingPos {
144 kX86GPReg0 = 0,
145 kX86RegSP = 4,
146 kX86FPReg0 = 16, // xmm0 .. xmm7/xmm15
147 kX86FPRegEnd = 32,
148 kX86RegEnd = kX86FPRegEnd,
Elliott Hughes719ace42012-03-09 18:06:03 -0800149};
Ian Rogerse32ca232012-03-05 10:20:23 -0800150
buzbeeec137432012-11-13 12:13:16 -0800151#define ENCODE_X86_REG_LIST(N) ((u8) N)
152#define ENCODE_X86_REG_SP (1ULL << kX86RegSP)
Ian Rogerse32ca232012-03-05 10:20:23 -0800153
154/*
155 * Annotate special-purpose core registers:
156 */
157
Elliott Hughes719ace42012-03-09 18:06:03 -0800158enum NativeRegisterPool {
Ian Rogerse32ca232012-03-05 10:20:23 -0800159 r0 = 0,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800160 rAX = r0,
Ian Rogerse32ca232012-03-05 10:20:23 -0800161 r1 = 1,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800162 rCX = r1,
Ian Rogerse32ca232012-03-05 10:20:23 -0800163 r2 = 2,
164 rDX = r2,
165 r3 = 3,
166 rBX = r3,
167 r4sp = 4,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800168 rSP = r4sp,
169 r4sib_no_index = r4sp,
Ian Rogerse32ca232012-03-05 10:20:23 -0800170 r5 = 5,
171 rBP = r5,
Ian Rogers7caad772012-03-30 01:07:54 -0700172 r5sib_no_base = r5,
Ian Rogerse32ca232012-03-05 10:20:23 -0800173 r6 = 6,
174 rSI = r6,
175 r7 = 7,
176 rDI = r7,
jeffhao703f2cd2012-07-13 17:25:52 -0700177#ifndef TARGET_REX_SUPPORT
178 rRET = 8, // fake return address register for core spill mask
179#else
Ian Rogerse32ca232012-03-05 10:20:23 -0800180 r8 = 8,
181 r9 = 9,
182 r10 = 10,
183 r11 = 11,
184 r12 = 12,
185 r13 = 13,
186 r14 = 14,
187 r15 = 15,
Ian Rogersf7d9ad32012-03-13 18:45:39 -0700188 rRET = 16, // fake return address register for core spill mask
jeffhao703f2cd2012-07-13 17:25:52 -0700189#endif
Ian Rogerse32ca232012-03-05 10:20:23 -0800190 fr0 = 0 + FP_REG_OFFSET,
191 fr1 = 1 + FP_REG_OFFSET,
192 fr2 = 2 + FP_REG_OFFSET,
193 fr3 = 3 + FP_REG_OFFSET,
194 fr4 = 4 + FP_REG_OFFSET,
195 fr5 = 5 + FP_REG_OFFSET,
196 fr6 = 6 + FP_REG_OFFSET,
197 fr7 = 7 + FP_REG_OFFSET,
198 fr8 = 8 + FP_REG_OFFSET,
199 fr9 = 9 + FP_REG_OFFSET,
200 fr10 = 10 + FP_REG_OFFSET,
201 fr11 = 11 + FP_REG_OFFSET,
202 fr12 = 12 + FP_REG_OFFSET,
203 fr13 = 13 + FP_REG_OFFSET,
204 fr14 = 14 + FP_REG_OFFSET,
205 fr15 = 15 + FP_REG_OFFSET,
Elliott Hughes719ace42012-03-09 18:06:03 -0800206};
Ian Rogerse32ca232012-03-05 10:20:23 -0800207
208/*
209 * Target-independent aliases
210 */
211
212#define rARG0 rAX
Ian Rogersb41b33b2012-03-20 14:22:54 -0700213#define rARG1 rCX
214#define rARG2 rDX
215#define rARG3 rBX
jeffhao30a33172012-10-22 18:16:22 -0700216#define rFARG0 rAX
217#define rFARG1 rCX
218#define rFARG2 rDX
219#define rFARG3 rBX
Ian Rogerse32ca232012-03-05 10:20:23 -0800220#define rRET0 rAX
221#define rRET1 rDX
Ian Rogers6cbb2bd2012-03-16 13:45:30 -0700222#define rINVOKE_TGT rAX
buzbeeb046e162012-10-30 15:48:42 -0700223#define rLR INVALID_REG
224#define rSUSPEND INVALID_REG
225#define rSELF INVALID_REG
226#define rCOUNT rCX
Ian Rogerse32ca232012-03-05 10:20:23 -0800227
228#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
229
230/*
Ian Rogersde797832012-03-06 10:18:10 -0800231 * The following enum defines the list of supported X86 instructions by the
232 * assembler. Their corresponding EncodingMap positions will be defined in
233 * Assemble.cc.
Ian Rogerse32ca232012-03-05 10:20:23 -0800234 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800235enum X86OpCode {
buzbeeb046e162012-10-30 15:48:42 -0700236 kX86First = 0,
Bill Buzbeea114add2012-05-03 15:00:40 -0700237 kX8632BitData = kX86First, /* data [31..0] */
238 kX86Bkpt,
239 kX86Nop,
240 // Define groups of binary operations
241 // MR - Memory Register - opcode [base + disp], reg
242 // - lir operands - 0: base, 1: disp, 2: reg
243 // AR - Array Register - opcode [base + index * scale + disp], reg
244 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
245 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
246 // - lir operands - 0: disp, 1: reg
247 // RR - Register Register - opcode reg1, reg2
248 // - lir operands - 0: reg1, 1: reg2
249 // RM - Register Memory - opcode reg, [base + disp]
250 // - lir operands - 0: reg, 1: base, 2: disp
251 // RA - Register Array - opcode reg, [base + index * scale + disp]
252 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
253 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
254 // - lir operands - 0: reg, 1: disp
255 // RI - Register Immediate - opcode reg, #immediate
256 // - lir operands - 0: reg, 1: immediate
257 // MI - Memory Immediate - opcode [base + disp], #immediate
258 // - lir operands - 0: base, 1: disp, 2: immediate
259 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
260 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
261 // TI - Thread Register - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
262 // - lir operands - 0: disp, 1: imm
Ian Rogers96ab4202012-03-05 19:51:02 -0800263#define BinaryOpCode(opcode) \
Ian Rogersb5d09b22012-03-06 22:14:17 -0800264 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
265 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
266 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
267 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
268 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
269 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
270 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
271 opcode ## 32MR, opcode ## 32AR, opcode ## 32TR, \
272 opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
273 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
274 opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8
Bill Buzbeea114add2012-05-03 15:00:40 -0700275 BinaryOpCode(kX86Add),
276 BinaryOpCode(kX86Or),
277 BinaryOpCode(kX86Adc),
278 BinaryOpCode(kX86Sbb),
279 BinaryOpCode(kX86And),
280 BinaryOpCode(kX86Sub),
281 BinaryOpCode(kX86Xor),
282 BinaryOpCode(kX86Cmp),
Ian Rogers96ab4202012-03-05 19:51:02 -0800283#undef BinaryOpCode
Bill Buzbeea114add2012-05-03 15:00:40 -0700284 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
285 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
286 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
287 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
288 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
289 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
290 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
291 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
292 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
293 kX86Mov32MR, kX86Mov32AR, kX86Mov32TR,
294 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
295 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
296 kX86Lea32RA,
297 // RC - Register CL - opcode reg, CL
298 // - lir operands - 0: reg, 1: CL
299 // MC - Memory CL - opcode [base + disp], CL
300 // - lir operands - 0: base, 1: disp, 2: CL
301 // AC - Array CL - opcode [base + index * scale + disp], CL
302 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
Ian Rogersb5d09b22012-03-06 22:14:17 -0800303#define BinaryShiftOpCode(opcode) \
Bill Buzbeea114add2012-05-03 15:00:40 -0700304 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
305 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
306 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
307 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
308 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
309 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC
310 BinaryShiftOpCode(kX86Rol),
311 BinaryShiftOpCode(kX86Ror),
312 BinaryShiftOpCode(kX86Rcl),
313 BinaryShiftOpCode(kX86Rcr),
314 BinaryShiftOpCode(kX86Sal),
315 BinaryShiftOpCode(kX86Shr),
316 BinaryShiftOpCode(kX86Sar),
Ian Rogersb5d09b22012-03-06 22:14:17 -0800317#undef BinaryShiftOpcode
jeffhao77ae36b2012-08-07 14:18:16 -0700318 kX86Cmc,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800319#define UnaryOpcode(opcode, reg, mem, array) \
Bill Buzbeea114add2012-05-03 15:00:40 -0700320 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
321 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
322 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array
323 UnaryOpcode(kX86Test, RI, MI, AI),
Ian Rogers2e9f7ed2012-09-26 11:30:43 -0700324 kX86Test32RR,
Bill Buzbeea114add2012-05-03 15:00:40 -0700325 UnaryOpcode(kX86Not, R, M, A),
326 UnaryOpcode(kX86Neg, R, M, A),
327 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
328 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
329 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
330 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
Ian Rogersb5d09b22012-03-06 22:14:17 -0800331#undef UnaryOpcode
332#define Binary0fOpCode(opcode) \
333 opcode ## RR, opcode ## RM, opcode ## RA
Bill Buzbeea114add2012-05-03 15:00:40 -0700334 Binary0fOpCode(kX86Movsd),
335 kX86MovsdMR,
336 kX86MovsdAR,
337 Binary0fOpCode(kX86Movss),
338 kX86MovssMR,
339 kX86MovssAR,
340 Binary0fOpCode(kX86Cvtsi2sd), // int to double
341 Binary0fOpCode(kX86Cvtsi2ss), // int to float
342 Binary0fOpCode(kX86Cvttsd2si),// truncating double to int
343 Binary0fOpCode(kX86Cvttss2si),// truncating float to int
344 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
345 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
346 Binary0fOpCode(kX86Ucomisd), // unordered double compare
347 Binary0fOpCode(kX86Ucomiss), // unordered float compare
348 Binary0fOpCode(kX86Comisd), // double compare
349 Binary0fOpCode(kX86Comiss), // float compare
350 Binary0fOpCode(kX86Orps), // or of floating point registers
351 Binary0fOpCode(kX86Xorps), // xor of floating point registers
352 Binary0fOpCode(kX86Addsd), // double add
353 Binary0fOpCode(kX86Addss), // float add
354 Binary0fOpCode(kX86Mulsd), // double multiply
355 Binary0fOpCode(kX86Mulss), // float multiply
Bill Buzbeea114add2012-05-03 15:00:40 -0700356 Binary0fOpCode(kX86Cvtsd2ss), // double to float
jeffhao292188d2012-05-17 15:45:04 -0700357 Binary0fOpCode(kX86Cvtss2sd), // float to double
Bill Buzbeea114add2012-05-03 15:00:40 -0700358 Binary0fOpCode(kX86Subsd), // double subtract
359 Binary0fOpCode(kX86Subss), // float subtract
360 Binary0fOpCode(kX86Divsd), // double divide
361 Binary0fOpCode(kX86Divss), // float divide
jeffhaofdffdf82012-07-11 16:08:43 -0700362 kX86PsrlqRI, // right shift of floating point registers
363 kX86PsllqRI, // left shift of floating point registers
Bill Buzbeea114add2012-05-03 15:00:40 -0700364 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
jeffhaofdffdf82012-07-11 16:08:43 -0700365 kX86MovdrxRR, kX86MovdrxMR, kX86MovdrxAR,// move into reg from xmm
Bill Buzbeea114add2012-05-03 15:00:40 -0700366 kX86Set8R, kX86Set8M, kX86Set8A,// set byte depending on condition operand
367 kX86Mfence, // memory barrier
368 Binary0fOpCode(kX86Imul16), // 16bit multiply
369 Binary0fOpCode(kX86Imul32), // 32bit multiply
jeffhao83025762012-08-02 11:08:56 -0700370 kX86CmpxchgRR, kX86CmpxchgMR, kX86CmpxchgAR,// compare and exchange
371 kX86LockCmpxchgRR, kX86LockCmpxchgMR, kX86LockCmpxchgAR,// locked compare and exchange
Bill Buzbeea114add2012-05-03 15:00:40 -0700372 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
373 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
374 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
375 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
Ian Rogersb5d09b22012-03-06 22:14:17 -0800376#undef Binary0fOpCode
Bill Buzbeea114add2012-05-03 15:00:40 -0700377 kX86Jcc8, kX86Jcc32, // jCC rel8/32; lir operands - 0: rel, 1: CC, target assigned
378 kX86Jmp8, kX86Jmp32, // jmp rel8/32; lir operands - 0: rel, target assigned
379 kX86JmpR, // jmp reg; lir operands - 0: reg
380 kX86CallR, // call reg; lir operands - 0: reg
381 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
382 kX86CallA, // call [base + index * scale + disp]
383 // lir operands - 0: base, 1: index, 2: scale, 3: disp
384 kX86CallT, // call fs:[disp]; fs: is equal to Thread::Current(); lir operands - 0: disp
385 kX86Ret, // ret; no lir operands
386 kX86StartOfMethod, // call 0; pop reg; sub reg, # - generate start of method into reg
387 // lir operands - 0: reg
388 kX86PcRelLoadRA, // mov reg, [base + index * scale + PC relative displacement]
389 // lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: table
390 kX86PcRelAdr, // mov reg, PC relative displacement; lir operands - 0: reg, 1: table
391 kX86Last
Elliott Hughes719ace42012-03-09 18:06:03 -0800392};
Ian Rogerse32ca232012-03-05 10:20:23 -0800393
Ian Rogersde797832012-03-06 10:18:10 -0800394/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800395enum X86EncodingKind {
Ian Rogersb5d09b22012-03-06 22:14:17 -0800396 kData, // Special case for raw data.
397 kNop, // Special case for variable length nop.
398 kNullary, // Opcode that takes no arguments.
399 kReg, kMem, kArray, // R, M and A instruction kinds.
400 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds.
401 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds.
jeffhaofdffdf82012-07-11 16:08:43 -0700402 kRegRegStore, // RR following the store modrm reg-reg encoding rather than the load.
Ian Rogersb5d09b22012-03-06 22:14:17 -0800403 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
404 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
405 kMovRegImm, // Shorter form move RI.
406 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
407 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
408 kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
409 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
Bill Buzbeea114add2012-05-03 15:00:40 -0700410 kJmp, kJcc, kCall, // Branch instruction kinds.
411 kPcRel, // Operation with displacement that is PC relative
412 kMacro, // An instruction composing multiple others
413 kUnimplemented // Encoding used when an instruction isn't yet implemented.
Elliott Hughes719ace42012-03-09 18:06:03 -0800414};
Ian Rogersde797832012-03-06 10:18:10 -0800415
Ian Rogersde797832012-03-06 10:18:10 -0800416/* Struct used to define the EncodingMap positions for each X86 opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800417struct X86EncodingMap {
Ian Rogersde797832012-03-06 10:18:10 -0800418 X86OpCode opcode; // e.g. kOpAddRI
419 X86EncodingKind kind; // Used to discriminate in the union below
buzbeeec137432012-11-13 12:13:16 -0800420 uint64_t flags;
Ian Rogersb5d09b22012-03-06 22:14:17 -0800421 struct {
Bill Buzbeea114add2012-05-03 15:00:40 -0700422 uint8_t prefix1; // non-zero => a prefix byte
423 uint8_t prefix2; // non-zero => a second prefix byte
424 uint8_t opcode; // 1 byte opcode
425 uint8_t extra_opcode1; // possible extra opcode byte
426 uint8_t extra_opcode2; // possible second extra opcode byte
427 // 3bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
428 // encoding kind
429 uint8_t modrm_opcode;
430 uint8_t ax_opcode; // non-zero => shorter encoding for AX as a destination
431 uint8_t immediate_bytes; // number of bytes of immediate
Ian Rogersde797832012-03-06 10:18:10 -0800432 } skeleton;
433 const char *name;
434 const char* fmt;
Elliott Hughes719ace42012-03-09 18:06:03 -0800435};
Ian Rogersde797832012-03-06 10:18:10 -0800436
437extern X86EncodingMap EncodingMap[kX86Last];
438
buzbeea7678db2012-03-05 15:35:46 -0800439// FIXME: mem barrier type - what do we do for x86?
440#define kSY 0
441#define kST 0
442
Ian Rogerse32ca232012-03-05 10:20:23 -0800443/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800444enum X86TargetOptHints {
Bill Buzbeea114add2012-05-03 15:00:40 -0700445 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800446};
Ian Rogerse32ca232012-03-05 10:20:23 -0800447
Ian Rogersb5d09b22012-03-06 22:14:17 -0800448/* Offsets of high and low halves of a 64bit value */
449#define LOWORD_OFFSET 0
450#define HIWORD_OFFSET 4
451
452/* Segment override instruction prefix used for quick TLS access to Thread::Current() */
453#define THREAD_PREFIX 0x64
Ian Rogerse32ca232012-03-05 10:20:23 -0800454
Ian Rogersde797832012-03-06 10:18:10 -0800455#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
Ian Rogersb5d09b22012-03-06 22:14:17 -0800456#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
Ian Rogerse32ca232012-03-05 10:20:23 -0800457
458} // namespace art
459
460#endif // ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_