/*
 * 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_RUNTIME_DEX_INSTRUCTION_INL_H_
#define ART_RUNTIME_DEX_INSTRUCTION_INL_H_

#include "dex_instruction.h"

namespace art {

//------------------------------------------------------------------------------
// VRegA
//------------------------------------------------------------------------------
inline bool Instruction::HasVRegA() const {
  switch (FormatOf(Opcode())) {
    case k10t: return true;
    case k10x: return true;
    case k11n: return true;
    case k11x: return true;
    case k12x: return true;
    case k20t: return true;
    case k21c: return true;
    case k21h: return true;
    case k21s: return true;
    case k21t: return true;
    case k22b: return true;
    case k22c: return true;
    case k22s: return true;
    case k22t: return true;
    case k22x: return true;
    case k23x: return true;
    case k30t: return true;
    case k31c: return true;
    case k31i: return true;
    case k31t: return true;
    case k32x: return true;
    case k35c: return true;
    case k3rc: return true;
    case k45cc: return true;
    case k4rcc: return true;
    case k51l: return true;
    default: return false;
  }
}

inline int32_t Instruction::VRegA() const {
  switch (FormatOf(Opcode())) {
    case k10t: return VRegA_10t();
    case k10x: return VRegA_10x();
    case k11n: return VRegA_11n();
    case k11x: return VRegA_11x();
    case k12x: return VRegA_12x();
    case k20t: return VRegA_20t();
    case k21c: return VRegA_21c();
    case k21h: return VRegA_21h();
    case k21s: return VRegA_21s();
    case k21t: return VRegA_21t();
    case k22b: return VRegA_22b();
    case k22c: return VRegA_22c();
    case k22s: return VRegA_22s();
    case k22t: return VRegA_22t();
    case k22x: return VRegA_22x();
    case k23x: return VRegA_23x();
    case k30t: return VRegA_30t();
    case k31c: return VRegA_31c();
    case k31i: return VRegA_31i();
    case k31t: return VRegA_31t();
    case k32x: return VRegA_32x();
    case k35c: return VRegA_35c();
    case k3rc: return VRegA_3rc();
    case k45cc: return VRegA_45cc();
    case k4rcc: return VRegA_4rcc();
    case k51l: return VRegA_51l();
    default:
      LOG(FATAL) << "Tried to access vA of instruction " << Name() << " which has no A operand.";
      exit(EXIT_FAILURE);
  }
}

inline int8_t Instruction::VRegA_10t(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k10t);
  return static_cast<int8_t>(InstAA(inst_data));
}

inline uint8_t Instruction::VRegA_10x(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k10x);
  return InstAA(inst_data);
}

inline uint4_t Instruction::VRegA_11n(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k11n);
  return InstA(inst_data);
}

inline uint8_t Instruction::VRegA_11x(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k11x);
  return InstAA(inst_data);
}

inline uint4_t Instruction::VRegA_12x(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k12x);
  return InstA(inst_data);
}

inline int16_t Instruction::VRegA_20t() const {
  DCHECK_EQ(FormatOf(Opcode()), k20t);
  return static_cast<int16_t>(Fetch16(1));
}

inline uint8_t Instruction::VRegA_21c(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k21c);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_21h(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k21h);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_21s(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k21s);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_21t(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k21t);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_22b(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22b);
  return InstAA(inst_data);
}

inline uint4_t Instruction::VRegA_22c(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22c);
  return InstA(inst_data);
}

inline uint4_t Instruction::VRegA_22s(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22s);
  return InstA(inst_data);
}

inline uint4_t Instruction::VRegA_22t(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22t);
  return InstA(inst_data);
}

inline uint8_t Instruction::VRegA_22x(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22x);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_23x(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k23x);
  return InstAA(inst_data);
}

inline int32_t Instruction::VRegA_30t() const {
  DCHECK_EQ(FormatOf(Opcode()), k30t);
  return static_cast<int32_t>(Fetch32(1));
}

inline uint8_t Instruction::VRegA_31c(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k31c);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_31i(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k31i);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_31t(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k31t);
  return InstAA(inst_data);
}

inline uint16_t Instruction::VRegA_32x() const {
  DCHECK_EQ(FormatOf(Opcode()), k32x);
  return Fetch16(1);
}

inline uint4_t Instruction::VRegA_35c(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k35c);
  return InstB(inst_data);  // This is labeled A in the spec.
}

inline uint8_t Instruction::VRegA_3rc(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k3rc);
  return InstAA(inst_data);
}

inline uint8_t Instruction::VRegA_51l(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k51l);
  return InstAA(inst_data);
}

inline uint4_t Instruction::VRegA_45cc(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k45cc);
  return InstB(inst_data);  // This is labeled A in the spec.
}

inline uint8_t Instruction::VRegA_4rcc(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
  return InstAA(inst_data);
}

//------------------------------------------------------------------------------
// VRegB
//------------------------------------------------------------------------------
inline bool Instruction::HasVRegB() const {
  switch (FormatOf(Opcode())) {
    case k11n: return true;
    case k12x: return true;
    case k21c: return true;
    case k21h: return true;
    case k21s: return true;
    case k21t: return true;
    case k22b: return true;
    case k22c: return true;
    case k22s: return true;
    case k22t: return true;
    case k22x: return true;
    case k23x: return true;
    case k31c: return true;
    case k31i: return true;
    case k31t: return true;
    case k32x: return true;
    case k35c: return true;
    case k3rc: return true;
    case k45cc: return true;
    case k4rcc: return true;
    case k51l: return true;
    default: return false;
  }
}

inline bool Instruction::HasWideVRegB() const {
  return FormatOf(Opcode()) == k51l;
}

inline int32_t Instruction::VRegB() const {
  switch (FormatOf(Opcode())) {
    case k11n: return VRegB_11n();
    case k12x: return VRegB_12x();
    case k21c: return VRegB_21c();
    case k21h: return VRegB_21h();
    case k21s: return VRegB_21s();
    case k21t: return VRegB_21t();
    case k22b: return VRegB_22b();
    case k22c: return VRegB_22c();
    case k22s: return VRegB_22s();
    case k22t: return VRegB_22t();
    case k22x: return VRegB_22x();
    case k23x: return VRegB_23x();
    case k31c: return VRegB_31c();
    case k31i: return VRegB_31i();
    case k31t: return VRegB_31t();
    case k32x: return VRegB_32x();
    case k35c: return VRegB_35c();
    case k3rc: return VRegB_3rc();
    case k45cc: return VRegB_45cc();
    case k4rcc: return VRegB_4rcc();
    case k51l: return VRegB_51l();
    default:
      LOG(FATAL) << "Tried to access vB of instruction " << Name() << " which has no B operand.";
      exit(EXIT_FAILURE);
  }
}

inline uint64_t Instruction::WideVRegB() const {
  return VRegB_51l();
}

inline int4_t Instruction::VRegB_11n(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k11n);
  return static_cast<int4_t>((InstB(inst_data) << 28) >> 28);
}

inline uint4_t Instruction::VRegB_12x(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k12x);
  return InstB(inst_data);
}

inline uint16_t Instruction::VRegB_21c() const {
  DCHECK_EQ(FormatOf(Opcode()), k21c);
  return Fetch16(1);
}

inline uint16_t Instruction::VRegB_21h() const {
  DCHECK_EQ(FormatOf(Opcode()), k21h);
  return Fetch16(1);
}

inline int16_t Instruction::VRegB_21s() const {
  DCHECK_EQ(FormatOf(Opcode()), k21s);
  return static_cast<int16_t>(Fetch16(1));
}

inline int16_t Instruction::VRegB_21t() const {
  DCHECK_EQ(FormatOf(Opcode()), k21t);
  return static_cast<int16_t>(Fetch16(1));
}

inline uint8_t Instruction::VRegB_22b() const {
  DCHECK_EQ(FormatOf(Opcode()), k22b);
  return static_cast<uint8_t>(Fetch16(1) & 0xff);
}

inline uint4_t Instruction::VRegB_22c(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22c);
  return InstB(inst_data);
}

inline uint4_t Instruction::VRegB_22s(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22s);
  return InstB(inst_data);
}

inline uint4_t Instruction::VRegB_22t(uint16_t inst_data) const {
  DCHECK_EQ(FormatOf(Opcode()), k22t);
  return InstB(inst_data);
}

inline uint16_t Instruction::VRegB_22x() const {
  DCHECK_EQ(FormatOf(Opcode()), k22x);
  return Fetch16(1);
}

inline uint8_t Instruction::VRegB_23x() const {
  DCHECK_EQ(FormatOf(Opcode()), k23x);
  return static_cast<uint8_t>(Fetch16(1) & 0xff);
}

inline uint32_t Instruction::VRegB_31c() const {
  DCHECK_EQ(FormatOf(Opcode()), k31c);
  return Fetch32(1);
}

inline int32_t Instruction::VRegB_31i() const {
  DCHECK_EQ(FormatOf(Opcode()), k31i);
  return static_cast<int32_t>(Fetch32(1));
}

inline int32_t Instruction::VRegB_31t() const {
  DCHECK_EQ(FormatOf(Opcode()), k31t);
  return static_cast<int32_t>(Fetch32(1));
}

inline uint16_t Instruction::VRegB_32x() const {
  DCHECK_EQ(FormatOf(Opcode()), k32x);
  return Fetch16(2);
}

inline uint16_t Instruction::VRegB_35c() const {
  DCHECK_EQ(FormatOf(Opcode()), k35c);
  return Fetch16(1);
}

inline uint16_t Instruction::VRegB_3rc() const {
  DCHECK_EQ(FormatOf(Opcode()), k3rc);
  return Fetch16(1);
}

inline uint16_t Instruction::VRegB_45cc() const {
  DCHECK_EQ(FormatOf(Opcode()), k45cc);
  return Fetch16(1);
}

inline uint16_t Instruction::VRegB_4rcc() const {
  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
  return Fetch16(1);
}

inline uint64_t Instruction::VRegB_51l() const {
  DCHECK_EQ(FormatOf(Opcode()), k51l);
  uint64_t vB_wide = Fetch32(1) | ((uint64_t) Fetch32(3) << 32);
  return vB_wide;
}

//------------------------------------------------------------------------------
// VRegC
//------------------------------------------------------------------------------
inline bool Instruction::HasVRegC() const {
  switch (FormatOf(Opcode())) {
    case k22b: return true;
    case k22c: return true;
    case k22s: return true;
    case k22t: return true;
    case k23x: return true;
    case k35c: return true;
    case k3rc: return true;
    case k45cc: return true;
    case k4rcc: return true;
    default: return false;
  }
}

inline int32_t Instruction::VRegC() const {
  switch (FormatOf(Opcode())) {
    case k22b: return VRegC_22b();
    case k22c: return VRegC_22c();
    case k22s: return VRegC_22s();
    case k22t: return VRegC_22t();
    case k23x: return VRegC_23x();
    case k35c: return VRegC_35c();
    case k3rc: return VRegC_3rc();
    case k45cc: return VRegC_45cc();
    case k4rcc: return VRegC_4rcc();
    default:
      LOG(FATAL) << "Tried to access vC of instruction " << Name() << " which has no C operand.";
      exit(EXIT_FAILURE);
  }
}

inline int8_t Instruction::VRegC_22b() const {
  DCHECK_EQ(FormatOf(Opcode()), k22b);
  return static_cast<int8_t>(Fetch16(1) >> 8);
}

inline uint16_t Instruction::VRegC_22c() const {
  DCHECK_EQ(FormatOf(Opcode()), k22c);
  return Fetch16(1);
}

inline int16_t Instruction::VRegC_22s() const {
  DCHECK_EQ(FormatOf(Opcode()), k22s);
  return static_cast<int16_t>(Fetch16(1));
}

inline int16_t Instruction::VRegC_22t() const {
  DCHECK_EQ(FormatOf(Opcode()), k22t);
  return static_cast<int16_t>(Fetch16(1));
}

inline uint8_t Instruction::VRegC_23x() const {
  DCHECK_EQ(FormatOf(Opcode()), k23x);
  return static_cast<uint8_t>(Fetch16(1) >> 8);
}

inline uint4_t Instruction::VRegC_35c() const {
  DCHECK_EQ(FormatOf(Opcode()), k35c);
  return static_cast<uint4_t>(Fetch16(2) & 0x0f);
}

inline uint16_t Instruction::VRegC_3rc() const {
  DCHECK_EQ(FormatOf(Opcode()), k3rc);
  return Fetch16(2);
}

inline uint4_t Instruction::VRegC_45cc() const {
  DCHECK_EQ(FormatOf(Opcode()), k45cc);
  return static_cast<uint4_t>(Fetch16(2) & 0x0f);
}

inline uint16_t Instruction::VRegC_4rcc() const {
  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
  return Fetch16(2);
}

//------------------------------------------------------------------------------
// VRegH
//------------------------------------------------------------------------------
inline bool Instruction::HasVRegH() const {
  switch (FormatOf(Opcode())) {
    case k45cc: return true;
    case k4rcc: return true;
    default : return false;
  }
}

inline int32_t Instruction::VRegH() const {
  switch (FormatOf(Opcode())) {
    case k45cc: return VRegH_45cc();
    case k4rcc: return VRegH_4rcc();
    default :
      LOG(FATAL) << "Tried to access vH of instruction " << Name() << " which has no H operand.";
      exit(EXIT_FAILURE);
  }
}

inline uint16_t Instruction::VRegH_45cc() const {
  DCHECK_EQ(FormatOf(Opcode()), k45cc);
  return Fetch16(3);
}

inline uint16_t Instruction::VRegH_4rcc() const {
  DCHECK_EQ(FormatOf(Opcode()), k4rcc);
  return Fetch16(3);
}

inline bool Instruction::HasVarArgs() const {
  return (FormatOf(Opcode()) == k35c) || (FormatOf(Opcode()) == k45cc);
}

inline void Instruction::GetVarArgs(uint32_t arg[kMaxVarArgRegs], uint16_t inst_data) const {
  DCHECK(HasVarArgs());

  /*
   * Note that the fields mentioned in the spec don't appear in
   * their "usual" positions here compared to most formats. This
   * was done so that the field names for the argument count and
   * reference index match between this format and the corresponding
   * range formats (3rc and friends).
   *
   * Bottom line: The argument count is always in vA, and the
   * method constant (or equivalent) is always in vB.
   */
  uint16_t regList = Fetch16(2);
  uint4_t count = InstB(inst_data);  // This is labeled A in the spec.
  DCHECK_LE(count, 5U) << "Invalid arg count in 35c (" << count << ")";

  /*
   * Copy the argument registers into the arg[] array, and
   * also copy the first argument (if any) into vC. (The
   * DecodedInstruction structure doesn't have separate
   * fields for {vD, vE, vF, vG}, so there's no need to make
   * copies of those.) Note that cases 5..2 fall through.
   */
  switch (count) {
    case 5:
      arg[4] = InstA(inst_data);
      FALLTHROUGH_INTENDED;
    case 4:
      arg[3] = (regList >> 12) & 0x0f;
      FALLTHROUGH_INTENDED;
    case 3:
      arg[2] = (regList >> 8) & 0x0f;
      FALLTHROUGH_INTENDED;
    case 2:
      arg[1] = (regList >> 4) & 0x0f;
      FALLTHROUGH_INTENDED;
    case 1:
      arg[0] = regList & 0x0f;
      break;
    default:  // case 0
      break;  // Valid, but no need to do anything.
  }
}

}  // namespace art

#endif  // ART_RUNTIME_DEX_INSTRUCTION_INL_H_
