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