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