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