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