blob: 1e4022ee4b82989d438ee127831459179d0f045b [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) */
126#define LOC_C_RETURN {kLocPhysReg, 0, 0, r0, INVALID_REG, INVALID_SREG, \
127 1, kLocPhysReg, r0, INVALID_REG, INVALID_OFFSET}
128#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r0, r1, INVALID_SREG, \
129 1, kLocPhysReg, r0, r1, INVALID_OFFSET}
130/* RegisterLocation templates for interpState->retVal; */
131#define LOC_DALVIK_RETURN_VAL {kLocPhysReg, 0, 0, r0, INVALID_REG, \
132 INVALID_SREG, 1, kLocPhysReg, r0, INVALID_REG, \
133 INVALID_OFFSET}
134#define LOC_DALVIK_RETURN_VAL_WIDE {kLocPhysReg, 1, 0, r0, r1, \
135 INVALID_SREG, 1, kLocPhysReg, r0, r1, INVALID_OFFSET}
136
137 /*
138 * Data structure tracking the mapping between a Dalvik register (pair) and a
139 * native register (pair). The idea is to reuse the previously loaded value
140 * if possible, otherwise to keep the value in a native register as long as
141 * possible.
142 */
143typedef struct RegisterInfo {
144 int reg; // Reg number
145 bool inUse; // Has it been allocated?
146 bool isTemp; // Can allocate as temp?
147 bool pair; // Part of a register pair?
148 int partner; // If pair, other reg of pair
149 bool live; // Is there an associated SSA name?
150 bool dirty; // If live, is it dirty?
151 int sReg; // Name of live value
152 struct LIR *defStart; // Starting inst in last def sequence
153 struct LIR *defEnd; // Ending inst in last def sequence
154} RegisterInfo;
155
156typedef struct RegisterPool {
buzbee67bf8852011-08-17 17:51:35 -0700157 int numCoreRegs;
158 RegisterInfo *coreRegs;
159 int nextCoreReg;
160 int numFPRegs;
161 RegisterInfo *FPRegs;
162 int nextFPReg;
163} RegisterPool;
164
165typedef enum ResourceEncodingPos {
166 kGPReg0 = 0,
167 kRegSP = 13,
168 kRegLR = 14,
169 kRegPC = 15,
170 kFPReg0 = 16,
171 kFPReg16 = 32,
172 kRegEnd = 48,
173 kCCode = kRegEnd,
174 kFPStatus, // FP status word
175 // The following four bits are for memory disambiguation
176 kDalvikReg, // 1 Dalvik Frame (can be fully disambiguated)
177 kLiteral, // 2 Literal pool (can be fully disambiguated)
178 kHeapRef, // 3 Somewhere on the heap (alias with any other heap)
179 kMustNotAlias, // 4 Guaranteed to be non-alias (eg *(r6+x))
180} ResourceEncodingPos;
181
182#define ENCODE_REG_LIST(N) ((u8) N)
183#define ENCODE_REG_SP (1ULL << kRegSP)
184#define ENCODE_REG_LR (1ULL << kRegLR)
185#define ENCODE_REG_PC (1ULL << kRegPC)
186#define ENCODE_CCODE (1ULL << kCCode)
187#define ENCODE_FP_STATUS (1ULL << kFPStatus)
188#define ENCODE_REG_FPCS_LIST(N) ((u8)N << kFPReg16)
189
190/* Abstract memory locations */
191#define ENCODE_DALVIK_REG (1ULL << kDalvikReg)
192#define ENCODE_LITERAL (1ULL << kLiteral)
193#define ENCODE_HEAP_REF (1ULL << kHeapRef)
194#define ENCODE_MUST_NOT_ALIAS (1ULL << kMustNotAlias)
195
196#define ENCODE_ALL (~0ULL)
197#define ENCODE_MEM (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
198 ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
199
200#define DECODE_ALIAS_INFO_REG(X) (X & 0xffff)
201#define DECODE_ALIAS_INFO_WIDE(X) ((X & 0x80000000) ? 1 : 0)
202
203typedef enum OpSize {
204 kWord,
205 kLong,
206 kSingle,
207 kDouble,
208 kUnsignedHalf,
209 kSignedHalf,
210 kUnsignedByte,
211 kSignedByte,
212} OpSize;
213
214typedef enum OpKind {
215 kOpMov,
216 kOpMvn,
217 kOpCmp,
218 kOpLsl,
219 kOpLsr,
220 kOpAsr,
221 kOpRor,
222 kOpNot,
223 kOpAnd,
224 kOpOr,
225 kOpXor,
226 kOpNeg,
227 kOpAdd,
228 kOpAdc,
229 kOpSub,
230 kOpSbc,
231 kOpRsub,
232 kOpMul,
233 kOpDiv,
234 kOpRem,
235 kOpBic,
236 kOpCmn,
237 kOpTst,
238 kOpBkpt,
239 kOpBlx,
240 kOpPush,
241 kOpPop,
242 kOp2Char,
243 kOp2Short,
244 kOp2Byte,
245 kOpCondBr,
246 kOpUncondBr,
247} OpKind;
248
249/*
250 * Annotate special-purpose core registers:
buzbeec1f45042011-09-21 16:03:19 -0700251 * - VM: r6SELF
buzbee67bf8852011-08-17 17:51:35 -0700252 * - ARM architecture: r13sp, r14lr, and r15pc
253 *
254 * rPC, rFP, and rSELF are for architecture-independent code to use.
255 */
256typedef enum NativeRegisterPool {
257 r0 = 0,
258 r1 = 1,
259 r2 = 2,
260 r3 = 3,
buzbeec1f45042011-09-21 16:03:19 -0700261 rSUSPEND = 4,
buzbee67bf8852011-08-17 17:51:35 -0700262 r5 = 5,
263 r6 = 6,
264 r7 = 7,
265 r8 = 8,
266 rSELF = 9,
267 r10 = 10,
268 r11 = 11,
269 r12 = 12,
270 r13sp = 13,
271 rSP = 13,
272 r14lr = 14,
273 rLR = 14,
274 r15pc = 15,
275 rPC = 15,
276 fr0 = 0 + FP_REG_OFFSET,
277 fr1 = 1 + FP_REG_OFFSET,
278 fr2 = 2 + FP_REG_OFFSET,
279 fr3 = 3 + FP_REG_OFFSET,
280 fr4 = 4 + FP_REG_OFFSET,
281 fr5 = 5 + FP_REG_OFFSET,
282 fr6 = 6 + FP_REG_OFFSET,
283 fr7 = 7 + FP_REG_OFFSET,
284 fr8 = 8 + FP_REG_OFFSET,
285 fr9 = 9 + FP_REG_OFFSET,
286 fr10 = 10 + FP_REG_OFFSET,
287 fr11 = 11 + FP_REG_OFFSET,
288 fr12 = 12 + FP_REG_OFFSET,
289 fr13 = 13 + FP_REG_OFFSET,
290 fr14 = 14 + FP_REG_OFFSET,
291 fr15 = 15 + FP_REG_OFFSET,
292 fr16 = 16 + FP_REG_OFFSET,
293 fr17 = 17 + FP_REG_OFFSET,
294 fr18 = 18 + FP_REG_OFFSET,
295 fr19 = 19 + FP_REG_OFFSET,
296 fr20 = 20 + FP_REG_OFFSET,
297 fr21 = 21 + FP_REG_OFFSET,
298 fr22 = 22 + FP_REG_OFFSET,
299 fr23 = 23 + FP_REG_OFFSET,
300 fr24 = 24 + FP_REG_OFFSET,
301 fr25 = 25 + FP_REG_OFFSET,
302 fr26 = 26 + FP_REG_OFFSET,
303 fr27 = 27 + FP_REG_OFFSET,
304 fr28 = 28 + FP_REG_OFFSET,
305 fr29 = 29 + FP_REG_OFFSET,
306 fr30 = 30 + FP_REG_OFFSET,
307 fr31 = 31 + FP_REG_OFFSET,
308 dr0 = fr0 + FP_DOUBLE,
309 dr1 = fr2 + FP_DOUBLE,
310 dr2 = fr4 + FP_DOUBLE,
311 dr3 = fr6 + FP_DOUBLE,
312 dr4 = fr8 + FP_DOUBLE,
313 dr5 = fr10 + FP_DOUBLE,
314 dr6 = fr12 + FP_DOUBLE,
315 dr7 = fr14 + FP_DOUBLE,
316 dr8 = fr16 + FP_DOUBLE,
317 dr9 = fr18 + FP_DOUBLE,
318 dr10 = fr20 + FP_DOUBLE,
319 dr11 = fr22 + FP_DOUBLE,
320 dr12 = fr24 + FP_DOUBLE,
321 dr13 = fr26 + FP_DOUBLE,
322 dr14 = fr28 + FP_DOUBLE,
323 dr15 = fr30 + FP_DOUBLE,
324} NativeRegisterPool;
325
326/* Shift encodings */
327typedef enum ArmShiftEncodings {
328 kArmLsl = 0x0,
329 kArmLsr = 0x1,
330 kArmAsr = 0x2,
331 kArmRor = 0x3
332} ArmShiftEncodings;
333
334/* Thumb condition encodings */
335typedef enum ArmConditionCode {
336 kArmCondEq = 0x0, /* 0000 */
337 kArmCondNe = 0x1, /* 0001 */
338 kArmCondCs = 0x2, /* 0010 */
339 kArmCondCc = 0x3, /* 0011 */
340 kArmCondMi = 0x4, /* 0100 */
341 kArmCondPl = 0x5, /* 0101 */
342 kArmCondVs = 0x6, /* 0110 */
343 kArmCondVc = 0x7, /* 0111 */
344 kArmCondHi = 0x8, /* 1000 */
345 kArmCondLs = 0x9, /* 1001 */
346 kArmCondGe = 0xa, /* 1010 */
347 kArmCondLt = 0xb, /* 1011 */
348 kArmCondGt = 0xc, /* 1100 */
349 kArmCondLe = 0xd, /* 1101 */
350 kArmCondAl = 0xe, /* 1110 */
351 kArmCondNv = 0xf, /* 1111 */
352} ArmConditionCode;
353
buzbee5ade1d22011-09-09 14:44:52 -0700354typedef enum ArmThrowKind {
355 kArmThrowNullPointer,
356 kArmThrowDivZero,
357 kArmThrowArrayBounds,
358 kArmThrowVerificationError,
359 kArmThrowNegArraySize,
buzbee5ade1d22011-09-09 14:44:52 -0700360 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] */
buzbeee7070802011-10-09 17:56:06 -0700696 kThumb2Push1, /* t3 encoding of push */
697 kThumb2Pop1, /* t3 encoding of pop */
buzbee67bf8852011-08-17 17:51:35 -0700698 kArmLast,
699} ArmOpcode;
700
701/* DMB option encodings */
702typedef enum ArmOpDmbOptions {
703 kSY = 0xf,
704 kST = 0xe,
705 kISH = 0xb,
706 kISHST = 0xa,
707 kNSH = 0x7,
708 kNSHST = 0x6
709} ArmOpDmbOptions;
710
711/* Bit flags describing the behavior of each native opcode */
712typedef enum ArmOpFeatureFlags {
713 kIsBranch = 0,
714 kRegDef0,
715 kRegDef1,
716 kRegDefSP,
717 kRegDefLR,
718 kRegDefList0,
719 kRegDefList1,
720 kRegDefFPCSList0,
721 kRegDefFPCSList2,
722 kRegDefList2,
723 kRegUse0,
724 kRegUse1,
725 kRegUse2,
726 kRegUse3,
727 kRegUseSP,
728 kRegUsePC,
729 kRegUseList0,
730 kRegUseList1,
731 kRegUseFPCSList0,
732 kRegUseFPCSList2,
733 kNoOperand,
734 kIsUnaryOp,
735 kIsBinaryOp,
736 kIsTertiaryOp,
737 kIsQuadOp,
738 kIsIT,
739 kSetsCCodes,
740 kUsesCCodes,
741 kMemLoad,
742 kMemStore,
743} ArmOpFeatureFlags;
744
745#define IS_LOAD (1 << kMemLoad)
746#define IS_STORE (1 << kMemStore)
747#define IS_BRANCH (1 << kIsBranch)
748#define REG_DEF0 (1 << kRegDef0)
749#define REG_DEF1 (1 << kRegDef1)
750#define REG_DEF_SP (1 << kRegDefSP)
751#define REG_DEF_LR (1 << kRegDefLR)
752#define REG_DEF_LIST0 (1 << kRegDefList0)
753#define REG_DEF_LIST1 (1 << kRegDefList1)
754#define REG_DEF_FPCS_LIST0 (1 << kRegDefFPCSList0)
755#define REG_DEF_FPCS_LIST2 (1 << kRegDefFPCSList2)
756#define REG_USE0 (1 << kRegUse0)
757#define REG_USE1 (1 << kRegUse1)
758#define REG_USE2 (1 << kRegUse2)
759#define REG_USE3 (1 << kRegUse3)
760#define REG_USE_SP (1 << kRegUseSP)
761#define REG_USE_PC (1 << kRegUsePC)
762#define REG_USE_LIST0 (1 << kRegUseList0)
763#define REG_USE_LIST1 (1 << kRegUseList1)
764#define REG_USE_FPCS_LIST0 (1 << kRegUseFPCSList0)
765#define REG_USE_FPCS_LIST2 (1 << kRegUseFPCSList2)
766#define NO_OPERAND (1 << kNoOperand)
767#define IS_UNARY_OP (1 << kIsUnaryOp)
768#define IS_BINARY_OP (1 << kIsBinaryOp)
769#define IS_TERTIARY_OP (1 << kIsTertiaryOp)
770#define IS_QUAD_OP (1 << kIsQuadOp)
771#define IS_IT (1 << kIsIT)
772#define SETS_CCODES (1 << kSetsCCodes)
773#define USES_CCODES (1 << kUsesCCodes)
774
775/* Common combo register usage patterns */
776#define REG_USE01 (REG_USE0 | REG_USE1)
777#define REG_USE012 (REG_USE01 | REG_USE2)
778#define REG_USE12 (REG_USE1 | REG_USE2)
779#define REG_DEF0_USE0 (REG_DEF0 | REG_USE0)
780#define REG_DEF0_USE1 (REG_DEF0 | REG_USE1)
781#define REG_DEF0_USE01 (REG_DEF0 | REG_USE01)
782#define REG_DEF0_USE12 (REG_DEF0 | REG_USE12)
783#define REG_DEF01_USE2 (REG_DEF0 | REG_DEF1 | REG_USE2)
784
785/* Instruction assembly fieldLoc kind */
786typedef enum ArmEncodingKind {
787 kFmtUnused,
788 kFmtBitBlt, /* Bit string using end/start */
789 kFmtDfp, /* Double FP reg */
790 kFmtSfp, /* Single FP reg */
791 kFmtModImm, /* Shifted 8-bit immed using [26,14..12,7..0] */
792 kFmtImm16, /* Zero-extended immed using [26,19..16,14..12,7..0] */
793 kFmtImm6, /* Encoded branch target using [9,7..3]0 */
794 kFmtImm12, /* Zero-extended immediate using [26,14..12,7..0] */
795 kFmtShift, /* Shift descriptor, [14..12,7..4] */
796 kFmtLsb, /* least significant bit using [14..12][7..6] */
797 kFmtBWidth, /* bit-field width, encoded as width-1 */
798 kFmtShift5, /* Shift count, [14..12,7..6] */
799 kFmtBrOffset, /* Signed extended [26,11,13,21-16,10-0]:0 */
800 kFmtFPImm, /* Encoded floating point immediate */
801 kFmtOff24, /* 24-bit Thumb2 unconditional branch encoding */
802} ArmEncodingKind;
803
804/* Struct used to define the snippet positions for each Thumb opcode */
805typedef struct ArmEncodingMap {
806 u4 skeleton;
807 struct {
808 ArmEncodingKind kind;
809 int end; /* end for kFmtBitBlt, 1-bit slice end for FP regs */
810 int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
811 } fieldLoc[4];
812 ArmOpcode opcode;
813 int flags;
814 const char* name;
815 const char* fmt;
816 int size;
817} ArmEncodingMap;
818
819/* Keys for target-specific scheduling and other optimization hints */
820typedef enum ArmTargetOptHints {
821 kMaxHoistDistance,
822} ArmTargetOptHints;
823
824extern ArmEncodingMap EncodingMap[kArmLast];
825
826/*
827 * Each instance of this struct holds a pseudo or real LIR instruction:
828 * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
829 * - real ones will be assembled into Thumb instructions.
830 *
831 * Machine resources are encoded into a 64-bit vector, where the encodings are
832 * as following:
833 * - [ 0..15]: general purpose registers including PC, SP, and LR
834 * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
835 * starts at bit 16
836 * - [48]: IT block
837 * - [49]: integer condition code
838 * - [50]: floatint-point status word
839 */
840typedef struct ArmLIR {
841 LIR generic;
842 ArmOpcode opcode;
843 int operands[4]; // [0..3] = [dest, src1, src2, extra]
844 struct {
845 bool isNop:1; // LIR is optimized away
846 bool insertWrapper:1; // insert branch to emulate memory accesses
buzbee12246b82011-09-29 14:15:05 -0700847 bool squashed:1; // Eliminated def
buzbee67bf8852011-08-17 17:51:35 -0700848 unsigned int age:4; // default is 0, set lazily by the optimizer
849 unsigned int size:3; // bytes (2 for thumb, 2/4 for thumb2)
buzbee6181f792011-09-29 11:14:04 -0700850 unsigned int unused:22;
buzbee67bf8852011-08-17 17:51:35 -0700851 } flags;
852 int aliasInfo; // For Dalvik register & litpool disambiguation
853 u8 useMask; // Resource mask for use
854 u8 defMask; // Resource mask for def
855} ArmLIR;
856
857typedef struct SwitchTable {
858 int offset;
859 const u2* table; // Original dex table
860 int vaddr; // Dalvik offset of switch opcode
861 ArmLIR* bxInst; // Switch indirect branch instruction
862 ArmLIR** targets; // Array of case targets
863} SwitchTable;
864
865typedef struct FillArrayData {
866 int offset;
867 const u2* table; // Original dex table
868 int size;
869 int vaddr; // Dalvik offset of OP_FILL_ARRAY_DATA opcode
870} FillArrayData;
871
872/* Init values when a predicted chain is initially assembled */
873/* E7FE is branch to self */
874#define PREDICTED_CHAIN_BX_PAIR_INIT 0xe7fe
875
876/* Utility macros to traverse the LIR/ArmLIR list */
877#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
878#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
879
880#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
881#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
882
883#define CHAIN_CELL_OFFSET_TAG 0xcdab
884
885#define CHAIN_CELL_NORMAL_SIZE 12
886#define CHAIN_CELL_PREDICTED_SIZE 16
887
888#endif // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_