// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_WASM_BASELINE_LIFTOFF_REGISTER_H_
#define V8_WASM_BASELINE_LIFTOFF_REGISTER_H_

#include <iosfwd>
#include <memory>

#include "src/base/bits.h"
#include "src/wasm/baseline/liftoff-assembler-defs.h"
#include "src/wasm/wasm-opcodes.h"

namespace v8 {
namespace internal {
namespace wasm {

static constexpr bool kNeedI64RegPair = kSystemPointerSize == 4;
static constexpr bool kNeedS128RegPair = !kSimpleFPAliasing;

enum RegClass : uint8_t {
  kGpReg,
  kFpReg,
  kGpRegPair = kFpReg + 1 + (kNeedS128RegPair && !kNeedI64RegPair),
  kFpRegPair = kFpReg + 1 + kNeedI64RegPair,
  kNoReg = kFpRegPair + kNeedS128RegPair,
  // +------------------+-------------------------------+
  // |                  |        kNeedI64RegPair        |
  // +------------------+---------------+---------------+
  // | kNeedS128RegPair |     true      |    false      |
  // +------------------+---------------+---------------+
  // |             true | 0,1,2,3,4 (a) | 0,1,3,2,3     |
  // |            false | 0,1,2,3,3 (b) | 0,1,2,2,2 (c) |
  // +------------------+---------------+---------------+
  // (a) arm
  // (b) ia32
  // (c) x64, arm64
};

static_assert(kNeedI64RegPair == (kGpRegPair != kNoReg),
              "kGpRegPair equals kNoReg if unused");
static_assert(kNeedS128RegPair == (kFpRegPair != kNoReg),
              "kFpRegPair equals kNoReg if unused");

enum RegPairHalf : uint8_t { kLowWord = 0, kHighWord = 1 };

static inline constexpr bool needs_gp_reg_pair(ValueType type) {
  return kNeedI64RegPair && type == kWasmI64;
}

static inline constexpr bool needs_fp_reg_pair(ValueType type) {
  return kNeedS128RegPair && type == kWasmS128;
}

static inline constexpr RegClass reg_class_for(ValueType::Kind kind) {
  switch (kind) {
    case ValueType::kF32:
    case ValueType::kF64:
      return kFpReg;
    case ValueType::kI32:
      return kGpReg;
    case ValueType::kI64:
      return kNeedI64RegPair ? kGpRegPair : kGpReg;
    case ValueType::kS128:
      return kNeedS128RegPair ? kFpRegPair : kFpReg;
    case ValueType::kRef:
    case ValueType::kOptRef:
      return kGpReg;
    default:
      return kNoReg;  // unsupported type
  }
}

static inline constexpr RegClass reg_class_for(ValueType type) {
  return reg_class_for(type.kind());
}

// Description of LiftoffRegister code encoding.
// This example uses the ARM architecture, which as of writing has:
// - 9 GP registers, requiring 4 bits
// - 13 FP regitsters, requiring 5 bits
// - kNeedI64RegPair is true
// - kNeedS128RegPair is true
// - thus, kBitsPerRegPair is 2 + 2 * 4 = 10
// - storage_t is uint16_t
// The table below illustrates how each RegClass is encoded, with brackets
// surrounding the bits which encode the register number.
//
// +----------------+------------------+
// | RegClass       | Example          |
// +----------------+------------------+
// | kGpReg (1)     | [00 0000   0000] |
// | kFpReg (2)     | [00 0000   1001] |
// | kGpRegPair (3) | 01 [0000] [0001] |
// | kFpRegPair (4) | 10  000[0  0010] |
// +----------------+------------------+
//
// gp and fp registers are encoded in the same index space, which means that
// code has to check for kGpRegPair and kFpRegPair before it can treat the code
// as a register code.
// (1) [0 .. kMaxGpRegCode] encodes gp registers
// (2) [kMaxGpRegCode + 1 .. kMaxGpRegCode + kMaxFpRegCode] encodes fp
// registers, so in this example, 1001 is really fp register 0.
// (3) The second top bit is set for kGpRegPair, and the two gp registers are
// stuffed side by side in code. Note that this is not the second top bit of
// storage_t, since storage_t is larger than the number of meaningful bits we
// need for the encoding.
// (4) The top bit is set for kFpRegPair, and the fp register is stuffed into
// the bottom part of the code. Unlike (2), this is the fp register code itself
// (not sharing index space with gp), so in this example, it is fp register 2.

// Maximum code of a gp cache register.
static constexpr int kMaxGpRegCode =
    8 * sizeof(kLiftoffAssemblerGpCacheRegs) -
    base::bits::CountLeadingZeros(kLiftoffAssemblerGpCacheRegs) - 1;
// Maximum code of an fp cache register.
static constexpr int kMaxFpRegCode =
    8 * sizeof(kLiftoffAssemblerFpCacheRegs) -
    base::bits::CountLeadingZeros(kLiftoffAssemblerFpCacheRegs) - 1;
static constexpr int kAfterMaxLiftoffGpRegCode = kMaxGpRegCode + 1;
static constexpr int kAfterMaxLiftoffFpRegCode =
    kAfterMaxLiftoffGpRegCode + kMaxFpRegCode + 1;
static constexpr int kAfterMaxLiftoffRegCode = kAfterMaxLiftoffFpRegCode;
static constexpr int kBitsPerLiftoffRegCode =
    32 - base::bits::CountLeadingZeros<uint32_t>(kAfterMaxLiftoffRegCode - 1);
static constexpr int kBitsPerGpRegCode =
    32 - base::bits::CountLeadingZeros<uint32_t>(kMaxGpRegCode);
static constexpr int kBitsPerFpRegCode =
    32 - base::bits::CountLeadingZeros<uint32_t>(kMaxFpRegCode);
// GpRegPair requires 1 extra bit, S128RegPair also needs an extra bit.
static constexpr int kBitsPerRegPair =
    (kNeedS128RegPair ? 2 : 1) + 2 * kBitsPerGpRegCode;

static_assert(2 * kBitsPerGpRegCode >= kBitsPerFpRegCode,
              "encoding for gp pair and fp pair collides");

class LiftoffRegister {
  static constexpr int needed_bits =
      std::max(kNeedI64RegPair || kNeedS128RegPair ? kBitsPerRegPair : 0,
               kBitsPerLiftoffRegCode);
  using storage_t = std::conditional<
      needed_bits <= 8, uint8_t,
      std::conditional<needed_bits <= 16, uint16_t, uint32_t>::type>::type;

