blob: 3b2e986acb01bc223c5c4f13e7f46fcf8352ef06 [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] */
buzbee58f92742011-10-01 11:22:17 -0700537 kThumb2MvnImm12, /* mov(T2) rd, #<const> [11110] i [00011011110]
buzbee67bf8852011-08-17 17:51:35 -0700538 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 */
buzbee58f92742011-10-01 11:22:17 -0700694 kThumb2OrrRRRs, /* orrx [111010100101] rn[19..16] [0000] rd[11..8]
695 [0000] rm[3..0] */
buzbee67bf8852011-08-17 17:51:35 -0700696 kArmLast,
697} ArmOpcode;
698
699/* DMB option encodings */
700typedef enum ArmOpDmbOptions {
701 kSY = 0xf,
702 kST = 0xe,
703 kISH = 0xb,
704 kISHST = 0xa,
705 kNSH = 0x7,
706 kNSHST = 0x6
707} ArmOpDmbOptions;
708
709/* Bit flags describing the behavior of each native opcode */
710typedef enum ArmOpFeatureFlags {
711 kIsBranch = 0,
712 kRegDef0,
713 kRegDef1,
714 kRegDefSP,
715 kRegDefLR,
716 kRegDefList0,
717 kRegDefList1,
718 kRegDefFPCSList0,
719 kRegDefFPCSList2,
720 kRegDefList2,
721 kRegUse0,
722 kRegUse1,
723 kRegUse2,
724 kRegUse3,
725 kRegUseSP,
726 kRegUsePC,
727 kRegUseList0,
728 kRegUseList1,
729 kRegUseFPCSList0,
730 kRegUseFPCSList2,
731 kNoOperand,
732 kIsUnaryOp,
733 kIsBinaryOp,
734 kIsTertiaryOp,
735 kIsQuadOp,
736 kIsIT,
737 kSetsCCodes,
738 kUsesCCodes,
739 kMemLoad,
740 kMemStore,
741} ArmOpFeatureFlags;
742
743#define IS_LOAD (1 << kMemLoad)
744#define IS_STORE (1 << kMemStore)
745#define IS_BRANCH (1 << kIsBranch)
746#define REG_DEF0 (1 << kRegDef0)
747#define REG_DEF1 (1 << kRegDef1)
748#define REG_DEF_SP (1 << kRegDefSP)
749#define REG_DEF_LR (1 << kRegDefLR)
750#define REG_DEF_LIST0 (1 << kRegDefList0)
751#define REG_DEF_LIST1 (1 << kRegDefList1)
752#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0)
753#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2)
754#define REG_USE0 (1 << kRegUse0)
755#define REG_USE1 (1 << kRegUse1)
756#define REG_USE2 (1 << kRegUse2)
757#define REG_USE3 (1 << kRegUse3)
758#define REG_USE_SP (1 << kRegUseSP)
759#define REG_USE_PC (1 << kRegUsePC)
760#define REG_USE_LIST0 (1 << kRegUseList0)
761#define REG_USE_LIST1 (1 << kRegUseList1)
762#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0)
763#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2)
764#define NO_OPERAND (1 << kNoOperand)
765#define IS_UNARY_OP (1 << kIsUnaryOp)
766#define IS_BINARY_OP (1 << kIsBinaryOp)
767#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
768#define IS_QUAD_OP (1 << kIsQuadOp)
769#define IS_IT (1 << kIsIT)
770#define SETS_CCODES (1 << kSetsCCodes)
771#define USES_CCODES (1 << kUsesCCodes)
772
773/* Common combo register usage patterns */
774#define REG_USE01 (REG_USE0 | REG_USE1)
775#define REG_USE012 (REG_USE01 | REG_USE2)
776#define REG_USE12 (REG_USE1 | REG_USE2)
777#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
778#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
779#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
780#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
781#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
782
783/* Instruction assembly fieldLoc kind */
784typedef enum ArmEncodingKind {
785 kFmtUnused,
786 kFmtBitBlt, /* Bit string using end/start */
787 kFmtDfp, /* Double FP reg */
788 kFmtSfp, /* Single FP reg */
789 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
790 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
791 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
792 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
793 kFmtShift, /* Shift descriptor, [14..12,7..4] */
794 kFmtLsb, /* least significant bit using [14..12][7..6] */
795 kFmtBWidth, /* bit-field width, encoded as width-1 */
796 kFmtShift5, /* Shift count, [14..12,7..6] */
797 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
798 kFmtFPImm, /* Encoded floating point immediate */
799 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
800} ArmEncodingKind;
801
802/* Struct used to define the snippet positions for each Thumb opcode */
803typedef struct ArmEncodingMap {
804 u4 skeleton;
805 struct {
806 ArmEncodingKind kind;
807 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
808 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
809 } fieldLoc[4];
810 ArmOpcode opcode;
811 int flags;
812 const char* name;
813 const char* fmt;
814 int size;
815} ArmEncodingMap;
816
817/* Keys for target-specific scheduling and other optimization hints */
818typedef enum ArmTargetOptHints {
819 kMaxHoistDistance,
820} ArmTargetOptHints;
821
822extern ArmEncodingMap EncodingMap[kArmLast];
823
824/*
825 * Each instance of this struct holds a pseudo or real LIR instruction:
826 * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
827 * - real ones will be assembled into Thumb instructions.
828 *
829 * Machine resources are encoded into a 64-bit vector, where the encodings are
830 * as following:
831 * - [ 0..15]: general purpose registers including PC, SP, and LR
832 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
833 * starts at bit 16
834 * - [48]: IT block
835 * - [49]: integer condition code
836 * - [50]: floatint-point status word
837 */
838typedef struct ArmLIR {
839 LIR generic;
840 ArmOpcode opcode;
841 int operands[4]; // [0..3] = [dest, src1, src2, extra]
842 struct {
843 bool isNop:1; // LIR is optimized away
844 bool insertWrapper:1; // insert branch to emulate memory accesses
buzbee12246b82011-09-29 14:15:05 -0700845 bool squashed:1; // Eliminated def
buzbee67bf8852011-08-17 17:51:35 -0700846 unsigned int age:4; // default is 0, set lazily by the optimizer
847 unsigned int size:3; // bytes (2 for thumb, 2/4 for thumb2)
buzbee6181f792011-09-29 11:14:04 -0700848 unsigned int unused:22;
buzbee67bf8852011-08-17 17:51:35 -0700849 } flags;
850 int aliasInfo; // For Dalvik register & litpool disambiguation
851 u8 useMask; // Resource mask for use
852 u8 defMask; // Resource mask for def
853} ArmLIR;
854
855typedef struct SwitchTable {
856 int offset;
857 const u2* table; // Original dex table
858 int vaddr; // Dalvik offset of switch opcode
859 ArmLIR* bxInst; // Switch indirect branch instruction
860 ArmLIR** targets; // Array of case targets
861} SwitchTable;
862
863typedef struct FillArrayData {
864 int offset;
865 const u2* table; // Original dex table
866 int size;
867 int vaddr; // Dalvik offset of OP_FILL_ARRAY_DATA opcode
868} FillArrayData;
869
870/* Init values when a predicted chain is initially assembled */
871/* E7FE is branch to self */
872#define PREDICTED_CHAIN_BX_PAIR_INIT 0xe7fe
873
874/* Utility macros to traverse the LIR/ArmLIR list */
875#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
876#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
877
878#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
879#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
880
881#define CHAIN_CELL_OFFSET_TAG 0xcdab
882
883#define CHAIN_CELL_NORMAL_SIZE 12
884#define CHAIN_CELL_PREDICTED_SIZE 16
885
886#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_