Home | History | Annotate | Download | only in mips
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
     18 #define DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
     19 
     20 #include "Dalvik.h"
     21 #include "compiler/CompilerInternals.h"
     22 
     23 /*
     24  * zero is always the value 0
     25  * at is scratch for Jit (normally used as temp reg by assembler)
     26  * v0, v1 are scratch for Jit (normally hold subroutine return values)
     27  * a0-a3 are scratch for Jit (normally hold subroutine arguments)
     28  * t0-t7 are scratch for Jit
     29  * t8 is scratch for Jit
     30  * t9 is scratch for Jit (normally used for function calls)
     31  * s0 (rFP) is reserved [holds Dalvik frame pointer]
     32  * s1 (rSELF) is reserved [holds current &Thread]
     33  * s2 (rINST) is scratch for Jit
     34  * s3 (rIBASE) is scratch for Jit
     35  * s4-s7 are scratch for Jit
     36  * k0, k1 are reserved for use by interrupt handlers
     37  * gp is reserved for global pointer
     38  * sp is reserved
     39  * s8 is scratch for Jit
     40  * ra is scratch for Jit (normally holds the return addr)
     41  *
     42  * Preserved across C calls: s0-s8
     43  * Trashed across C calls: at, v0-v1, a0-a3, t0-t9, gp, ra
     44  *
     45  * Floating pointer registers
     46  * NOTE: there are 32 fp registers (16 df pairs), but current Jit code
     47  *       only support 16 fp registers (8 df pairs).
     48  * f0-f15
     49  * df0-df7, where df0={f0,f1}, df1={f2,f3}, ... , df7={f14,f15}
     50  *
     51  * f0-f15 (df0-df7) trashed across C calls
     52  *
     53  * For mips32 code use:
     54  *      a0-a3 to hold operands
     55  *      v0-v1 to hold results
     56  *      t0-t9 for temps
     57  *
     58  * All jump/branch instructions have a delay slot after it.
     59  *
     60  */
     61 
     62 /* Offset to distingish FP regs */
     63 #define FP_REG_OFFSET 32
     64 /* Offset to distinguish DP FP regs */
     65 #define FP_DOUBLE 64
     66 /* Offset to distingish the extra regs */
     67 #define EXTRA_REG_OFFSET 128
     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 EXTRAREG(x) ((x & EXTRA_REG_OFFSET) == EXTRA_REG_OFFSET)
     72 #define LOWREG(x) ((x & 0x1f) == x)
     73 #define DOUBLEREG(x) ((x & FP_DOUBLE) == FP_DOUBLE)
     74 #define SINGLEREG(x) (FPREG(x) && !DOUBLEREG(x))
     75 /*
     76  * Note: the low register of a floating point pair is sufficient to
     77  * create the name of a double, but require both names to be passed to
     78  * allow for asserts to verify that the pair is consecutive if significant
     79  * rework is done in this area.  Also, it is a good reminder in the calling
     80  * code that reg locations always describe doubles as a pair of singles.
     81  */
     82 #define S2D(x,y) ((x) | FP_DOUBLE)
     83 /* Mask to strip off fp flags */
     84 #define FP_REG_MASK (FP_REG_OFFSET-1)
     85 /* non-existent Dalvik register */
     86 #define vNone   (-1)
     87 /* non-existant physical register */
     88 #define rNone   (-1)
     89 
     90 #ifdef HAVE_LITTLE_ENDIAN
     91 #define LOWORD_OFFSET 0
     92 #define HIWORD_OFFSET 4
     93 #define r_ARG0 r_A0
     94 #define r_ARG1 r_A1
     95 #define r_ARG2 r_A2
     96 #define r_ARG3 r_A3
     97 #define r_RESULT0 r_V0
     98 #define r_RESULT1 r_V1
     99 #else
    100 #define LOWORD_OFFSET 4
    101 #define HIWORD_OFFSET 0
    102 #define r_ARG0 r_A1
    103 #define r_ARG1 r_A0
    104 #define r_ARG2 r_A3
    105 #define r_ARG3 r_A2
    106 #define r_RESULT0 r_V1
    107 #define r_RESULT1 r_V0
    108 #endif
    109 
    110 /* These are the same for both big and little endian. */
    111 #define r_FARG0 r_F12
    112 #define r_FARG1 r_F13
    113 #define r_FRESULT0 r_F0
    114 #define r_FRESULT1 r_F1
    115 
    116 /* RegisterLocation templates return values (r_V0, or r_V0/r_V1) */
    117 #define LOC_C_RETURN {kLocPhysReg, 0, 0, r_V0, 0, -1}
    118 #define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, r_RESULT0, r_RESULT1, -1}
    119 #define LOC_C_RETURN_ALT {kLocPhysReg, 0, 1, r_F0, 0, -1}
    120 #define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 1, r_FRESULT0, r_FRESULT1, -1}
    121 /* RegisterLocation templates for interpState->retVal; */
    122 #define LOC_DALVIK_RETURN_VAL {kLocRetval, 0, 0, 0, 0, -1}
    123 #define LOC_DALVIK_RETURN_VAL_WIDE {kLocRetval, 1, 0, 0, 0, -1}
    124 
    125  /*
    126  * Data structure tracking the mapping between a Dalvik register (pair) and a
    127  * native register (pair). The idea is to reuse the previously loaded value
    128  * if possible, otherwise to keep the value in a native register as long as
    129  * possible.
    130  */
    131 typedef struct RegisterInfo {
    132     int reg;                    // Reg number
    133     bool inUse;                 // Has it been allocated?
    134     bool pair;                  // Part of a register pair?
    135     int partner;                // If pair, other reg of pair
    136     bool live;                  // Is there an associated SSA name?
    137     bool dirty;                 // If live, is it dirty?
    138     int sReg;                   // Name of live value
    139     struct LIR *defStart;       // Starting inst in last def sequence
    140     struct LIR *defEnd;         // Ending inst in last def sequence
    141 } RegisterInfo;
    142 
    143 typedef struct RegisterPool {
    144     BitVector *nullCheckedRegs; // Track which registers have been null-checked
    145     int numCoreTemps;
    146     RegisterInfo *coreTemps;
    147     int nextCoreTemp;
    148     int numFPTemps;
    149     RegisterInfo *FPTemps;
    150     int nextFPTemp;
    151 } RegisterPool;
    152 
    153 typedef enum ResourceEncodingPos {
    154     kGPReg0     = 0,
    155     kRegSP      = 29,
    156     kRegLR      = 31,
    157     kFPReg0     = 32, /* only 16 fp regs supported currently */
    158     kFPRegEnd   = 48,
    159     kRegHI      = kFPRegEnd,
    160     kRegLO,
    161     kRegPC,
    162     kRegEnd     = 51,
    163     kCCode      = kRegEnd,
    164     kFPStatus,          // FP status word
    165     // The following four bits are for memory disambiguation
    166     kDalvikReg,         // 1 Dalvik Frame (can be fully disambiguated)
    167     kLiteral,           // 2 Literal pool (can be fully disambiguated)
    168     kHeapRef,           // 3 Somewhere on the heap (alias with any other heap)
    169     kMustNotAlias,      // 4 Guaranteed to be non-alias (eg *(r6+x))
    170 } ResourceEncodingPos;
    171 
    172 #define ENCODE_REG_LIST(N)      ((u8) N)
    173 #define ENCODE_REG_SP           (1ULL << kRegSP)
    174 #define ENCODE_REG_LR           (1ULL << kRegLR)
    175 #define ENCODE_REG_PC           (1ULL << kRegPC)
    176 #define ENCODE_CCODE            (1ULL << kCCode)
    177 #define ENCODE_FP_STATUS        (1ULL << kFPStatus)
    178 
    179 /* Abstract memory locations */
    180 #define ENCODE_DALVIK_REG       (1ULL << kDalvikReg)
    181 #define ENCODE_LITERAL          (1ULL << kLiteral)
    182 #define ENCODE_HEAP_REF         (1ULL << kHeapRef)
    183 #define ENCODE_MUST_NOT_ALIAS   (1ULL << kMustNotAlias)
    184 
    185 #define ENCODE_ALL              (~0ULL)
    186 #define ENCODE_MEM              (ENCODE_DALVIK_REG | ENCODE_LITERAL | \
    187                                  ENCODE_HEAP_REF | ENCODE_MUST_NOT_ALIAS)
    188 
    189 #define DECODE_ALIAS_INFO_REG(X)        (X & 0xffff)
    190 #define DECODE_ALIAS_INFO_WIDE(X)       ((X & 0x80000000) ? 1 : 0)
    191 
    192 typedef enum OpSize {
    193     kWord,
    194     kLong,
    195     kSingle,
    196     kDouble,
    197     kUnsignedHalf,
    198     kSignedHalf,
    199     kUnsignedByte,
    200     kSignedByte,
    201 } OpSize;
    202 
    203 typedef enum OpKind {
    204     kOpMov,
    205     kOpMvn,
    206     kOpCmp,
    207     kOpLsl,
    208     kOpLsr,
    209     kOpAsr,
    210     kOpRor,
    211     kOpNot,
    212     kOpAnd,
    213     kOpOr,
    214     kOpXor,
    215     kOpNeg,
    216     kOpAdd,
    217     kOpAdc,
    218     kOpSub,
    219     kOpSbc,
    220     kOpRsub,
    221     kOpMul,
    222     kOpDiv,
    223     kOpRem,
    224     kOpBic,
    225     kOpCmn,
    226     kOpTst,
    227     kOpBkpt,
    228     kOpBlx,
    229     kOpPush,
    230     kOpPop,
    231     kOp2Char,
    232     kOp2Short,
    233     kOp2Byte,
    234     kOpCondBr,
    235     kOpUncondBr,
    236 } OpKind;
    237 
    238 /*
    239  * Annotate special-purpose core registers:
    240  *
    241  * rPC, rFP, and rSELF are for architecture-independent code to use.
    242  */
    243 typedef enum NativeRegisterPool {
    244     r_ZERO = 0,
    245     r_AT = 1,
    246     r_V0 = 2,
    247     r_V1 = 3,
    248     r_A0 = 4,
    249     r_A1 = 5,
    250     r_A2 = 6,
    251     r_A3 = 7,
    252     r_T0 = 8,
    253     r_T1 = 9,
    254     r_T2 = 10,
    255     r_T3 = 11,
    256     r_T4 = 12,
    257     r_T5 = 13,
    258     r_T6 = 14,
    259     r_T7 = 15,
    260     r_S0 = 16,
    261     r_S1 = 17,
    262     r_S2 = 18,
    263     r_S3 = 19,
    264     r_S4 = 20,
    265     r_S5 = 21,
    266     r_S6 = 22,
    267     r_S7 = 23,
    268     r_T8 = 24,
    269     r_T9 = 25,
    270     r_K0 = 26,
    271     r_K1 = 27,
    272     r_GP = 28,
    273     r_SP = 29,
    274     r_FP = 30,
    275     r_RA = 31,
    276 
    277     r_F0 = 0 + FP_REG_OFFSET,
    278     r_F1,
    279     r_F2,
    280     r_F3,
    281     r_F4,
    282     r_F5,
    283     r_F6,
    284     r_F7,
    285     r_F8,
    286     r_F9,
    287     r_F10,
    288     r_F11,
    289     r_F12,
    290     r_F13,
    291     r_F14,
    292     r_F15,
    293 #if 0 /* only 16 fp regs supported currently */
    294     r_F16,
    295     r_F17,
    296     r_F18,
    297     r_F19,
    298     r_F20,
    299     r_F21,
    300     r_F22,
    301     r_F23,
    302     r_F24,
    303     r_F25,
    304     r_F26,
    305     r_F27,
    306     r_F28,
    307     r_F29,
    308     r_F30,
    309     r_F31,
    310 #endif
    311     r_DF0 = r_F0 + FP_DOUBLE,
    312     r_DF1 = r_F2 + FP_DOUBLE,
    313     r_DF2 = r_F4 + FP_DOUBLE,
    314     r_DF3 = r_F6 + FP_DOUBLE,
    315     r_DF4 = r_F8 + FP_DOUBLE,
    316     r_DF5 = r_F10 + FP_DOUBLE,
    317     r_DF6 = r_F12 + FP_DOUBLE,
    318     r_DF7 = r_F14 + FP_DOUBLE,
    319 #if 0 /* only 16 fp regs supported currently */
    320     r_DF8 = r_F16 + FP_DOUBLE,
    321     r_DF9 = r_F18 + FP_DOUBLE,
    322     r_DF10 = r_F20 + FP_DOUBLE,
    323     r_DF11 = r_F22 + FP_DOUBLE,
    324     r_DF12 = r_F24 + FP_DOUBLE,
    325     r_DF13 = r_F26 + FP_DOUBLE,
    326     r_DF14 = r_F28 + FP_DOUBLE,
    327     r_DF15 = r_F30 + FP_DOUBLE,
    328 #endif
    329     r_HI = EXTRA_REG_OFFSET,
    330     r_LO,
    331     r_PC,
    332 } NativeRegisterPool;
    333 
    334 
    335 /* must match gp offset used mterp/mips files */
    336 #define STACK_OFFSET_GP 84
    337 
    338 /* MIPSTODO: properly remap arm regs (dPC, dFP, dGLUE) and remove these mappings */
    339 #define r4PC r_S0
    340 #define rFP r_S1
    341 #define rSELF r_S2
    342 #define rINST r_S4
    343 
    344 /* Shift encodings */
    345 typedef enum MipsShiftEncodings {
    346     kMipsLsl = 0x0,
    347     kMipsLsr = 0x1,
    348     kMipsAsr = 0x2,
    349     kMipsRor = 0x3
    350 } MipsShiftEncodings;
    351 
    352 /* condition encodings */
    353 typedef enum MipsConditionCode {
    354     kMipsCondEq = 0x0,    /* 0000 */
    355     kMipsCondNe = 0x1,    /* 0001 */
    356     kMipsCondCs = 0x2,    /* 0010 */
    357     kMipsCondCc = 0x3,    /* 0011 */
    358     kMipsCondMi = 0x4,    /* 0100 */
    359     kMipsCondPl = 0x5,    /* 0101 */
    360     kMipsCondVs = 0x6,    /* 0110 */
    361     kMipsCondVc = 0x7,    /* 0111 */
    362     kMipsCondHi = 0x8,    /* 1000 */
    363     kMipsCondLs = 0x9,    /* 1001 */
    364     kMipsCondGe = 0xa,    /* 1010 */
    365     kMipsCondLt = 0xb,    /* 1011 */
    366     kMipsCondGt = 0xc,    /* 1100 */
    367     kMipsCondLe = 0xd,    /* 1101 */
    368     kMipsCondAl = 0xe,    /* 1110 */
    369     kMipsCondNv = 0xf,    /* 1111 */
    370 } MipsConditionCode;
    371 
    372 #define isPseudoOpCode(opCode) ((int)(opCode) < 0)
    373 
    374 /*
    375  * The following enum defines the list of supported Thumb instructions by the
    376  * assembler. Their corresponding snippet positions will be defined in
    377  * Assemble.c.
    378  */
    379 typedef enum MipsOpCode {
    380     kMipsChainingCellBottom = -18,
    381     kMipsPseudoBarrier = -17,
    382     kMipsPseudoExtended = -16,
    383     kMipsPseudoSSARep = -15,
    384     kMipsPseudoEntryBlock = -14,
    385     kMipsPseudoExitBlock = -13,
    386     kMipsPseudoTargetLabel = -12,
    387     kMipsPseudoChainingCellBackwardBranch = -11,
    388     kMipsPseudoChainingCellHot = -10,
    389     kMipsPseudoChainingCellInvokePredicted = -9,
    390     kMipsPseudoChainingCellInvokeSingleton = -8,
    391     kMipsPseudoChainingCellNormal = -7,
    392     kMipsPseudoDalvikByteCodeBoundary = -6,
    393     kMipsPseudoPseudoAlign4 = -5,
    394     kMipsPseudoPCReconstructionCell = -4,
    395     kMipsPseudoPCReconstructionBlockLabel = -3,
    396     kMipsPseudoEHBlockLabel = -2,
    397     kMipsPseudoNormalBlockLabel = -1,
    398 
    399     kMipsFirst,
    400     kMips32BitData = kMipsFirst, /* data [31..0] */
    401     kMipsAddiu,   /* addiu t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
    402     kMipsAddu,    /* add d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100001] */
    403     kMipsAnd,     /* and d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100100] */
    404     kMipsAndi,    /* andi t,s,imm16 [001100] s[25..21] t[20..16] imm16[15..0] */
    405     kMipsB,       /* b o   [0001000000000000] o[15..0] */
    406     kMipsBal,     /* bal o [0000010000010001] o[15..0] */
    407     /* NOTE: the code tests the range kMipsBeq thru kMipsBne, so
    408              adding an instruction in this range may require updates */
    409     kMipsBeq,     /* beq s,t,o [000100] s[25..21] t[20..16] o[15..0] */
    410     kMipsBeqz,    /* beqz s,o [000100] s[25..21] [00000] o[15..0] */
    411     kMipsBgez,    /* bgez s,o [000001] s[25..21] [00001] o[15..0] */
    412     kMipsBgtz,    /* bgtz s,o [000111] s[25..21] [00000] o[15..0] */
    413     kMipsBlez,    /* blez s,o [000110] s[25..21] [00000] o[15..0] */
    414     kMipsBltz,    /* bltz s,o [000001] s[25..21] [00000] o[15..0] */
    415     kMipsBnez,    /* bnez s,o [000101] s[25..21] [00000] o[15..0] */
    416     kMipsBne,     /* bne s,t,o [000101] s[25..21] t[20..16] o[15..0] */
    417     kMipsDiv,     /* div s,t [000000] s[25..21] t[20..16] [0000000000011010] */
    418 #if __mips_isa_rev>=2
    419     kMipsExt,     /* ext t,s,p,z [011111] s[25..21] t[20..16] z[15..11] p[10..6] [000000] */
    420 #endif
    421     kMipsJal,     /* jal t [000011] t[25..0] */
    422     kMipsJalr,    /* jalr d,s [000000] s[25..21] [00000] d[15..11]
    423                                   hint[10..6] [001001] */
    424     kMipsJr,      /* jr s [000000] s[25..21] [0000000000] hint[10..6] [001000] */
    425     kMipsLahi,    /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] load addr hi */
    426     kMipsLalo,    /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] load addr lo */
    427     kMipsLui,     /* lui t,imm16 [00111100000] t[20..16] imm16[15..0] */
    428     kMipsLb,      /* lb t,o(b) [100000] b[25..21] t[20..16] o[15..0] */
    429     kMipsLbu,     /* lbu t,o(b) [100100] b[25..21] t[20..16] o[15..0] */
    430     kMipsLh,      /* lh t,o(b) [100001] b[25..21] t[20..16] o[15..0] */
    431     kMipsLhu,     /* lhu t,o(b) [100101] b[25..21] t[20..16] o[15..0] */
    432     kMipsLw,      /* lw t,o(b) [100011] b[25..21] t[20..16] o[15..0] */
    433     kMipsMfhi,    /* mfhi d [0000000000000000] d[15..11] [00000010000] */
    434     kMipsMflo,    /* mflo d [0000000000000000] d[15..11] [00000010010] */
    435     kMipsMove,    /* move d,s [000000] s[25..21] [00000] d[15..11] [00000100101] */
    436     kMipsMovz,    /* movz d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000001010] */
    437     kMipsMul,     /* mul d,s,t [011100] s[25..21] t[20..16] d[15..11] [00000000010] */
    438     kMipsNop,     /* nop [00000000000000000000000000000000] */
    439     kMipsNor,     /* nor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100111] */
    440     kMipsOr,      /* or d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100101] */
    441     kMipsOri,     /* ori t,s,imm16 [001001] s[25..21] t[20..16] imm16[15..0] */
    442     kMipsPref,    /* pref h,o(b) [101011] b[25..21] h[20..16] o[15..0] */
    443     kMipsSb,      /* sb t,o(b) [101000] b[25..21] t[20..16] o[15..0] */
    444 #if __mips_isa_rev>=2
    445     kMipsSeb,     /* seb d,t [01111100000] t[20..16] d[15..11] [10000100000] */
    446     kMipsSeh,     /* seh d,t [01111100000] t[20..16] d[15..11] [11000100000] */
    447 #endif
    448     kMipsSh,      /* sh t,o(b) [101001] b[25..21] t[20..16] o[15..0] */
    449     kMipsSll,     /* sll d,t,a [00000000000] t[20..16] d[15..11] a[10..6] [000000] */
    450     kMipsSllv,    /* sllv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000100] */
    451     kMipsSlt,     /* slt d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101010] */
    452     kMipsSlti,    /* slti t,s,imm16 [001010] s[25..21] t[20..16] imm16[15..0] */
    453     kMipsSltu,    /* sltu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000101011] */
    454     kMipsSra,     /* sra d,s,imm5 [00000000000] t[20..16] d[15..11] imm5[10..6] [000011] */
    455     kMipsSrav,    /* srav d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000111] */
    456     kMipsSrl,     /* srl d,t,a [00000000000] t[20..16] d[20..16] a[10..6] [000010] */
    457     kMipsSrlv,    /* srlv d,t,s [000000] s[25..21] t[20..16] d[15..11] [00000000110] */
    458     kMipsSubu,    /* subu d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100011] */
    459     kMipsSw,      /* sw t,o(b) [101011] b[25..21] t[20..16] o[15..0] */
    460     kMipsXor,     /* xor d,s,t [000000] s[25..21] t[20..16] d[15..11] [00000100110] */
    461     kMipsXori,    /* xori t,s,imm16 [001110] s[25..21] t[20..16] imm16[15..0] */
    462 #ifdef __mips_hard_float
    463     kMipsFadds,   /* add.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000000] */
    464     kMipsFsubs,   /* sub.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000001] */
    465     kMipsFmuls,   /* mul.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000010] */
    466     kMipsFdivs,   /* div.s d,s,t [01000110000] t[20..16] s[15..11] d[10..6] [000011] */
    467     kMipsFaddd,   /* add.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000000] */
    468     kMipsFsubd,   /* sub.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000001] */
    469     kMipsFmuld,   /* mul.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000010] */
    470     kMipsFdivd,   /* div.d d,s,t [01000110001] t[20..16] s[15..11] d[10..6] [000011] */
    471     kMipsFcvtsd,  /* cvt.s.d d,s [01000110001] [00000] s[15..11] d[10..6] [100000] */
    472     kMipsFcvtsw,  /* cvt.s.w d,s [01000110100] [00000] s[15..11] d[10..6] [100000] */
    473     kMipsFcvtds,  /* cvt.d.s d,s [01000110000] [00000] s[15..11] d[10..6] [100001] */
    474     kMipsFcvtdw,  /* cvt.d.w d,s [01000110100] [00000] s[15..11] d[10..6] [100001] */
    475     kMipsFcvtws,  /* cvt.w.d d,s [01000110000] [00000] s[15..11] d[10..6] [100100] */
    476     kMipsFcvtwd,  /* cvt.w.d d,s [01000110001] [00000] s[15..11] d[10..6] [100100] */
    477     kMipsFmovs,   /* mov.s d,s [01000110000] [00000] s[15..11] d[10..6] [000110] */
    478     kMipsFmovd,   /* mov.d d,s [01000110001] [00000] s[15..11] d[10..6] [000110] */
    479     kMipsFlwc1,   /* lwc1 t,o(b) [110001] b[25..21] t[20..16] o[15..0] */
    480     kMipsFldc1,   /* ldc1 t,o(b) [110101] b[25..21] t[20..16] o[15..0] */
    481     kMipsFswc1,   /* swc1 t,o(b) [111001] b[25..21] t[20..16] o[15..0] */
    482     kMipsFsdc1,   /* sdc1 t,o(b) [111101] b[25..21] t[20..16] o[15..0] */
    483     kMipsMfc1,    /* mfc1 t,s [01000100000] t[20..16] s[15..11] [00000000000] */
    484     kMipsMtc1,    /* mtc1 t,s [01000100100] t[20..16] s[15..11] [00000000000] */
    485 #endif
    486     kMipsUndefined,  /* undefined [011001xxxxxxxxxxxxxxxx] */
    487     kMipsLast
    488 } MipsOpCode;
    489 
    490 /* Bit flags describing the behavior of each native opcode */
    491 typedef enum MipsOpFeatureFlags {
    492     kIsBranch = 0,
    493     kRegDef0,
    494     kRegDef1,
    495     kRegDefSP,
    496     kRegDefLR,
    497     kRegDefList0,
    498     kRegDefList1,
    499     kRegUse0,
    500     kRegUse1,
    501     kRegUse2,
    502     kRegUse3,
    503     kRegUseSP,
    504     kRegUsePC,
    505     kRegUseList0,
    506     kRegUseList1,
    507     kNoOperand,
    508     kIsUnaryOp,
    509     kIsBinaryOp,
    510     kIsTertiaryOp,
    511     kIsQuadOp,
    512     kIsIT,
    513     kSetsCCodes,
    514     kUsesCCodes,
    515     kMemLoad,
    516     kMemStore,
    517 } MipsOpFeatureFlags;
    518 
    519 #define IS_LOAD         (1 << kMemLoad)
    520 #define IS_STORE        (1 << kMemStore)
    521 #define IS_BRANCH       (1 << kIsBranch)
    522 #define REG_DEF0        (1 << kRegDef0)
    523 #define REG_DEF1        (1 << kRegDef1)
    524 #define REG_DEF_SP      (1 << kRegDefSP)
    525 #define REG_DEF_LR      (1 << kRegDefLR)
    526 #define REG_DEF_LIST0   (1 << kRegDefList0)
    527 #define REG_DEF_LIST1   (1 << kRegDefList1)
    528 #define REG_USE0        (1 << kRegUse0)
    529 #define REG_USE1        (1 << kRegUse1)
    530 #define REG_USE2        (1 << kRegUse2)
    531 #define REG_USE3        (1 << kRegUse3)
    532 #define REG_USE_SP      (1 << kRegUseSP)
    533 #define REG_USE_PC      (1 << kRegUsePC)
    534 #define REG_USE_LIST0   (1 << kRegUseList0)
    535 #define REG_USE_LIST1   (1 << kRegUseList1)
    536 #define NO_OPERAND      (1 << kNoOperand)
    537 #define IS_UNARY_OP     (1 << kIsUnaryOp)
    538 #define IS_BINARY_OP    (1 << kIsBinaryOp)
    539 #define IS_TERTIARY_OP  (1 << kIsTertiaryOp)
    540 #define IS_QUAD_OP      (1 << kIsQuadOp)
    541 #define IS_IT           (1 << kIsIT)
    542 #define SETS_CCODES     (1 << kSetsCCodes)
    543 #define USES_CCODES     (1 << kUsesCCodes)
    544 
    545 /* Common combo register usage patterns */
    546 #define REG_USE01       (REG_USE0 | REG_USE1)
    547 #define REG_USE02       (REG_USE0 | REG_USE2)
    548 #define REG_USE012      (REG_USE01 | REG_USE2)
    549 #define REG_USE12       (REG_USE1 | REG_USE2)
    550 #define REG_USE23       (REG_USE2 | REG_USE3)
    551 #define REG_DEF01       (REG_DEF0 | REG_DEF1)
    552 #define REG_DEF0_USE0   (REG_DEF0 | REG_USE0)
    553 #define REG_DEF0_USE1   (REG_DEF0 | REG_USE1)
    554 #define REG_DEF0_USE2   (REG_DEF0 | REG_USE2)
    555 #define REG_DEF0_USE01  (REG_DEF0 | REG_USE01)
    556 #define REG_DEF0_USE12  (REG_DEF0 | REG_USE12)
    557 #define REG_DEF01_USE2  (REG_DEF0 | REG_DEF1 | REG_USE2)
    558 
    559 /* Instruction assembly fieldLoc kind */
    560 typedef enum MipsEncodingKind {
    561     kFmtUnused,
    562     kFmtBitBlt,        /* Bit string using end/start */
    563     kFmtDfp,           /* Double FP reg */
    564     kFmtSfp,           /* Single FP reg */
    565 } MipsEncodingKind;
    566 
    567 /* Struct used to define the snippet positions for each Thumb opcode */
    568 typedef struct MipsEncodingMap {
    569     u4 skeleton;
    570     struct {
    571         MipsEncodingKind kind;
    572         int end;   /* end for kFmtBitBlt, 1-bit slice end for FP regs */
    573         int start; /* start for kFmtBitBlt, 4-bit slice end for FP regs */
    574     } fieldLoc[4];
    575     MipsOpCode opcode;
    576     int flags;
    577     const char *name;
    578     const char* fmt;
    579     int size;
    580 } MipsEncodingMap;
    581 
    582 /* Keys for target-specific scheduling and other optimization hints */
    583 typedef enum MipsTargetOptHints {
    584     kMaxHoistDistance,
    585 } MipsTargetOptHints;
    586 
    587 extern MipsEncodingMap EncodingMap[kMipsLast];
    588 
    589 /*
    590  * Each instance of this struct holds a pseudo or real LIR instruction:
    591  * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
    592  * - real ones will be assembled into Thumb instructions.
    593  *
    594  * Machine resources are encoded into a 64-bit vector, where the encodings are
    595  * as following:
    596  * - [ 0..15]: general purpose registers including PC, SP, and LR
    597  * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
    598  *   starts at bit 16
    599  * - [48]: IT block
    600  * - [49]: integer condition code
    601  * - [50]: floatint-point status word
    602  */
    603 typedef struct MipsLIR {
    604     LIR generic;
    605     MipsOpCode opcode;
    606     int operands[4];            // [0..3] = [dest, src1, src2, extra]
    607     struct {
    608         bool isNop:1;           // LIR is optimized away
    609         bool insertWrapper:1;   // insert branch to emulate memory accesses
    610         unsigned int age:4;     // default is 0, set lazily by the optimizer
    611         unsigned int size:3;    // bytes (2 for thumb, 2/4 for thumb2)
    612         unsigned int unused:23;
    613     } flags;
    614     int aliasInfo;              // For Dalvik register access & litpool disambiguation
    615     u8 useMask;                 // Resource mask for use
    616     u8 defMask;                 // Resource mask for def
    617 } MipsLIR;
    618 
    619 /* Init values when a predicted chain is initially assembled */
    620 /* E7FE is branch to self */
    621 #define PREDICTED_CHAIN_BX_PAIR_INIT     0xe7fe
    622 #define PREDICTED_CHAIN_DELAY_SLOT_INIT  0
    623 #define PREDICTED_CHAIN_CLAZZ_INIT       0
    624 #define PREDICTED_CHAIN_METHOD_INIT      0
    625 #define PREDICTED_CHAIN_COUNTER_INIT     0
    626 
    627 /* Utility macros to traverse the LIR/MipsLIR list */
    628 #define NEXT_LIR(lir) ((MipsLIR *) lir->generic.next)
    629 #define PREV_LIR(lir) ((MipsLIR *) lir->generic.prev)
    630 
    631 #define NEXT_LIR_LVALUE(lir) (lir)->generic.next
    632 #define PREV_LIR_LVALUE(lir) (lir)->generic.prev
    633 
    634 #define CHAIN_CELL_OFFSET_TAG   0xcdabcdabL
    635 
    636 #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
    637 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
    638 #define IS_SIMM16_2WORD(v) ((-32764 <= (v)) && ((v) <= 32763)) /* 2 offsets must fit */
    639 
    640 #define CHAIN_CELL_NORMAL_SIZE    16
    641 #define CHAIN_CELL_PREDICTED_SIZE 20
    642 
    643 
    644 #endif  // DALVIK_VM_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
    645