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