  static_assert(8 * sizeof(storage_t) >= needed_bits,
                "chosen type is big enough");
  // Check for smallest required data type being chosen.
  // Special case for uint8_t as there are no smaller types.
  static_assert((8 * sizeof(storage_t) < 2 * needed_bits) ||
                    (sizeof(storage_t) == sizeof(uint8_t)),
                "chosen type is small enough");

 public:
  explicit LiftoffRegister(Register reg) : LiftoffRegister(reg.code()) {
    DCHECK_NE(0, kLiftoffAssemblerGpCacheRegs & reg.bit());
    DCHECK_EQ(reg, gp());
  }
  explicit LiftoffRegister(DoubleRegister reg)
      : LiftoffRegister(kAfterMaxLiftoffGpRegCode + reg.code()) {
    DCHECK_NE(0, kLiftoffAssemblerFpCacheRegs & reg.bit());
    DCHECK_EQ(reg, fp());
  }

  static LiftoffRegister from_liftoff_code(int code) {
    LiftoffRegister reg{static_cast<storage_t>(code)};
    // Check that the code is correct by round-tripping through the
    // reg-class-specific constructor.
    DCHECK(
        (reg.is_gp() && code == LiftoffRegister{reg.gp()}.liftoff_code()) ||
        (reg.is_fp() && code == LiftoffRegister{reg.fp()}.liftoff_code()) ||
        (reg.is_gp_pair() &&
         code == ForPair(reg.low_gp(), reg.high_gp()).liftoff_code()) ||
        (reg.is_fp_pair() && code == ForFpPair(reg.low_fp()).liftoff_code()));
    return reg;
  }

  static LiftoffRegister from_code(RegClass rc, int code) {
    switch (rc) {
      case kGpReg:
        return LiftoffRegister(Register::from_code(code));
      case kFpReg:
        return LiftoffRegister(DoubleRegister::from_code(code));
      default:
        UNREACHABLE();
    }
  }

