blob: 31449e0d126e111234bef8e5c8043d5ea41fdfcc [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))
121/*
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 */
130#define FP_REG_MASK (FP_REG_OFFSET-1)
131/* non-existent Dalvik register */
132#define vNone (-1)
133/* non-existant physical register */
134#define rNone (-1)
135
buzbeea7678db2012-03-05 15:35:46 -0800136/* RegisterLocation templates return values (r0, or r0/r1) */
137#define LOC_C_RETURN {kLocPhysReg, 0, 0, 0, 0, 0, 1, rAX, INVALID_REG,\
138 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,
180 rAX = r0,
181 r1 = 1,
182 rCX = r1,
183 r2 = 2,
184 rDX = r2,
185 r3 = 3,
186 rBX = r3,
187 r4sp = 4,
188 rSP =r4sp,
189 r5 = 5,
190 rBP = r5,
191 r6 = 6,
192 rSI = r6,
193 r7 = 7,
194 rDI = r7,
195 r8 = 8,
196 r9 = 9,
197 r10 = 10,
198 r11 = 11,
199 r12 = 12,
200 r13 = 13,
201 r14 = 14,
202 r15 = 15,
203 fr0 = 0 + FP_REG_OFFSET,
204 fr1 = 1 + FP_REG_OFFSET,
205 fr2 = 2 + FP_REG_OFFSET,
206 fr3 = 3 + FP_REG_OFFSET,
207 fr4 = 4 + FP_REG_OFFSET,
208 fr5 = 5 + FP_REG_OFFSET,
209 fr6 = 6 + FP_REG_OFFSET,
210 fr7 = 7 + FP_REG_OFFSET,
211 fr8 = 8 + FP_REG_OFFSET,
212 fr9 = 9 + FP_REG_OFFSET,
213 fr10 = 10 + FP_REG_OFFSET,
214 fr11 = 11 + FP_REG_OFFSET,
215 fr12 = 12 + FP_REG_OFFSET,
216 fr13 = 13 + FP_REG_OFFSET,
217 fr14 = 14 + FP_REG_OFFSET,
218 fr15 = 15 + FP_REG_OFFSET,
Elliott Hughes719ace42012-03-09 18:06:03 -0800219};
Ian Rogerse32ca232012-03-05 10:20:23 -0800220
221/*
222 * Target-independent aliases
223 */
224
225#define rARG0 rAX
226#define rARG1 rDX
227#define rARG2 rCX
228#define rRET0 rAX
229#define rRET1 rDX
230
231#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
232
233/*
Ian Rogersde797832012-03-06 10:18:10 -0800234 * The following enum defines the list of supported X86 instructions by the
235 * assembler. Their corresponding EncodingMap positions will be defined in
236 * Assemble.cc.
Ian Rogerse32ca232012-03-05 10:20:23 -0800237 */
Elliott Hughes719ace42012-03-09 18:06:03 -0800238enum X86OpCode {
Ian Rogerse32ca232012-03-05 10:20:23 -0800239 kPseudoSuspendTarget = -15,
240 kPseudoThrowTarget = -14,
241 kPseudoCaseLabel = -13,
242 kPseudoMethodEntry = -12,
243 kPseudoMethodExit = -11,
244 kPseudoBarrier = -10,
245 kPseudoExtended = -9,
246 kPseudoSSARep = -8,
247 kPseudoEntryBlock = -7,
248 kPseudoExitBlock = -6,
249 kPseudoTargetLabel = -5,
250 kPseudoDalvikByteCodeBoundary = -4,
251 kPseudoPseudoAlign4 = -3,
252 kPseudoEHBlockLabel = -2,
253 kPseudoNormalBlockLabel = -1,
Ian Rogerse32ca232012-03-05 10:20:23 -0800254 kX86First,
Ian Rogers96ab4202012-03-05 19:51:02 -0800255 kX8632BitData = kX86First, /* data [31..0] */
Ian Rogersde797832012-03-06 10:18:10 -0800256 // Define groups of binary operations
257 // RI - Register Immediate - opcode reg, #immediate
258 // - lir operands - 0: reg, 1: immediate
259 // MI - Memory Immediate - opcode [base + disp], #immediate
260 // - lir operands - 0: base, 1: disp, 2: immediate
261 // AI - Array Immediate - opcode [base + index * scale + disp], #immediate
262 // - lir operands - 0: base, 1: index, 2: scale, 3: disp 4: immediate
263 // RR - Register Register - opcode reg1, reg2
264 // - lir operands - 0: reg1, 1: reg2
265 // RM - Register Memory - opcode reg, [base + disp]
266 // - lir operands - 0: reg, 1: base, 2: disp
267 // RA - Register Array - opcode reg, [base + index * scale + disp]
268 // - lir operands - 0: reg, 1: base, 2: index, 3: scale, 4: disp
269 // MR - Memory Register - opcode [base + disp], reg
270 // - lir operands - 0: base, 1: disp, 2: reg
271 // AR - Array Register - opcode [base + index * scale + disp], reg
272 // - lir operands - 0: base, 1: index, 2: scale, 3: disp, 4: reg
Ian Rogers96ab4202012-03-05 19:51:02 -0800273#define BinaryOpCode(opcode) \
274 opcode ## RI, opcode ## MI, opcode ##AI, \
275 opcode ## RR, opcode ## RM, opcode ##RA, \
276 opcode ## MR, opcode ## AR
277 BinaryOpCode(kOpAdd),
278 BinaryOpCode(kOpOr),
279 BinaryOpCode(kOpAdc),
280 BinaryOpCode(kOpSbb),
281 BinaryOpCode(kOpAnd),
282 BinaryOpCode(kOpSub),
283 BinaryOpCode(kOpXor),
284 BinaryOpCode(kOpCmp),
Ian Rogersde797832012-03-06 10:18:10 -0800285 BinaryOpCode(kOpMov),
Ian Rogers96ab4202012-03-05 19:51:02 -0800286#undef BinaryOpCode
Ian Rogerse32ca232012-03-05 10:20:23 -0800287 kX86Last
Elliott Hughes719ace42012-03-09 18:06:03 -0800288};
Ian Rogerse32ca232012-03-05 10:20:23 -0800289
Ian Rogersde797832012-03-06 10:18:10 -0800290/* Instruction assembly fieldLoc kind */
Elliott Hughes719ace42012-03-09 18:06:03 -0800291enum X86EncodingKind {
Ian Rogersde797832012-03-06 10:18:10 -0800292 kData, // Special case for raw data
293 kRegImm, kMemImm, kArrayImm, // RI, MI, AI instruction kinds
294 kRegReg, kRegMem, kRegArray, // RR, RM, RA instruction kinds
295 kMemReg, kArrayReg, // MR and AR instruction kinds
296 kUnimplemented // Encoding used when an instruction isn't yet implemented.
Elliott Hughes719ace42012-03-09 18:06:03 -0800297};
Ian Rogersde797832012-03-06 10:18:10 -0800298
299/* A form of instruction with an opcode byte and a secondary opcode within the modrm byte */
Elliott Hughes719ace42012-03-09 18:06:03 -0800300struct OpcodeModRMOpcode {
Ian Rogersde797832012-03-06 10:18:10 -0800301 uint8_t opcode; // 1 byte opcode
302 uint8_t modrm_opcode; // 3 bit opcode that gets encoded in the register bits of the modrm byte
Elliott Hughes719ace42012-03-09 18:06:03 -0800303};
Ian Rogersde797832012-03-06 10:18:10 -0800304
305/* Struct used to define the EncodingMap positions for each X86 opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800306struct X86EncodingMap {
Ian Rogersde797832012-03-06 10:18:10 -0800307 X86OpCode opcode; // e.g. kOpAddRI
308 X86EncodingKind kind; // Used to discriminate in the union below
309 int flags;
310 union {
311 struct {
312 uint8_t rax8_i8_opcode;
313 uint8_t rax32_i32_opcode;
314 OpcodeModRMOpcode rm8_i8_opcode;
315 OpcodeModRMOpcode rm32_i32_opcode;
316 OpcodeModRMOpcode rm32_i8_opcode;
317 } RegMem_Immediate; // kind: kRegImm, kMemImm, kArrayImm
318 struct {
319 uint8_t r8_rm8_opcode;
320 uint8_t r32_rm32_opcode;
321 } Reg_RegMem; // kind: kRegReg, kRegMem, kRegArray
322 struct {
323 uint8_t rm8_r8_opcode;
324 uint8_t rm32_r32_opcode;
325 } RegMem_Reg; // kind: kMemReg, kArrayReg
326 // This is a convenience for static initialization where the kind doesn't require opcode data.
327 int unused; // kind: kData, kUnimplemented
328 } skeleton;
329 const char *name;
330 const char* fmt;
Elliott Hughes719ace42012-03-09 18:06:03 -0800331};
Ian Rogersde797832012-03-06 10:18:10 -0800332
333extern X86EncodingMap EncodingMap[kX86Last];
334
buzbeea7678db2012-03-05 15:35:46 -0800335// FIXME: mem barrier type - what do we do for x86?
336#define kSY 0
337#define kST 0
338
Ian Rogerse32ca232012-03-05 10:20:23 -0800339/* Bit flags describing the behavior of each native opcode */
Elliott Hughes719ace42012-03-09 18:06:03 -0800340enum X86OpFeatureFlags {
Ian Rogerse32ca232012-03-05 10:20:23 -0800341 kIsBranch = 0,
342 kRegDef0,
343 kRegDef1,
344 kRegDefSP,
345 kRegDefList0,
346 kRegDefList1,
347 kRegUse0,
348 kRegUse1,
349 kRegUse2,
350 kRegUse3,
351 kRegUseSP,
352 kRegUseList0,
353 kRegUseList1,
354 kNoOperand,
355 kIsUnaryOp,
356 kIsBinaryOp,
357 kIsTertiaryOp,
358 kIsQuadOp,
359 kIsIT,
360 kSetsCCodes,
361 kUsesCCodes,
362 kMemLoad,
363 kMemStore,
364 kPCRelFixup,
365// FIXME: add NEEDS_FIXUP to instruction attributes
Elliott Hughes719ace42012-03-09 18:06:03 -0800366};
Ian Rogerse32ca232012-03-05 10:20:23 -0800367
368#define IS_LOAD (1 << kMemLoad)
369#define IS_STORE (1 << kMemStore)
370#define IS_BRANCH (1 << kIsBranch)
371#define REG_DEF0 (1 << kRegDef0)
372#define REG_DEF1 (1 << kRegDef1)
373#define REG_DEF_SP (1 << kRegDefSP)
374#define REG_DEF_LR (1 << kRegDefLR)
375#define REG_DEF_LIST0 (1 << kRegDefList0)
376#define REG_DEF_LIST1 (1 << kRegDefList1)
377#define REG_USE0 (1 << kRegUse0)
378#define REG_USE1 (1 << kRegUse1)
379#define REG_USE2 (1 << kRegUse2)
380#define REG_USE3 (1 << kRegUse3)
381#define REG_USE_SP (1 << kRegUseSP)
382#define REG_USE_PC (1 << kRegUsePC)
383#define REG_USE_LIST0 (1 << kRegUseList0)
384#define REG_USE_LIST1 (1 << kRegUseList1)
385#define NO_OPERAND (1 << kNoOperand)
386#define IS_UNARY_OP (1 << kIsUnaryOp)
387#define IS_BINARY_OP (1 << kIsBinaryOp)
388#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
389#define IS_QUAD_OP (1 << kIsQuadOp)
390#define IS_IT (1 << kIsIT)
391#define SETS_CCODES (1 << kSetsCCodes)
392#define USES_CCODES (1 << kUsesCCodes)
393#define NEEDS_FIXUP (1 << kPCRelFixup)
394
395/* attributes, included for compatibility */
396#define REG_DEF_FPCS_LIST0 (0)
397#define REG_DEF_FPCS_LIST2 (0)
398
399
400/* Common combo register usage patterns */
401#define REG_USE01 (REG_USE0 | REG_USE1)
402#define REG_USE02 (REG_USE0 | REG_USE2)
403#define REG_USE012 (REG_USE01 | REG_USE2)
404#define REG_USE12 (REG_USE1 | REG_USE2)
405#define REG_USE23 (REG_USE2 | REG_USE3)
406#define REG_DEF01 (REG_DEF0 | REG_DEF1)
407#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
408#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
409#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
410#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
411#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
412#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
413
Ian Rogerse32ca232012-03-05 10:20:23 -0800414/* Keys for target-specific scheduling and other optimization hints */
Elliott Hughes719ace42012-03-09 18:06:03 -0800415enum X86TargetOptHints {
Ian Rogerse32ca232012-03-05 10:20:23 -0800416 kMaxHoistDistance,
Elliott Hughes719ace42012-03-09 18:06:03 -0800417};
Ian Rogerse32ca232012-03-05 10:20:23 -0800418
Ian Rogerse32ca232012-03-05 10:20:23 -0800419
Ian Rogersde797832012-03-06 10:18:10 -0800420#define IS_SIMM8(v) ((-128 <= (v)) && ((v) <= 127))
Ian Rogerse32ca232012-03-05 10:20:23 -0800421
422} // namespace art
423
424#endif // ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_