// 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_SIM_GENERIC_REGISTER_H_
#define MPACT_SIM_GENERIC_REGISTER_H_

// Contains the basic generic definitions for classes used to model
// register state in simulated architectures, as in the kind of registers
// used in instruction visible register files. Registers can be scalar,
// one dimensional vector, or two dimensional array with a base value type.

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

#include "absl/strings/string_view.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/data_buffer.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/signed_type.h"
#include "mpact/sim/generic/state_item.h"
#include "mpact/sim/generic/state_item_base.h"

namespace mpact {
namespace sim {
namespace generic {

class ArchState;
class RegisterBase;
class SimpleResource;

// A register source operand with value type T used to access (read/write)
// register values from instruction semantic functions.
template <typename T>
class RegisterSourceOperand : public SourceOperandInterface {
 public:
  // Constructor. Note, default constructor deleted.
  RegisterSourceOperand(RegisterBase *reg, const std::string op_name);
  explicit RegisterSourceOperand(RegisterBase *reg);

  RegisterSourceOperand() = delete;

  // Accessor methods call into the register_ data_buffer to obtain the values.
  // The index is in one dimension. For scalar registers it should always be
  // zero, for vector registers it is the element index. For higher order
  // register shapes it should be the linearized row-major order index.
  // In order to properly cast signed values, an internal helper template
  // is used to get the signed type equivalent of any unsigned register unit
  // value type.
  bool AsBool(int i) final;
  int8_t AsInt8(int i) final;
  uint8_t AsUint8(int i) final;
  int16_t AsInt16(int i) final;
  uint16_t AsUint16(int i) final;
  int32_t AsInt32(int i) final;
  uint32_t AsUint32(int i) final;
  int64_t AsInt64(int i) final;
  uint64_t AsUint64(int i) final;
  // Returns the RegisterBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(register_); }
  // Non-inherited method to get the register object.
  RegisterBase *GetRegister() const { return register_; }
  // Returns the shape of the register.
  std::vector<int> shape() const override;

  std::string AsString() const override { return op_name_; }

 private:
  RegisterBase *register_;
  std::string op_name_;
};

// Register destination operand type with element value type T. It is agnostic
// of the actual structure of the underlying register (scalar, vector, matrix).
template <typename T>
class RegisterDestinationOperand : public DestinationOperandInterface {
 public:
  // Constructor and Destructor
  RegisterDestinationOperand(RegisterBase *reg, int latency);
  RegisterDestinationOperand(RegisterBase *reg, int latency,
                             std::string op_name);
  RegisterDestinationOperand() = delete;

  // Initializes the DataBuffer instance so that when Submit is called, it can
  // be entered into the correct delay line, with the correct latency, targeting
  // the correct register.
  void InitializeDataBuffer(DataBuffer *db) override;

  // Allocates and returns an initialized DataBuffer instance that contains a
  // copy of the current value of the register. This is useful when only part
  // of the destination register will be modified.
  DataBuffer *CopyDataBuffer() override;

  // Allocates and returns an initialized DataBuffer instance.
  DataBuffer *AllocateDataBuffer() final;

  // Returns the latency associated with writes to this register operand.
  int latency() const override { return latency_; }

  // Returns the RegisterBase object wrapped in absl::any.
  std::any GetObject() const override { return std::any(register_); }
  // Non-inherited method to get the register object.
  RegisterBase *GetRegister() const { return register_; }

  // Returns the shape of the underlying register (the number of elements in
  // each dimension). For instance {0} indicates a scalar quantity, whereas
  // {128} indicates an 128 element vector quantity.
  std::vector<int> shape() const override;

  std::string AsString() const override { return op_name_; }

 private:
  RegisterBase *register_;
  DataBufferFactory *db_factory_;
  int latency_;
  DataBufferDelayLine *delay_line_;
  std::string op_name_;
};

// Base class for register types with the DataBufferDestination interface.
// No default constructor - should only be constructed/destructed from the
// derived classes.
class RegisterBase : public StateItemBase {
 public:
  // Type alias for the notification callback function type.
  using UpdateCallbackFunction = std::function<void()>;
  // Constructors are only called from derived classes and are in the
  // protected section below.
  ~RegisterBase() override;
  RegisterBase() = delete;
  RegisterBase(const RegisterBase &) = delete;
  RegisterBase &operator=(const RegisterBase &) = delete;

  // DecRef's the current data buffer and replaces it with a new one.
  void SetDataBuffer(DataBuffer *db) override;
  // Returns a pointer to the DataBuffer that contains the current value of
  // the register.
  DataBuffer *data_buffer() const { return data_buffer_; }

 protected:
  RegisterBase(ArchState *state, absl::string_view name,
               const std::vector<int> &shape, int unit_size);

 private:
  DataBuffer *data_buffer_;
  std::vector<UpdateCallbackFunction> next_update_callbacks_;
};

// A register class that frees a SimpleResource instance when written to. This
// is intended to be used in modeling dynamic stalls/hold issue due to data
// dependencies on long latency operations with a protected pipeline.
class ReservedRegisterBase : public RegisterBase {
 public:
  ReservedRegisterBase() = delete;
  ReservedRegisterBase(const ReservedRegisterBase &) = delete;
  ReservedRegisterBase &operator=(const ReservedRegisterBase &) = delete;

  // Override the SetDataBuffer to release the SimpleResource instance when
  // called.
  void SetDataBuffer(DataBuffer *db) override;

  // Accessor.
  SimpleResource *resource() const { return resource_; }

