/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
#define ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_

#include <android-base/logging.h>

#include "base/globals.h"
#include "base/macros.h"

typedef uint8_t uint4_t;
typedef int8_t int4_t;

namespace art {

class DexFile;

enum {
  kNumPackedOpcodes = 0x100
};

class Instruction {
 public:
  // NOP-encoded switch-statement signatures.
  enum Signatures {
    kPackedSwitchSignature = 0x0100,
    kSparseSwitchSignature = 0x0200,
    kArrayDataSignature = 0x0300,
  };

  struct PACKED(4) PackedSwitchPayload {
    const uint16_t ident;
    const uint16_t case_count;
    const int32_t first_key;
    const int32_t targets[];

   private:
    DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload);
  };

  struct PACKED(4) SparseSwitchPayload {
    const uint16_t ident;
    const uint16_t case_count;
    const int32_t keys_and_targets[];

   public:
    const int32_t* GetKeys() const {
      return keys_and_targets;
    }

    const int32_t* GetTargets() const {
      return keys_and_targets + case_count;
    }

   private:
    DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload);
  };

  struct PACKED(4) ArrayDataPayload {
    const uint16_t ident;
    const uint16_t element_width;
    const uint32_t element_count;
    const uint8_t data[];

   private:
    DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
  };

  enum Code {  // private marker to avoid generate-operator-out.py from processing.
#define INSTRUCTION_ENUM(opcode, cname, p, f, i, a, e, v) cname = (opcode),
#include "dex_instruction_list.h"
    DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
#undef DEX_INSTRUCTION_LIST
#undef INSTRUCTION_ENUM
    RSUB_INT_LIT16 = RSUB_INT,
  };

  enum Format : uint8_t {
    k10x,  // op
    k12x,  // op vA, vB
    k11n,  // op vA, #+B
    k11x,  // op vAA
    k10t,  // op +AA
    k20t,  // op +AAAA
    k22x,  // op vAA, vBBBB
    k21t,  // op vAA, +BBBB
    k21s,  // op vAA, #+BBBB
    k21h,  // op vAA, #+BBBB00000[00000000]
    k21c,  // op vAA, thing@BBBB
    k23x,  // op vAA, vBB, vCC
    k22b,  // op vAA, vBB, #+CC
    k22t,  // op vA, vB, +CCCC
    k22s,  // op vA, vB, #+CCCC
    k22c,  // op vA, vB, thing@CCCC
    k32x,  // op vAAAA, vBBBB
    k30t,  // op +AAAAAAAA
    k31t,  // op vAA, +BBBBBBBB
    k31i,  // op vAA, #+BBBBBBBB
    k31c,  // op vAA, thing@BBBBBBBB
    k35c,  // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
    k3rc,  // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB

    // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH (A: count)
    // format: AG op BBBB FEDC HHHH
    k45cc,

    // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
    // format: AA op BBBB CCCC HHHH
    k4rcc,  // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)

    k51l,  // op vAA, #+BBBBBBBBBBBBBBBB
    kInvalidFormat,
  };

  enum IndexType : uint8_t {
    kIndexUnknown = 0,
    kIndexNone,               // has no index
    kIndexTypeRef,            // type reference index
    kIndexStringRef,          // string reference index
    kIndexMethodRef,          // method reference index
    kIndexFieldRef,           // field reference index
    kIndexFieldOffset,        // field offset (for static linked fields)
    kIndexVtableOffset,       // vtable offset (for static linked methods)
    kIndexMethodAndProtoRef,  // method and a proto reference index (for invoke-polymorphic)
    kIndexCallSiteRef,        // call site reference index
    kIndexMethodHandleRef,    // constant method handle reference index
    kIndexProtoRef,           // prototype reference index
  };

  enum Flags : uint8_t {
    kBranch              = 0x01,  // conditional or unconditional branch
    kContinue            = 0x02,  // flow can continue to next statement
    kSwitch              = 0x04,  // switch statement
    kThrow               = 0x08,  // could cause an exception to be thrown
    kReturn              = 0x10,  // returns, no additional statements
    kInvoke              = 0x20,  // a flavor of invoke
    kUnconditional       = 0x40,  // unconditional branch
    kExperimental        = 0x80,  // is an experimental opcode
  };

  // Old flags. Keeping them around in case we might need them again some day.
  enum ExtendedFlags : uint32_t {
    kAdd                 = 0x0000080,  // addition
    kSubtract            = 0x0000100,  // subtract
    kMultiply            = 0x0000200,  // multiply
    kDivide              = 0x0000400,  // division
    kRemainder           = 0x0000800,  // remainder
    kAnd                 = 0x0001000,  // and
    kOr                  = 0x0002000,  // or
    kXor                 = 0x0004000,  // xor
    kShl                 = 0x0008000,  // shl
    kShr                 = 0x0010000,  // shr
    kUshr                = 0x0020000,  // ushr
    kCast                = 0x0040000,  // cast
    kStore               = 0x0080000,  // store opcode
    kLoad                = 0x0100000,  // load opcode
    kClobber             = 0x0200000,  // clobbers memory in a big way (not just a write)
    kRegCFieldOrConstant = 0x0400000,  // is the third virtual register a field or literal constant (vC)
    kRegBFieldOrConstant = 0x0800000,  // is the second virtual register a field or literal constant (vB)
  };

  enum VerifyFlag : uint32_t {
    kVerifyNothing            = 0x0000000,
    kVerifyRegA               = 0x0000001,
    kVerifyRegAWide           = 0x0000002,
    kVerifyRegB               = 0x0000004,
    kVerifyRegBField          = 0x0000008,
    kVerifyRegBMethod         = 0x0000010,
    kVerifyRegBNewInstance    = 0x0000020,
    kVerifyRegBString         = 0x0000040,
    kVerifyRegBType           = 0x0000080,
    kVerifyRegBWide           = 0x0000100,
    kVerifyRegC               = 0x0000200,
    kVerifyRegCField          = 0x0000400,
    kVerifyRegCNewArray       = 0x0000800,
    kVerifyRegCType           = 0x0001000,
    kVerifyRegCWide           = 0x0002000,
    kVerifyArrayData          = 0x0004000,
    kVerifyBranchTarget       = 0x0008000,
    kVerifySwitchTargets      = 0x0010000,
    kVerifyVarArg             = 0x0020000,
    kVerifyVarArgNonZero      = 0x0040000,
    kVerifyVarArgRange        = 0x0080000,
    kVerifyVarArgRangeNonZero = 0x0100000,
    kVerifyRuntimeOnly        = 0x0200000,
    kVerifyError              = 0x0400000,
    kVerifyRegHPrototype      = 0x0800000,
    kVerifyRegBCallSite       = 0x1000000,
    kVerifyRegBMethodHandle   = 0x2000000,
    kVerifyRegBPrototype      = 0x4000000,
  };

  // Collect the enums in a struct for better locality.
  struct InstructionDescriptor {
    uint32_t verify_flags;         // Set of VerifyFlag.
    Format format;
    IndexType index_type;
    uint8_t flags;                 // Set of Flags.
    int8_t size_in_code_units;
  };

  static constexpr uint32_t kMaxVarArgRegs = 5;

  static constexpr bool kHaveExperimentalInstructions = false;

  // Returns the size (in 2 byte code units) of this instruction.
  size_t SizeInCodeUnits() const {
    int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
    if (UNLIKELY(result < 0)) {
      return SizeInCodeUnitsComplexOpcode();
    } else {
      return static_cast<size_t>(result);
    }
  }

  // Returns the size (in 2 byte code units) of the given instruction format.
  ALWAYS_INLINE static constexpr size_t SizeInCodeUnits(Format format);

  // Code units required to calculate the size of the instruction.
  size_t CodeUnitsRequiredForSizeComputation() const {
    const int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
    return UNLIKELY(result < 0) ? CodeUnitsRequiredForSizeOfComplexOpcode() : 1;
  }

  // Reads an instruction out of the stream at the specified address.
  static const Instruction* At(const uint16_t* code) {
    DCHECK(code != nullptr);
    return reinterpret_cast<const Instruction*>(code);
  }

  // Reads an instruction out of the stream from the current address plus an offset.
  const Instruction* RelativeAt(int32_t offset) const WARN_UNUSED {
    return At(reinterpret_cast<const uint16_t*>(this) + offset);
  }

  // Returns a pointer to the next instruction in the stream.
  const Instruction* Next() const {
    return RelativeAt(SizeInCodeUnits());
  }

  // Returns a pointer to the instruction after this 1xx instruction in the stream.
  const Instruction* Next_1xx() const {
    DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
    return RelativeAt(1);
  }

  // Returns a pointer to the instruction after this 2xx instruction in the stream.
  const Instruction* Next_2xx() const {
    DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
    return RelativeAt(2);
  }

  // Returns a pointer to the instruction after this 3xx instruction in the stream.
  const Instruction* Next_3xx() const {
    DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
    return RelativeAt(3);
  }

  // Returns a pointer to the instruction after this 4xx instruction in the stream.
  const Instruction* Next_4xx() const {
    DCHECK(FormatOf(Opcode()) >= k45cc && FormatOf(Opcode()) <= k4rcc);
    return RelativeAt(4);
  }

  // Returns a pointer to the instruction after this 51l instruction in the stream.
  const Instruction* Next_51l() const {
    DCHECK(FormatOf(Opcode()) == k51l);
    return RelativeAt(5);
  }

  // Returns the name of this instruction's opcode.
  const char* Name() const {
    return Instruction::Name(Opcode());
  }

  // Returns the name of the given opcode.
  static const char* Name(Code opcode) {
    return kInstructionNames[opcode];
  }

  // VRegA
  bool HasVRegA() const;
  ALWAYS_INLINE int32_t VRegA() const;
  ALWAYS_INLINE int32_t VRegA(Format format, uint16_t inst_data) const;

  int8_t VRegA_10t() const {
    return VRegA_10t(Fetch16(0));
  }
  uint8_t VRegA_10x() const {
    return VRegA_10x(Fetch16(0));
  }
  uint4_t VRegA_11n() const {
    return VRegA_11n(Fetch16(0));
  }
  uint8_t VRegA_11x() const {
    return VRegA_11x(Fetch16(0));
  }
  uint4_t VRegA_12x() const {
    return VRegA_12x(Fetch16(0));
  }
  int16_t VRegA_20t() const;
  uint8_t VRegA_21c() const {
    return VRegA_21c(Fetch16(0));
  }
  uint8_t VRegA_21h() const {
    return VRegA_21h(Fetch16(0));
  }
  uint8_t VRegA_21s() const {
    return VRegA_21s(Fetch16(0));
  }
  uint8_t VRegA_21t() const {
    return VRegA_21t(Fetch16(0));
  }
  uint8_t VRegA_22b() const {
    return VRegA_22b(Fetch16(0));
  }
  uint4_t VRegA_22c() const {
    return VRegA_22c(Fetch16(0));
  }
  uint4_t VRegA_22s() const {
    return VRegA_22s(Fetch16(0));
  }
  uint4_t VRegA_22t() const {
    return VRegA_22t(Fetch16(0));
  }
  uint8_t VRegA_22x() const {
    return VRegA_22x(Fetch16(0));
  }
  uint8_t VRegA_23x() const {
    return VRegA_23x(Fetch16(0));
  }
  int32_t VRegA_30t() const;
  uint8_t VRegA_31c() const {
    return VRegA_31c(Fetch16(0));
  }
  uint8_t VRegA_31i() const {
    return VRegA_31i(Fetch16(0));
  }
  uint8_t VRegA_31t() const {
    return VRegA_31t(Fetch16(0));
  }
  uint16_t VRegA_32x() const;
  uint4_t VRegA_35c() const {
    return VRegA_35c(Fetch16(0));
  }
  uint8_t VRegA_3rc() const {
    return VRegA_3rc(Fetch16(0));
  }
  uint8_t VRegA_51l() const {
    return VRegA_51l(Fetch16(0));
  }
  uint4_t VRegA_45cc() const {
    return VRegA_45cc(Fetch16(0));
  }
  uint8_t VRegA_4rcc() const {
    return VRegA_4rcc(Fetch16(0));
  }

  // The following methods return the vA operand for various instruction formats. The "inst_data"
  // parameter holds the first 16 bits of instruction which the returned value is decoded from.
  int8_t VRegA_10t(uint16_t inst_data) const;
  uint8_t VRegA_10x(uint16_t inst_data) const;
  uint4_t VRegA_11n(uint16_t inst_data) const;
  uint8_t VRegA_11x(uint16_t inst_data) const;
  uint4_t VRegA_12x(uint16_t inst_data) const;
  uint8_t VRegA_21c(uint16_t inst_data) const;
  uint8_t VRegA_21h(uint16_t inst_data) const;
  uint8_t VRegA_21s(uint16_t inst_data) const;
  uint8_t VRegA_21t(uint16_t inst_data) const;
  uint8_t VRegA_22b(uint16_t inst_data) const;
  uint4_t VRegA_22c(uint16_t inst_data) const;
  uint4_t VRegA_22s(uint16_t inst_data) const;
  uint4_t VRegA_22t(uint16_t inst_data) const;
  uint8_t VRegA_22x(uint16_t inst_data) const;
  uint8_t VRegA_23x(uint16_t inst_data) const;
  uint8_t VRegA_31c(uint16_t inst_data) const;
  uint8_t VRegA_31i(uint16_t inst_data) const;
  uint8_t VRegA_31t(uint16_t inst_data) const;
  uint4_t VRegA_35c(uint16_t inst_data) const;
  uint8_t VRegA_3rc(uint16_t inst_data) const;
  uint8_t VRegA_51l(uint16_t inst_data) const;
  uint4_t VRegA_45cc(uint16_t inst_data) const;
  uint8_t VRegA_4rcc(uint16_t inst_data) const;

  // VRegB
  bool HasVRegB() const;
  ALWAYS_INLINE int32_t VRegB() const;
  ALWAYS_INLINE int32_t VRegB(Format format, uint16_t inst_data) const;

  bool HasWideVRegB() const;
  uint64_t WideVRegB() const;

  int4_t VRegB_11n() const {
    return VRegB_11n(Fetch16(0));
  }
  uint4_t VRegB_12x() const {
    return VRegB_12x(Fetch16(0));
  }
  uint16_t VRegB_21c() const;
  uint16_t VRegB_21h() const;
  int16_t VRegB_21s() const;
  int16_t VRegB_21t() const;
  uint8_t VRegB_22b() const;
  uint4_t VRegB_22c() const {
    return VRegB_22c(Fetch16(0));
  }
  uint4_t VRegB_22s() const {
    return VRegB_22s(Fetch16(0));
  }
  uint4_t VRegB_22t() const {
    return VRegB_22t(Fetch16(0));
  }
  uint16_t VRegB_22x() const;
  uint8_t VRegB_23x() const;
  uint32_t VRegB_31c() const;
  int32_t VRegB_31i() const;
  int32_t VRegB_31t() const;
  uint16_t VRegB_32x() const;
  uint16_t VRegB_35c() const;
  uint16_t VRegB_3rc() const;
  uint64_t VRegB_51l() const;  // vB_wide
  uint16_t VRegB_45cc() const;
  uint16_t VRegB_4rcc() const;

  // The following methods return the vB operand for all instruction formats where it is encoded in
  // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned
  // value is decoded from it.
  int4_t VRegB_11n(uint16_t inst_data) const;
  uint4_t VRegB_12x(uint16_t inst_data) const;
  uint4_t VRegB_22c(uint16_t inst_data) const;
  uint4_t VRegB_22s(uint16_t inst_data) const;
  uint4_t VRegB_22t(uint16_t inst_data) const;

  // VRegC
  bool HasVRegC() const;
  ALWAYS_INLINE int32_t VRegC() const;
  ALWAYS_INLINE int32_t VRegC(Format format) const;

  int8_t VRegC_22b() const;
  uint16_t VRegC_22c() const;
  int16_t VRegC_22s() const;
  int16_t VRegC_22t() const;
  uint8_t VRegC_23x() const;
  uint4_t VRegC_35c() const;
  uint16_t VRegC_3rc() const;
  uint4_t VRegC_45cc() const;
  uint16_t VRegC_4rcc() const;


  // VRegH
  bool HasVRegH() const;
  int32_t VRegH() const;
  uint16_t VRegH_45cc() const;
  uint16_t VRegH_4rcc() const;

  // Fills the given array with the 'arg' array of the instruction.
  bool HasVarArgs() const;
  uint32_t GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const;
  uint32_t GetVarArgs(uint32_t args[kMaxVarArgRegs]) const {
    return GetVarArgs(args, Fetch16(0));
  }

  // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first
  // 16 bits of instruction.
  Code Opcode(uint16_t inst_data) const {
    DCHECK_EQ(inst_data, Fetch16(0));
    return static_cast<Code>(inst_data & 0xFF);
  }

  // Returns the opcode field of the instruction from the first 16 bits of instruction.
  Code Opcode() const {
    return Opcode(Fetch16(0));
  }

  void SetOpcode(Code opcode) {
    DCHECK_LT(static_cast<uint16_t>(opcode), 256u);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode);
  }

  void SetVRegA_10x(uint8_t val) {
    DCHECK(FormatOf(Opcode()) == k10x);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[0] = (val << 8) | (insns[0] & 0x00ff);
  }

  void SetVRegB_3rc(uint16_t val) {
    DCHECK(FormatOf(Opcode()) == k3rc);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[1] = val;
  }

  void SetVRegB_35c(uint16_t val) {
    DCHECK(FormatOf(Opcode()) == k35c);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[1] = val;
  }

  void SetVRegC_22c(uint16_t val) {
    DCHECK(FormatOf(Opcode()) == k22c);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[1] = val;
  }

  void SetVRegA_21c(uint8_t val) {
    DCHECK(FormatOf(Opcode()) == k21c);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[0] = (val << 8) | (insns[0] & 0x00ff);
  }

  void SetVRegB_21c(uint16_t val) {
    DCHECK(FormatOf(Opcode()) == k21c);
    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
    insns[1] = val;
  }

  // Returns the format of the given opcode.
  static Format FormatOf(Code opcode) {
    return kInstructionDescriptors[opcode].format;
  }

  // Returns the index type of the given opcode.
  static IndexType IndexTypeOf(Code opcode) {
    return kInstructionDescriptors[opcode].index_type;
  }

  // Returns the flags for the given opcode.
  static uint8_t FlagsOf(Code opcode) {
    return kInstructionDescriptors[opcode].flags;
  }

  // Return the verify flags for the given opcode.
  static uint32_t VerifyFlagsOf(Code opcode) {
    return kInstructionDescriptors[opcode].verify_flags;
  }

  // Returns true if this instruction is a branch.
  bool IsBranch() const {
    return (kInstructionDescriptors[Opcode()].flags & kBranch) != 0;
  }

  // Returns true if this instruction is a unconditional branch.
  bool IsUnconditional() const {
    return (kInstructionDescriptors[Opcode()].flags & kUnconditional) != 0;
  }

  // Returns the branch offset if this instruction is a branch.
  int32_t GetTargetOffset() const;

  // Returns true if the instruction allows control flow to go to the following instruction.
  bool CanFlowThrough() const;

  // Returns true if the instruction is a quickened instruction.
  bool IsQuickened() const {
    return (kInstructionDescriptors[Opcode()].index_type == kIndexFieldOffset) ||
        (kInstructionDescriptors[Opcode()].index_type == kIndexVtableOffset);
  }

  // Returns true if this instruction is a switch.
  bool IsSwitch() const {
    return (kInstructionDescriptors[Opcode()].flags & kSwitch) != 0;
  }

  // Returns true if this instruction can throw.
  bool IsThrow() const {
    return (kInstructionDescriptors[Opcode()].flags & kThrow) != 0;
  }

  // Determine if the instruction is any of 'return' instructions.
  bool IsReturn() const {
    return (kInstructionDescriptors[Opcode()].flags & kReturn) != 0;
  }

  // Determine if this instruction ends execution of its basic block.
  bool IsBasicBlockEnd() const {
    return IsBranch() || IsReturn() || Opcode() == THROW;
  }

  // Determine if this instruction is an invoke.
  bool IsInvoke() const {
    return (kInstructionDescriptors[Opcode()].flags & kInvoke) != 0;
  }

  // Determine if this instruction is experimental.
  bool IsExperimental() const {
    return (kInstructionDescriptors[Opcode()].flags & kExperimental) != 0;
  }

  int GetVerifyTypeArgumentA() const {
    return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegA | kVerifyRegAWide));
  }

  int GetVerifyTypeArgumentB() const {
    return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegB | kVerifyRegBField |
        kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType |
        kVerifyRegBWide));
  }

  int GetVerifyTypeArgumentC() const {
    return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegC | kVerifyRegCField |
        kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide));
  }

  int GetVerifyTypeArgumentH() const {
    return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRegHPrototype);
  }

  int GetVerifyExtraFlags() const {
    return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyArrayData |
        kVerifyBranchTarget | kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero |
        kVerifyVarArgRange | kVerifyVarArgRangeNonZero | kVerifyError));
  }

  bool GetVerifyIsRuntimeOnly() const {
    return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRuntimeOnly) != 0;
  }

  // Get the dex PC of this instruction as a offset in code units from the beginning of insns.
  uint32_t GetDexPc(const uint16_t* insns) const {
    return (reinterpret_cast<const uint16_t*>(this) - insns);
  }

  // Dump decoded version of instruction
  std::string DumpString(const DexFile*) const;

  // Dump code_units worth of this instruction, padding to code_units for shorter instructions
  std::string DumpHex(size_t code_units) const;

  // Little-endian dump code_units worth of this instruction, padding to code_units for
  // shorter instructions
  std::string DumpHexLE(size_t instr_code_units) const;

  uint16_t Fetch16(size_t offset) const {
    const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
    return insns[offset];
  }

 private:
  size_t SizeInCodeUnitsComplexOpcode() const;

  // Return how many code unit words are required to compute the size of the opcode.
  size_t CodeUnitsRequiredForSizeOfComplexOpcode() const;

  uint32_t Fetch32(size_t offset) const {
    return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
  }

  uint4_t InstA() const {
    return InstA(Fetch16(0));
  }

  uint4_t InstB() const {
    return InstB(Fetch16(0));
  }

  uint8_t InstAA() const {
    return InstAA(Fetch16(0));
  }

  uint4_t InstA(uint16_t inst_data) const {
    DCHECK_EQ(inst_data, Fetch16(0));
    return static_cast<uint4_t>((inst_data >> 8) & 0x0f);
  }

  uint4_t InstB(uint16_t inst_data) const {
    DCHECK_EQ(inst_data, Fetch16(0));
    return static_cast<uint4_t>(inst_data >> 12);
  }

  uint8_t InstAA(uint16_t inst_data) const {
    DCHECK_EQ(inst_data, Fetch16(0));
    return static_cast<uint8_t>(inst_data >> 8);
  }

  static const char* const kInstructionNames[];

  static const InstructionDescriptor kInstructionDescriptors[];

  DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
};
std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);

