Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2011 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_RUNTIME_DEX_INSTRUCTION_H_
     18 #define ART_RUNTIME_DEX_INSTRUCTION_H_
     19 
     20 #include "base/logging.h"
     21 #include "base/macros.h"
     22 #include "globals.h"
     23 
     24 typedef uint8_t uint4_t;
     25 typedef int8_t int4_t;
     26 
     27 namespace art {
     28 
     29 class DexFile;
     30 
     31 enum {
     32   kNumPackedOpcodes = 0x100
     33 };
     34 
     35 class Instruction {
     36  public:
     37   // NOP-encoded switch-statement signatures.
     38   enum Signatures {
     39     kPackedSwitchSignature = 0x0100,
     40     kSparseSwitchSignature = 0x0200,
     41     kArrayDataSignature = 0x0300,
     42   };
     43 
     44   struct PACKED(4) PackedSwitchPayload {
     45     const uint16_t ident;
     46     const uint16_t case_count;
     47     const int32_t first_key;
     48     const int32_t targets[];
     49 
     50    private:
     51     DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload);
     52   };
     53 
     54   struct PACKED(4) SparseSwitchPayload {
     55     const uint16_t ident;
     56     const uint16_t case_count;
     57     const int32_t keys_and_targets[];
     58 
     59    public:
     60     const int32_t* GetKeys() const {
     61       return keys_and_targets;
     62     }
     63 
     64     const int32_t* GetTargets() const {
     65       return keys_and_targets + case_count;
     66     }
     67 
     68    private:
     69     DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload);
     70   };
     71 
     72   struct PACKED(4) ArrayDataPayload {
     73     const uint16_t ident;
     74     const uint16_t element_width;
     75     const uint32_t element_count;
     76     const uint8_t data[];
     77 
     78    private:
     79     DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
     80   };
     81 
     82   enum Code {  // private marker to avoid generate-operator-out.py from processing.
     83 #define INSTRUCTION_ENUM(opcode, cname, p, f, i, a, e, v) cname = (opcode),
     84 #include "dex_instruction_list.h"
     85     DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
     86 #undef DEX_INSTRUCTION_LIST
     87 #undef INSTRUCTION_ENUM
     88     RSUB_INT_LIT16 = RSUB_INT,
     89   };
     90 
     91   enum Format : uint8_t {
     92     k10x,  // op
     93     k12x,  // op vA, vB
     94     k11n,  // op vA, #+B
     95     k11x,  // op vAA
     96     k10t,  // op +AA
     97     k20t,  // op +AAAA
     98     k22x,  // op vAA, vBBBB
     99     k21t,  // op vAA, +BBBB
    100     k21s,  // op vAA, #+BBBB
    101     k21h,  // op vAA, #+BBBB00000[00000000]
    102     k21c,  // op vAA, thing@BBBB
    103     k23x,  // op vAA, vBB, vCC
    104     k22b,  // op vAA, vBB, #+CC
    105     k22t,  // op vA, vB, +CCCC
    106     k22s,  // op vA, vB, #+CCCC
    107     k22c,  // op vA, vB, thing@CCCC
    108     k32x,  // op vAAAA, vBBBB
    109     k30t,  // op +AAAAAAAA
    110     k31t,  // op vAA, +BBBBBBBB
    111     k31i,  // op vAA, #+BBBBBBBB
    112     k31c,  // op vAA, thing@BBBBBBBB
    113     k35c,  // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
    114     k3rc,  // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
    115 
    116     // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH (A: count)
    117     // format: AG op BBBB FEDC HHHH
    118     k45cc,
    119 
    120     // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
    121     // format: AA op BBBB CCCC HHHH
    122     k4rcc,  // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
    123 
    124     k51l,  // op vAA, #+BBBBBBBBBBBBBBBB
    125   };
    126 
    127   enum IndexType : uint8_t {
    128     kIndexUnknown = 0,
    129     kIndexNone,               // has no index
    130     kIndexTypeRef,            // type reference index
    131     kIndexStringRef,          // string reference index
    132     kIndexMethodRef,          // method reference index
    133     kIndexFieldRef,           // field reference index
    134     kIndexFieldOffset,        // field offset (for static linked fields)
    135     kIndexVtableOffset,       // vtable offset (for static linked methods)
    136     kIndexMethodAndProtoRef,  // method and a proto reference index (for invoke-polymorphic)
    137     kIndexCallSiteRef,        // call site reference index
    138   };
    139 
    140   enum Flags : uint8_t {
    141     kBranch              = 0x01,  // conditional or unconditional branch
    142     kContinue            = 0x02,  // flow can continue to next statement
    143     kSwitch              = 0x04,  // switch statement
    144     kThrow               = 0x08,  // could cause an exception to be thrown
    145     kReturn              = 0x10,  // returns, no additional statements
    146     kInvoke              = 0x20,  // a flavor of invoke
    147     kUnconditional       = 0x40,  // unconditional branch
    148     kExperimental        = 0x80,  // is an experimental opcode
    149   };
    150 
    151   // Old flags. Keeping them around in case we might need them again some day.
    152   enum ExtendedFlags : uint32_t {
    153     kAdd                 = 0x0000080,  // addition
    154     kSubtract            = 0x0000100,  // subtract
    155     kMultiply            = 0x0000200,  // multiply
    156     kDivide              = 0x0000400,  // division
    157     kRemainder           = 0x0000800,  // remainder
    158     kAnd                 = 0x0001000,  // and
    159     kOr                  = 0x0002000,  // or
    160     kXor                 = 0x0004000,  // xor
    161     kShl                 = 0x0008000,  // shl
    162     kShr                 = 0x0010000,  // shr
    163     kUshr                = 0x0020000,  // ushr
    164     kCast                = 0x0040000,  // cast
    165     kStore               = 0x0080000,  // store opcode
    166     kLoad                = 0x0100000,  // load opcode
    167     kClobber             = 0x0200000,  // clobbers memory in a big way (not just a write)
    168     kRegCFieldOrConstant = 0x0400000,  // is the third virtual register a field or literal constant (vC)
    169     kRegBFieldOrConstant = 0x0800000,  // is the second virtual register a field or literal constant (vB)
    170   };
    171 
    172   enum VerifyFlag : uint32_t {
    173     kVerifyNone               = 0x0000000,
    174     kVerifyRegA               = 0x0000001,
    175     kVerifyRegAWide           = 0x0000002,
    176     kVerifyRegB               = 0x0000004,
    177     kVerifyRegBField          = 0x0000008,
    178     kVerifyRegBMethod         = 0x0000010,
    179     kVerifyRegBNewInstance    = 0x0000020,
    180     kVerifyRegBString         = 0x0000040,
    181     kVerifyRegBType           = 0x0000080,
    182     kVerifyRegBWide           = 0x0000100,
    183     kVerifyRegC               = 0x0000200,
    184     kVerifyRegCField          = 0x0000400,
    185     kVerifyRegCNewArray       = 0x0000800,
    186     kVerifyRegCType           = 0x0001000,
    187     kVerifyRegCWide           = 0x0002000,
    188     kVerifyArrayData          = 0x0004000,
    189     kVerifyBranchTarget       = 0x0008000,
    190     kVerifySwitchTargets      = 0x0010000,
    191     kVerifyVarArg             = 0x0020000,
    192     kVerifyVarArgNonZero      = 0x0040000,
    193     kVerifyVarArgRange        = 0x0080000,
    194     kVerifyVarArgRangeNonZero = 0x0100000,
    195     kVerifyRuntimeOnly        = 0x0200000,
    196     kVerifyError              = 0x0400000,
    197     kVerifyRegHPrototype      = 0x0800000,
    198     kVerifyRegBCallSite       = 0x1000000
    199   };
    200 
    201   // Collect the enums in a struct for better locality.
    202   struct InstructionDescriptor {
    203     uint32_t verify_flags;         // Set of VerifyFlag.
    204     Format format;
    205     IndexType index_type;
    206     uint8_t flags;                 // Set of Flags.
    207     int8_t size_in_code_units;
    208   };
    209 
    210   static constexpr uint32_t kMaxVarArgRegs = 5;
    211 
    212   static constexpr bool kHaveExperimentalInstructions = false;
    213 
    214   // Returns the size (in 2 byte code units) of this instruction.
    215   size_t SizeInCodeUnits() const {
    216     int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
    217     if (UNLIKELY(result < 0)) {
    218       return SizeInCodeUnitsComplexOpcode();
    219     } else {
    220       return static_cast<size_t>(result);
    221     }
    222   }
    223 
    224   // Reads an instruction out of the stream at the specified address.
    225   static const Instruction* At(const uint16_t* code) {
    226     DCHECK(code != nullptr);
    227     return reinterpret_cast<const Instruction*>(code);
    228   }
    229 
    230   // Reads an instruction out of the stream from the current address plus an offset.
    231   const Instruction* RelativeAt(int32_t offset) const WARN_UNUSED {
    232     return At(reinterpret_cast<const uint16_t*>(this) + offset);
    233   }
    234 
    235   // Returns a pointer to the next instruction in the stream.
    236   const Instruction* Next() const {
    237     return RelativeAt(SizeInCodeUnits());
    238   }
    239 
    240   // Returns a pointer to the instruction after this 1xx instruction in the stream.
    241   const Instruction* Next_1xx() const {
    242     DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
    243     return RelativeAt(1);
    244   }
    245 
    246   // Returns a pointer to the instruction after this 2xx instruction in the stream.
    247   const Instruction* Next_2xx() const {
    248     DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
    249     return RelativeAt(2);
    250   }
    251 
    252   // Returns a pointer to the instruction after this 3xx instruction in the stream.
    253   const Instruction* Next_3xx() const {
    254     DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
    255     return RelativeAt(3);
    256   }
    257 
    258   // Returns a pointer to the instruction after this 4xx instruction in the stream.
    259   const Instruction* Next_4xx() const {
    260     DCHECK(FormatOf(Opcode()) >= k45cc && FormatOf(Opcode()) <= k4rcc);
    261     return RelativeAt(4);
    262   }
    263 
    264   // Returns a pointer to the instruction after this 51l instruction in the stream.
    265   const Instruction* Next_51l() const {
    266     DCHECK(FormatOf(Opcode()) == k51l);
    267     return RelativeAt(5);
    268   }
    269 
    270   // Returns the name of this instruction's opcode.
    271   const char* Name() const {
    272     return Instruction::Name(Opcode());
    273   }
    274 
    275   // Returns the name of the given opcode.
    276   static const char* Name(Code opcode) {
    277     return kInstructionNames[opcode];
    278   }
    279 
    280   // VRegA
    281   bool HasVRegA() const;
    282   ALWAYS_INLINE int32_t VRegA() const;
    283 
    284   int8_t VRegA_10t() const {
    285     return VRegA_10t(Fetch16(0));
    286   }
    287   uint8_t VRegA_10x() const {
    288     return VRegA_10x(Fetch16(0));
    289   }
    290   uint4_t VRegA_11n() const {
    291     return VRegA_11n(Fetch16(0));
    292   }
    293   uint8_t VRegA_11x() const {
    294     return VRegA_11x(Fetch16(0));
    295   }
    296   uint4_t VRegA_12x() const {
    297     return VRegA_12x(Fetch16(0));
    298   }
    299   int16_t VRegA_20t() const;
    300   uint8_t VRegA_21c() const {
    301     return VRegA_21c(Fetch16(0));
    302   }
    303   uint8_t VRegA_21h() const {
    304     return VRegA_21h(Fetch16(0));
    305   }
    306   uint8_t VRegA_21s() const {
    307     return VRegA_21s(Fetch16(0));
    308   }
    309   uint8_t VRegA_21t() const {
    310     return VRegA_21t(Fetch16(0));
    311   }
    312   uint8_t VRegA_22b() const {
    313     return VRegA_22b(Fetch16(0));
    314   }
    315   uint4_t VRegA_22c() const {
    316     return VRegA_22c(Fetch16(0));
    317   }
    318   uint4_t VRegA_22s() const {
    319     return VRegA_22s(Fetch16(0));
    320   }
    321   uint4_t VRegA_22t() const {
    322     return VRegA_22t(Fetch16(0));
    323   }
    324   uint8_t VRegA_22x() const {
    325     return VRegA_22x(Fetch16(0));
    326   }
    327   uint8_t VRegA_23x() const {
    328     return VRegA_23x(Fetch16(0));
    329   }
    330   int32_t VRegA_30t() const;
    331   uint8_t VRegA_31c() const {
    332     return VRegA_31c(Fetch16(0));
    333   }
    334   uint8_t VRegA_31i() const {
    335     return VRegA_31i(Fetch16(0));
    336   }
    337   uint8_t VRegA_31t() const {
    338     return VRegA_31t(Fetch16(0));
    339   }
    340   uint16_t VRegA_32x() const;
    341   uint4_t VRegA_35c() const {
    342     return VRegA_35c(Fetch16(0));
    343   }
    344   uint8_t VRegA_3rc() const {
    345     return VRegA_3rc(Fetch16(0));
    346   }
    347   uint8_t VRegA_51l() const {
    348     return VRegA_51l(Fetch16(0));
    349   }
    350   uint4_t VRegA_45cc() const {
    351     return VRegA_45cc(Fetch16(0));
    352   }
    353   uint8_t VRegA_4rcc() const {
    354     return VRegA_4rcc(Fetch16(0));
    355   }
    356 
    357   // The following methods return the vA operand for various instruction formats. The "inst_data"
    358   // parameter holds the first 16 bits of instruction which the returned value is decoded from.
    359   int8_t VRegA_10t(uint16_t inst_data) const;
    360   uint8_t VRegA_10x(uint16_t inst_data) const;
    361   uint4_t VRegA_11n(uint16_t inst_data) const;
    362   uint8_t VRegA_11x(uint16_t inst_data) const;
    363   uint4_t VRegA_12x(uint16_t inst_data) const;
    364   uint8_t VRegA_21c(uint16_t inst_data) const;
    365   uint8_t VRegA_21h(uint16_t inst_data) const;
    366   uint8_t VRegA_21s(uint16_t inst_data) const;
    367   uint8_t VRegA_21t(uint16_t inst_data) const;
    368   uint8_t VRegA_22b(uint16_t inst_data) const;
    369   uint4_t VRegA_22c(uint16_t inst_data) const;
    370   uint4_t VRegA_22s(uint16_t inst_data) const;
    371   uint4_t VRegA_22t(uint16_t inst_data) const;
    372   uint8_t VRegA_22x(uint16_t inst_data) const;
    373   uint8_t VRegA_23x(uint16_t inst_data) const;
    374   uint8_t VRegA_31c(uint16_t inst_data) const;
    375   uint8_t VRegA_31i(uint16_t inst_data) const;
    376   uint8_t VRegA_31t(uint16_t inst_data) const;
    377   uint4_t VRegA_35c(uint16_t inst_data) const;
    378   uint8_t VRegA_3rc(uint16_t inst_data) const;
    379   uint8_t VRegA_51l(uint16_t inst_data) const;
    380   uint4_t VRegA_45cc(uint16_t inst_data) const;
    381   uint8_t VRegA_4rcc(uint16_t inst_data) const;
    382 
    383   // VRegB
    384   bool HasVRegB() const;
    385   int32_t VRegB() const;
    386 
    387   bool HasWideVRegB() const;
    388   uint64_t WideVRegB() const;
    389 
    390   int4_t VRegB_11n() const {
    391     return VRegB_11n(Fetch16(0));
    392   }
    393   uint4_t VRegB_12x() const {
    394     return VRegB_12x(Fetch16(0));
    395   }
    396   uint16_t VRegB_21c() const;
    397   uint16_t VRegB_21h() const;
    398   int16_t VRegB_21s() const;
    399   int16_t VRegB_21t() const;
    400   uint8_t VRegB_22b() const;
    401   uint4_t VRegB_22c() const {
    402     return VRegB_22c(Fetch16(0));
    403   }
    404   uint4_t VRegB_22s() const {
    405     return VRegB_22s(Fetch16(0));
    406   }
    407   uint4_t VRegB_22t() const {
    408     return VRegB_22t(Fetch16(0));
    409   }
    410   uint16_t VRegB_22x() const;
    411   uint8_t VRegB_23x() const;
    412   uint32_t VRegB_31c() const;
    413   int32_t VRegB_31i() const;
    414   int32_t VRegB_31t() const;
    415   uint16_t VRegB_32x() const;
    416   uint16_t VRegB_35c() const;
    417   uint16_t VRegB_3rc() const;
    418   uint64_t VRegB_51l() const;  // vB_wide
    419   uint16_t VRegB_45cc() const;
    420   uint16_t VRegB_4rcc() const;
    421 
    422   // The following methods return the vB operand for all instruction formats where it is encoded in
    423   // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned
    424   // value is decoded from it.
    425   int4_t VRegB_11n(uint16_t inst_data) const;
    426   uint4_t VRegB_12x(uint16_t inst_data) const;
    427   uint4_t VRegB_22c(uint16_t inst_data) const;
    428   uint4_t VRegB_22s(uint16_t inst_data) const;
    429   uint4_t VRegB_22t(uint16_t inst_data) const;
    430 
    431   // VRegC
    432   bool HasVRegC() const;
    433   int32_t VRegC() const;
    434 
    435   int8_t VRegC_22b() const;
    436   uint16_t VRegC_22c() const;
    437   int16_t VRegC_22s() const;
    438   int16_t VRegC_22t() const;
    439   uint8_t VRegC_23x() const;
    440   uint4_t VRegC_35c() const;
    441   uint16_t VRegC_3rc() const;
    442   uint4_t VRegC_45cc() const;
    443   uint16_t VRegC_4rcc() const;
    444 
    445 
    446   // VRegH
    447   bool HasVRegH() const;
    448   int32_t VRegH() const;
    449   uint16_t VRegH_45cc() const;
    450   uint16_t VRegH_4rcc() const;
    451 
    452   // Fills the given array with the 'arg' array of the instruction.
    453   bool HasVarArgs() const;
    454   void GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const;
    455   void GetVarArgs(uint32_t args[kMaxVarArgRegs]) const {
    456     return GetVarArgs(args, Fetch16(0));
    457   }
    458 
    459   // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first
    460   // 16 bits of instruction.
    461   Code Opcode(uint16_t inst_data) const {
    462     DCHECK_EQ(inst_data, Fetch16(0));
    463     return static_cast<Code>(inst_data & 0xFF);
    464   }
    465 
    466   // Returns the opcode field of the instruction from the first 16 bits of instruction.
    467   Code Opcode() const {
    468     return Opcode(Fetch16(0));
    469   }
    470 
    471   void SetOpcode(Code opcode) {
    472     DCHECK_LT(static_cast<uint16_t>(opcode), 256u);
    473     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    474     insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode);
    475   }
    476 
    477   void SetVRegA_10x(uint8_t val) {
    478     DCHECK(FormatOf(Opcode()) == k10x);
    479     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    480     insns[0] = (val << 8) | (insns[0] & 0x00ff);
    481   }
    482 
    483   void SetVRegB_3rc(uint16_t val) {
    484     DCHECK(FormatOf(Opcode()) == k3rc);
    485     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    486     insns[1] = val;
    487   }
    488 
    489   void SetVRegB_35c(uint16_t val) {
    490     DCHECK(FormatOf(Opcode()) == k35c);
    491     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    492     insns[1] = val;
    493   }
    494 
    495   void SetVRegC_22c(uint16_t val) {
    496     DCHECK(FormatOf(Opcode()) == k22c);
    497     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    498     insns[1] = val;
    499   }
    500 
    501   void SetVRegA_21c(uint8_t val) {
    502     DCHECK(FormatOf(Opcode()) == k21c);
    503     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    504     insns[0] = (val << 8) | (insns[0] & 0x00ff);
    505   }
    506 
    507   void SetVRegB_21c(uint16_t val) {
    508     DCHECK(FormatOf(Opcode()) == k21c);
    509     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    510     insns[1] = val;
    511   }
    512 
    513   // Returns the format of the given opcode.
    514   static Format FormatOf(Code opcode) {
    515     return kInstructionDescriptors[opcode].format;
    516   }
    517 
    518   // Returns the index type of the given opcode.
    519   static IndexType IndexTypeOf(Code opcode) {
    520     return kInstructionDescriptors[opcode].index_type;
    521   }
    522 
    523   // Returns the flags for the given opcode.
    524   static uint8_t FlagsOf(Code opcode) {
    525     return kInstructionDescriptors[opcode].flags;
    526   }
    527 
    528   // Return the verify flags for the given opcode.
    529   static uint32_t VerifyFlagsOf(Code opcode) {
    530     return kInstructionDescriptors[opcode].verify_flags;
    531   }
    532 
    533   // Returns true if this instruction is a branch.
    534   bool IsBranch() const {
    535     return (kInstructionDescriptors[Opcode()].flags & kBranch) != 0;
    536   }
    537 
    538   // Returns true if this instruction is a unconditional branch.
    539   bool IsUnconditional() const {
    540     return (kInstructionDescriptors[Opcode()].flags & kUnconditional) != 0;
    541   }
    542 
    543   // Returns the branch offset if this instruction is a branch.
    544   int32_t GetTargetOffset() const;
    545 
    546   // Returns true if the instruction allows control flow to go to the following instruction.
    547   bool CanFlowThrough() const;
    548 
    549   // Returns true if the instruction is a quickened instruction.
    550   bool IsQuickened() const {
    551     return (kInstructionDescriptors[Opcode()].index_type == kIndexFieldOffset) ||
    552         (kInstructionDescriptors[Opcode()].index_type == kIndexVtableOffset);
    553   }
    554 
    555   // Returns true if this instruction is a switch.
    556   bool IsSwitch() const {
    557     return (kInstructionDescriptors[Opcode()].flags & kSwitch) != 0;
    558   }
    559 
    560   // Returns true if this instruction can throw.
    561   bool IsThrow() const {
    562     return (kInstructionDescriptors[Opcode()].flags & kThrow) != 0;
    563   }
    564 
    565   // Determine if the instruction is any of 'return' instructions.
    566   bool IsReturn() const {
    567     return (kInstructionDescriptors[Opcode()].flags & kReturn) != 0;
    568   }
    569 
    570   // Determine if this instruction ends execution of its basic block.
    571   bool IsBasicBlockEnd() const {
    572     return IsBranch() || IsReturn() || Opcode() == THROW;
    573   }
    574 
    575   // Determine if this instruction is an invoke.
    576   bool IsInvoke() const {
    577     return (kInstructionDescriptors[Opcode()].flags & kInvoke) != 0;
    578   }
    579 
    580   // Determine if this instruction is experimental.
    581   bool IsExperimental() const {
    582     return (kInstructionDescriptors[Opcode()].flags & kExperimental) != 0;
    583   }
    584 
    585   int GetVerifyTypeArgumentA() const {
    586     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegA | kVerifyRegAWide));
    587   }
    588 
    589   int GetVerifyTypeArgumentB() const {
    590     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegB | kVerifyRegBField |
    591         kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType |
    592         kVerifyRegBWide));
    593   }
    594 
    595   int GetVerifyTypeArgumentC() const {
    596     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegC | kVerifyRegCField |
    597         kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide));
    598   }
    599 
    600   int GetVerifyTypeArgumentH() const {
    601     return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRegHPrototype);
    602   }
    603 
    604   int GetVerifyExtraFlags() const {
    605     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyArrayData |
    606         kVerifyBranchTarget | kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero |
    607         kVerifyVarArgRange | kVerifyVarArgRangeNonZero | kVerifyError));
    608   }
    609 
    610   bool GetVerifyIsRuntimeOnly() const {
    611     return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRuntimeOnly) != 0;
    612   }
    613 
    614   // Get the dex PC of this instruction as a offset in code units from the beginning of insns.
    615   uint32_t GetDexPc(const uint16_t* insns) const {
    616     return (reinterpret_cast<const uint16_t*>(this) - insns);
    617   }
    618 
    619   // Dump decoded version of instruction
    620   std::string DumpString(const DexFile*) const;
    621 
    622   // Dump code_units worth of this instruction, padding to code_units for shorter instructions
    623   std::string DumpHex(size_t code_units) const;
    624 
    625   // Little-endian dump code_units worth of this instruction, padding to code_units for
    626   // shorter instructions
    627   std::string DumpHexLE(size_t instr_code_units) const;
    628 
    629   uint16_t Fetch16(size_t offset) const {
    630     const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
    631     return insns[offset];
    632   }
    633 
    634  private:
    635   size_t SizeInCodeUnitsComplexOpcode() const;
    636 
    637   uint32_t Fetch32(size_t offset) const {
    638     return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
    639   }
    640 
    641   uint4_t InstA() const {
    642     return InstA(Fetch16(0));
    643   }
    644 
    645   uint4_t InstB() const {
    646     return InstB(Fetch16(0));
    647   }
    648 
    649   uint8_t InstAA() const {
    650     return InstAA(Fetch16(0));
    651   }
    652 
    653   uint4_t InstA(uint16_t inst_data) const {
    654     DCHECK_EQ(inst_data, Fetch16(0));
    655     return static_cast<uint4_t>((inst_data >> 8) & 0x0f);
    656   }
    657 
    658   uint4_t InstB(uint16_t inst_data) const {
    659     DCHECK_EQ(inst_data, Fetch16(0));
    660     return static_cast<uint4_t>(inst_data >> 12);
    661   }
    662 
    663   uint8_t InstAA(uint16_t inst_data) const {
    664     DCHECK_EQ(inst_data, Fetch16(0));
    665     return static_cast<uint8_t>(inst_data >> 8);
    666   }
    667 
    668   static const char* const kInstructionNames[];
    669 
    670   static const InstructionDescriptor kInstructionDescriptors[];
    671 
    672   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
    673 };
    674 std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
    675 std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
    676 std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
    677 std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);
    678 
    679 }  // namespace art
    680 
    681 #endif  // ART_RUNTIME_DEX_INSTRUCTION_H_
    682