Home | History | Annotate | Download | only in dex
      1 /*
      2  * Copyright (C) 2012 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 ART_COMPILER_DEX_COMPILER_ENUMS_H_
     18 #define ART_COMPILER_DEX_COMPILER_ENUMS_H_
     19 
     20 #include "dex_instruction.h"
     21 
     22 namespace art {
     23 
     24 enum RegisterClass {
     25   kInvalidRegClass,
     26   kCoreReg,
     27   kFPReg,
     28   kRefReg,
     29   kAnyReg,
     30 };
     31 std::ostream& operator<<(std::ostream& os, const RegisterClass& rhs);
     32 
     33 enum BitsUsed {
     34   kSize32Bits,
     35   kSize64Bits,
     36   kSize128Bits,
     37   kSize256Bits,
     38   kSize512Bits,
     39   kSize1024Bits,
     40 };
     41 std::ostream& operator<<(std::ostream& os, const BitsUsed& rhs);
     42 
     43 enum SpecialTargetRegister {
     44   kSelf,            // Thread pointer.
     45   kSuspend,         // Used to reduce suspend checks for some targets.
     46   kLr,
     47   kPc,
     48   kSp,
     49   kArg0,
     50   kArg1,
     51   kArg2,
     52   kArg3,
     53   kArg4,
     54   kArg5,
     55   kArg6,
     56   kArg7,
     57   kFArg0,
     58   kFArg1,
     59   kFArg2,
     60   kFArg3,
     61   kFArg4,
     62   kFArg5,
     63   kFArg6,
     64   kFArg7,
     65   kFArg8,
     66   kFArg9,
     67   kFArg10,
     68   kFArg11,
     69   kFArg12,
     70   kFArg13,
     71   kFArg14,
     72   kFArg15,
     73   kRet0,
     74   kRet1,
     75   kInvokeTgt,
     76   kHiddenArg,
     77   kHiddenFpArg,
     78   kCount
     79 };
     80 std::ostream& operator<<(std::ostream& os, const SpecialTargetRegister& code);
     81 
     82 enum RegLocationType {
     83   kLocDalvikFrame = 0,  // Normal Dalvik register
     84   kLocPhysReg,
     85   kLocCompilerTemp,
     86   kLocInvalid
     87 };
     88 std::ostream& operator<<(std::ostream& os, const RegLocationType& rhs);
     89 
     90 enum BBType {
     91   kNullBlock,
     92   kEntryBlock,
     93   kDalvikByteCode,
     94   kExitBlock,
     95   kExceptionHandling,
     96   kDead,
     97 };
     98 std::ostream& operator<<(std::ostream& os, const BBType& code);
     99 
    100 // Shared pseudo opcodes - must be < 0.
    101 enum LIRPseudoOpcode {
    102   kPseudoPrologueBegin = -18,
    103   kPseudoPrologueEnd = -17,
    104   kPseudoEpilogueBegin = -16,
    105   kPseudoEpilogueEnd = -15,
    106   kPseudoExportedPC = -14,
    107   kPseudoSafepointPC = -13,
    108   kPseudoIntrinsicRetry = -12,
    109   kPseudoSuspendTarget = -11,
    110   kPseudoThrowTarget = -10,
    111   kPseudoCaseLabel = -9,
    112   kPseudoBarrier = -8,
    113   kPseudoEntryBlock = -7,
    114   kPseudoExitBlock = -6,
    115   kPseudoTargetLabel = -5,
    116   kPseudoDalvikByteCodeBoundary = -4,
    117   kPseudoPseudoAlign4 = -3,
    118   kPseudoEHBlockLabel = -2,
    119   kPseudoNormalBlockLabel = -1,
    120 };
    121 std::ostream& operator<<(std::ostream& os, const LIRPseudoOpcode& rhs);
    122 
    123 enum ExtendedMIROpcode {
    124   kMirOpFirst = kNumPackedOpcodes,
    125   kMirOpPhi = kMirOpFirst,
    126 
    127   // @brief Copy from one VR to another.
    128   // @details
    129   // vA: destination VR
    130   // vB: source VR
    131   kMirOpCopy,
    132 
    133   // @brief Used to do float comparison with less-than bias.
    134   // @details Unlike cmpl-float, this does not store result of comparison in VR.
    135   // vA: left-hand side VR for comparison.
    136   // vB: right-hand side VR for comparison.
    137   kMirOpFusedCmplFloat,
    138 
    139   // @brief Used to do float comparison with greater-than bias.
    140   // @details Unlike cmpg-float, this does not store result of comparison in VR.
    141   // vA: left-hand side VR for comparison.
    142   // vB: right-hand side VR for comparison.
    143   kMirOpFusedCmpgFloat,
    144 
    145   // @brief Used to do double comparison with less-than bias.
    146   // @details Unlike cmpl-double, this does not store result of comparison in VR.
    147   // vA: left-hand side wide VR for comparison.
    148   // vB: right-hand side wide VR for comparison.
    149   kMirOpFusedCmplDouble,
    150 
    151   // @brief Used to do double comparison with greater-than bias.
    152   // @details Unlike cmpl-double, this does not store result of comparison in VR.
    153   // vA: left-hand side wide VR for comparison.
    154   // vB: right-hand side wide VR for comparison.
    155   kMirOpFusedCmpgDouble,
    156 
    157   // @brief Used to do comparison of 64-bit long integers.
    158   // @details Unlike cmp-long, this does not store result of comparison in VR.
    159   // vA: left-hand side wide VR for comparison.
    160   // vB: right-hand side wide VR for comparison.
    161   kMirOpFusedCmpLong,
    162 
    163   // @brief This represents no-op.
    164   kMirOpNop,
    165 
    166   // @brief Do a null check on the object register.
    167   // @details The backends may implement this implicitly or explicitly. This MIR is guaranteed
    168   // to have the correct offset as an exception thrower.
    169   // vA: object register
    170   kMirOpNullCheck,
    171 
    172   kMirOpRangeCheck,
    173   kMirOpDivZeroCheck,
    174   kMirOpCheck,
    175   kMirOpSelect,
    176 
    177   // Vector opcodes:
    178   // TypeSize is an encoded field giving the element type and the vector size.
    179   // It is encoded as OpSize << 16 | (number of bits in vector)
    180   //
    181   // Destination and source are integers that will be interpreted by the
    182   // backend that supports Vector operations.  Backends are permitted to support only
    183   // certain vector register sizes.
    184   //
    185   // At this point, only two operand instructions are supported.  Three operand instructions
    186   // could be supported by using a bit in TypeSize and arg[0] where needed.
    187 
    188   // @brief MIR to move constant data to a vector register
    189   // vA: destination
    190   // vB: number of bits in register
    191   // args[0]~args[3]: up to 128 bits of data for initialization
    192   kMirOpConstVector,
    193 
    194   // @brief MIR to move a vectorized register to another
    195   // vA: destination
    196   // vB: source
    197   // vC: TypeSize
    198   kMirOpMoveVector,
    199 
    200   // @brief Packed multiply of units in two vector registers: vB = vB .* vC using vA to know the type of the vector.
    201   // vA: destination and source
    202   // vB: source
    203   // vC: TypeSize
    204   kMirOpPackedMultiply,
    205 
    206   // @brief Packed addition of units in two vector registers: vB = vB .+ vC using vA to know the type of the vector.
    207   // vA: destination and source
    208   // vB: source
    209   // vC: TypeSize
    210   kMirOpPackedAddition,
    211 
    212   // @brief Packed subtraction of units in two vector registers: vB = vB .- vC using vA to know the type of the vector.
    213   // vA: destination and source
    214   // vB: source
    215   // vC: TypeSize
    216   kMirOpPackedSubtract,
    217 
    218   // @brief Packed shift left of units in two vector registers: vB = vB .<< vC using vA to know the type of the vector.
    219   // vA: destination and source
    220   // vB: amount to shift
    221   // vC: TypeSize
    222   kMirOpPackedShiftLeft,
    223 
    224   // @brief Packed signed shift right of units in two vector registers: vB = vB .>> vC using vA to know the type of the vector.
    225   // vA: destination and source
    226   // vB: amount to shift
    227   // vC: TypeSize
    228   kMirOpPackedSignedShiftRight,
    229 
    230   // @brief Packed unsigned shift right of units in two vector registers: vB = vB .>>> vC using vA to know the type of the vector.
    231   // vA: destination and source
    232   // vB: amount to shift
    233   // vC: TypeSize
    234   kMirOpPackedUnsignedShiftRight,
    235 
    236   // @brief Packed bitwise and of units in two vector registers: vB = vB .& vC using vA to know the type of the vector.
    237   // vA: destination and source
    238   // vB: source
    239   // vC: TypeSize
    240   kMirOpPackedAnd,
    241 
    242   // @brief Packed bitwise or of units in two vector registers: vB = vB .| vC using vA to know the type of the vector.
    243   // vA: destination and source
    244   // vB: source
    245   // vC: TypeSize
    246   kMirOpPackedOr,
    247 
    248   // @brief Packed bitwise xor of units in two vector registers: vB = vB .^ vC using vA to know the type of the vector.
    249   // vA: destination and source
    250   // vB: source
    251   // vC: TypeSize
    252   kMirOpPackedXor,
    253 
    254   // @brief Reduce a 128-bit packed element into a single VR by taking lower bits
    255   // @details Instruction does a horizontal addition of the packed elements and then adds it to VR
    256   // vA: destination and source VR (not vector register)
    257   // vB: source (vector register)
    258   // vC: TypeSize
    259   kMirOpPackedAddReduce,
    260 
    261   // @brief Extract a packed element into a single VR.
    262   // vA: destination VR (not vector register)
    263   // vB: source (vector register)
    264   // vC: TypeSize
    265   // arg[0]: The index to use for extraction from vector register (which packed element)
    266   kMirOpPackedReduce,
    267 
    268   // @brief Create a vector value, with all TypeSize values equal to vC
    269   // vA: destination vector register
    270   // vB: source VR (not vector register)
    271   // vC: TypeSize
    272   kMirOpPackedSet,
    273 
    274   // @brief Reserve a range of vector registers.
    275   // vA: Start vector register to reserve.
    276   // vB: Inclusive end vector register to reserve.
    277   // @note: The backend may choose to map vector numbers used in vector opcodes.
    278   //  Reserved registers are removed from the list of backend temporary pool.
    279   kMirOpReserveVectorRegisters,
    280 
    281   // @brief Free a range of reserved vector registers
    282   // vA: Start vector register to unreserve.
    283   // vB: Inclusive end vector register to unreserve.
    284   // @note: All currently reserved vector registers are returned to the temporary pool.
    285   kMirOpReturnVectorRegisters,
    286 
    287   // @brief Create a memory barrier.
    288   // vA: a constant defined by enum MemBarrierKind.
    289   kMirOpMemBarrier,
    290 
    291   // @brief Used to fill a vector register with array values.
    292   // @details Just as with normal arrays, access on null object register must ensure NullPointerException
    293   // and invalid index must ensure ArrayIndexOutOfBoundsException. Exception behavior must be the same
    294   // as the aget it replaced and must happen at same index. Therefore, it is generally recommended that
    295   // before using this MIR, it is proven that exception is guaranteed to not be thrown and marked with
    296   // MIR_IGNORE_NULL_CHECK and MIR_IGNORE_RANGE_CHECK.
    297   // vA: destination vector register
    298   // vB: array register
    299   // vC: index register
    300   // arg[0]: TypeSize (most other vector opcodes have this in vC)
    301   kMirOpPackedArrayGet,
    302 
    303   // @brief Used to store a vector register into array.
    304   // @details Just as with normal arrays, access on null object register must ensure NullPointerException
    305   // and invalid index must ensure ArrayIndexOutOfBoundsException. Exception behavior must be the same
    306   // as the aget it replaced and must happen at same index. Therefore, it is generally recommended that
    307   // before using this MIR, it is proven that exception is guaranteed to not be thrown and marked with
    308   // MIR_IGNORE_NULL_CHECK and MIR_IGNORE_RANGE_CHECK.
    309   // vA: source vector register
    310   // vB: array register
    311   // vC: index register
    312   // arg[0]: TypeSize (most other vector opcodes have this in vC)
    313   kMirOpPackedArrayPut,
    314 
    315   // @brief Multiply-add integer.
    316   // vA: destination
    317   // vB: multiplicand
    318   // vC: multiplier
    319   // arg[0]: addend
    320   kMirOpMaddInt,
    321 
    322   // @brief Multiply-subtract integer.
    323   // vA: destination
    324   // vB: multiplicand
    325   // vC: multiplier
    326   // arg[0]: minuend
    327   kMirOpMsubInt,
    328 
    329   // @brief Multiply-add long.
    330   // vA: destination
    331   // vB: multiplicand
    332   // vC: multiplier
    333   // arg[0]: addend
    334   kMirOpMaddLong,
    335 
    336   // @brief Multiply-subtract long.
    337   // vA: destination
    338   // vB: multiplicand
    339   // vC: multiplier
    340   // arg[0]: minuend
    341   kMirOpMsubLong,
    342 
    343   kMirOpLast,
    344 };
    345 
    346 enum MIROptimizationFlagPositions {
    347   kMIRIgnoreNullCheck = 0,
    348   kMIRIgnoreRangeCheck,
    349   kMIRIgnoreCheckCast,
    350   kMIRStoreNonNullValue,              // Storing non-null value, always mark GC card.
    351   kMIRClassIsInitialized,
    352   kMIRClassIsInDexCache,
    353   kMirIgnoreDivZeroCheck,
    354   kMIRInlined,                        // Invoke is inlined (ie dead).
    355   kMIRInlinedPred,                    // Invoke is inlined via prediction.
    356   kMIRCallee,                         // Instruction is inlined from callee.
    357   kMIRIgnoreSuspendCheck,
    358   kMIRDup,
    359   kMIRMark,                           // Temporary node mark can be used by
    360                                       // opt passes for their private needs.
    361   kMIRStoreNonTemporal,
    362   kMIRLastMIRFlag,
    363 };
    364 
    365 // For successor_block_list.
    366 enum BlockListType {
    367   kNotUsed = 0,
    368   kCatch,
    369   kPackedSwitch,
    370   kSparseSwitch,
    371 };
    372 std::ostream& operator<<(std::ostream& os, const BlockListType& rhs);
    373 
    374 enum AssemblerStatus {
    375   kSuccess,
    376   kRetryAll,
    377 };
    378 std::ostream& operator<<(std::ostream& os, const AssemblerStatus& rhs);
    379 
    380 enum OpSize {
    381   kWord,            // Natural word size of target (32/64).
    382   k32,
    383   k64,
    384   kReference,       // Object reference; compressed on 64-bit targets.
    385   kSingle,
    386   kDouble,
    387   kUnsignedHalf,
    388   kSignedHalf,
    389   kUnsignedByte,
    390   kSignedByte,
    391 };
    392 std::ostream& operator<<(std::ostream& os, const OpSize& kind);
    393 
    394 enum OpKind {
    395   kOpMov,
    396   kOpCmov,
    397   kOpMvn,
    398   kOpCmp,
    399   kOpLsl,
    400   kOpLsr,
    401   kOpAsr,
    402   kOpRor,
    403   kOpNot,
    404   kOpAnd,
    405   kOpOr,
    406   kOpXor,
    407   kOpNeg,
    408   kOpAdd,
    409   kOpAdc,
    410   kOpSub,
    411   kOpSbc,
    412   kOpRsub,
    413   kOpMul,
    414   kOpDiv,
    415   kOpRem,
    416   kOpBic,
    417   kOpCmn,
    418   kOpTst,
    419   kOpRev,
    420   kOpRevsh,
    421   kOpBkpt,
    422   kOpBlx,
    423   kOpPush,
    424   kOpPop,
    425   kOp2Char,
    426   kOp2Short,
    427   kOp2Byte,
    428   kOpCondBr,
    429   kOpUncondBr,
    430   kOpBx,
    431   kOpInvalid,
    432 };
    433 std::ostream& operator<<(std::ostream& os, const OpKind& rhs);
    434 
    435 enum MoveType {
    436   kMov8GP,      // Move 8-bit general purpose register.
    437   kMov16GP,     // Move 16-bit general purpose register.
    438   kMov32GP,     // Move 32-bit general purpose register.
    439   kMov64GP,     // Move 64-bit general purpose register.
    440   kMov32FP,     // Move 32-bit FP register.
    441   kMov64FP,     // Move 64-bit FP register.
    442   kMovLo64FP,   // Move low 32-bits of 64-bit FP register.
    443   kMovHi64FP,   // Move high 32-bits of 64-bit FP register.
    444   kMovU128FP,   // Move 128-bit FP register to/from possibly unaligned region.
    445   kMov128FP = kMovU128FP,
    446   kMovA128FP,   // Move 128-bit FP register to/from region surely aligned to 16-bytes.
    447   kMovLo128FP,  // Move low 64-bits of 128-bit FP register.
    448   kMovHi128FP,  // Move high 64-bits of 128-bit FP register.
    449 };
    450 std::ostream& operator<<(std::ostream& os, const MoveType& kind);
    451 
    452 enum ConditionCode {
    453   kCondEq,  // equal
    454   kCondNe,  // not equal
    455   kCondCs,  // carry set
    456   kCondCc,  // carry clear
    457   kCondUlt,  // unsigned less than
    458   kCondUge,  // unsigned greater than or same
    459   kCondMi,  // minus
    460   kCondPl,  // plus, positive or zero
    461   kCondVs,  // overflow
    462   kCondVc,  // no overflow
    463   kCondHi,  // unsigned greater than
    464   kCondLs,  // unsigned lower or same
    465   kCondGe,  // signed greater than or equal
    466   kCondLt,  // signed less than
    467   kCondGt,  // signed greater than
    468   kCondLe,  // signed less than or equal
    469   kCondAl,  // always
    470   kCondNv,  // never
    471 };
    472 std::ostream& operator<<(std::ostream& os, const ConditionCode& kind);
    473 
    474 // Target specific condition encodings
    475 enum ArmConditionCode {
    476   kArmCondEq = 0x0,  // 0000
    477   kArmCondNe = 0x1,  // 0001
    478   kArmCondCs = 0x2,  // 0010
    479   kArmCondCc = 0x3,  // 0011
    480   kArmCondMi = 0x4,  // 0100
    481   kArmCondPl = 0x5,  // 0101
    482   kArmCondVs = 0x6,  // 0110
    483   kArmCondVc = 0x7,  // 0111
    484   kArmCondHi = 0x8,  // 1000
    485   kArmCondLs = 0x9,  // 1001
    486   kArmCondGe = 0xa,  // 1010
    487   kArmCondLt = 0xb,  // 1011
    488   kArmCondGt = 0xc,  // 1100
    489   kArmCondLe = 0xd,  // 1101
    490   kArmCondAl = 0xe,  // 1110
    491   kArmCondNv = 0xf,  // 1111
    492 };
    493 std::ostream& operator<<(std::ostream& os, const ArmConditionCode& kind);
    494 
    495 enum X86ConditionCode {
    496   kX86CondO   = 0x0,    // overflow
    497   kX86CondNo  = 0x1,    // not overflow
    498 
    499   kX86CondB   = 0x2,    // below
    500   kX86CondNae = kX86CondB,  // not-above-equal
    501   kX86CondC   = kX86CondB,  // carry
    502 
    503   kX86CondNb  = 0x3,    // not-below
    504   kX86CondAe  = kX86CondNb,  // above-equal
    505   kX86CondNc  = kX86CondNb,  // not-carry
    506 
    507   kX86CondZ   = 0x4,    // zero
    508   kX86CondEq  = kX86CondZ,  // equal
    509 
    510   kX86CondNz  = 0x5,    // not-zero
    511   kX86CondNe  = kX86CondNz,  // not-equal
    512 
    513   kX86CondBe  = 0x6,    // below-equal
    514   kX86CondNa  = kX86CondBe,  // not-above
    515 
    516   kX86CondNbe = 0x7,    // not-below-equal
    517   kX86CondA   = kX86CondNbe,  // above
    518 
    519   kX86CondS   = 0x8,    // sign
    520   kX86CondNs  = 0x9,    // not-sign
    521 
    522   kX86CondP   = 0xa,    // 8-bit parity even
    523   kX86CondPE  = kX86CondP,
    524 
    525   kX86CondNp  = 0xb,    // 8-bit parity odd
    526   kX86CondPo  = kX86CondNp,
    527 
    528   kX86CondL   = 0xc,    // less-than
    529   kX86CondNge = kX86CondL,  // not-greater-equal
    530 
    531   kX86CondNl  = 0xd,    // not-less-than
    532   kX86CondGe  = kX86CondNl,  // not-greater-equal
    533 
    534   kX86CondLe  = 0xe,    // less-than-equal
    535   kX86CondNg  = kX86CondLe,  // not-greater
    536 
    537   kX86CondNle = 0xf,    // not-less-than
    538   kX86CondG   = kX86CondNle,  // greater
    539 };
    540 std::ostream& operator<<(std::ostream& os, const X86ConditionCode& kind);
    541 
    542 enum DividePattern {
    543   DivideNone,
    544   Divide3,
    545   Divide5,
    546   Divide7,
    547 };
    548 std::ostream& operator<<(std::ostream& os, const DividePattern& pattern);
    549 
    550 /**
    551  * @brief Memory barrier types (see "The JSR-133 Cookbook for Compiler Writers").
    552  * @details We define the combined barrier types that are actually required
    553  * by the Java Memory Model, rather than using exactly the terminology from
    554  * the JSR-133 cookbook.  These should, in many cases, be replaced by acquire/release
    555  * primitives.  Note that the JSR-133 cookbook generally does not deal with
    556  * store atomicity issues, and the recipes there are not always entirely sufficient.
    557  * The current recipe is as follows:
    558  * -# Use AnyStore ~= (LoadStore | StoreStore) ~= release barrier before volatile store.
    559  * -# Use AnyAny barrier after volatile store.  (StoreLoad is as expensive.)
    560  * -# Use LoadAny barrier ~= (LoadLoad | LoadStore) ~= acquire barrier after each volatile load.
    561  * -# Use StoreStore barrier after all stores but before return from any constructor whose
    562  *    class has final fields.
    563  * -# Use NTStoreStore to order non-temporal stores with respect to all later
    564  *    store-to-memory instructions.  Only generated together with non-temporal stores.
    565  */
    566 enum MemBarrierKind {
    567   kAnyStore,
    568   kLoadAny,
    569   kStoreStore,
    570   kAnyAny,
    571   kNTStoreStore,
    572 };
    573 std::ostream& operator<<(std::ostream& os, const MemBarrierKind& kind);
    574 
    575 enum OpFeatureFlags {
    576   kIsBranch = 0,
    577   kNoOperand,
    578   kIsUnaryOp,
    579   kIsBinaryOp,
    580   kIsTertiaryOp,
    581   kIsQuadOp,
    582   kIsQuinOp,
    583   kIsSextupleOp,
    584   kIsIT,
    585   kIsMoveOp,
    586   kMemLoad,
    587   kMemStore,
    588   kMemVolatile,
    589   kMemScaledx0,
    590   kMemScaledx2,
    591   kMemScaledx4,
    592   kPCRelFixup,  // x86 FIXME: add NEEDS_FIXUP to instruction attributes.
    593   kRegDef0,
    594   kRegDef1,
    595   kRegDef2,
    596   kRegDefA,
    597   kRegDefD,
    598   kRegDefFPCSList0,
    599   kRegDefFPCSList2,
    600   kRegDefList0,
    601   kRegDefList1,
    602   kRegDefList2,
    603   kRegDefLR,
    604   kRegDefSP,
    605   kRegUse0,
    606   kRegUse1,
    607   kRegUse2,
    608   kRegUse3,
    609   kRegUse4,
    610   kRegUseA,
    611   kRegUseC,
    612   kRegUseD,
    613   kRegUseB,
    614   kRegUseFPCSList0,
    615   kRegUseFPCSList2,
    616   kRegUseList0,
    617   kRegUseList1,
    618   kRegUseLR,
    619   kRegUsePC,
    620   kRegUseSP,
    621   kSetsCCodes,
    622   kUsesCCodes,
    623   kUseFpStack,
    624   kUseHi,
    625   kUseLo,
    626   kDefHi,
    627   kDefLo
    628 };
    629 std::ostream& operator<<(std::ostream& os, const OpFeatureFlags& rhs);
    630 
    631 enum SelectInstructionKind {
    632   kSelectNone,
    633   kSelectConst,
    634   kSelectMove,
    635   kSelectGoto
    636 };
    637 std::ostream& operator<<(std::ostream& os, const SelectInstructionKind& kind);
    638 
    639 // LIR fixup kinds for Arm and X86.
    640 enum FixupKind {
    641   kFixupNone,
    642   kFixupLabel,             // For labels we just adjust the offset.
    643   kFixupLoad,              // Mostly for immediates.
    644   kFixupVLoad,             // FP load which *may* be pc-relative.
    645   kFixupCBxZ,              // Cbz, Cbnz.
    646   kFixupTBxZ,              // Tbz, Tbnz.
    647   kFixupCondBranch,        // Conditional branch
    648   kFixupT1Branch,          // Thumb1 Unconditional branch
    649   kFixupT2Branch,          // Thumb2 Unconditional branch
    650   kFixupBlx1,              // Blx1 (start of Blx1/Blx2 pair).
    651   kFixupBl1,               // Bl1 (start of Bl1/Bl2 pair).
    652   kFixupAdr,               // Adr.
    653   kFixupMovImmLST,         // kThumb2MovImm16LST.
    654   kFixupMovImmHST,         // kThumb2MovImm16HST.
    655   kFixupAlign4,            // Align to 4-byte boundary.
    656   kFixupA53Erratum835769,  // Cortex A53 Erratum 835769.
    657   kFixupSwitchTable,       // X86_64 packed switch table.
    658 };
    659 std::ostream& operator<<(std::ostream& os, const FixupKind& kind);
    660 
    661 enum VolatileKind {
    662   kNotVolatile,      // Load/Store is not volatile
    663   kVolatile          // Load/Store is volatile
    664 };
    665 std::ostream& operator<<(std::ostream& os, const VolatileKind& kind);
    666 
    667 enum WideKind {
    668   kNotWide,      // Non-wide view
    669   kWide,         // Wide view
    670   kRef           // Ref width
    671 };
    672 std::ostream& operator<<(std::ostream& os, const WideKind& kind);
    673 
    674 }  // namespace art
    675 
    676 #endif  // ART_COMPILER_DEX_COMPILER_ENUMS_H_
    677