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