  // Shifts the register code depending on the type before converting to a
  // LiftoffRegister.
  static LiftoffRegister from_external_code(RegClass rc, ValueType type,
                                            int code) {
    if (!kSimpleFPAliasing && type == kWasmF32) {
      // Liftoff assumes a one-to-one mapping between float registers and
      // double registers, and so does not distinguish between f32 and f64
      // registers. The f32 register code must therefore be halved in order
      // to pass the f64 code to Liftoff.
      DCHECK_EQ(0, code % 2);
      return LiftoffRegister::from_code(rc, code >> 1);
    }
    if (kNeedS128RegPair && type == kWasmS128) {
      // Similarly for double registers and SIMD registers, the SIMD code
      // needs to be doubled to pass the f64 code to Liftoff.
      return LiftoffRegister::ForFpPair(DoubleRegister::from_code(code << 1));
    }
    return LiftoffRegister::from_code(rc, code);
  }

  static LiftoffRegister ForPair(Register low, Register high) {
    DCHECK(kNeedI64RegPair);
    DCHECK_NE(low, high);
    storage_t combined_code = low.code() | high.code() << kBitsPerGpRegCode |
                              1 << (2 * kBitsPerGpRegCode);
    return LiftoffRegister(combined_code);
  }

  static LiftoffRegister ForFpPair(DoubleRegister low) {
    DCHECK(kNeedS128RegPair);
    DCHECK_EQ(0, low.code() % 2);
    storage_t combined_code = low.code() | 2 << (2 * kBitsPerGpRegCode);
    return LiftoffRegister(combined_code);
  }

  constexpr bool is_pair() const {
    return (kNeedI64RegPair || kNeedS128RegPair) &&
           (code_ & (3 << (2 * kBitsPerGpRegCode)));
  }

  constexpr bool is_gp_pair() const {
    return kNeedI64RegPair && (code_ & (1 << (2 * kBitsPerGpRegCode))) != 0;
  }
  constexpr bool is_fp_pair() const {
    return kNeedS128RegPair && (code_ & (2 << (2 * kBitsPerGpRegCode))) != 0;
  }
  constexpr bool is_gp() const { return code_ < kAfterMaxLiftoffGpRegCode; }
  constexpr bool is_fp() const {
    return code_ >= kAfterMaxLiftoffGpRegCode &&
           code_ < kAfterMaxLiftoffFpRegCode;
  }

  LiftoffRegister low() const {
    // Common case for most archs where only gp pair supported.
    if (!kNeedS128RegPair) return LiftoffRegister(low_gp());
    return is_gp_pair() ? LiftoffRegister(low_gp()) : LiftoffRegister(low_fp());
  }

  LiftoffRegister high() const {
    // Common case for most archs where only gp pair supported.
    if (!kNeedS128RegPair) return LiftoffRegister(high_gp());
    return is_gp_pair() ? LiftoffRegister(high_gp())
                        : LiftoffRegister(high_fp());
  }

  Register low_gp() const {
    DCHECK(is_gp_pair());
    static constexpr storage_t kCodeMask = (1 << kBitsPerGpRegCode) - 1;
    return Register::from_code(code_ & kCodeMask);
  }

  Register high_gp() const {
    DCHECK(is_gp_pair());
    static constexpr storage_t kCodeMask = (1 << kBitsPerGpRegCode) - 1;
    return Register::from_code((code_ >> kBitsPerGpRegCode) & kCodeMask);
  }

  DoubleRegister low_fp() const {
    DCHECK(is_fp_pair());
    static constexpr storage_t kCodeMask = (1 << kBitsPerFpRegCode) - 1;
    return DoubleRegister::from_code(code_ & kCodeMask);
  }

  DoubleRegister high_fp() const {
    DCHECK(is_fp_pair());
    static constexpr storage_t kCodeMask = (1 << kBitsPerFpRegCode) - 1;
    return DoubleRegister::from_code((code_ & kCodeMask) + 1);
  }

  Register gp() const {
    DCHECK(is_gp());
    return Register::from_code(code_);
  }

  DoubleRegister fp() const {
    DCHECK(is_fp());
    return DoubleRegister::from_code(code_ - kAfterMaxLiftoffGpRegCode);
  }

  int liftoff_code() const {
    STATIC_ASSERT(sizeof(int) >= sizeof(storage_t));
    return static_cast<int>(code_);
  }

