/*
 * Copyright (C) 2014 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_COMPILER_DEX_REG_STORAGE_H_
#define ART_COMPILER_DEX_REG_STORAGE_H_

#include "base/logging.h"

namespace art {

/*
 * 16-bit representation of the physical register container holding a Dalvik value.
 * The encoding allows up to 64 physical elements per storage class, and supports eight
 * register container shapes.
 *
 * [V] [HHHHH] [SSS] [F] [LLLLLL]
 *
 * [LLLLLL]
 *  Physical register number for the low or solo register.
 *    0..63
 *
 * [F]
 *  Describes type of the [LLLLL] register.
 *    0: Core
 *    1: Floating point
 *
 * [SSS]
 *  Shape of the register container.
 *    000: Invalid
 *    001: 32-bit solo register
 *    010: 64-bit solo register
 *    011: 64-bit pair consisting of two 32-bit solo registers
 *    100: 128-bit solo register
 *    101: 256-bit solo register
 *    110: 512-bit solo register
 *    111: 1024-bit solo register
 *
 * [HHHHH]
 *  Physical register number of the high register (valid only for register pair).
 *    0..31
 *
 * [V]
 *    0 -> Invalid
 *    1 -> Valid
 *
 * Note that in all non-invalid cases, we can determine if the storage is floating point
 * by testing bit 7.  Note also that a register pair is effectively limited to a pair of
 * physical register numbers in the 0..31 range.
 *
 * On some target architectures, the same underlying physical register container can be given
 * different views.  For example, Arm's 32-bit single-precision floating point registers
 * s2 and s3 map to the low and high halves of double-precision d1.  Similarly, X86's xmm3
 * vector register can be viewed as 32-bit, 64-bit, 128-bit, etc.  In these cases the use of
 * one view will affect the other views.  The RegStorage class does not concern itself
 * with potential aliasing.  That will be done using the associated RegisterInfo struct.
 * Distinct RegStorage elements should be created for each view of a physical register
 * container.  The management of the aliased physical elements will be handled via RegisterInfo
 * records.
 */

class RegStorage {
 public:
  enum RegStorageKind {
    kValidMask     = 0x8000,
    kValid         = 0x8000,
    kInvalid       = 0x0000,
    kShapeMask     = 0x0380,
    k32BitSolo     = 0x0080,
    k64BitSolo     = 0x0100,
    k64BitPair     = 0x0180,
    k128BitSolo    = 0x0200,
    k256BitSolo    = 0x0280,
    k512BitSolo    = 0x0300,
    k1024BitSolo   = 0x0380,
    k64BitMask     = 0x0300,
    k64Bits        = 0x0100,
    kShapeTypeMask = 0x03c0,
    kFloatingPoint = 0x0040,
    kCoreRegister  = 0x0000,
  };

  static const uint16_t kRegValMask  = 0x03ff;     // Num, type and shape.
  static const uint16_t kRegTypeMask = 0x007f;     // Num and type.
  static const uint16_t kRegNumMask  = 0x003f;     // Num only.
  static const uint16_t kHighRegNumMask = 0x001f;  // 0..31 for high reg
  static const uint16_t kMaxRegs     = kRegValMask + 1;
  // TODO: deprecate use of kInvalidRegVal and speed up GetReg().  Rely on valid bit instead.
  static const uint16_t kInvalidRegVal = 0x03ff;
  static const uint16_t kHighRegShift = 10;
  static const uint16_t kHighRegMask = (kHighRegNumMask << kHighRegShift);

