// Copyright 2023 Google LLC
//
// 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
//
//     https://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 MPACT_RISCV_RISCV_RISCV_REGISTER_H_
#define MPACT_RISCV_RISCV_RISCV_REGISTER_H_

#include <any>
#include <cstdint>
#include <string>
#include <vector>

#include "absl/types/span.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/register.h"
#include "mpact/sim/generic/state_item.h"

// File contains shorthand type definitions for RiscV32G registers.

namespace mpact {
namespace sim {
namespace riscv {

class RiscVState;

// The value type of the register must be an unsigned integer type.
using RV32Register = generic::Register<uint32_t>;
using RV64Register = generic::Register<uint64_t>;

using RVXRegister = RV32Register;
using RVFpRegister = RV64Register;

// The RiscV vector registers are treated like a long bit string that can
// be divided into byte, half word, word or double word quantities. RiscV
// allows for up to 8 registers to be combined by setting the LMUL
// appropriately. This operand therefore needs to be able to refer to up to
// 8 registers. Only vector register 0, 8, 16, and 24 can be treated as 8
// register groups. Vector registers 0, 4, 8, 12, 16, 20, 24, and 28, can
// be treated as 4 register groups. Even vector registers can be grouped into
// pairs, while vector registers with odd numbers can not be the start of a
// group. While this operand doesn't check for this, it has to be aware that
// some registers in the register array may be nullptr.

class RV32VectorSourceOperand : public generic::SourceOperandInterface {
 public:
  RV32VectorSourceOperand(absl::Span<generic::RegisterBase*> reg_span,
                          std::string op_name);
  explicit RV32VectorSourceOperand(absl::Span<generic::RegisterBase*> reg_span);
  explicit RV32VectorSourceOperand(generic::RegisterBase* reg);
  RV32VectorSourceOperand(generic::RegisterBase* reg, std::string op_name);

  RV32VectorSourceOperand() = delete;
  bool AsBool(int i) override;
  int8_t AsInt8(int i) override;
  uint8_t AsUint8(int i) override;
  int16_t AsInt16(int i) override;
  uint16_t AsUint16(int i) override;
  int32_t AsInt32(int i) override;
  uint32_t AsUint32(int i) override;
  int64_t AsInt64(int i) override;
  uint64_t AsUint64(int i) override;
  // Returns the RegisterBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(registers_[0]); }
  // Non-inherited method to get the register object.
  generic::RegisterBase* GetRegister(int i) const { return registers_[i]; }
  // Returns the shape of the register.
  std::vector<int> shape() const override { return registers_[0]->shape(); }
  std::string AsString() const override { return registers_[0]->name(); }
  // New methods.
  std::any GetObject(int i) const;
  int size() const { return registers_.size(); }

 private:
  int group_size_ = 0;
  int vector_size_ = 0;
  int vector_byte_size_ = 0;
  std::vector<generic::RegisterBase*> registers_;
  std::string op_name_;
};

class RV32VectorTrueOperand : public RV32VectorSourceOperand {
 public:
  explicit RV32VectorTrueOperand(RiscVState* state);

  RV32VectorTrueOperand() = delete;
  bool AsBool(int) final { return true; }
  int8_t AsInt8(int) final { return 0xff; }
  uint8_t AsUint8(int) final { return 0xff; }
  int16_t AsInt16(int) final { return 0xffff; }
  uint16_t AsUint16(int) final { return 0xffff; }
  int32_t AsInt32(int) final { return 0xffff'ffff; }
  uint32_t AsUint32(int) final { return 0xffff'ffff; }
  int64_t AsInt64(int) final { return 0xffff'ffff'ffff'ffffULL; }
  uint64_t AsUint64(int) final { return 0xffff'ffff'ffff'ffffLL; }
  std::string AsString() const override { return ""; }

 private:
  static constexpr char kName[] = "__VectorTrue__";
};

class RV32VectorDestinationOperand
    : public generic::DestinationOperandInterface {
 public:
  RV32VectorDestinationOperand(absl::Span<generic::RegisterBase*> reg_span,
                               int latency, std::string op_name);
  RV32VectorDestinationOperand(absl::Span<generic::RegisterBase*> reg_span,
                               int latency);
  RV32VectorDestinationOperand(generic::RegisterBase* reg, int latency,
                               std::string op_name);
  RV32VectorDestinationOperand(generic::RegisterBase* reg, int latency);
  generic::DataBuffer* AllocateDataBuffer() override;
  void InitializeDataBuffer(generic::DataBuffer* db) override;
  generic::DataBuffer* CopyDataBuffer() override;
  int latency() const override;
  std::any GetObject() const override;
  std::vector<int> shape() const override;
  std::string AsString() const override;
  // New method.
  generic::DataBuffer* AllocateDataBuffer(int i);
  void InitializeDataBuffer(int i, generic::DataBuffer* db);
  generic::DataBuffer* CopyDataBuffer(int i);
  std::any GetObject(int i) const;
  int size() const { return registers_.size(); }

 private:
  generic::DataBufferFactory* db_factory_;
  generic::DataBufferDelayLine* delay_line_;
  int latency_ = 0;
  int group_size_ = 0;
  int vector_size_ = 0;
  int vector_byte_size_ = 0;
  std::vector<generic::RegisterBase*> registers_;
  std::string op_name_;
};

using RVVectorRegister =
    generic::StateItem<generic::RegisterBase, uint8_t*, RV32VectorSourceOperand,
                       RV32VectorDestinationOperand>;

}  // namespace riscv
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_RISCV_RISCV_RISCV_REGISTER_H_
