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