Home | History | Annotate | Download | only in arm
      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  */
    102 typedef 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 
    114 typedef 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 
    128 typedef 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 
    168 typedef enum OpSize {
    169     kWord,
    170     kLong,
    171     kSingle,
    172     kDouble,
    173     kUnsignedHalf,
    174     kSignedHalf,
    175     kUnsignedByte,
    176     kSignedByte,
    177 } OpSize;
    178 
    179 typedef 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 
    214 typedef 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 */
    282 typedef enum ArmShiftEncodings {
    283     kArmLsl = 0x0,
    284     kArmLsr = 0x1,
    285     kArmAsr = 0x2,
    286     kArmRor = 0x3
    287 } ArmShiftEncodings;
    288 
    289 /* Thumb condition encodings */
    290 typedef 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  */
    316 typedef 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     kThumb2Dmb,          /* dmb [1111001110111111100011110101] option[3-0] */
    626 
    627     kArmLast,
    628 } ArmOpCode;
    629 
    630 /* DMB option encodings */
    631 typedef enum ArmOpDmbOptions {
    632     kSY = 0xf,
    633     kST = 0xe,
    634     kISH = 0xb,
    635     kISHST = 0xa,
    636     kNSH = 0x7,
    637     kNSHST = 0x6
    638 } ArmOpDmbOptions;
    639 
    640 /* Bit flags describing the behavior of each native opcode */
    641 typedef enum ArmOpFeatureFlags {
    642     kIsBranch = 0,
    643     kRegDef0,
    644     kRegDef1,
    645     kRegDefSP,
    646     kRegDefLR,
    647     kRegDefList0,
    648     kRegDefList1,
    649     kRegUse0,
    650     kRegUse1,
    651     kRegUse2,
    652     kRegUse3,
    653     kRegUseSP,
    654     kRegUsePC,
    655     kRegUseList0,
    656     kRegUseList1,
    657     kNoOperand,
    658     kIsUnaryOp,
    659     kIsBinaryOp,
    660     kIsTertiaryOp,
    661     kIsQuadOp,
    662     kIsIT,
    663     kSetsCCodes,
    664     kUsesCCodes,
    665     kMemLoad,
    666     kMemStore,
    667 } ArmOpFeatureFlags;
    668 
    669 #define IS_LOAD         (1 << kMemLoad)
    670 #define IS_STORE        (1 << kMemStore)
    671 #define IS_BRANCH       (1 << kIsBranch)
    672 #define REG_DEF0        (1 << kRegDef0)
    673 #define REG_DEF1        (1 << kRegDef1)
    674 #define REG_DEF_SP      (1 << kRegDefSP)
    675 #define REG_DEF_LR      (1 << kRegDefLR)
    676 #define REG_DEF_LIST0   (1 << kRegDefList0)
    677 #define REG_DEF_LIST1   (1 << kRegDefList1)
    678 #define REG_USE0        (1 << kRegUse0)
    679 #define REG_USE1        (1 << kRegUse1)
    680 #define REG_USE2        (1 << kRegUse2)
    681 #define REG_USE3        (1 << kRegUse3)
    682 #define REG_USE_SP      (1 << kRegUseSP)
    683 #define REG_USE_PC      (1 << kRegUsePC)
    684 #define REG_USE_LIST0   (1 << kRegUseList0)
    685 #define REG_USE_LIST1   (1 << kRegUseList1)
    686 #define NO_OPERAND      (1 << kNoOperand)
    687 #define IS_UNARY_OP     (1 << kIsUnaryOp)
    688 #define IS_BINARY_OP    (1 << kIsBinaryOp)
    689 #define IS_TERTIARY_OP  (1 << kIsTertiaryOp)
    690 #define IS_QUAD_OP      (1 << kIsQuadOp)
    691 #define IS_IT           (1 << kIsIT)
    692 #define SETS_CCODES     (1 << kSetsCCodes)
    693 #define USES_CCODES     (1 << kUsesCCodes)
    694 
    695 /* Common combo register usage patterns */
    696 #define REG_USE01       (REG_USE0 | REG_USE1)
    697 #define REG_USE012      (REG_USE01 | REG_USE2)
    698 #define REG_USE12       (REG_USE1 | REG_USE2)
    699 #define REG_DEF0_USE0   (REG_DEF0 | REG_USE0)
    700 #define REG_DEF0_USE1   (REG_DEF0 | REG_USE1)
    701 #define REG_DEF0_USE01  (REG_DEF0 | REG_USE01)
    702 #define REG_DEF0_USE12  (REG_DEF0 | REG_USE12)
    703 #define REG_DEF01_USE2  (REG_DEF0 | REG_DEF1 | REG_USE2)
    704 
    705 /* Instruction assembly fieldLoc kind */
    706 typedef enum ArmEncodingKind {
    707     kFmtUnused,
    708     kFmtBitBlt,        /* Bit string using end/start */
    709     kFmtDfp,           /* Double FP reg */
    710     kFmtSfp,           /* Single FP reg */
    711     kFmtModImm,        /* Shifted 8-bit immed using [26,14..12,7..0] */
    712     kFmtImm16,         /* Zero-extended immed using [26,19..16,14..12,7..0] */
    713     kFmtImm6,          /* Encoded branch target using [9,7..3]0 */
    714     kFmtImm12,         /* Zero-extended immediate using [26,14..12,7..0] */
    715     kFmtShift,         /* Shift descriptor, [14..12,7..4] */
    716     kFmtLsb,           /* least significant bit using [14..12][7..6] */
    717     kFmtBWidth,        /* bit-field width, encoded as width-1 */
    718     kFmtShift5,        /* Shift count, [14..12,7..6] */
    719     kFmtBrOffset,      /* Signed extended [26,11,13,21-16,10-0]:0 */
    720     kFmtFPImm,         /* Encoded floating point immediate */
    721 } ArmEncodingKind;
    722 
    723 /* Struct used to define the snippet positions for each Thumb opcode */
    724 typedef struct ArmEncodingMap {
    725     u4 skeleton;
    726     struct {
    727         ArmEncodingKind kind;
    728         int end;   /* end for kFmtBitBlt, 1-bit slice end for FP regs */
    729         int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
    730     } fieldLoc[4];
    731     ArmOpCode opCode;
    732     int flags;
    733     char *name;
    734     char* fmt;
    735     int size;
    736 } ArmEncodingMap;
    737 
    738 /* Keys for target-specific scheduling and other optimization hints */
    739 typedef enum ArmTargetOptHints {
    740     kMaxHoistDistance,
    741 } ArmTargetOptHints;
    742 
    743 extern ArmEncodingMap EncodingMap[kArmLast];
    744 
    745 /*
    746  * Each instance of this struct holds a pseudo or real LIR instruction:
    747  * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
    748  * - real ones will be assembled into Thumb instructions.
    749  *
    750  * Machine resources are encoded into a 64-bit vector, where the encodings are
    751  * as following:
    752  * - [ 0..15]: general purpose registers including PC, SP, and LR
    753  * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
    754  *   starts at bit 16
    755  * - [48]: IT block
    756  * - [49]: integer condition code
    757  * - [50]: floatint-point status word
    758  */
    759 typedef struct ArmLIR {
    760     LIR generic;
    761     ArmOpCode opCode;
    762     int operands[4];    // [0..3] = [dest, src1, src2, extra]
    763     bool isNop;         // LIR is optimized away
    764     bool branchInsertSV;// mark for insertion of branch before this instruction,
    765                         // used to identify mem ops for self verification mode
    766     int age;            // default is 0, set lazily by the optimizer
    767     int size;           // 16-bit unit size (1 for thumb, 1 or 2 for thumb2)
    768     int aliasInfo;      // For Dalvik register access & litpool disambiguation
    769     u8 useMask;         // Resource mask for use
    770     u8 defMask;         // Resource mask for def
    771 } ArmLIR;
    772 
    773 /* Init values when a predicted chain is initially assembled */
    774 /* E7FE is branch to self */
    775 #define PREDICTED_CHAIN_BX_PAIR_INIT     0xe7fe
    776 
    777 /* Utility macros to traverse the LIR/ArmLIR list */
    778 #define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
    779 #define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
    780 
    781 #define NEXT_LIR_LVALUE(lir) (lir)->generic.next
    782 #define PREV_LIR_LVALUE(lir) (lir)->generic.prev
    783 
    784 #define CHAIN_CELL_OFFSET_TAG   0xcdab
    785 
    786 #define CHAIN_CELL_NORMAL_SIZE 12
    787 #define CHAIN_CELL_PREDICTED_SIZE 16
    788 
    789 #endif /* _DALVIK_VM_COMPILER_CODEGEN_ARM_ARMLIR_H */
    790