  // Reg is [F][LLLLL], will override any existing shape and use rs_kind.
  constexpr RegStorage(RegStorageKind rs_kind, int reg)
      : reg_(
          DCHECK_CONSTEXPR(rs_kind != k64BitPair, , 0u)
          DCHECK_CONSTEXPR((rs_kind & ~kShapeMask) == 0, , 0u)
          kValid | rs_kind | (reg & kRegTypeMask)) {
  }
  constexpr RegStorage(RegStorageKind rs_kind, int low_reg, int high_reg)
      : reg_(
          DCHECK_CONSTEXPR(rs_kind == k64BitPair, << rs_kind, 0u)
          DCHECK_CONSTEXPR((low_reg & kFloatingPoint) == (high_reg & kFloatingPoint),
                           << low_reg << ", " << high_reg, 0u)
          DCHECK_CONSTEXPR((high_reg & kRegNumMask) <= kHighRegNumMask,
                           << "High reg must be in 0..31: " << high_reg, false)
          kValid | rs_kind | ((high_reg & kHighRegNumMask) << kHighRegShift) |
                  (low_reg & kRegTypeMask)) {
  }
  constexpr explicit RegStorage(uint16_t val) : reg_(val) {}
  RegStorage() : reg_(kInvalid) {}

  // We do not provide a general operator overload for equality of reg storage, as this is
  // dangerous in the case of architectures with multiple views, and the naming ExactEquals
  // expresses the exact match expressed here. It is more likely that a comparison between the views
  // is intended in most cases. Such code can be found in, for example, Mir2Lir::IsSameReg.
  //
  // If you know what you are doing, include reg_storage_eq.h, which defines == and != for brevity.

  bool ExactlyEquals(const RegStorage& rhs) const {
    return (reg_ == rhs.GetRawBits());
  }

  bool NotExactlyEquals(const RegStorage& rhs) const {
    return (reg_ != rhs.GetRawBits());
  }

  constexpr bool Valid() const {
    return ((reg_ & kValidMask) == kValid);
  }

  constexpr bool Is32Bit() const {
    return ((reg_ & kShapeMask) == k32BitSolo);
  }

  constexpr bool Is64Bit() const {
    return ((reg_ & k64BitMask) == k64Bits);
  }

  constexpr bool Is64BitSolo() const {
    return ((reg_ & kShapeMask) == k64BitSolo);
  }

  constexpr bool IsPair() const {
    return ((reg_ & kShapeMask) == k64BitPair);
  }

  constexpr bool IsFloat() const {
    return
        DCHECK_CONSTEXPR(Valid(), , false)
        ((reg_ & kFloatingPoint) == kFloatingPoint);
  }

  constexpr bool IsDouble() const {
    return
        DCHECK_CONSTEXPR(Valid(), , false)
        (reg_ & (kFloatingPoint | k64BitMask)) == (kFloatingPoint | k64Bits);
  }

  constexpr bool IsSingle() const {
    return
        DCHECK_CONSTEXPR(Valid(), , false)
        (reg_ & (kFloatingPoint | k64BitMask)) == kFloatingPoint;
  }

  static constexpr bool IsFloat(uint16_t reg) {
    return ((reg & kFloatingPoint) == kFloatingPoint);
  }

  static constexpr bool IsDouble(uint16_t reg) {
    return (reg & (kFloatingPoint | k64BitMask)) == (kFloatingPoint | k64Bits);
  }

  static constexpr bool IsSingle(uint16_t reg) {
    return (reg & (kFloatingPoint | k64BitMask)) == kFloatingPoint;
  }

  // Used to retrieve either the low register of a pair, or the only register.
  int GetReg() const {
    DCHECK(!IsPair()) << "reg_ = 0x" << std::hex << reg_;
    return Valid() ? (reg_ & kRegValMask) : kInvalidRegVal;
  }

  // Sets shape, type and num of solo.
  void SetReg(int reg) {
    DCHECK(Valid());
    DCHECK(!IsPair());
    reg_ = (reg_ & ~kRegValMask) | reg;
  }

  // Set the reg number and type only, target remain 64-bit pair.
  void SetLowReg(int reg) {
    DCHECK(IsPair());
    reg_ = (reg_ & ~kRegTypeMask) | (reg & kRegTypeMask);
  }

  // Retrieve the least significant register of a pair and return as 32-bit solo.
  int GetLowReg() const {
    DCHECK(IsPair());
    return ((reg_ & kRegTypeMask) | k32BitSolo);
  }

