blob: 65f07cfa70114a0ae74cab0b45b0e5475102a241 [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
25// Set to 1 to measure cost of suspend check
26#define NO_SUSPEND 0
27
28/*
29 * Runtime register conventions. We consider both x86, x86-64 and x32 (32bit mode x86-64), although
30 * we currently only target x86. The ABI has different conventions and we hope to have a single
31 * convention to simplify code generation. Changing something that is callee save and making it
32 * caller save places a burden on up-calls to save/restore the callee save register, however, there
33 * are few registers that are callee save in the ABI. Changing something that is caller save and
34 * making it callee save places a burden on down-calls to save/restore the callee save register.
35 * For these reasons we aim to match native conventions for caller and callee save
36 *
37 * General Purpose Register:
38 * Native: x86 | x86-64 / x32 | ART
39 * r0/eax: caller save | caller save | caller, Method*, scratch, return value
40 * r1/ecx: caller save | caller save, arg4 | caller, arg2, scratch
41 * r2/edx: caller save | caller save, arg3 | caller, arg1, scratch, high half of long return
42 * r3/ebx: callee save | callee save | callee, available for dalvik register promotion
43 * r4/esp: stack pointer
44 * r5/ebp: callee save | callee save | callee, available for dalvik register promotion
45 * r6/esi: callEE save | callER save, arg2 | callee, available for dalvik register promotion
46 * r7/edi: callEE save | callER save, arg1 | callee, available for dalvik register promotion
47 * --- x86-64/x32 registers
48 * Native: x86-64 / x32 | ART
49 * r8: caller save, arg5 | caller, scratch
50 * r9: caller save, arg6 | caller, scratch
51 * r10: caller save | caller, scratch
52 * r11: caller save | caller, scratch
53 * r12: callee save | callee, available for dalvik register promotion
54 * r13: callee save | callee, available for dalvik register promotion
55 * r14: callee save | callee, available for dalvik register promotion
56 * r15: callee save | callee, available for dalvik register promotion
57 *
58 * There is no rSELF, instead on x86 fs: has a base address of Thread::Current, whereas on
59 * x86-64/x32 gs: holds it.
60 *
61 * For floating point we don't support CPUs without SSE2 support (ie newer than PIII):
62 * Native: x86 | x86-64 / x32 | ART
63 * XMM0: caller save |caller save, arg1 | caller, float/double return value (except for native x86 code)
64 * XMM1: caller save |caller save, arg2 | caller, scratch
65 * XMM2: caller save |caller save, arg3 | caller, scratch
66 * XMM3: caller save |caller save, arg4 | caller, scratch
67 * XMM4: caller save |caller save, arg5 | caller, scratch
68 * XMM5: caller save |caller save, arg6 | caller, scratch
69 * XMM6: caller save |caller save, arg7 | caller, scratch
70 * XMM7: caller save |caller save, arg8 | caller, scratch
71 * --- x86-64/x32 registers
72 * XMM8 .. 15: caller save
73 *
74 * X87 is a necessary evil outside of ART code:
75 * 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):
79 *
80 * +------------------------+
81 * | IN[ins-1] | {Note: resides in caller's frame}
82 * | . |
83 * | IN[0] |
84 * | caller's Method* |
85 * +========================+ {Note: start of callee's frame}
86 * | return address | {pushed by call}
87 * | spill region | {variable sized}
88 * +------------------------+
89 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
90 * +------------------------+
91 * | V[locals-1] |
92 * | V[locals-2] |
93 * | . |
94 * | . |
95 * | V[1] |
96 * | V[0] |
97 * +------------------------+
98 * | 0 to 3 words padding |
99 * +------------------------+
100 * | OUT[outs-1] |
101 * | OUT[outs-2] |
102 * | . |
103 * | OUT[0] |
104 * | curMethod* | <<== sp w/ 16-byte alignment
105 * +========================+
106 */
107
108/* Offset to distingish FP regs */
109#define FP_REG_OFFSET 16
110/* Offset to distinguish DP FP regs */
111#define FP_DOUBLE 32
112/* Offset to distingish the extra regs */
113#define EXTRA_REG_OFFSET 64
114/* Reg types */
115#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
116#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
117#define EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET)
118#define LOWREG(x) ((x & 0x1f) == x)
119#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
120#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
Ian Rogersb5d09b22012-03-06 22:14:17 -0800121
Ian Rogerse32ca232012-03-05 10:20:23 -0800122/*
123 * Note: the low register of a floating point pair is sufficient to
124 * create the name of a double, but require both names to be passed to
125 * allow for asserts to verify that the pair is consecutive if significant
126 * rework is done in this area. Also, it is a good reminder in the calling
127 * code that reg locations always describe doubles as a pair of singles.
128 */
129#define S2D(x,y) ((x) | FP_DOUBLE)
130/* Mask to strip off fp flags */
131#define FP_REG_MASK (FP_REG_OFFSET-1)
132/* non-existent Dalvik register */
133#define vNone (-1)
134/* non-existant physical register */
135#define rNone (-1)
136
Ian Rogersb5d09b22012-03-06 22:14:17 -0800137/* RegisterLocation templates return values (rAX, or rAX/rDX) */
138#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, rAX, INVALID_REG, INVALID_SREG}
139#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, rAX, rDX, INVALID_SREG}
Ian Rogerse32ca232012-03-05 10:20:23 -0800140
Elliott Hughes719ace42012-03-09 18:06:03 -0800141enum ResourceEncodingPos {
Ian Rogerse32ca232012-03-05 10:20:23 -0800142 kGPReg0 = 0,
143 kRegSP = 4,
144 kRegLR = -1,
145 kFPReg0 = 16, // xmm0 .. xmm7/xmm15
146 kFPRegEnd = 32,
147 kRegEnd = kFPRegEnd,
148 kCCode = kRegEnd,
149 // The following four bits are for memory disambiguation
150 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
151 kLiteral, // 2 Literal pool (can be fully disambiguated)
152 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
153 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
Elliott Hughes719ace42012-03-09 18:06:03 -0800154};
Ian Rogerse32ca232012-03-05 10:20:23 -0800155
156#define ENCODE_REG_LIST(N) ((u8) N)
157#define ENCODE_REG_SP (1ULL << kRegSP)
158#define ENCODE_CCODE (1ULL << kCCode)
159#define ENCODE_FP_STATUS (1ULL << kFPStatus)
160
161/* Abstract memory locations */
162#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
163#define ENCODE_LITERAL (1ULL << kLiteral)
164#define ENCODE_HEAP_REF (1ULL << kHeapRef)
165#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
166
167#define ENCODE_ALL (~0ULL)
168#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
169 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
170
171#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
172#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
173
174/*
175 * Annotate special-purpose core registers:
176 */
177
Elliott Hughes719ace42012-03-09 18:06:03 -0800178enum NativeRegisterPool {
Ian Rogerse32ca232012-03-05 10:20:23 -0800179 r0 = 0,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800180 rAX = r0,
Ian Rogerse32ca232012-03-05 10:20:23 -0800181 r1 = 1,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800182 rCX = r1,
Ian Rogerse32ca232012-03-05 10:20:23 -0800183 r2 = 2,
184 rDX = r2,
185 r3 = 3,
186 rBX = r3,
187 r4sp = 4,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800188 rSP = r4sp,
189 r4sib_no_index = r4sp,
Ian Rogerse32ca232012-03-05 10:20:23 -0800190 r5 = 5,
191 rBP = r5,
192 r6 = 6,
193 rSI = r6,
194 r7 = 7,
195 rDI = r7,
196 r8 = 8,
197 r9 = 9,
198 r10 = 10,
199 r11 = 11,
200 r12 = 12,
201 r13 = 13,
202 r14 = 14,
203 r15 = 15,
204 fr0 = 0 + FP_REG_OFFSET,
205 fr1 = 1 + FP_REG_OFFSET,
206 fr2 = 2 + FP_REG_OFFSET,
207 fr3 = 3 + FP_REG_OFFSET,
208 fr4 = 4 + FP_REG_OFFSET,
209 fr5 = 5 + FP_REG_OFFSET,
210 fr6 = 6 + FP_REG_OFFSET,
211 fr7 = 7 + FP_REG_OFFSET,
212 fr8 = 8 + FP_REG_OFFSET,
213 fr9 = 9 + FP_REG_OFFSET,
214 fr10 = 10 + FP_REG_OFFSET,
215 fr11 = 11 + FP_REG_OFFSET,
216 fr12 = 12 + FP_REG_OFFSET,
217 fr13 = 13 + FP_REG_OFFSET,
218 fr14 = 14 + FP_REG_OFFSET,
219 fr15 = 15 + FP_REG_OFFSET,
Elliott Hughes719ace42012-03-09 18:06:03 -0800220};
Ian Rogerse32ca232012-03-05 10:20:23 -0800221
222/*
223 * Target-independent aliases
224 */
225
226#define rARG0 rAX
227#define rARG1 rDX
228#define rARG2 rCX
229#define rRET0 rAX
230#define rRET1 rDX
231
232#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
233
Ian Rogersb5d09b22012-03-06 22:14:17 -0800234/* X86 condition encodings */
235enum X86ConditionCode {
236 kX86CondO = 0x0, // overflow
237 kX86CondNo = 0x1, // not overflow
238
239 kX86CondB = 0x2, // below
240 kX86CondNae = kX86CondB, // not-above-equal
241 kX86CondC = kX86CondB, // carry
242
243 kX86CondNb = 0x3, // not-below
244 kX86CondAe = kX86CondNb, // above-equal
245 kX86CondNc = kX86CondNb, // not-carry
246
247 kX86CondZ = 0x4, // zero
248 kX86CondEq = kX86CondZ, // equal
249
250 kX86CondNz = 0x5, // not-zero
251 kX86CondNe = kX86CondNz, // not-equal
252
253 kX86CondBe = 0x6, // below-equal
254 kX86CondNa = kX86CondBe, // not-above
255
256 kX86CondNbe = 0x7, // not-below-equal
257 kX86CondA = kX86CondNbe,// above
258
259 kX86CondS = 0x8, // sign
260 kX86CondNs = 0x9, // not-sign
261
262 kX86CondP = 0xA, // 8-bit parity even
263 kX86CondPE = kX86CondP,
264
265 kX86CondNp = 0xB, // 8-bit parity odd
266 kX86CondPo = kX86CondNp,
267
268 kX86CondL = 0xC, // less-than
269 kX86CondNge = kX86CondL, // not-greater-equal
270
271 kX86CondNl = 0xD, // not-less-than
272 kX86CondGe = kX86CondL, // not-greater-equal
273
274 kX86CondLe = 0xE, // less-than-equal
275 kX86CondNg = kX86CondLe, // not-greater
276
277 kX86CondNle = 0xF, // not-less-than
278 kX86CondG = kX86CondNle,// greater
279};
280
Ian Rogerse32ca232012-03-05 10:20:23 -0800281/*
Ian Rogersde797832012-03-06 10:18:10 -0800282 * The following enum defines the list of supported X86 instructions by the
283 * assembler. Their corresponding EncodingMap positions will be defined in
284 * Assemble.cc.
Ian Rogerse32ca232012-03-05 10:20:23 -0800285 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800286enum X86OpCode {
Ian Rogerse32ca232012-03-05 10:20:23 -0800287 kPseudoSuspendTarget = -15,
288 kPseudoThrowTarget = -14,
289 kPseudoCaseLabel = -13,
290 kPseudoMethodEntry = -12,
291 kPseudoMethodExit = -11,
292 kPseudoBarrier = -10,
293 kPseudoExtended = -9,
294 kPseudoSSARep = -8,
295 kPseudoEntryBlock = -7,
296 kPseudoExitBlock = -6,
297 kPseudoTargetLabel = -5,
298 kPseudoDalvikByteCodeBoundary = -4,
299 kPseudoPseudoAlign4 = -3,
300 kPseudoEHBlockLabel = -2,
301 kPseudoNormalBlockLabel = -1,
Ian Rogerse32ca232012-03-05 10:20:23 -0800302 kX86First,
Ian Rogers96ab4202012-03-05 19:51:02 -0800303 kX8632BitData = kX86First, /* data [31..0] */
Ian Rogersb5d09b22012-03-06 22:14:17 -0800304 kX86Bkpt,
305 kX86Nop,
Ian Rogersde797832012-03-06 10:18:10 -0800306 // Define groups of binary operations
Ian Rogersb5d09b22012-03-06 22:14:17 -0800307 // MR - Memory Register - opcode [base + disp], reg
308 // - lir operands - 0: base, 1: disp, 2: reg
309 // AR - Array Register - opcode [base + index * scale + disp], reg
310 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
311 // TR - Thread Register - opcode fs:[disp], reg - where fs: is equal to Thread::Current()
312 // - lir operands - 0: disp, 1: reg
Ian Rogersde797832012-03-06 10:18:10 -0800313 // RR - Register Register - opcode reg1, reg2
314 // - lir operands - 0: reg1, 1: reg2
315 // RM - Register Memory - opcode reg, [base + disp]
316 // - lir operands - 0: reg, 1: base, 2: disp
317 // RA - Register Array - opcode reg, [base + index * scale + disp]
318 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
Ian Rogersb5d09b22012-03-06 22:14:17 -0800319 // RT - Register Thread - opcode reg, fs:[disp] - where fs: is equal to Thread::Current()
320 // - lir operands - 0: reg, 1: disp
321 // RI - Register Immediate - opcode reg, #immediate
322 // - lir operands - 0: reg, 1: immediate
323 // MI - Memory Immediate - opcode [base + disp], #immediate
324 // - lir operands - 0: base, 1: disp, 2: immediate
325 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
326 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
327 // TI - Thread Register - opcode fs:[disp], imm - where fs: is equal to Thread::Current()
328 // - lir operands - 0: disp, 1: imm
Ian Rogers96ab4202012-03-05 19:51:02 -0800329#define BinaryOpCode(opcode) \
Ian Rogersb5d09b22012-03-06 22:14:17 -0800330 opcode ## 8MR, opcode ## 8AR, opcode ## 8TR, \
331 opcode ## 8RR, opcode ## 8RM, opcode ## 8RA, opcode ## 8RT, \
332 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, opcode ## 8TI, \
333 opcode ## 16MR, opcode ## 16AR, opcode ## 16TR, \
334 opcode ## 16RR, opcode ## 16RM, opcode ## 16RA, opcode ## 16RT, \
335 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, opcode ## 16TI, \
336 opcode ## 16RI8, opcode ## 16MI8, opcode ## 16AI8, opcode ## 16TI8, \
337 opcode ## 32MR, opcode ## 32AR, opcode ## 32TR, \
338 opcode ## 32RR, opcode ## 32RM, opcode ## 32RA, opcode ## 32RT, \
339 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, opcode ## 32TI, \
340 opcode ## 32RI8, opcode ## 32MI8, opcode ## 32AI8, opcode ## 32TI8
341 BinaryOpCode(kX86Add),
342 BinaryOpCode(kX86Or),
343 BinaryOpCode(kX86Adc),
344 BinaryOpCode(kX86Sbb),
345 BinaryOpCode(kX86And),
346 BinaryOpCode(kX86Sub),
347 BinaryOpCode(kX86Xor),
348 BinaryOpCode(kX86Cmp),
Ian Rogers96ab4202012-03-05 19:51:02 -0800349#undef BinaryOpCode
Ian Rogersb5d09b22012-03-06 22:14:17 -0800350 kX86Imul16RRI, kX86Imul16RMI, kX86Imul16RAI,
351 kX86Imul32RRI, kX86Imul32RMI, kX86Imul32RAI,
352 kX86Imul32RRI8, kX86Imul32RMI8, kX86Imul32RAI8,
353 kX86Mov8MR, kX86Mov8AR, kX86Mov8TR,
354 kX86Mov8RR, kX86Mov8RM, kX86Mov8RA, kX86Mov8RT,
355 kX86Mov8RI, kX86Mov8MI, kX86Mov8AI, kX86Mov8TI,
356 kX86Mov16MR, kX86Mov16AR, kX86Mov16TR,
357 kX86Mov16RR, kX86Mov16RM, kX86Mov16RA, kX86Mov16RT,
358 kX86Mov16RI, kX86Mov16MI, kX86Mov16AI, kX86Mov16TI,
359 kX86Mov32MR, kX86Mov32AR, kX86Mov32TR,
360 kX86Mov32RR, kX86Mov32RM, kX86Mov32RA, kX86Mov32RT,
361 kX86Mov32RI, kX86Mov32MI, kX86Mov32AI, kX86Mov32TI,
362 kX86Lea32RA,
363 // RC - Register CL - opcode reg, CL
364 // - lir operands - 0: reg, 1: CL
365 // MC - Memory CL - opcode [base + disp], CL
366 // - lir operands - 0: base, 1: disp, 2: CL
367 // AC - Array CL - opcode [base + index * scale + disp], CL
368 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: CL
369#define BinaryShiftOpCode(opcode) \
370 opcode ## 8RI, opcode ## 8MI, opcode ## 8AI, \
371 opcode ## 8RC, opcode ## 8MC, opcode ## 8AC, \
372 opcode ## 16RI, opcode ## 16MI, opcode ## 16AI, \
373 opcode ## 16RC, opcode ## 16MC, opcode ## 16AC, \
374 opcode ## 32RI, opcode ## 32MI, opcode ## 32AI, \
375 opcode ## 32RC, opcode ## 32MC, opcode ## 32AC
376 BinaryShiftOpCode(kX86Rol),
377 BinaryShiftOpCode(kX86Ror),
378 BinaryShiftOpCode(kX86Rcl),
379 BinaryShiftOpCode(kX86Rcr),
380 BinaryShiftOpCode(kX86Sal),
381 BinaryShiftOpCode(kX86Shl),
382 BinaryShiftOpCode(kX86Shr),
383 BinaryShiftOpCode(kX86Sar),
384#undef BinaryShiftOpcode
385#define UnaryOpcode(opcode, reg, mem, array) \
386 opcode ## 8 ## reg, opcode ## 8 ## mem, opcode ## 8 ## array, \
387 opcode ## 16 ## reg, opcode ## 16 ## mem, opcode ## 16 ## array, \
388 opcode ## 32 ## reg, opcode ## 32 ## mem, opcode ## 32 ## array
389 UnaryOpcode(kX86Test, RI, MI, AI),
390 UnaryOpcode(kX86Not, R, M, A),
391 UnaryOpcode(kX86Neg, R, M, A),
392 UnaryOpcode(kX86Mul, DaR, DaM, DaA),
393 UnaryOpcode(kX86Imul, DaR, DaM, DaA),
394 UnaryOpcode(kX86Divmod, DaR, DaM, DaA),
395 UnaryOpcode(kX86Idivmod, DaR, DaM, DaA),
396#undef UnaryOpcode
397#define Binary0fOpCode(opcode) \
398 opcode ## RR, opcode ## RM, opcode ## RA
399 Binary0fOpCode(kX86Movsd),
400 kX86MovsdMR,
401 kX86MovsdAR,
402 Binary0fOpCode(kX86Movss),
403 kX86MovssMR,
404 kX86MovssAR,
405 Binary0fOpCode(kX86Cvtsi2sd), // int to double
406 Binary0fOpCode(kX86Cvtsi2ss), // int to float
407 Binary0fOpCode(kX86Cvttsd2si), // truncating double to int
408 Binary0fOpCode(kX86Cvttss2si), // truncating float to int
409 Binary0fOpCode(kX86Cvtsd2si), // rounding double to int
410 Binary0fOpCode(kX86Cvtss2si), // rounding float to int
411 Binary0fOpCode(kX86Ucomisd), // unordered double compare
412 Binary0fOpCode(kX86Ucomiss), // unordered float compare
413 Binary0fOpCode(kX86Comisd), // double compare
414 Binary0fOpCode(kX86Comiss), // float compare
415 Binary0fOpCode(kX86Addsd), // double add
416 Binary0fOpCode(kX86Addss), // float add
417 Binary0fOpCode(kX86Mulsd), // double multiply
418 Binary0fOpCode(kX86Mulss), // float multiply
419 Binary0fOpCode(kX86Cvtss2sd), // float to double
420 Binary0fOpCode(kX86Cvtsd2ss), // double to float
421 Binary0fOpCode(kX86Subsd), // double subtract
422 Binary0fOpCode(kX86Subss), // float subtract
423 Binary0fOpCode(kX86Divsd), // double subtract
424 Binary0fOpCode(kX86Divss), // float subtract
425 Binary0fOpCode(kX86Movdxr), // move into xmm from gpr
426 Binary0fOpCode(kX86Movdrx), // move into reg from xmm
427 kX86Set8R, kX86Set8M, kX86Set8A,// set byte depending on condition operand
428 Binary0fOpCode(kX86Imul16), // 16bit multiply
429 Binary0fOpCode(kX86Imul32), // 32bit multiply
430 Binary0fOpCode(kX86Movzx8), // zero-extend 8-bit value
431 Binary0fOpCode(kX86Movzx16), // zero-extend 16-bit value
432 Binary0fOpCode(kX86Movsx8), // sign-extend 8-bit value
433 Binary0fOpCode(kX86Movsx16), // sign-extend 16-bit value
434#undef Binary0fOpCode
435 kX86Jcc, // jCC rel; lir operands - 0: rel, 1: CC, target assigned
436 kX86Jmp, // jmp rel; lir operands - 0: rel, target assigned
437 kX86CallR, // call reg; lir operands - 0: reg
438 kX86CallM, // call [base + disp]; lir operands - 0: base, 1: disp
439 kX86CallA, // call [base + index * scale + disp]
440 // lir operands - 0: base, 1: index, 2: scale, 3: disp
441 kX86Ret, // ret; no lir operands
Ian Rogerse32ca232012-03-05 10:20:23 -0800442 kX86Last
Elliott Hughes719ace42012-03-09 18:06:03 -0800443};
Ian Rogerse32ca232012-03-05 10:20:23 -0800444
Ian Rogersde797832012-03-06 10:18:10 -0800445/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800446enum X86EncodingKind {
Ian Rogersb5d09b22012-03-06 22:14:17 -0800447 kData, // Special case for raw data.
448 kNop, // Special case for variable length nop.
449 kNullary, // Opcode that takes no arguments.
450 kReg, kMem, kArray, // R, M and A instruction kinds.
451 kMemReg, kArrayReg, kThreadReg, // MR, AR and TR instruction kinds.
452 kRegReg, kRegMem, kRegArray, kRegThread, // RR, RM, RA and RT instruction kinds.
453 kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds.
454 kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds.
455 kMovRegImm, // Shorter form move RI.
456 kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate.
457 kShiftRegCl, kShiftMemCl, kShiftArrayCl, // Shift opcode with register CL.
458 kRegRegReg, kRegRegMem, kRegRegArray, // RRR, RRM, RRA instruction kinds.
459 kRegCond, kMemCond, kArrayCond, // R, M, A instruction kinds following by a condition.
460 kJmp, kJcc, kCall, // Branch instruction kinds.
Ian Rogersde797832012-03-06 10:18:10 -0800461 kUnimplemented // Encoding used when an instruction isn't yet implemented.
Elliott Hughes719ace42012-03-09 18:06:03 -0800462};
Ian Rogersde797832012-03-06 10:18:10 -0800463
Ian Rogersde797832012-03-06 10:18:10 -0800464/* Struct used to define the EncodingMap positions for each X86 opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800465struct X86EncodingMap {
Ian Rogersde797832012-03-06 10:18:10 -0800466 X86OpCode opcode; // e.g. kOpAddRI
467 X86EncodingKind kind; // Used to discriminate in the union below
468 int flags;
Ian Rogersb5d09b22012-03-06 22:14:17 -0800469 struct {
470 uint8_t prefix1; // non-zero => a prefix byte
471 uint8_t prefix2; // non-zero => a second prefix byte
472 uint8_t opcode; // 1 byte opcode
473 uint8_t extra_opcode1; // possible extra opcode byte
474 uint8_t extra_opcode2; // possible second extra opcode byte
475 // 3bit opcode that gets encoded in the register bits of the modrm byte, use determined by the
476 // encoding kind
477 uint8_t modrm_opcode;
478 uint8_t ax_opcode; // non-zero => shorter encoding for AX as a destination
479 uint8_t immediate_bytes; // number of bytes of immediate
Ian Rogersde797832012-03-06 10:18:10 -0800480 } skeleton;
481 const char *name;
482 const char* fmt;
Elliott Hughes719ace42012-03-09 18:06:03 -0800483};
Ian Rogersde797832012-03-06 10:18:10 -0800484
485extern X86EncodingMap EncodingMap[kX86Last];
486
buzbeea7678db2012-03-05 15:35:46 -0800487// FIXME: mem barrier type - what do we do for x86?
488#define kSY 0
489#define kST 0
490
Ian Rogerse32ca232012-03-05 10:20:23 -0800491/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800492enum X86OpFeatureFlags {
Ian Rogerse32ca232012-03-05 10:20:23 -0800493 kIsBranch = 0,
494 kRegDef0,
495 kRegDef1,
496 kRegDefSP,
497 kRegDefList0,
498 kRegDefList1,
499 kRegUse0,
500 kRegUse1,
501 kRegUse2,
502 kRegUse3,
503 kRegUseSP,
504 kRegUseList0,
505 kRegUseList1,
506 kNoOperand,
507 kIsUnaryOp,
508 kIsBinaryOp,
509 kIsTertiaryOp,
510 kIsQuadOp,
Ian Rogersb5d09b22012-03-06 22:14:17 -0800511 kIsQuinOp,
512 kIsSextupleOp,
Ian Rogerse32ca232012-03-05 10:20:23 -0800513 kIsIT,
514 kSetsCCodes,
515 kUsesCCodes,
516 kMemLoad,
517 kMemStore,
518 kPCRelFixup,
519// FIXME: add NEEDS_FIXUP to instruction attributes
Elliott Hughes719ace42012-03-09 18:06:03 -0800520};
Ian Rogerse32ca232012-03-05 10:20:23 -0800521
522#define IS_LOAD (1 << kMemLoad)
523#define IS_STORE (1 << kMemStore)
524#define IS_BRANCH (1 << kIsBranch)
525#define REG_DEF0 (1 << kRegDef0)
526#define REG_DEF1 (1 << kRegDef1)
527#define REG_DEF_SP (1 << kRegDefSP)
528#define REG_DEF_LR (1 << kRegDefLR)
529#define REG_DEF_LIST0 (1 << kRegDefList0)
530#define REG_DEF_LIST1 (1 << kRegDefList1)
531#define REG_USE0 (1 << kRegUse0)
532#define REG_USE1 (1 << kRegUse1)
533#define REG_USE2 (1 << kRegUse2)
534#define REG_USE3 (1 << kRegUse3)
535#define REG_USE_SP (1 << kRegUseSP)
536#define REG_USE_PC (1 << kRegUsePC)
537#define REG_USE_LIST0 (1 << kRegUseList0)
538#define REG_USE_LIST1 (1 << kRegUseList1)
539#define NO_OPERAND (1 << kNoOperand)
540#define IS_UNARY_OP (1 << kIsUnaryOp)
541#define IS_BINARY_OP (1 << kIsBinaryOp)
542#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
543#define IS_QUAD_OP (1 << kIsQuadOp)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800544#define IS_QUIN_OP (1 << kIsQuinOp)
545#define IS_SEXTUPLE_OP (1 << kIsSextupleOp)
Ian Rogerse32ca232012-03-05 10:20:23 -0800546#define IS_IT (1 << kIsIT)
547#define SETS_CCODES (1 << kSetsCCodes)
548#define USES_CCODES (1 << kUsesCCodes)
Ian Rogersb5d09b22012-03-06 22:14:17 -0800549#define NEEDS_FIXUP (1 << kPCRelFixup)
Ian Rogerse32ca232012-03-05 10:20:23 -0800550
551/* attributes, included for compatibility */
552#define REG_DEF_FPCS_LIST0 (0)
553#define REG_DEF_FPCS_LIST2 (0)
554
555
556/* Common combo register usage patterns */
557#define REG_USE01 (REG_USE0 | REG_USE1)
558#define REG_USE02 (REG_USE0 | REG_USE2)
559#define REG_USE012 (REG_USE01 | REG_USE2)
560#define REG_USE12 (REG_USE1 | REG_USE2)
561#define REG_USE23 (REG_USE2 | REG_USE3)
562#define REG_DEF01 (REG_DEF0 | REG_DEF1)
563#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
564#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
565#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
566#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
567#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
568#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
569
Ian Rogerse32ca232012-03-05 10:20:23 -0800570/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800571enum X86TargetOptHints {
Ian Rogerse32ca232012-03-05 10:20:23 -0800572 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800573};
Ian Rogerse32ca232012-03-05 10:20:23 -0800574
Ian Rogersb5d09b22012-03-06 22:14:17 -0800575/* Offsets of high and low halves of a 64bit value */
576#define LOWORD_OFFSET 0
577#define HIWORD_OFFSET 4
578
579/* Segment override instruction prefix used for quick TLS access to Thread::Current() */
580#define THREAD_PREFIX 0x64
Ian Rogerse32ca232012-03-05 10:20:23 -0800581
Ian Rogersde797832012-03-06 10:18:10 -0800582#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
Ian Rogersb5d09b22012-03-06 22:14:17 -0800583#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32767))
Ian Rogerse32ca232012-03-05 10:20:23 -0800584
585} // namespace art
586
587#endif // ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_