 protected:
  ReservedRegisterBase(ArchState *state, absl::string_view name,
                       const std::vector<int> &shape, int unit_size,
                       SimpleResource *resource);

 private:
  // SimpleResource instance associated with the register.
  SimpleResource *resource_;
};

// Scalar register type with value type ElementType.
template <typename ElementType>
using Register =
    StateItem<RegisterBase, ElementType, RegisterSourceOperand<ElementType>,
              RegisterDestinationOperand<ElementType>>;

// N long vector register type with element value type ElementType.
template <typename ElementType, int N>
using VectorRegister =
    StateItem<RegisterBase, ElementType, RegisterSourceOperand<ElementType>,
              RegisterDestinationOperand<ElementType>, N>;

// MxN matrix register type with element value type ElementType.
template <typename ElementType, int M, int N>
using MatrixRegister =
    StateItem<RegisterBase, ElementType, RegisterSourceOperand<ElementType>,
              RegisterDestinationOperand<ElementType>, M, N>;

// Scalar register type with value type ElementType.
template <typename ElementType>
using ReservedRegister = StateItem<ReservedRegisterBase, ElementType,
                                   RegisterSourceOperand<ElementType>,
                                   RegisterDestinationOperand<ElementType>>;

// N long vector register type with element value type ElementType.
template <typename ElementType, int N>
using ReservedVectorRegister =
    StateItem<ReservedRegisterBase, ElementType,
              RegisterSourceOperand<ElementType>,
              RegisterDestinationOperand<ElementType>, N>;

// MxN matrix register type with element value type ElementType.
template <typename ElementType, int M, int N>
using ReservedMatrixRegister =
    StateItem<ReservedRegisterBase, ElementType,
              RegisterSourceOperand<ElementType>,
              RegisterDestinationOperand<ElementType>, M, N>;

template <typename T>
RegisterSourceOperand<T>::RegisterSourceOperand(RegisterBase *reg,
                                                const std::string op_name)
    : register_(reg), op_name_(op_name) {}

template <typename T>
RegisterSourceOperand<T>::RegisterSourceOperand(RegisterBase *reg)
    : RegisterSourceOperand(reg, reg->name()) {}

template <typename T>
bool RegisterSourceOperand<T>::AsBool(int i) {
  return static_cast<bool>(register_->data_buffer()->Get<T>(i));
}
template <typename T>
int8_t RegisterSourceOperand<T>::AsInt8(int i) {
  return static_cast<int8_t>(
      register_->data_buffer()->Get<typename internal::SignedType<T>::type>(i));
}
template <typename T>
uint8_t RegisterSourceOperand<T>::AsUint8(int i) {
  return static_cast<uint8_t>(register_->data_buffer()->Get<T>(i));
}
template <typename T>
int16_t RegisterSourceOperand<T>::AsInt16(int i) {
  return static_cast<int16_t>(
      register_->data_buffer()->Get<typename internal::SignedType<T>::type>(i));
}
template <typename T>
uint16_t RegisterSourceOperand<T>::AsUint16(int i) {
  return static_cast<uint16_t>(register_->data_buffer()->Get<T>(i));
}
template <typename T>
int32_t RegisterSourceOperand<T>::AsInt32(int i) {
  return static_cast<int32_t>(
      register_->data_buffer()->Get<typename internal::SignedType<T>::type>(i));
}
template <typename T>
uint32_t RegisterSourceOperand<T>::AsUint32(int i) {
  return static_cast<uint32_t>(register_->data_buffer()->Get<T>(i));
}
template <typename T>
int64_t RegisterSourceOperand<T>::AsInt64(int i) {
  return static_cast<int64_t>(
      register_->data_buffer()->Get<typename internal::SignedType<T>::type>(i));
}
template <typename T>
uint64_t RegisterSourceOperand<T>::AsUint64(int i) {
  return static_cast<uint64_t>(register_->data_buffer()->Get<T>(i));
}

template <typename T>
std::vector<int> RegisterSourceOperand<T>::shape() const {
  return register_->shape();
}

template <typename T>
RegisterDestinationOperand<T>::RegisterDestinationOperand(RegisterBase *reg,
                                                          int latency,
                                                          std::string op_name)
    : register_(reg),
      db_factory_(reg->arch_state()->db_factory()),
      latency_(latency),
      delay_line_(reg->arch_state()->data_buffer_delay_line()),
      op_name_(op_name) {}

template <typename T>
RegisterDestinationOperand<T>::RegisterDestinationOperand(RegisterBase *reg,
                                                          int latency)
    : RegisterDestinationOperand(reg, latency, reg->name()) {}

template <typename T>
void RegisterDestinationOperand<T>::InitializeDataBuffer(DataBuffer *db) {
  db->set_destination(register_);
  db->set_latency(latency_);
  db->set_delay_line(delay_line_);
}

template <typename T>
DataBuffer *RegisterDestinationOperand<T>::CopyDataBuffer() {
  DataBuffer *db = db_factory_->MakeCopyOf(register_->data_buffer());
  InitializeDataBuffer(db);
  return db;
}

template <typename T>
DataBuffer *RegisterDestinationOperand<T>::AllocateDataBuffer() {
  DataBuffer *db = db_factory_->Allocate(register_->size());
  InitializeDataBuffer(db);
  return db;
}

template <typename T>
std::vector<int> RegisterDestinationOperand<T>::shape() const {
  return register_->shape();
}
}  // namespace generic
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_GENERIC_REGISTER_H_