  // Create a stand-alone RegStorage from the low reg of a pair.
  RegStorage GetLow() const {
    DCHECK(IsPair());
    return RegStorage(k32BitSolo, reg_ & kRegTypeMask);
  }

  // Retrieve the most significant register of a pair.
  int GetHighReg() const {
    DCHECK(IsPair());
    return k32BitSolo | ((reg_ & kHighRegMask) >> kHighRegShift) | (reg_ & kFloatingPoint);
  }

  // Create a stand-alone RegStorage from the high reg of a pair.
  RegStorage GetHigh() const {
    DCHECK(IsPair());
    return RegStorage(kValid | GetHighReg());
  }

  void SetHighReg(int reg) {
    DCHECK(IsPair());
    reg_ = (reg_ & ~kHighRegMask) | ((reg & kHighRegNumMask) << kHighRegShift);
  }

  // Return the register number of low or solo.
  constexpr int GetRegNum() const {
    return reg_ & kRegNumMask;
  }

  // Is register number in 0..7?
  constexpr bool Low8() const {
    return GetRegNum() < 8;
  }

  // Is register number in 0..3?
  constexpr bool Low4() const {
    return GetRegNum() < 4;
  }

  // Combine 2 32-bit solo regs into a pair.
  static RegStorage MakeRegPair(RegStorage low, RegStorage high) {
    DCHECK(!low.IsPair());
    DCHECK(low.Is32Bit());
    DCHECK(!high.IsPair());
    DCHECK(high.Is32Bit());
    return RegStorage(k64BitPair, low.GetReg(), high.GetReg());
  }

  static constexpr bool SameRegType(RegStorage reg1, RegStorage reg2) {
    return (reg1.IsDouble() == reg2.IsDouble()) && (reg1.IsSingle() == reg2.IsSingle());
  }

  static constexpr bool SameRegType(int reg1, int reg2) {
    return (IsDouble(reg1) == IsDouble(reg2)) && (IsSingle(reg1) == IsSingle(reg2));
  }

  // Create a 32-bit solo.
  static RegStorage Solo32(int reg_num) {
    return RegStorage(k32BitSolo, reg_num & kRegTypeMask);
  }

  // Create a floating point 32-bit solo.
  static constexpr RegStorage FloatSolo32(int reg_num) {
    return RegStorage(k32BitSolo, (reg_num & kRegNumMask) | kFloatingPoint);
  }

  // Create a 128-bit solo.
  static constexpr RegStorage Solo128(int reg_num) {
    return RegStorage(k128BitSolo, reg_num & kRegTypeMask);
  }

  // Create a 64-bit solo.
  static constexpr RegStorage Solo64(int reg_num) {
    return RegStorage(k64BitSolo, reg_num & kRegTypeMask);
  }

  // Create a floating point 64-bit solo.
  static RegStorage FloatSolo64(int reg_num) {
    return RegStorage(k64BitSolo, (reg_num & kRegNumMask) | kFloatingPoint);
  }

  static constexpr RegStorage InvalidReg() {
    return RegStorage(kInvalid);
  }

  static constexpr uint16_t RegNum(int raw_reg_bits) {
    return raw_reg_bits & kRegNumMask;
  }

  constexpr int GetRawBits() const {
    return reg_;
  }

  size_t StorageSize() const {
    switch (reg_ & kShapeMask) {
      case kInvalid: return 0;
      case k32BitSolo: return 4;
      case k64BitSolo: return 8;
      case k64BitPair: return 8;  // Is this useful?  Might want to disallow taking size of pair.
      case k128BitSolo: return 16;
      case k256BitSolo: return 32;
      case k512BitSolo: return 64;
      case k1024BitSolo: return 128;
      default: LOG(FATAL) << "Unexpected shape";
    }
    return 0;
  }

 private:
  uint16_t reg_;
};

}  // namespace art

#endif  // ART_COMPILER_DEX_REG_STORAGE_H_
