blob: 9d22c4ffae4a052961c8cc5838a46878496d796b [file] [log] [blame]
buzbee67bf8852011-08-17 17:51:35 -07001/*
2 * Copyright (C) 2011 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_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
18#define ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
19
20#include "../../Dalvik.h"
21#include "../../CompilerInternals.h"
22
23/*
24 * Runtime register usage conventions.
25 *
26 * r0-r3: Argument registers in both Dalvik and C/C++ conventions.
27 * However, for Dalvik->Dalvik calls we'll pass the target's Method*
28 * pointer in r0 as a hidden arg0. Otherwise used as codegen scratch
29 * registers.
30 * r0-r1: As in C/C++ r0 is 32-bit return register and r0/r1 is 64-bit
31 * r4 : Callee save (promotion target)
32 * r5 : Callee save (promotion target)
33 * r6 : Callee save (promotion target)
34 * r7 : Callee save (promotion target)
35 * r8 : Callee save (promotion target)
36 * r9 : (rSELF) is reserved (pointer to thread-local storage)
37 * r10 : Callee save (promotion target)
38 * r11 : Callee save (promotion target)
39 * r12 : Scratch, may be trashed by linkage stubs
40 * r13 : (sp) is reserved
41 * r14 : (lr) is reserved
42 * r15 : (pc) is reserved
43 *
44 * 5 core temps that codegen can use (r0, r1, r2, r3, r12)
45 * 7 core registers that can be used for promotion
46 *
47 * Floating pointer registers
48 * s0-s31
49 * d0-d15, where d0={s0,s1}, d1={s2,s3}, ... , d15={s30,s31}
50 *
51 * s16-s31 (d8-d15) preserved across C calls
52 * s0-s15 (d0-d7) trashed across C calls
53 *
54 * s0-s15/d0-d7 used as codegen temp/scratch
55 * s16-s31/d8-d31 can be used for promotion.
56 *
57 * Calling convention
58 * o On a call to a Dalvik method, pass target's Method* in r0
59 * o r1-r3 will be used for up to the first 3 words of arguments
60 * o Arguments past the first 3 words will be placed in appropriate
61 * out slots by the caller.
62 * o If a 64-bit argument would span the register/memory argument
63 * boundary, it will instead be fully passed in the frame.
64 * o Maintain a 16-byte stack alignment
65 *
66 * Stack frame diagram (stack grows down, higher addresses at top):
67 *
68 * +------------------------+
69 * | IN[ins-1] | {Note: resides in caller's frame}
70 * | . |
71 * | IN[0] |
72 * | caller's Method* |
73 * +========================+ {Note: start of callee's frame}
74 * | spill region | {variable sized - will include lr if non-leaf.}
75 * +------------------------+
76 * | ...filler word... | {Note: used as 2nd word of V[locals-1] if long]
77 * +------------------------+
78 * | V[locals-1] |
79 * | V[locals-2] |
80 * | . |
81 * | . |
82 * | V[1] |
83 * | V[0] |
84 * +------------------------+
85 * | 0 to 3 words padding |
86 * +------------------------+
87 * | OUT[outs-1] |
88 * | OUT[outs-2] |
89 * | . |
90 * | OUT[0] |
91 * | curMethod* | <<== sp w/ 16-byte alignment
92 * +========================+
93 */
94
95/* Offset to distingish FP regs */
96#define FP_REG_OFFSET 32
97/* Offset to distinguish DP FP regs */
98#define FP_DOUBLE 64
99/* Reg types */
100#define REGTYPE(x) (x & (FP_REG_OFFSET | FP_DOUBLE))
101#define FPREG(x) ((x & FP_REG_OFFSET) == FP_REG_OFFSET)
102#define LOWREG(x) ((x & 0x7) == x)
103#define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
104#define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
105/*
106 * Note: the low register of a floating point pair is sufficient to
107 * create the name of a double, but require both names to be passed to
108 * allow for asserts to verify that the pair is consecutive if significant
109 * rework is done in this area. Also, it is a good reminder in the calling
110 * code that reg locations always describe doubles as a pair of singles.
111 */
112#define S2D(x,y) ((x) | FP_DOUBLE)
113/* Mask to strip off fp flags */
114#define FP_REG_MASK (FP_REG_OFFSET-1)
115/* non-existent Dalvik register */
116#define vNone (-1)
117/* non-existant physical register */
118#define rNone (-1)
119
120/* RegisterLocation templates return values (r0, or r0/r1) */
121#define LOC_C_RETURN {kLocPhysReg, 0, 0, r0, INVALID_REG, INVALID_SREG, \
122 1, kLocPhysReg, r0, INVALID_REG, INVALID_OFFSET}
123#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r0, r1, INVALID_SREG, \
124 1, kLocPhysReg, r0, r1, INVALID_OFFSET}
125/* RegisterLocation templates for interpState->retVal; */
126#define LOC_DALVIK_RETURN_VAL {kLocPhysReg, 0, 0, r0, INVALID_REG, \
127 INVALID_SREG, 1, kLocPhysReg, r0, INVALID_REG, \
128 INVALID_OFFSET}
129#define LOC_DALVIK_RETURN_VAL_WIDE {kLocPhysReg, 1, 0, r0, r1, \
130 INVALID_SREG, 1, kLocPhysReg, r0, r1, INVALID_OFFSET}
131
132 /*
133 * Data structure tracking the mapping between a Dalvik register (pair) and a
134 * native register (pair). The idea is to reuse the previously loaded value
135 * if possible, otherwise to keep the value in a native register as long as
136 * possible.
137 */
138typedef struct RegisterInfo {
139 int reg; // Reg number
140 bool inUse; // Has it been allocated?
141 bool isTemp; // Can allocate as temp?
142 bool pair; // Part of a register pair?
143 int partner; // If pair, other reg of pair
144 bool live; // Is there an associated SSA name?
145 bool dirty; // If live, is it dirty?
146 int sReg; // Name of live value
147 struct LIR *defStart; // Starting inst in last def sequence
148 struct LIR *defEnd; // Ending inst in last def sequence
149} RegisterInfo;
150
151typedef struct RegisterPool {
152 ArenaBitVector *nullCheckedRegs; // Which registers have been null-checked?
153 int numCoreRegs;
154 RegisterInfo *coreRegs;
155 int nextCoreReg;
156 int numFPRegs;
157 RegisterInfo *FPRegs;
158 int nextFPReg;
159} RegisterPool;
160
161typedef enum ResourceEncodingPos {
162 kGPReg0 = 0,
163 kRegSP = 13,
164 kRegLR = 14,
165 kRegPC = 15,
166 kFPReg0 = 16,
167 kFPReg16 = 32,
168 kRegEnd = 48,
169 kCCode = kRegEnd,
170 kFPStatus, // FP status word
171 // The following four bits are for memory disambiguation
172 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
173 kLiteral, // 2 Literal pool (can be fully disambiguated)
174 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
175 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
176} ResourceEncodingPos;
177
178#define ENCODE_REG_LIST(N) ((u8) N)
179#define ENCODE_REG_SP (1ULL << kRegSP)
180#define ENCODE_REG_LR (1ULL << kRegLR)
181#define ENCODE_REG_PC (1ULL << kRegPC)
182#define ENCODE_CCODE (1ULL << kCCode)
183#define ENCODE_FP_STATUS (1ULL << kFPStatus)
184#define ENCODE_REG_FPCS_LIST(N) ((u8)N << kFPReg16)
185
186/* Abstract memory locations */
187#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
188#define ENCODE_LITERAL (1ULL << kLiteral)
189#define ENCODE_HEAP_REF (1ULL << kHeapRef)
190#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
191
192#define ENCODE_ALL (~0ULL)
193#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
194 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
195
196#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
197#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
198
199typedef enum OpSize {
200 kWord,
201 kLong,
202 kSingle,
203 kDouble,
204 kUnsignedHalf,
205 kSignedHalf,
206 kUnsignedByte,
207 kSignedByte,
208} OpSize;
209
210typedef enum OpKind {
211 kOpMov,
212 kOpMvn,
213 kOpCmp,
214 kOpLsl,
215 kOpLsr,
216 kOpAsr,
217 kOpRor,
218 kOpNot,
219 kOpAnd,
220 kOpOr,
221 kOpXor,
222 kOpNeg,
223 kOpAdd,
224 kOpAdc,
225 kOpSub,
226 kOpSbc,
227 kOpRsub,
228 kOpMul,
229 kOpDiv,
230 kOpRem,
231 kOpBic,
232 kOpCmn,
233 kOpTst,
234 kOpBkpt,
235 kOpBlx,
236 kOpPush,
237 kOpPop,
238 kOp2Char,
239 kOp2Short,
240 kOp2Byte,
241 kOpCondBr,
242 kOpUncondBr,
243} OpKind;
244
245/*
246 * Annotate special-purpose core registers:
247 * - VM: r4PC, r5FP, and r6SELF
248 * - ARM architecture: r13sp, r14lr, and r15pc
249 *
250 * rPC, rFP, and rSELF are for architecture-independent code to use.
251 */
252typedef enum NativeRegisterPool {
253 r0 = 0,
254 r1 = 1,
255 r2 = 2,
256 r3 = 3,
257 r4 = 4,
258 r5 = 5,
259 r6 = 6,
260 r7 = 7,
261 r8 = 8,
262 rSELF = 9,
263 r10 = 10,
264 r11 = 11,
265 r12 = 12,
266 r13sp = 13,
267 rSP = 13,
268 r14lr = 14,
269 rLR = 14,
270 r15pc = 15,
271 rPC = 15,
272 fr0 = 0 + FP_REG_OFFSET,
273 fr1 = 1 + FP_REG_OFFSET,
274 fr2 = 2 + FP_REG_OFFSET,
275 fr3 = 3 + FP_REG_OFFSET,
276 fr4 = 4 + FP_REG_OFFSET,
277 fr5 = 5 + FP_REG_OFFSET,
278 fr6 = 6 + FP_REG_OFFSET,
279 fr7 = 7 + FP_REG_OFFSET,
280 fr8 = 8 + FP_REG_OFFSET,
281 fr9 = 9 + FP_REG_OFFSET,
282 fr10 = 10 + FP_REG_OFFSET,
283 fr11 = 11 + FP_REG_OFFSET,
284 fr12 = 12 + FP_REG_OFFSET,
285 fr13 = 13 + FP_REG_OFFSET,
286 fr14 = 14 + FP_REG_OFFSET,
287 fr15 = 15 + FP_REG_OFFSET,
288 fr16 = 16 + FP_REG_OFFSET,
289 fr17 = 17 + FP_REG_OFFSET,
290 fr18 = 18 + FP_REG_OFFSET,
291 fr19 = 19 + FP_REG_OFFSET,
292 fr20 = 20 + FP_REG_OFFSET,
293 fr21 = 21 + FP_REG_OFFSET,
294 fr22 = 22 + FP_REG_OFFSET,
295 fr23 = 23 + FP_REG_OFFSET,
296 fr24 = 24 + FP_REG_OFFSET,
297 fr25 = 25 + FP_REG_OFFSET,
298 fr26 = 26 + FP_REG_OFFSET,
299 fr27 = 27 + FP_REG_OFFSET,
300 fr28 = 28 + FP_REG_OFFSET,
301 fr29 = 29 + FP_REG_OFFSET,
302 fr30 = 30 + FP_REG_OFFSET,
303 fr31 = 31 + FP_REG_OFFSET,
304 dr0 = fr0 + FP_DOUBLE,
305 dr1 = fr2 + FP_DOUBLE,
306 dr2 = fr4 + FP_DOUBLE,
307 dr3 = fr6 + FP_DOUBLE,
308 dr4 = fr8 + FP_DOUBLE,
309 dr5 = fr10 + FP_DOUBLE,
310 dr6 = fr12 + FP_DOUBLE,
311 dr7 = fr14 + FP_DOUBLE,
312 dr8 = fr16 + FP_DOUBLE,
313 dr9 = fr18 + FP_DOUBLE,
314 dr10 = fr20 + FP_DOUBLE,
315 dr11 = fr22 + FP_DOUBLE,
316 dr12 = fr24 + FP_DOUBLE,
317 dr13 = fr26 + FP_DOUBLE,
318 dr14 = fr28 + FP_DOUBLE,
319 dr15 = fr30 + FP_DOUBLE,
320} NativeRegisterPool;
321
322/* Shift encodings */
323typedef enum ArmShiftEncodings {
324 kArmLsl = 0x0,
325 kArmLsr = 0x1,
326 kArmAsr = 0x2,
327 kArmRor = 0x3
328} ArmShiftEncodings;
329
330/* Thumb condition encodings */
331typedef enum ArmConditionCode {
332 kArmCondEq = 0x0, /* 0000 */
333 kArmCondNe = 0x1, /* 0001 */
334 kArmCondCs = 0x2, /* 0010 */
335 kArmCondCc = 0x3, /* 0011 */
336 kArmCondMi = 0x4, /* 0100 */
337 kArmCondPl = 0x5, /* 0101 */
338 kArmCondVs = 0x6, /* 0110 */
339 kArmCondVc = 0x7, /* 0111 */
340 kArmCondHi = 0x8, /* 1000 */
341 kArmCondLs = 0x9, /* 1001 */
342 kArmCondGe = 0xa, /* 1010 */
343 kArmCondLt = 0xb, /* 1011 */
344 kArmCondGt = 0xc, /* 1100 */
345 kArmCondLe = 0xd, /* 1101 */
346 kArmCondAl = 0xe, /* 1110 */
347 kArmCondNv = 0xf, /* 1111 */
348} ArmConditionCode;
349
350#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
351
352/*
353 * The following enum defines the list of supported Thumb instructions by the
354 * assembler. Their corresponding snippet positions will be defined in
355 * Assemble.c.
356 */
357typedef enum ArmOpcode {
358 kArmPseudoCaseLabel = -13,
359 kArmPseudoMethodEntry = -12,
360 kArmPseudoMethodExit = -11,
361 kArmPseudoBarrier = -10,
362 kArmPseudoExtended = -9,
363 kArmPseudoSSARep = -8,
364 kArmPseudoEntryBlock = -7,
365 kArmPseudoExitBlock = -6,
366 kArmPseudoTargetLabel = -5,
367 kArmPseudoDalvikByteCodeBoundary = -4,
368 kArmPseudoPseudoAlign4 = -3,
369 kArmPseudoEHBlockLabel = -2,
370 kArmPseudoNormalBlockLabel = -1,
371 /************************************************************************/
372 kArm16BitData, /* DATA [0] rd[15..0] */
373 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */
374 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
375 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
376 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
377 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
378 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
379 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
380 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */
381 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */
382 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */
383 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */
384 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
385 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
386 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */
387 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */
388 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */
389 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */
390 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */
391 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */
392 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */
393 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */
394 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */
395 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
396 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */
397 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
398 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
399 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
400 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
401 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
402 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */
403 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */
404 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
405 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
406 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
407 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
408 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
409 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
410 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
411 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
412 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
413 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
414 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
415 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
416 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
417 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
418 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
419 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
420 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
421 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
422 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
423 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */
424 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */
425 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */
426 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */
427 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */
428 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */
429 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */
430 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */
431 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */
432 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
433 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
434 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */
435 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
436 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
437 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
438 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
439 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
440 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
441 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
442 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */
443 kThumbSwi, /* swi [11011111] imm_8[7..0] */
444 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */
445 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
446 [1010] imm_8[7..0] */
447 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
448 [1011] imm_8[7..0] */
449 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16]
450 rd[15-12] [10100000] rm[3..0] */
451 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16]
452 rd[15-12] [10110000] rm[3..0] */
453 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
454 [1010] imm_8[7..0] */
455 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
456 [1011] imm_8[7..0] */
457 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16]
458 rd[15-12] [10100040] rm[3..0] */
459 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16]
460 rd[15-12] [10110040] rm[3..0] */
461 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16]
462 rd[15-12] [10100000] rm[3..0] */
463 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16]
464 rd[15-12] [10110000] rm[3..0] */
465 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16]
466 rd[15-12] [10100000] rm[3..0] */
467 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16]
468 rd[15-12] [10110000] rm[3..0] */
469 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
470 [10101100] vm[3..0] */
471 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
472 [10111100] vm[3..0] */
473 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
474 [10101100] vm[3..0] */
475 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
476 [10111100] vm[3..0] */
477 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
478 [10101100] vm[3..0] */
479 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
480 [10111100] vm[3..0] */
481 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
482 [10101100] vm[3..0] */
483 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
484 [10111100] vm[3..0] */
485 kThumb2MovImmShift, /* mov(T2) rd, #<const> [11110] i [00001001111]
486 imm3 rd[11..8] imm8 */
487 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
488 imm3 rd[11..8] imm8 */
489 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
490 rn[19..16] rt[15..12] imm12[11..0] */
491 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
492 rn[19..16] rt[15..12] imm12[11..0] */
493 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
494 rn[19..16] rt[15..12] [1100] imm[7..0]*/
495 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
496 rn[19..16] rt[15..12] [1100] imm[7..0]*/
497 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
498 rn[2..0] */
499 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3]
500 rn[2..0] */
501 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
502 [0] imm3[14..12] rd[11..8] imm8[7..0] */
503 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8]
504 [0000] rm[3..0] */
505 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000]
506 vd[15..12] 101001] M [0] vm[3..0] */
507 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000]
508 vd[15..12] 101101] M [0] vm[3..0] */
509 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
510 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */
511 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
512 [0000] rm[3..0] */
513 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
514 [0000] rm[3..0] */
515 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
516 [0000] rm[3..0] */
517 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111]
518 [0000] rm[3..0] */
519 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
520 [0] imm3[14..12] rd[11..8] imm8[7..0] */
521 kThumb2MvnImmShift, /* mov(T2) rd, #<const> [11110] i [00011011110]
522 imm3 rd[11..8] imm8 */
523 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
524 rm[3-0] */
525 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
526 [0] imm3[14-12] rd[11-8] w[4-0] */
527 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
528 [0] imm3[14-12] rd[11-8] w[4-0] */
529 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
530 rt[15-12] [000000] imm[5-4] rm[3-0] */
531 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
532 rt[15-12] [000000] imm[5-4] rm[3-0] */
533 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
534 rt[15-12] [000000] imm[5-4] rm[3-0] */
535 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
536 rt[15-12] [000000] imm[5-4] rm[3-0] */
537 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
538 rt[15-12] [000000] imm[5-4] rm[3-0] */
539 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
540 rt[15-12] [000000] imm[5-4] rm[3-0] */
541 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
542 rt[15-12] [000000] imm[5-4] rm[3-0] */
543 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
544 rt[15-12] [000000] imm[5-4] rm[3-0] */
545 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011]
546 rt[15..12] rn[19..16] imm12[11..0] */
547 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
548 rt[15..12] rn[19..16] imm12[11..0] */
549 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001]
550 rt[15..12] rn[19..16] imm12[11..0] */
551 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
552 rt[15..12] rn[19..16] imm12[11..0] */
553 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010]
554 rt[15..12] rn[19..16] imm12[11..0] */
555 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
556 rt[15..12] rn[19..16] imm12[11..0] */
557 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
558 kThumb2Push, /* push [1110100100101101] list[15-0]*/
559 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
560 imm3 [1111] imm8[7..0] */
561 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
562 [0000] rm[3..0] */
563 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
564 [0000] rm[3..0] */
565 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
566 [0000] rm[3..0] */
567 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111]
568 [0000] rm[3..0] */
569 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
570 [0000] rm[3..0] */
571 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
572 [0000] rm[3..0] */
573 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000]
574 rm[3..0] */
575 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
576 imm8[7..0] */
577 kThumb2NegRR, /* actually rsub rd, rn, #0 */
578 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
579 [0000] rm[3..0] */
580 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111]
581 [0000] rm[3..0] */
582 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
583 [0000] rm[3..0] */
584 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
585 [0000] rm[3..0] */
586 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
587 [0000] rm[3..0] */
588 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
589 [0000] rm[3..0] */
590 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
591 [00] rm[3..0] */
592 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
593 [01] rm[3..0] */
594 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
595 [10] rm[3..0] */
596 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
597 [11] rm[3..0] */
598 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3
599 rd[11..8] imm8 */
600 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3
601 rd[11..8] imm8 */
602 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3
603 rd[11..8] imm8 */
604 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3
605 rd[11..8] imm8 */
606 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3
607 rd[11..8] imm8 */
608 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3
609 rd[11..8] imm8 */
610 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3
611 rd[11..8] imm8 */
612 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3
613 rd[11..8] imm8 */
614 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */
615 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */
616 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011]
617 E [1] M [0] rm[3-0] */
618 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011]
619 E [1] M [0] rm[3-0] */
620 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
621 imm12[11-0] */
622 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
623 J1 [0] J2 imm11[10..0] */
624 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
625 M [0] vm[3-0] */
626 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
627 M [0] vm[3-0] */
628 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
629 N [0010000] */
630 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
631 N [0010000] */
632 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12]
633 [101100] M [1] vm[3-0] */
634 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12]
635 [101100] M [1] vm[3-0] */
636 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12]
637 [1011110] M [0] vm[3-0] */
638 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12]
639 [1010110] M [0] vm[3-0] */
640 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12]
641 [1011110] M [0] vm[3-0] */
642 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12]
643 [1010110] M [0] vm[3-0] */
644 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
645 [10100000] imm4l[3-0] */
646 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
647 [10110000] imm4l[3-0] */
648 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
649 [0000] rm[3-0] */
650 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12]
651 rdhi[11-8] [0000] rm[3-0] */
652 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
653 imm8[7-0] */
654 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
655 imm8[7-0] */
656 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
657 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
658 rd[11-8] imm2[7-6] [0] msb[4-0] */
659 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
660 rd[11-8] imm2[7-6] [0] msb[4-0] */
661 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */
662 kThumb2LdrPcReln12, /* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
663 imm12[11-0] */
664 kThumb2Stm, /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
665 kThumbUndefined, /* undefined [11011110xxxxxxxx] */
666 kThumb2VPopCS, /* vpop <list of callee save fp singles (s16+) */
667 kThumb2VPushCS, /* vpush <list callee save fp singles (s16+) */
668 kThumb2Vldms, /* vldms rd, <list> */
669 kThumb2Vstms, /* vstms rd, <list> */
670 kThumb2BUncond, /* b <label> */
671 kThumb2MovImm16H, /* similar to kThumb2MovImm16, but target high hw */
672 kThumb2AddPCR, /* Thumb2 2-operand add with hard-coded PC target */
673 kThumb2AdrST, /* Special purpose encoding of ADR for switch tables */
674 kThumb2MovImm16LST, /* Special purpose version for switch table use */
675 kThumb2MovImm16HST, /* Special purpose version for switch table use */
676 kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */
677 kThumb2SubsRRI12, /* setflags encoding */
678 kArmLast,
679} ArmOpcode;
680
681/* DMB option encodings */
682typedef enum ArmOpDmbOptions {
683 kSY = 0xf,
684 kST = 0xe,
685 kISH = 0xb,
686 kISHST = 0xa,
687 kNSH = 0x7,
688 kNSHST = 0x6
689} ArmOpDmbOptions;
690
691/* Bit flags describing the behavior of each native opcode */
692typedef enum ArmOpFeatureFlags {
693 kIsBranch = 0,
694 kRegDef0,
695 kRegDef1,
696 kRegDefSP,
697 kRegDefLR,
698 kRegDefList0,
699 kRegDefList1,
700 kRegDefFPCSList0,
701 kRegDefFPCSList2,
702 kRegDefList2,
703 kRegUse0,
704 kRegUse1,
705 kRegUse2,
706 kRegUse3,
707 kRegUseSP,
708 kRegUsePC,
709 kRegUseList0,
710 kRegUseList1,
711 kRegUseFPCSList0,
712 kRegUseFPCSList2,
713 kNoOperand,
714 kIsUnaryOp,
715 kIsBinaryOp,
716 kIsTertiaryOp,
717 kIsQuadOp,
718 kIsIT,
719 kSetsCCodes,
720 kUsesCCodes,
721 kMemLoad,
722 kMemStore,
723} ArmOpFeatureFlags;
724
725#define IS_LOAD (1 << kMemLoad)
726#define IS_STORE (1 << kMemStore)
727#define IS_BRANCH (1 << kIsBranch)
728#define REG_DEF0 (1 << kRegDef0)
729#define REG_DEF1 (1 << kRegDef1)
730#define REG_DEF_SP (1 << kRegDefSP)
731#define REG_DEF_LR (1 << kRegDefLR)
732#define REG_DEF_LIST0 (1 << kRegDefList0)
733#define REG_DEF_LIST1 (1 << kRegDefList1)
734#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0)
735#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2)
736#define REG_USE0 (1 << kRegUse0)
737#define REG_USE1 (1 << kRegUse1)
738#define REG_USE2 (1 << kRegUse2)
739#define REG_USE3 (1 << kRegUse3)
740#define REG_USE_SP (1 << kRegUseSP)
741#define REG_USE_PC (1 << kRegUsePC)
742#define REG_USE_LIST0 (1 << kRegUseList0)
743#define REG_USE_LIST1 (1 << kRegUseList1)
744#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0)
745#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2)
746#define NO_OPERAND (1 << kNoOperand)
747#define IS_UNARY_OP (1 << kIsUnaryOp)
748#define IS_BINARY_OP (1 << kIsBinaryOp)
749#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
750#define IS_QUAD_OP (1 << kIsQuadOp)
751#define IS_IT (1 << kIsIT)
752#define SETS_CCODES (1 << kSetsCCodes)
753#define USES_CCODES (1 << kUsesCCodes)
754
755/* Common combo register usage patterns */
756#define REG_USE01 (REG_USE0 | REG_USE1)
757#define REG_USE012 (REG_USE01 | REG_USE2)
758#define REG_USE12 (REG_USE1 | REG_USE2)
759#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
760#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
761#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
762#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
763#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
764
765/* Instruction assembly fieldLoc kind */
766typedef enum ArmEncodingKind {
767 kFmtUnused,
768 kFmtBitBlt, /* Bit string using end/start */
769 kFmtDfp, /* Double FP reg */
770 kFmtSfp, /* Single FP reg */
771 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
772 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
773 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
774 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
775 kFmtShift, /* Shift descriptor, [14..12,7..4] */
776 kFmtLsb, /* least significant bit using [14..12][7..6] */
777 kFmtBWidth, /* bit-field width, encoded as width-1 */
778 kFmtShift5, /* Shift count, [14..12,7..6] */
779 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
780 kFmtFPImm, /* Encoded floating point immediate */
781 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
782} ArmEncodingKind;
783
784/* Struct used to define the snippet positions for each Thumb opcode */
785typedef struct ArmEncodingMap {
786 u4 skeleton;
787 struct {
788 ArmEncodingKind kind;
789 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
790 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
791 } fieldLoc[4];
792 ArmOpcode opcode;
793 int flags;
794 const char* name;
795 const char* fmt;
796 int size;
797} ArmEncodingMap;
798
799/* Keys for target-specific scheduling and other optimization hints */
800typedef enum ArmTargetOptHints {
801 kMaxHoistDistance,
802} ArmTargetOptHints;
803
804extern ArmEncodingMap EncodingMap[kArmLast];
805
806/*
807 * Each instance of this struct holds a pseudo or real LIR instruction:
808 * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
809 * - real ones will be assembled into Thumb instructions.
810 *
811 * Machine resources are encoded into a 64-bit vector, where the encodings are
812 * as following:
813 * - [ 0..15]: general purpose registers including PC, SP, and LR
814 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
815 * starts at bit 16
816 * - [48]: IT block
817 * - [49]: integer condition code
818 * - [50]: floatint-point status word
819 */
820typedef struct ArmLIR {
821 LIR generic;
822 ArmOpcode opcode;
823 int operands[4]; // [0..3] = [dest, src1, src2, extra]
824 struct {
825 bool isNop:1; // LIR is optimized away
826 bool insertWrapper:1; // insert branch to emulate memory accesses
827 unsigned int age:4; // default is 0, set lazily by the optimizer
828 unsigned int size:3; // bytes (2 for thumb, 2/4 for thumb2)
829 unsigned int unused:23;
830 } flags;
831 int aliasInfo; // For Dalvik register & litpool disambiguation
832 u8 useMask; // Resource mask for use
833 u8 defMask; // Resource mask for def
834} ArmLIR;
835
836typedef struct SwitchTable {
837 int offset;
838 const u2* table; // Original dex table
839 int vaddr; // Dalvik offset of switch opcode
840 ArmLIR* bxInst; // Switch indirect branch instruction
841 ArmLIR** targets; // Array of case targets
842} SwitchTable;
843
844typedef struct FillArrayData {
845 int offset;
846 const u2* table; // Original dex table
847 int size;
848 int vaddr; // Dalvik offset of OP_FILL_ARRAY_DATA opcode
849} FillArrayData;
850
851/* Init values when a predicted chain is initially assembled */
852/* E7FE is branch to self */
853#define PREDICTED_CHAIN_BX_PAIR_INIT 0xe7fe
854
855/* Utility macros to traverse the LIR/ArmLIR list */
856#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
857#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
858
859#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
860#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
861
862#define CHAIN_CELL_OFFSET_TAG 0xcdab
863
864#define CHAIN_CELL_NORMAL_SIZE 12
865#define CHAIN_CELL_PREDICTED_SIZE 16
866
867#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_