/*
 * 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 {  // private marker to avoid generate-operator-out.py from processing.
    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 {  // private marker to avoid generate-operator-out.py from processing.
    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, Instruction::Code code);
std::ostream& operator<<(std::ostream& os, Instruction::Format format);

// 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_
