blob: 3681cdb482b0afa6b3e178de22cdd27d2f05f4ca [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
136
137typedef enum ResourceEncodingPos {
138 kGPReg0 = 0,
139 kRegSP = 4,
140 kRegLR = -1,
141 kFPReg0 = 16, // xmm0 .. xmm7/xmm15
142 kFPRegEnd = 32,
143 kRegEnd = kFPRegEnd,
144 kCCode = kRegEnd,
145 // The following four bits are for memory disambiguation
146 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
147 kLiteral, // 2 Literal pool (can be fully disambiguated)
148 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
149 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
150} ResourceEncodingPos;
151
152#define ENCODE_REG_LIST(N) ((u8) N)
153#define ENCODE_REG_SP (1ULL << kRegSP)
154#define ENCODE_CCODE (1ULL << kCCode)
155#define ENCODE_FP_STATUS (1ULL << kFPStatus)
156
157/* Abstract memory locations */
158#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
159#define ENCODE_LITERAL (1ULL << kLiteral)
160#define ENCODE_HEAP_REF (1ULL << kHeapRef)
161#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
162
163#define ENCODE_ALL (~0ULL)
164#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
165 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
166
167#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
168#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
169
170/*
171 * Annotate special-purpose core registers:
172 */
173
174typedef enum NativeRegisterPool {
175 r0 = 0,
176 rAX = r0,
177 r1 = 1,
178 rCX = r1,
179 r2 = 2,
180 rDX = r2,
181 r3 = 3,
182 rBX = r3,
183 r4sp = 4,
184 rSP =r4sp,
185 r5 = 5,
186 rBP = r5,
187 r6 = 6,
188 rSI = r6,
189 r7 = 7,
190 rDI = r7,
191 r8 = 8,
192 r9 = 9,
193 r10 = 10,
194 r11 = 11,
195 r12 = 12,
196 r13 = 13,
197 r14 = 14,
198 r15 = 15,
199 fr0 = 0 + FP_REG_OFFSET,
200 fr1 = 1 + FP_REG_OFFSET,
201 fr2 = 2 + FP_REG_OFFSET,
202 fr3 = 3 + FP_REG_OFFSET,
203 fr4 = 4 + FP_REG_OFFSET,
204 fr5 = 5 + FP_REG_OFFSET,
205 fr6 = 6 + FP_REG_OFFSET,
206 fr7 = 7 + FP_REG_OFFSET,
207 fr8 = 8 + FP_REG_OFFSET,
208 fr9 = 9 + FP_REG_OFFSET,
209 fr10 = 10 + FP_REG_OFFSET,
210 fr11 = 11 + FP_REG_OFFSET,
211 fr12 = 12 + FP_REG_OFFSET,
212 fr13 = 13 + FP_REG_OFFSET,
213 fr14 = 14 + FP_REG_OFFSET,
214 fr15 = 15 + FP_REG_OFFSET,
215} NativeRegisterPool;
216
217/*
218 * Target-independent aliases
219 */
220
221#define rARG0 rAX
222#define rARG1 rDX
223#define rARG2 rCX
224#define rRET0 rAX
225#define rRET1 rDX
226
227#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
228
229/*
230 * The following enum defines the list of supported Thumb instructions by the
231 * assembler. Their corresponding snippet positions will be defined in
232 * Assemble.c.
233 */
234typedef enum X86OpCode {
235 kPseudoSuspendTarget = -15,
236 kPseudoThrowTarget = -14,
237 kPseudoCaseLabel = -13,
238 kPseudoMethodEntry = -12,
239 kPseudoMethodExit = -11,
240 kPseudoBarrier = -10,
241 kPseudoExtended = -9,
242 kPseudoSSARep = -8,
243 kPseudoEntryBlock = -7,
244 kPseudoExitBlock = -6,
245 kPseudoTargetLabel = -5,
246 kPseudoDalvikByteCodeBoundary = -4,
247 kPseudoPseudoAlign4 = -3,
248 kPseudoEHBlockLabel = -2,
249 kPseudoNormalBlockLabel = -1,
250 kOpAddRR, // add reg, reg
251 kOpAddRM, // add reg, [reg + displacement]
252 kOpAddMR, // add [reg + displacement], reg
253 kOpAddRI, // add reg, #immediate
254 kOpAddMI, // add [reg + displacement], #immediate
255 kOpAddRA, // add reg, [base reg + index reg * scale + displacment]
256 kOpAddAR, // add [base reg + index reg * scale + displacment], reg
257 kOpAddAI, // add [base reg + index reg * scale + displacment], #immediate
258 kX86First,
259 kX86Last
260} X86OpCode;
261
262/* Bit flags describing the behavior of each native opcode */
263typedef enum X86OpFeatureFlags {
264 kIsBranch = 0,
265 kRegDef0,
266 kRegDef1,
267 kRegDefSP,
268 kRegDefList0,
269 kRegDefList1,
270 kRegUse0,
271 kRegUse1,
272 kRegUse2,
273 kRegUse3,
274 kRegUseSP,
275 kRegUseList0,
276 kRegUseList1,
277 kNoOperand,
278 kIsUnaryOp,
279 kIsBinaryOp,
280 kIsTertiaryOp,
281 kIsQuadOp,
282 kIsIT,
283 kSetsCCodes,
284 kUsesCCodes,
285 kMemLoad,
286 kMemStore,
287 kPCRelFixup,
288// FIXME: add NEEDS_FIXUP to instruction attributes
289} X86OpFeatureFlags;
290
291#define IS_LOAD (1 << kMemLoad)
292#define IS_STORE (1 << kMemStore)
293#define IS_BRANCH (1 << kIsBranch)
294#define REG_DEF0 (1 << kRegDef0)
295#define REG_DEF1 (1 << kRegDef1)
296#define REG_DEF_SP (1 << kRegDefSP)
297#define REG_DEF_LR (1 << kRegDefLR)
298#define REG_DEF_LIST0 (1 << kRegDefList0)
299#define REG_DEF_LIST1 (1 << kRegDefList1)
300#define REG_USE0 (1 << kRegUse0)
301#define REG_USE1 (1 << kRegUse1)
302#define REG_USE2 (1 << kRegUse2)
303#define REG_USE3 (1 << kRegUse3)
304#define REG_USE_SP (1 << kRegUseSP)
305#define REG_USE_PC (1 << kRegUsePC)
306#define REG_USE_LIST0 (1 << kRegUseList0)
307#define REG_USE_LIST1 (1 << kRegUseList1)
308#define NO_OPERAND (1 << kNoOperand)
309#define IS_UNARY_OP (1 << kIsUnaryOp)
310#define IS_BINARY_OP (1 << kIsBinaryOp)
311#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
312#define IS_QUAD_OP (1 << kIsQuadOp)
313#define IS_IT (1 << kIsIT)
314#define SETS_CCODES (1 << kSetsCCodes)
315#define USES_CCODES (1 << kUsesCCodes)
316#define NEEDS_FIXUP (1 << kPCRelFixup)
317
318/* attributes, included for compatibility */
319#define REG_DEF_FPCS_LIST0 (0)
320#define REG_DEF_FPCS_LIST2 (0)
321
322
323/* Common combo register usage patterns */
324#define REG_USE01 (REG_USE0 | REG_USE1)
325#define REG_USE02 (REG_USE0 | REG_USE2)
326#define REG_USE012 (REG_USE01 | REG_USE2)
327#define REG_USE12 (REG_USE1 | REG_USE2)
328#define REG_USE23 (REG_USE2 | REG_USE3)
329#define REG_DEF01 (REG_DEF0 | REG_DEF1)
330#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
331#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
332#define REG_DEF0_USE2 (REG_DEF0 | REG_USE2)
333#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
334#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
335#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
336
337/* Instruction assembly fieldLoc kind */
338typedef enum X86EncodingKind {
339 kFmtUnused,
340 kFmtBitBlt, /* Bit string using end/start */
341 kFmtDfp, /* Double FP reg */
342 kFmtSfp, /* Single FP reg */
343} X86EncodingKind;
344
345/* Struct used to define the snippet positions for each X86 opcode */
346typedef struct X86EncodingMap {
347 X86OpCode opcode;
348 int flags;
349 const char *name;
350 const char* fmt;
351 int size; /* Size in bytes */
352} X86EncodingMap;
353
354/* Keys for target-specific scheduling and other optimization hints */
355typedef enum X86TargetOptHints {
356 kMaxHoistDistance,
357} X86TargetOptHints;
358
359extern X86EncodingMap EncodingMap[kX86Last];
360
361#define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
362#define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
363#define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
364
365} // namespace art
366
367#endif // ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_