  RegClass reg_class() const {
    return is_fp_pair() ? kFpRegPair
                        : is_gp_pair() ? kGpRegPair : is_gp() ? kGpReg : kFpReg;
  }

  bool operator==(const LiftoffRegister other) const {
    DCHECK_EQ(is_gp_pair(), other.is_gp_pair());
    DCHECK_EQ(is_fp_pair(), other.is_fp_pair());
    return code_ == other.code_;
  }
  bool operator!=(const LiftoffRegister other) const {
    DCHECK_EQ(is_gp_pair(), other.is_gp_pair());
    DCHECK_EQ(is_fp_pair(), other.is_fp_pair());
    return code_ != other.code_;
  }
  bool overlaps(const LiftoffRegister other) const {
    if (is_pair()) return low().overlaps(other) || high().overlaps(other);
    if (other.is_pair()) return *this == other.low() || *this == other.high();
    return *this == other;
  }

 private:
  storage_t code_;

  explicit constexpr LiftoffRegister(storage_t code) : code_(code) {}
};
ASSERT_TRIVIALLY_COPYABLE(LiftoffRegister);

inline std::ostream& operator<<(std::ostream& os, LiftoffRegister reg) {
  if (reg.is_gp_pair()) {
    return os << "<" << reg.low_gp() << "+" << reg.high_gp() << ">";
  } else if (reg.is_fp_pair()) {
    return os << "<" << reg.low_fp() << "+" << reg.high_fp() << ">";
  } else if (reg.is_gp()) {
    return os << reg.gp();
  } else {
    return os << reg.fp();
  }
}

class LiftoffRegList {
 public:
  class Iterator;

  static constexpr bool use_u16 = kAfterMaxLiftoffRegCode <= 16;
  static constexpr bool use_u32 = !use_u16 && kAfterMaxLiftoffRegCode <= 32;
  using storage_t = std::conditional<
      use_u16, uint16_t,
      std::conditional<use_u32, uint32_t, uint64_t>::type>::type;

  static constexpr storage_t kGpMask = storage_t{kLiftoffAssemblerGpCacheRegs};
  static constexpr storage_t kFpMask = storage_t{kLiftoffAssemblerFpCacheRegs}
                                       << kAfterMaxLiftoffGpRegCode;
  // Sets all even numbered fp registers.
  static constexpr uint64_t kEvenFpSetMask = uint64_t{0x5555555555555555}
                                             << kAfterMaxLiftoffGpRegCode;

  constexpr LiftoffRegList() = default;

  Register set(Register reg) { return set(LiftoffRegister(reg)).gp(); }
  DoubleRegister set(DoubleRegister reg) {
    return set(LiftoffRegister(reg)).fp();
  }

  LiftoffRegister set(LiftoffRegister reg) {
    if (reg.is_pair()) {
      regs_ |= storage_t{1} << reg.low().liftoff_code();
      regs_ |= storage_t{1} << reg.high().liftoff_code();
    } else {
      regs_ |= storage_t{1} << reg.liftoff_code();
    }
    return reg;
  }

  LiftoffRegister clear(LiftoffRegister reg) {
    if (reg.is_pair()) {
      regs_ &= ~(storage_t{1} << reg.low().liftoff_code());
      regs_ &= ~(storage_t{1} << reg.high().liftoff_code());
    } else {
      regs_ &= ~(storage_t{1} << reg.liftoff_code());
    }
    return reg;
  }

  bool has(LiftoffRegister reg) const {
    if (reg.is_pair()) {
      DCHECK_EQ(has(reg.low()), has(reg.high()));
      reg = reg.low();
    }
    return (regs_ & (storage_t{1} << reg.liftoff_code())) != 0;
  }
  bool has(Register reg) const { return has(LiftoffRegister(reg)); }
  bool has(DoubleRegister reg) const { return has(LiftoffRegister(reg)); }

  constexpr bool is_empty() const { return regs_ == 0; }

  constexpr unsigned GetNumRegsSet() const {
    return base::bits::CountPopulation(regs_);
  }

  constexpr LiftoffRegList operator&(const LiftoffRegList other) const {
    return LiftoffRegList(regs_ & other.regs_);
  }

  constexpr LiftoffRegList operator|(const LiftoffRegList other) const {
    return LiftoffRegList(regs_ | other.regs_);
  }