// Base class for accessing instruction operands. Unifies operand
// access for instructions that have range and varargs forms
// (e.g. invoke-polymoprhic/range and invoke-polymorphic).
class InstructionOperands {
 public:
  explicit InstructionOperands(size_t num_operands) : num_operands_(num_operands) {}
  virtual ~InstructionOperands() {}
  virtual uint32_t GetOperand(size_t index) const = 0;
  size_t GetNumberOfOperands() const { return num_operands_; }

 private:
  const size_t num_operands_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(InstructionOperands);
};

// Class for accessing operands for instructions with a range format
// (e.g. 3rc and 4rcc).
class RangeInstructionOperands final : public InstructionOperands {
 public:
  RangeInstructionOperands(uint32_t first_operand, size_t num_operands)
      : InstructionOperands(num_operands), first_operand_(first_operand) {}
  ~RangeInstructionOperands() {}
  uint32_t GetOperand(size_t operand_index) const override;

 private:
  const uint32_t first_operand_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(RangeInstructionOperands);
};

// Class for accessing operands for instructions with a variable
// number of arguments format (e.g. 35c and 45cc).
class VarArgsInstructionOperands final : public InstructionOperands {
 public:
  VarArgsInstructionOperands(const uint32_t (&operands)[Instruction::kMaxVarArgRegs],
                             size_t num_operands)
      : InstructionOperands(num_operands), operands_(operands) {}
  ~VarArgsInstructionOperands() {}
  uint32_t GetOperand(size_t operand_index) const override;

 private:
  const uint32_t (&operands_)[Instruction::kMaxVarArgRegs];

  DISALLOW_IMPLICIT_CONSTRUCTORS(VarArgsInstructionOperands);
};

// Class for accessing operands without the receiver by wrapping an
// existing InstructionOperands instance.
class NoReceiverInstructionOperands final : public InstructionOperands {
 public:
  explicit NoReceiverInstructionOperands(const InstructionOperands* const inner)
      : InstructionOperands(inner->GetNumberOfOperands() - 1), inner_(inner) {}
  ~NoReceiverInstructionOperands() {}
  uint32_t GetOperand(size_t operand_index) const override;

 private:
  const InstructionOperands* const inner_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(NoReceiverInstructionOperands);
};

}  // namespace art

#endif  // ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
