blob: 212358f2adb45f22ab56f17fd52ee17c97862f7b [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
buzbee5ade1d22011-09-09 14:44:52 -0700350typedef enum ArmThrowKind {
351 kArmThrowNullPointer,
352 kArmThrowDivZero,
353 kArmThrowArrayBounds,
354 kArmThrowVerificationError,
355 kArmThrowNegArraySize,
356 kArmThrowInternalError,
357 kArmThrowRuntimeException,
358 kArmThrowNoSuchMethod,
buzbeeec5adf32011-09-11 15:25:43 -0700359 kArmThrowStackOverflow,
buzbee5ade1d22011-09-09 14:44:52 -0700360} ArmThrowKind;
361
buzbee67bf8852011-08-17 17:51:35 -0700362#define isPseudoOpcode(opcode) ((int)(opcode) < 0)
363
364/*
365 * The following enum defines the list of supported Thumb instructions by the
366 * assembler. Their corresponding snippet positions will be defined in
367 * Assemble.c.
368 */
369typedef enum ArmOpcode {
buzbee5ade1d22011-09-09 14:44:52 -0700370 kArmPseudoThrowTarget = -14,
buzbee67bf8852011-08-17 17:51:35 -0700371 kArmPseudoCaseLabel = -13,
372 kArmPseudoMethodEntry = -12,
373 kArmPseudoMethodExit = -11,
374 kArmPseudoBarrier = -10,
375 kArmPseudoExtended = -9,
376 kArmPseudoSSARep = -8,
377 kArmPseudoEntryBlock = -7,
378 kArmPseudoExitBlock = -6,
379 kArmPseudoTargetLabel = -5,
380 kArmPseudoDalvikByteCodeBoundary = -4,
381 kArmPseudoPseudoAlign4 = -3,
382 kArmPseudoEHBlockLabel = -2,
383 kArmPseudoNormalBlockLabel = -1,
384 /************************************************************************/
385 kArm16BitData, /* DATA [0] rd[15..0] */
386 kThumbAdcRR, /* adc [0100000101] rm[5..3] rd[2..0] */
387 kThumbAddRRI3, /* add(1) [0001110] imm_3[8..6] rn[5..3] rd[2..0]*/
388 kThumbAddRI8, /* add(2) [00110] rd[10..8] imm_8[7..0] */
389 kThumbAddRRR, /* add(3) [0001100] rm[8..6] rn[5..3] rd[2..0] */
390 kThumbAddRRLH, /* add(4) [01000100] H12[01] rm[5..3] rd[2..0] */
391 kThumbAddRRHL, /* add(4) [01001000] H12[10] rm[5..3] rd[2..0] */
392 kThumbAddRRHH, /* add(4) [01001100] H12[11] rm[5..3] rd[2..0] */
393 kThumbAddPcRel, /* add(5) [10100] rd[10..8] imm_8[7..0] */
394 kThumbAddSpRel, /* add(6) [10101] rd[10..8] imm_8[7..0] */
395 kThumbAddSpI7, /* add(7) [101100000] imm_7[6..0] */
396 kThumbAndRR, /* and [0100000000] rm[5..3] rd[2..0] */
397 kThumbAsrRRI5, /* asr(1) [00010] imm_5[10..6] rm[5..3] rd[2..0] */
398 kThumbAsrRR, /* asr(2) [0100000100] rs[5..3] rd[2..0] */
399 kThumbBCond, /* b(1) [1101] cond[11..8] offset_8[7..0] */
400 kThumbBUncond, /* b(2) [11100] offset_11[10..0] */
401 kThumbBicRR, /* bic [0100001110] rm[5..3] rd[2..0] */
402 kThumbBkpt, /* bkpt [10111110] imm_8[7..0] */
403 kThumbBlx1, /* blx(1) [111] H[10] offset_11[10..0] */
404 kThumbBlx2, /* blx(1) [111] H[01] offset_11[10..0] */
405 kThumbBl1, /* blx(1) [111] H[10] offset_11[10..0] */
406 kThumbBl2, /* blx(1) [111] H[11] offset_11[10..0] */
407 kThumbBlxR, /* blx(2) [010001111] rm[6..3] [000] */
408 kThumbBx, /* bx [010001110] H2[6..6] rm[5..3] SBZ[000] */
409 kThumbCmnRR, /* cmn [0100001011] rm[5..3] rd[2..0] */
410 kThumbCmpRI8, /* cmp(1) [00101] rn[10..8] imm_8[7..0] */
411 kThumbCmpRR, /* cmp(2) [0100001010] rm[5..3] rd[2..0] */
412 kThumbCmpLH, /* cmp(3) [01000101] H12[01] rm[5..3] rd[2..0] */
413 kThumbCmpHL, /* cmp(3) [01000110] H12[10] rm[5..3] rd[2..0] */
414 kThumbCmpHH, /* cmp(3) [01000111] H12[11] rm[5..3] rd[2..0] */
415 kThumbEorRR, /* eor [0100000001] rm[5..3] rd[2..0] */
416 kThumbLdmia, /* ldmia [11001] rn[10..8] reglist [7..0] */
417 kThumbLdrRRI5, /* ldr(1) [01101] imm_5[10..6] rn[5..3] rd[2..0] */
418 kThumbLdrRRR, /* ldr(2) [0101100] rm[8..6] rn[5..3] rd[2..0] */
419 kThumbLdrPcRel, /* ldr(3) [01001] rd[10..8] imm_8[7..0] */
420 kThumbLdrSpRel, /* ldr(4) [10011] rd[10..8] imm_8[7..0] */
421 kThumbLdrbRRI5, /* ldrb(1) [01111] imm_5[10..6] rn[5..3] rd[2..0] */
422 kThumbLdrbRRR, /* ldrb(2) [0101110] rm[8..6] rn[5..3] rd[2..0] */
423 kThumbLdrhRRI5, /* ldrh(1) [10001] imm_5[10..6] rn[5..3] rd[2..0] */
424 kThumbLdrhRRR, /* ldrh(2) [0101101] rm[8..6] rn[5..3] rd[2..0] */
425 kThumbLdrsbRRR, /* ldrsb [0101011] rm[8..6] rn[5..3] rd[2..0] */
426 kThumbLdrshRRR, /* ldrsh [0101111] rm[8..6] rn[5..3] rd[2..0] */
427 kThumbLslRRI5, /* lsl(1) [00000] imm_5[10..6] rm[5..3] rd[2..0] */
428 kThumbLslRR, /* lsl(2) [0100000010] rs[5..3] rd[2..0] */
429 kThumbLsrRRI5, /* lsr(1) [00001] imm_5[10..6] rm[5..3] rd[2..0] */
430 kThumbLsrRR, /* lsr(2) [0100000011] rs[5..3] rd[2..0] */
431 kThumbMovImm, /* mov(1) [00100] rd[10..8] imm_8[7..0] */
432 kThumbMovRR, /* mov(2) [0001110000] rn[5..3] rd[2..0] */
433 kThumbMovRR_H2H, /* mov(3) [01000111] H12[11] rm[5..3] rd[2..0] */
434 kThumbMovRR_H2L, /* mov(3) [01000110] H12[01] rm[5..3] rd[2..0] */
435 kThumbMovRR_L2H, /* mov(3) [01000101] H12[10] rm[5..3] rd[2..0] */
436 kThumbMul, /* mul [0100001101] rm[5..3] rd[2..0] */
437 kThumbMvn, /* mvn [0100001111] rm[5..3] rd[2..0] */
438 kThumbNeg, /* neg [0100001001] rm[5..3] rd[2..0] */
439 kThumbOrr, /* orr [0100001100] rm[5..3] rd[2..0] */
440 kThumbPop, /* pop [1011110] r[8..8] rl[7..0] */
441 kThumbPush, /* push [1011010] r[8..8] rl[7..0] */
442 kThumbRorRR, /* ror [0100000111] rs[5..3] rd[2..0] */
443 kThumbSbc, /* sbc [0100000110] rm[5..3] rd[2..0] */
444 kThumbStmia, /* stmia [11000] rn[10..8] reglist [7.. 0] */
445 kThumbStrRRI5, /* str(1) [01100] imm_5[10..6] rn[5..3] rd[2..0] */
446 kThumbStrRRR, /* str(2) [0101000] rm[8..6] rn[5..3] rd[2..0] */
447 kThumbStrSpRel, /* str(3) [10010] rd[10..8] imm_8[7..0] */
448 kThumbStrbRRI5, /* strb(1) [01110] imm_5[10..6] rn[5..3] rd[2..0] */
449 kThumbStrbRRR, /* strb(2) [0101010] rm[8..6] rn[5..3] rd[2..0] */
450 kThumbStrhRRI5, /* strh(1) [10000] imm_5[10..6] rn[5..3] rd[2..0] */
451 kThumbStrhRRR, /* strh(2) [0101001] rm[8..6] rn[5..3] rd[2..0] */
452 kThumbSubRRI3, /* sub(1) [0001111] imm_3[8..6] rn[5..3] rd[2..0]*/
453 kThumbSubRI8, /* sub(2) [00111] rd[10..8] imm_8[7..0] */
454 kThumbSubRRR, /* sub(3) [0001101] rm[8..6] rn[5..3] rd[2..0] */
455 kThumbSubSpI7, /* sub(4) [101100001] imm_7[6..0] */
456 kThumbSwi, /* swi [11011111] imm_8[7..0] */
457 kThumbTst, /* tst [0100001000] rm[5..3] rn[2..0] */
458 kThumb2Vldrs, /* vldr low sx [111011011001] rn[19..16] rd[15-12]
459 [1010] imm_8[7..0] */
460 kThumb2Vldrd, /* vldr low dx [111011011001] rn[19..16] rd[15-12]
461 [1011] imm_8[7..0] */
462 kThumb2Vmuls, /* vmul vd, vn, vm [111011100010] rn[19..16]
463 rd[15-12] [10100000] rm[3..0] */
464 kThumb2Vmuld, /* vmul vd, vn, vm [111011100010] rn[19..16]
465 rd[15-12] [10110000] rm[3..0] */
466 kThumb2Vstrs, /* vstr low sx [111011011000] rn[19..16] rd[15-12]
467 [1010] imm_8[7..0] */
468 kThumb2Vstrd, /* vstr low dx [111011011000] rn[19..16] rd[15-12]
469 [1011] imm_8[7..0] */
470 kThumb2Vsubs, /* vsub vd, vn, vm [111011100011] rn[19..16]
471 rd[15-12] [10100040] rm[3..0] */
472 kThumb2Vsubd, /* vsub vd, vn, vm [111011100011] rn[19..16]
473 rd[15-12] [10110040] rm[3..0] */
474 kThumb2Vadds, /* vadd vd, vn, vm [111011100011] rn[19..16]
475 rd[15-12] [10100000] rm[3..0] */
476 kThumb2Vaddd, /* vadd vd, vn, vm [111011100011] rn[19..16]
477 rd[15-12] [10110000] rm[3..0] */
478 kThumb2Vdivs, /* vdiv vd, vn, vm [111011101000] rn[19..16]
479 rd[15-12] [10100000] rm[3..0] */
480 kThumb2Vdivd, /* vdiv vd, vn, vm [111011101000] rn[19..16]
481 rd[15-12] [10110000] rm[3..0] */
482 kThumb2VcvtIF, /* vcvt.F32 vd, vm [1110111010111000] vd[15..12]
483 [10101100] vm[3..0] */
484 kThumb2VcvtID, /* vcvt.F64 vd, vm [1110111010111000] vd[15..12]
485 [10111100] vm[3..0] */
486 kThumb2VcvtFI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
487 [10101100] vm[3..0] */
488 kThumb2VcvtDI, /* vcvt.S32.F32 vd, vm [1110111010111101] vd[15..12]
489 [10111100] vm[3..0] */
490 kThumb2VcvtFd, /* vcvt.F64.F32 vd, vm [1110111010110111] vd[15..12]
491 [10101100] vm[3..0] */
492 kThumb2VcvtDF, /* vcvt.F32.F64 vd, vm [1110111010110111] vd[15..12]
493 [10111100] vm[3..0] */
494 kThumb2Vsqrts, /* vsqrt.f32 vd, vm [1110111010110001] vd[15..12]
495 [10101100] vm[3..0] */
496 kThumb2Vsqrtd, /* vsqrt.f64 vd, vm [1110111010110001] vd[15..12]
497 [10111100] vm[3..0] */
498 kThumb2MovImmShift, /* mov(T2) rd, #<const> [11110] i [00001001111]
499 imm3 rd[11..8] imm8 */
500 kThumb2MovImm16, /* mov(T3) rd, #<const> [11110] i [0010100] imm4 [0]
501 imm3 rd[11..8] imm8 */
502 kThumb2StrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
503 rn[19..16] rt[15..12] imm12[11..0] */
504 kThumb2LdrRRI12, /* str(Imm,T3) rd,[rn,#imm12] [111110001100]
505 rn[19..16] rt[15..12] imm12[11..0] */
506 kThumb2StrRRI8Predec, /* str(Imm,T4) rd,[rn,#-imm8] [111110000100]
507 rn[19..16] rt[15..12] [1100] imm[7..0]*/
508 kThumb2LdrRRI8Predec, /* ldr(Imm,T4) rd,[rn,#-imm8] [111110000101]
509 rn[19..16] rt[15..12] [1100] imm[7..0]*/
510 kThumb2Cbnz, /* cbnz rd,<label> [101110] i [1] imm5[7..3]
511 rn[2..0] */
512 kThumb2Cbz, /* cbn rd,<label> [101100] i [1] imm5[7..3]
513 rn[2..0] */
514 kThumb2AddRRI12, /* add rd, rn, #imm12 [11110] i [100000] rn[19..16]
515 [0] imm3[14..12] rd[11..8] imm8[7..0] */
516 kThumb2MovRR, /* mov rd, rm [11101010010011110000] rd[11..8]
517 [0000] rm[3..0] */
518 kThumb2Vmovs, /* vmov.f32 vd, vm [111011101] D [110000]
519 vd[15..12] 101001] M [0] vm[3..0] */
520 kThumb2Vmovd, /* vmov.f64 vd, vm [111011101] D [110000]
521 vd[15..12] 101101] M [0] vm[3..0] */
522 kThumb2Ldmia, /* ldmia [111010001001[ rn[19..16] mask[15..0] */
523 kThumb2Stmia, /* stmia [111010001000[ rn[19..16] mask[15..0] */
524 kThumb2AddRRR, /* add [111010110000] rn[19..16] [0000] rd[11..8]
525 [0000] rm[3..0] */
526 kThumb2SubRRR, /* sub [111010111010] rn[19..16] [0000] rd[11..8]
527 [0000] rm[3..0] */
528 kThumb2SbcRRR, /* sbc [111010110110] rn[19..16] [0000] rd[11..8]
529 [0000] rm[3..0] */
530 kThumb2CmpRR, /* cmp [111010111011] rn[19..16] [0000] [1111]
531 [0000] rm[3..0] */
532 kThumb2SubRRI12, /* sub rd, rn, #imm12 [11110] i [01010] rn[19..16]
533 [0] imm3[14..12] rd[11..8] imm8[7..0] */
534 kThumb2MvnImmShift, /* mov(T2) rd, #<const> [11110] i [00011011110]
535 imm3 rd[11..8] imm8 */
536 kThumb2Sel, /* sel rd, rn, rm [111110101010] rn[19-16] rd[11-8]
537 rm[3-0] */
538 kThumb2Ubfx, /* ubfx rd,rn,#lsb,#width [111100111100] rn[19..16]
539 [0] imm3[14-12] rd[11-8] w[4-0] */
540 kThumb2Sbfx, /* ubfx rd,rn,#lsb,#width [111100110100] rn[19..16]
541 [0] imm3[14-12] rd[11-8] w[4-0] */
542 kThumb2LdrRRR, /* ldr rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
543 rt[15-12] [000000] imm[5-4] rm[3-0] */
544 kThumb2LdrhRRR, /* ldrh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
545 rt[15-12] [000000] imm[5-4] rm[3-0] */
546 kThumb2LdrshRRR, /* ldrsh rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
547 rt[15-12] [000000] imm[5-4] rm[3-0] */
548 kThumb2LdrbRRR, /* ldrb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
549 rt[15-12] [000000] imm[5-4] rm[3-0] */
550 kThumb2LdrsbRRR, /* ldrsb rt,[rn,rm,LSL #imm] [111110000101] rn[19-16]
551 rt[15-12] [000000] imm[5-4] rm[3-0] */
552 kThumb2StrRRR, /* str rt,[rn,rm,LSL #imm] [111110000100] rn[19-16]
553 rt[15-12] [000000] imm[5-4] rm[3-0] */
554 kThumb2StrhRRR, /* str rt,[rn,rm,LSL #imm] [111110000010] rn[19-16]
555 rt[15-12] [000000] imm[5-4] rm[3-0] */
556 kThumb2StrbRRR, /* str rt,[rn,rm,LSL #imm] [111110000000] rn[19-16]
557 rt[15-12] [000000] imm[5-4] rm[3-0] */
558 kThumb2LdrhRRI12, /* ldrh rt,[rn,#imm12] [111110001011]
559 rt[15..12] rn[19..16] imm12[11..0] */
560 kThumb2LdrshRRI12, /* ldrsh rt,[rn,#imm12] [111110011011]
561 rt[15..12] rn[19..16] imm12[11..0] */
562 kThumb2LdrbRRI12, /* ldrb rt,[rn,#imm12] [111110001001]
563 rt[15..12] rn[19..16] imm12[11..0] */
564 kThumb2LdrsbRRI12, /* ldrsb rt,[rn,#imm12] [111110011001]
565 rt[15..12] rn[19..16] imm12[11..0] */
566 kThumb2StrhRRI12, /* strh rt,[rn,#imm12] [111110001010]
567 rt[15..12] rn[19..16] imm12[11..0] */
568 kThumb2StrbRRI12, /* strb rt,[rn,#imm12] [111110001000]
569 rt[15..12] rn[19..16] imm12[11..0] */
570 kThumb2Pop, /* pop [1110100010111101] list[15-0]*/
571 kThumb2Push, /* push [1110100100101101] list[15-0]*/
572 kThumb2CmpRI8, /* cmp rn, #<const> [11110] i [011011] rn[19-16] [0]
573 imm3 [1111] imm8[7..0] */
574 kThumb2AdcRRR, /* adc [111010110101] rn[19..16] [0000] rd[11..8]
575 [0000] rm[3..0] */
576 kThumb2AndRRR, /* and [111010100000] rn[19..16] [0000] rd[11..8]
577 [0000] rm[3..0] */
578 kThumb2BicRRR, /* bic [111010100010] rn[19..16] [0000] rd[11..8]
579 [0000] rm[3..0] */
580 kThumb2CmnRR, /* cmn [111010110001] rn[19..16] [0000] [1111]
581 [0000] rm[3..0] */
582 kThumb2EorRRR, /* eor [111010101000] rn[19..16] [0000] rd[11..8]
583 [0000] rm[3..0] */
584 kThumb2MulRRR, /* mul [111110110000] rn[19..16] [1111] rd[11..8]
585 [0000] rm[3..0] */
586 kThumb2MnvRR, /* mvn [11101010011011110] rd[11-8] [0000]
587 rm[3..0] */
588 kThumb2RsubRRI8, /* rsub [111100011100] rn[19..16] [0000] rd[11..8]
589 imm8[7..0] */
590 kThumb2NegRR, /* actually rsub rd, rn, #0 */
591 kThumb2OrrRRR, /* orr [111010100100] rn[19..16] [0000] rd[11..8]
592 [0000] rm[3..0] */
593 kThumb2TstRR, /* tst [111010100001] rn[19..16] [0000] [1111]
594 [0000] rm[3..0] */
595 kThumb2LslRRR, /* lsl [111110100000] rn[19..16] [1111] rd[11..8]
596 [0000] rm[3..0] */
597 kThumb2LsrRRR, /* lsr [111110100010] rn[19..16] [1111] rd[11..8]
598 [0000] rm[3..0] */
599 kThumb2AsrRRR, /* asr [111110100100] rn[19..16] [1111] rd[11..8]
600 [0000] rm[3..0] */
601 kThumb2RorRRR, /* ror [111110100110] rn[19..16] [1111] rd[11..8]
602 [0000] rm[3..0] */
603 kThumb2LslRRI5, /* lsl [11101010010011110] imm[14.12] rd[11..8]
604 [00] rm[3..0] */
605 kThumb2LsrRRI5, /* lsr [11101010010011110] imm[14.12] rd[11..8]
606 [01] rm[3..0] */
607 kThumb2AsrRRI5, /* asr [11101010010011110] imm[14.12] rd[11..8]
608 [10] rm[3..0] */
609 kThumb2RorRRI5, /* ror [11101010010011110] imm[14.12] rd[11..8]
610 [11] rm[3..0] */
611 kThumb2BicRRI8, /* bic [111100000010] rn[19..16] [0] imm3
612 rd[11..8] imm8 */
613 kThumb2AndRRI8, /* bic [111100000000] rn[19..16] [0] imm3
614 rd[11..8] imm8 */
615 kThumb2OrrRRI8, /* orr [111100000100] rn[19..16] [0] imm3
616 rd[11..8] imm8 */
617 kThumb2EorRRI8, /* eor [111100001000] rn[19..16] [0] imm3
618 rd[11..8] imm8 */
619 kThumb2AddRRI8, /* add [111100001000] rn[19..16] [0] imm3
620 rd[11..8] imm8 */
621 kThumb2AdcRRI8, /* adc [111100010101] rn[19..16] [0] imm3
622 rd[11..8] imm8 */
623 kThumb2SubRRI8, /* sub [111100011011] rn[19..16] [0] imm3
624 rd[11..8] imm8 */
625 kThumb2SbcRRI8, /* sbc [111100010111] rn[19..16] [0] imm3
626 rd[11..8] imm8 */
627 kThumb2It, /* it [10111111] firstcond[7-4] mask[3-0] */
628 kThumb2Fmstat, /* fmstat [11101110111100011111101000010000] */
629 kThumb2Vcmpd, /* vcmp [111011101] D [11011] rd[15-12] [1011]
630 E [1] M [0] rm[3-0] */
631 kThumb2Vcmps, /* vcmp [111011101] D [11010] rd[15-12] [1011]
632 E [1] M [0] rm[3-0] */
633 kThumb2LdrPcRel12, /* ldr rd,[pc,#imm12] [1111100011011111] rt[15-12]
634 imm12[11-0] */
635 kThumb2BCond, /* b<c> [1110] S cond[25-22] imm6[21-16] [10]
636 J1 [0] J2 imm11[10..0] */
637 kThumb2Vmovd_RR, /* vmov [111011101] D [110000] vd[15-12 [101101]
638 M [0] vm[3-0] */
639 kThumb2Vmovs_RR, /* vmov [111011101] D [110000] vd[15-12 [101001]
640 M [0] vm[3-0] */
641 kThumb2Fmrs, /* vmov [111011100000] vn[19-16] rt[15-12] [1010]
642 N [0010000] */
643 kThumb2Fmsr, /* vmov [111011100001] vn[19-16] rt[15-12] [1010]
644 N [0010000] */
645 kThumb2Fmrrd, /* vmov [111011000100] rt2[19-16] rt[15-12]
646 [101100] M [1] vm[3-0] */
647 kThumb2Fmdrr, /* vmov [111011000101] rt2[19-16] rt[15-12]
648 [101100] M [1] vm[3-0] */
649 kThumb2Vabsd, /* vabs.f64 [111011101] D [110000] rd[15-12]
650 [1011110] M [0] vm[3-0] */
651 kThumb2Vabss, /* vabs.f32 [111011101] D [110000] rd[15-12]
652 [1010110] M [0] vm[3-0] */
653 kThumb2Vnegd, /* vneg.f64 [111011101] D [110000] rd[15-12]
654 [1011110] M [0] vm[3-0] */
655 kThumb2Vnegs, /* vneg.f32 [111011101] D [110000] rd[15-12]
656 [1010110] M [0] vm[3-0] */
657 kThumb2Vmovs_IMM8, /* vmov.f32 [111011101] D [11] imm4h[19-16] vd[15-12]
658 [10100000] imm4l[3-0] */
659 kThumb2Vmovd_IMM8, /* vmov.f64 [111011101] D [11] imm4h[19-16] vd[15-12]
660 [10110000] imm4l[3-0] */
661 kThumb2Mla, /* mla [111110110000] rn[19-16] ra[15-12] rd[7-4]
662 [0000] rm[3-0] */
663 kThumb2Umull, /* umull [111110111010] rn[19-16], rdlo[15-12]
664 rdhi[11-8] [0000] rm[3-0] */
665 kThumb2Ldrex, /* ldrex [111010000101] rn[19-16] rt[11-8] [1111]
666 imm8[7-0] */
667 kThumb2Strex, /* strex [111010000100] rn[19-16] rt[11-8] rd[11-8]
668 imm8[7-0] */
669 kThumb2Clrex, /* clrex [111100111011111110000111100101111] */
670 kThumb2Bfi, /* bfi [111100110110] rn[19-16] [0] imm3[14-12]
671 rd[11-8] imm2[7-6] [0] msb[4-0] */
672 kThumb2Bfc, /* bfc [11110011011011110] [0] imm3[14-12]
673 rd[11-8] imm2[7-6] [0] msb[4-0] */
674 kThumb2Dmb, /* dmb [1111001110111111100011110101] option[3-0] */
675 kThumb2LdrPcReln12, /* ldr rd,[pc,-#imm12] [1111100011011111] rt[15-12]
676 imm12[11-0] */
677 kThumb2Stm, /* stm <list> [111010010000] rn[19-16] 000 rl[12-0] */
678 kThumbUndefined, /* undefined [11011110xxxxxxxx] */
679 kThumb2VPopCS, /* vpop <list of callee save fp singles (s16+) */
680 kThumb2VPushCS, /* vpush <list callee save fp singles (s16+) */
681 kThumb2Vldms, /* vldms rd, <list> */
682 kThumb2Vstms, /* vstms rd, <list> */
683 kThumb2BUncond, /* b <label> */
684 kThumb2MovImm16H, /* similar to kThumb2MovImm16, but target high hw */
685 kThumb2AddPCR, /* Thumb2 2-operand add with hard-coded PC target */
686 kThumb2AdrST, /* Special purpose encoding of ADR for switch tables */
687 kThumb2MovImm16LST, /* Special purpose version for switch table use */
688 kThumb2MovImm16HST, /* Special purpose version for switch table use */
689 kThumb2LdmiaWB, /* ldmia [111010011001[ rn[19..16] mask[15..0] */
690 kThumb2SubsRRI12, /* setflags encoding */
691 kArmLast,
692} ArmOpcode;
693
694/* DMB option encodings */
695typedef enum ArmOpDmbOptions {
696 kSY = 0xf,
697 kST = 0xe,
698 kISH = 0xb,
699 kISHST = 0xa,
700 kNSH = 0x7,
701 kNSHST = 0x6
702} ArmOpDmbOptions;
703
704/* Bit flags describing the behavior of each native opcode */
705typedef enum ArmOpFeatureFlags {
706 kIsBranch = 0,
707 kRegDef0,
708 kRegDef1,
709 kRegDefSP,
710 kRegDefLR,
711 kRegDefList0,
712 kRegDefList1,
713 kRegDefFPCSList0,
714 kRegDefFPCSList2,
715 kRegDefList2,
716 kRegUse0,
717 kRegUse1,
718 kRegUse2,
719 kRegUse3,
720 kRegUseSP,
721 kRegUsePC,
722 kRegUseList0,
723 kRegUseList1,
724 kRegUseFPCSList0,
725 kRegUseFPCSList2,
726 kNoOperand,
727 kIsUnaryOp,
728 kIsBinaryOp,
729 kIsTertiaryOp,
730 kIsQuadOp,
731 kIsIT,
732 kSetsCCodes,
733 kUsesCCodes,
734 kMemLoad,
735 kMemStore,
736} ArmOpFeatureFlags;
737
738#define IS_LOAD (1 << kMemLoad)
739#define IS_STORE (1 << kMemStore)
740#define IS_BRANCH (1 << kIsBranch)
741#define REG_DEF0 (1 << kRegDef0)
742#define REG_DEF1 (1 << kRegDef1)
743#define REG_DEF_SP (1 << kRegDefSP)
744#define REG_DEF_LR (1 << kRegDefLR)
745#define REG_DEF_LIST0 (1 << kRegDefList0)
746#define REG_DEF_LIST1 (1 << kRegDefList1)
747#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0)
748#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2)
749#define REG_USE0 (1 << kRegUse0)
750#define REG_USE1 (1 << kRegUse1)
751#define REG_USE2 (1 << kRegUse2)
752#define REG_USE3 (1 << kRegUse3)
753#define REG_USE_SP (1 << kRegUseSP)
754#define REG_USE_PC (1 << kRegUsePC)
755#define REG_USE_LIST0 (1 << kRegUseList0)
756#define REG_USE_LIST1 (1 << kRegUseList1)
757#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0)
758#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2)
759#define NO_OPERAND (1 << kNoOperand)
760#define IS_UNARY_OP (1 << kIsUnaryOp)
761#define IS_BINARY_OP (1 << kIsBinaryOp)
762#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
763#define IS_QUAD_OP (1 << kIsQuadOp)
764#define IS_IT (1 << kIsIT)
765#define SETS_CCODES (1 << kSetsCCodes)
766#define USES_CCODES (1 << kUsesCCodes)
767
768/* Common combo register usage patterns */
769#define REG_USE01 (REG_USE0 | REG_USE1)
770#define REG_USE012 (REG_USE01 | REG_USE2)
771#define REG_USE12 (REG_USE1 | REG_USE2)
772#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
773#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
774#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
775#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
776#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
777
778/* Instruction assembly fieldLoc kind */
779typedef enum ArmEncodingKind {
780 kFmtUnused,
781 kFmtBitBlt, /* Bit string using end/start */
782 kFmtDfp, /* Double FP reg */
783 kFmtSfp, /* Single FP reg */
784 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
785 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
786 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
787 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
788 kFmtShift, /* Shift descriptor, [14..12,7..4] */
789 kFmtLsb, /* least significant bit using [14..12][7..6] */
790 kFmtBWidth, /* bit-field width, encoded as width-1 */
791 kFmtShift5, /* Shift count, [14..12,7..6] */
792 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
793 kFmtFPImm, /* Encoded floating point immediate */
794 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
795} ArmEncodingKind;
796
797/* Struct used to define the snippet positions for each Thumb opcode */
798typedef struct ArmEncodingMap {
799 u4 skeleton;
800 struct {
801 ArmEncodingKind kind;
802 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
803 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
804 } fieldLoc[4];
805 ArmOpcode opcode;
806 int flags;
807 const char* name;
808 const char* fmt;
809 int size;
810} ArmEncodingMap;
811
812/* Keys for target-specific scheduling and other optimization hints */
813typedef enum ArmTargetOptHints {
814 kMaxHoistDistance,
815} ArmTargetOptHints;
816
817extern ArmEncodingMap EncodingMap[kArmLast];
818
819/*
820 * Each instance of this struct holds a pseudo or real LIR instruction:
821 * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
822 * - real ones will be assembled into Thumb instructions.
823 *
824 * Machine resources are encoded into a 64-bit vector, where the encodings are
825 * as following:
826 * - [ 0..15]: general purpose registers including PC, SP, and LR
827 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
828 * starts at bit 16
829 * - [48]: IT block
830 * - [49]: integer condition code
831 * - [50]: floatint-point status word
832 */
833typedef struct ArmLIR {
834 LIR generic;
835 ArmOpcode opcode;
836 int operands[4]; // [0..3] = [dest, src1, src2, extra]
837 struct {
838 bool isNop:1; // LIR is optimized away
839 bool insertWrapper:1; // insert branch to emulate memory accesses
840 unsigned int age:4; // default is 0, set lazily by the optimizer
841 unsigned int size:3; // bytes (2 for thumb, 2/4 for thumb2)
842 unsigned int unused:23;
843 } flags;
844 int aliasInfo; // For Dalvik register & litpool disambiguation
845 u8 useMask; // Resource mask for use
846 u8 defMask; // Resource mask for def
847} ArmLIR;
848
849typedef struct SwitchTable {
850 int offset;
851 const u2* table; // Original dex table
852 int vaddr; // Dalvik offset of switch opcode
853 ArmLIR* bxInst; // Switch indirect branch instruction
854 ArmLIR** targets; // Array of case targets
855} SwitchTable;
856
857typedef struct FillArrayData {
858 int offset;
859 const u2* table; // Original dex table
860 int size;
861 int vaddr; // Dalvik offset of OP_FILL_ARRAY_DATA opcode
862} FillArrayData;
863
864/* Init values when a predicted chain is initially assembled */
865/* E7FE is branch to self */
866#define PREDICTED_CHAIN_BX_PAIR_INIT 0xe7fe
867
868/* Utility macros to traverse the LIR/ArmLIR list */
869#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
870#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
871
872#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
873#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
874
875#define CHAIN_CELL_OFFSET_TAG 0xcdab
876
877#define CHAIN_CELL_NORMAL_SIZE 12
878#define CHAIN_CELL_PREDICTED_SIZE 16
879
880#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_