blob: 31f86af2698a7ef9a3ee7f5b7a1f6406d78d23e9 [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
141typedef enum ResourceEncodingPos {
142 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))
154} ResourceEncodingPos;
155
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
178typedef enum NativeRegisterPool {
179 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,
219} NativeRegisterPool;
220
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/*
234 * The following enum defines the list of supported Thumb instructions by the
235 * assembler. Their corresponding snippet positions will be defined in
236 * Assemble.c.
237 */
238typedef enum X86OpCode {
239 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,
254 kOpAddRR, // add reg, reg
255 kOpAddRM, // add reg, [reg + displacement]
256 kOpAddMR, // add [reg + displacement], reg
257 kOpAddRI, // add reg, #immediate
258 kOpAddMI, // add [reg + displacement], #immediate
259 kOpAddRA, // add reg, [base reg + index reg * scale + displacment]
260 kOpAddAR, // add [base reg + index reg * scale + displacment], reg
261 kOpAddAI, // add [base reg + index reg * scale + displacment], #immediate
262 kX86First,
263 kX86Last
264} X86OpCode;
265
buzbeea7678db2012-03-05 15:35:46 -0800266// FIXME: mem barrier type - what do we do for x86?
267#define kSY 0
268#define kST 0
269
Ian Rogerse32ca232012-03-05 10:20:23 -0800270/* Bit flags describing the behavior of each native opcode */
271typedef enum X86OpFeatureFlags {
272 kIsBranch = 0,
273 kRegDef0,
274 kRegDef1,
275 kRegDefSP,
276 kRegDefList0,
277 kRegDefList1,
278 kRegUse0,
279 kRegUse1,
280 kRegUse2,
281 kRegUse3,
282 kRegUseSP,
283 kRegUseList0,
284 kRegUseList1,
285 kNoOperand,
286 kIsUnaryOp,
287 kIsBinaryOp,
288 kIsTertiaryOp,
289 kIsQuadOp,
290 kIsIT,
291 kSetsCCodes,
292 kUsesCCodes,
293 kMemLoad,
294 kMemStore,
295 kPCRelFixup,
296// FIXME: add NEEDS_FIXUP to instruction attributes
297} X86OpFeatureFlags;
298
299#define IS_LOAD (1 << kMemLoad)
300#define IS_STORE (1 << kMemStore)
301#define IS_BRANCH (1 << kIsBranch)
302#define REG_DEF0 (1 << kRegDef0)
303#define REG_DEF1 (1 << kRegDef1)
304#define REG_DEF_SP (1 << kRegDefSP)
305#define REG_DEF_LR (1 << kRegDefLR)
306#define REG_DEF_LIST0 (1 << kRegDefList0)
307#define REG_DEF_LIST1 (1 << kRegDefList1)
308#define REG_USE0 (1 << kRegUse0)
309#define REG_USE1 (1 << kRegUse1)
310#define REG_USE2 (1 << kRegUse2)
311#define REG_USE3 (1 << kRegUse3)
312#define REG_USE_SP (1 << kRegUseSP)
313#define REG_USE_PC (1 << kRegUsePC)
314#define REG_USE_LIST0 (1 << kRegUseList0)
315#define REG_USE_LIST1 (1 << kRegUseList1)
316#define NO_OPERAND (1 << kNoOperand)
317#define IS_UNARY_OP (1 << kIsUnaryOp)
318#define IS_BINARY_OP (1 << kIsBinaryOp)
319#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
320#define IS_QUAD_OP (1 << kIsQuadOp)
321#define IS_IT (1 << kIsIT)
322#define SETS_CCODES (1 << kSetsCCodes)
323#define USES_CCODES (1 << kUsesCCodes)
324#define NEEDS_FIXUP (1 << kPCRelFixup)
325
326/* attributes, included for compatibility */
327#define REG_DEF_FPCS_LIST0 (0)
328#define REG_DEF_FPCS_LIST2 (0)
329
330
331/* Common combo register usage patterns */
332#define REG_USE01 (REG_USE0 | REG_USE1)
333#define REG_USE02 (REG_USE0 | REG_USE2)
334#define REG_USE012 (REG_USE01 | REG_USE2)
335#define REG_USE12 (REG_USE1 | REG_USE2)
336#define REG_USE23 (REG_USE2 | REG_USE3)
337#define REG_DEF01 (REG_DEF0 | REG_DEF1)
338#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
339#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
340#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
341#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
342#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
343#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
344
345/* Instruction assembly fieldLoc kind */
346typedef enum X86EncodingKind {
347 kFmtUnused,
348 kFmtBitBlt, /* Bit string using end/start */
349 kFmtDfp, /* Double FP reg */
350 kFmtSfp, /* Single FP reg */
351} X86EncodingKind;
352
353/* Struct used to define the snippet positions for each X86 opcode */
354typedef struct X86EncodingMap {
355 X86OpCode opcode;
356 int flags;
357 const char *name;
358 const char* fmt;
359 int size; /* Size in bytes */
360} X86EncodingMap;
361
362/* Keys for target-specific scheduling and other optimization hints */
363typedef enum X86TargetOptHints {
364 kMaxHoistDistance,
365} X86TargetOptHints;
366
367extern X86EncodingMap EncodingMap[kX86Last];
368
369#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
370#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
371#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
372
373} // namespace art
374
375#endif // ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_