  constexpr LiftoffRegList GetAdjacentFpRegsSet() const {
    // And regs_ with a right shifted version of itself, so reg[i] is set only
    // if reg[i+1] is set. We only care about the even fp registers.
    storage_t available = (regs_ >> 1) & regs_ & kEvenFpSetMask;
    return LiftoffRegList(available);
  }

  constexpr bool HasAdjacentFpRegsSet() const {
    return !GetAdjacentFpRegsSet().is_empty();
  }

  constexpr bool operator==(const LiftoffRegList other) const {
    return regs_ == other.regs_;
  }
  constexpr bool operator!=(const LiftoffRegList other) const {
    return regs_ != other.regs_;
  }

  LiftoffRegister GetFirstRegSet() const {
    DCHECK(!is_empty());
    int first_code = base::bits::CountTrailingZeros(regs_);
    return LiftoffRegister::from_liftoff_code(first_code);
  }

  LiftoffRegister GetLastRegSet() const {
    DCHECK(!is_empty());
    int last_code =
        8 * sizeof(regs_) - 1 - base::bits::CountLeadingZeros(regs_);
    return LiftoffRegister::from_liftoff_code(last_code);
  }

  LiftoffRegList MaskOut(const LiftoffRegList mask) const {
    // Masking out is guaranteed to return a correct reg list, hence no checks
    // needed.
    return FromBits(regs_ & ~mask.regs_);
  }

  RegList GetGpList() { return regs_ & kGpMask; }
  RegList GetFpList() { return (regs_ & kFpMask) >> kAfterMaxLiftoffGpRegCode; }

  inline Iterator begin() const;
  inline Iterator end() const;

  static LiftoffRegList FromBits(storage_t bits) {
    DCHECK_EQ(bits, bits & (kGpMask | kFpMask));
    return LiftoffRegList(bits);
  }

  template <storage_t bits>
  static constexpr LiftoffRegList FromBits() {
    static_assert(bits == (bits & (kGpMask | kFpMask)), "illegal reg list");
    return LiftoffRegList(bits);
  }

  template <typename... Regs>
  static LiftoffRegList ForRegs(Regs... regs) {
    LiftoffRegList list;
    for (LiftoffRegister reg : {LiftoffRegister(regs)...}) list.set(reg);
    return list;
  }

 private:
  storage_t regs_ = 0;

  // Unchecked constructor. Only use for valid bits.
  explicit constexpr LiftoffRegList(storage_t bits) : regs_(bits) {}
};
ASSERT_TRIVIALLY_COPYABLE(LiftoffRegList);

static constexpr LiftoffRegList kGpCacheRegList =
    LiftoffRegList::FromBits<LiftoffRegList::kGpMask>();
static constexpr LiftoffRegList kFpCacheRegList =
    LiftoffRegList::FromBits<LiftoffRegList::kFpMask>();

class LiftoffRegList::Iterator {
 public:
  LiftoffRegister operator*() { return remaining_.GetFirstRegSet(); }
  Iterator& operator++() {
    remaining_.clear(remaining_.GetFirstRegSet());
    return *this;
  }
  bool operator==(Iterator other) { return remaining_ == other.remaining_; }
  bool operator!=(Iterator other) { return remaining_ != other.remaining_; }

 private:
  explicit Iterator(LiftoffRegList remaining) : remaining_(remaining) {}
  friend class LiftoffRegList;

  LiftoffRegList remaining_;
};

LiftoffRegList::Iterator LiftoffRegList::begin() const {
  return Iterator{*this};
}
LiftoffRegList::Iterator LiftoffRegList::end() const {
  return Iterator{LiftoffRegList{}};
}

static constexpr LiftoffRegList GetCacheRegList(RegClass rc) {
  return rc == kFpReg ? kFpCacheRegList : kGpCacheRegList;
}

inline std::ostream& operator<<(std::ostream& os, LiftoffRegList reglist) {
  os << "{";
  for (bool first = true; !reglist.is_empty(); first = false) {
    LiftoffRegister reg = reglist.GetFirstRegSet();
    reglist.clear(reg);
    os << (first ? "" : ", ") << reg;
  }
  return os << "}";
}

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif  // V8_WASM_BASELINE_LIFTOFF_REGISTER_H_
