// 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_INSTRUCTION_H_
#define MPACT_SIM_GENERIC_INSTRUCTION_H_

#include <cstdint>
#include <functional>
#include <string>
#include <utility>
#include <vector>

#include "absl/numeric/int128.h"
#include "absl/types/span.h"
#include "mpact/sim/generic/arch_state.h"
#include "mpact/sim/generic/operand_interface.h"
#include "mpact/sim/generic/ref_count.h"

namespace mpact {
namespace sim {
namespace generic {

class ResourceOperandInterface;

// This is the class used to as the internal simulator representation of a
// target architecture instruction or a component operation of such an
// instruction. An example would be the individual operations of a VLIW
// instruction, or those instructions with semantics that may need to be modeled
// over multiple distinct architectural cycles (some memory loads for instance,
// where the returned data has to be transformed before being written back to
// the register). It is also used to represent the function responsible for
// issuing instructions, manages updates of simulated state due to instruction
// side-effects, and advances the program counter. Modeling the instruction
// issue as an instruction (with the instruction issue performed as its semantic
// function) makes it easier for the simulator core to remain
// architecture-agnostic. In this case, the semantic function responsible for
// instruction issue would call Execute on the child instruction, allocating and
// passing in any context structure as may be necessary for that architecture.
// Since the context may contain values that need to be accessed through a
// handle to the Instruction instance during the execution of the semantic
// function, it is copied to the instruction instance before the semantic
// function is called.
//
// The Instruction instance has pointers to Next, Child and Parent Instruction
// instances to manage the decomposition of complex instruction and instruction
// issue relationships. This is used to enable modeling of instruction
// hierarchies such as instructions in a VLIW ISA. In this case, a top level
// instruction (or instruction bundle) can use the Child pointer to point to the
// list of the individual instructions (or operations) that are to be issued as
// one "instruction bundle". The semantic function of the top level instruction
// is then responsible for "issuing" (call Execute()) for each of those
// instructions and handle any state updates/interactions required.
//
// The following diagram illustrates a possible VLIW instruction structure.
// Down arrows are the "next" pointers, whereas the right arrows are the Child
// pointers. The master_instruction implements instruction issue and
// architectural state maintenance. There is one master_instruction instance
// allocated for each PC that is decoded/executed.
//
// master_instruction --->  vliw_bundle 0 ---> inst 0
//                                               |
//                                               V
//                                             inst 1
//                                               |
//                                               V
//                                             inst 2
//
//
// master_instruction --->  vliw_bundle 1 ---> inst 0
//                                               |
//                                               V
//                                             inst 1
//                                              ...
//                                             inst N
class Instruction : public ReferenceCount {
 public:
  // Type Alias for the semantic function.
  using SemanticFunction = std::function<void(Instruction *)>;

  // Constructors and Destructors.
  explicit Instruction(ArchState *state);
  Instruction(uint64_t address, ArchState *state);
  ~Instruction() override;

  // Appends the instruction to the "next" list of instructions.
  void Append(Instruction *inst);
  // Appends the instruction the "child" list of instructions.
  void AppendChild(Instruction *inst);

  // Methods used for navigating instruction hierarchy.
  Instruction *child() const { return child_; }
  Instruction *parent() const { return parent_; }
  Instruction *next() const { return next_; }

  // Execute the instruction with the given context
  // Note: The context is stored into the instruction instance instead of
  // being passed as a parameter to the semantic function. This is intentional
  // to facilitate accessing the data in the context from the Instruction
  // instance itself. For instance, some values used as source operands for
  // an instruction may be stored in the context. The Operand instance has
  // only a handle to the Instruction instance as that is available during
  // instruction decode, and accessing the context otherwise would require
  // modifying the interface for all operands.
  void Execute(ReferenceCount *context) {
    context_ = context;
    semantic_fcn_(this);
    context_ = nullptr;
  }
  // Execute the instruction without context (context_ remains nullptr).
  void Execute() { semantic_fcn_(this); }

  // Accessors (getters/setters).
  ReferenceCount *context() const { return context_; }
  ArchState *state() const { return state_; }
  // Returns the pc value for the instruction.
  uint64_t address() const { return address_; }
  // The address should seldom be set outside the constructor.
  void set_address(uint64_t address) { address_ = address; }
  // The opcode as set by the decoder.
  int opcode() const { return opcode_; }
  void set_opcode(int opcode) { opcode_ = opcode; }
  // Returns the size in terms of pc increment value.
  int size() const { return size_; }
  // Sets the instruction size (pc increment).
  void set_size(int sz) { size_ = sz; }
  // Sets the semantic function callable - typically only used by the decoder.
  // The callable must be convertible to std::function<void(Instruction *)>.
  template <typename F>
  void set_semantic_function(F callable) {
    semantic_fcn_ = SemanticFunction(callable);
  }

  // PredicateOperand interface used for those ISAs that implement
  // instruction predicates.
  PredicateOperandInterface *Predicate() const { return predicate_; }
  void SetPredicate(PredicateOperandInterface *predicate);

  // SourceOperand interfaces for the instruction.
  SourceOperandInterface *Source(int i) const { return sources_[i]; }
  void AppendSource(SourceOperandInterface *op);
  int SourcesSize() const;

  // DestinationOperand interfaces for the instruction.
  DestinationOperandInterface *Destination(int i) const { return dests_[i]; }
  void AppendDestination(DestinationOperandInterface *op);
  int DestinationsSize() const;

  // Hold ResourceOperand interfaces for the instruction.
  inline std::vector<ResourceOperandInterface *> &ResourceHold() {
    return resource_hold_;
  }
  inline void AppendResourceHold(ResourceOperandInterface *op) {
    resource_hold_.push_back(op);
  }

  // Acquire ResourceOperand interfaces for the instruction.
  inline std::vector<ResourceOperandInterface *> &ResourceAcquire() {
    return resource_acquire_;
  }
  inline void AppendResourceAcquire(ResourceOperandInterface *op) {
    resource_acquire_.push_back(op);
  }

  void SetDisassemblyString(std::string disasm) {
    disasm_string_ = std::move(disasm);
  }

  virtual std::string AsString() const;

  // Setter and getter for the integer attributes.
  absl::Span<const int> Attributes() const { return attributes_; }

  void SetAttributes(absl::Span<const int> attributes);

 private:
  // Instruction operands.
  PredicateOperandInterface *predicate_ = nullptr;
  std::vector<SourceOperandInterface *> sources_;
  std::vector<DestinationOperandInterface *> dests_;

  // The resources that must be available in order to issue the instruction.
  // This includes any registers that are read.
  std::vector<ResourceOperandInterface *> resource_hold_;
  // The resources that must be reserved/acquired by the instruction. Each
  // vector element is a set of resources that are acquired when the instruction
  // issues. The method Acquire() should be called on each element of the
  // vector. The operands should contain all registers and other resources that
  // that need to be reserved for writing.
  std::vector<ResourceOperandInterface *> resource_acquire_;
  // Simulated instruction size.
  int size_;
  // Simulated instruction address.
  uint64_t address_;
  // Integer value of the opcode enum.
  int opcode_;
  // Text string of disassembly of the instruction.
  std::string disasm_string_;
  // Optional integer attribute array. This allows the decoder to create and
  // store a set of different attributes in the instruction. This is implemented
  // as absl::Span<int> so it can be used as an array of integer attributes
  // with length determined by the decoder. An example attribute is a
  // privilege level, or whether the instruction is a branch or not.
  // The attribute array is owned by the Instruction object. The attributes are
  // accessed as a const span, so the attributes are read only.
  int *attribute_array_ = nullptr;
  absl::Span<const int> attributes_ =
      absl::MakeConstSpan(static_cast<int *>(nullptr), 0);
  // Architecture state object.
  ArchState *state_;
  // Instruction execution context (this is usuall nullptr).
  ReferenceCount *context_;
  // Semantic function that implements the instruction semantics.
  SemanticFunction semantic_fcn_;
  // Pointer to the child (or sub) instruction. Used to break an instruction
  // up into multiple semantic actions, such as a VLIW instruction.
  Instruction *child_;
  // Parent instruction pointer from child instruction.
  Instruction *parent_;
  // Pointer to the "next" instruction (instructions can be linked into a list
  // of instructions), such as those instances that make up the instructions in
  // a VLIW instruction word.
  Instruction *next_;
};

// Templated inline helper functions for operand access. These are intended to
// provide access to instruction operands from instruction semantic functions
// that are themselves templated on the operand types.

// The base case shouldn't be matched. No return statement is provided.
template <typename T>
inline T GetInstructionSource(const Instruction *inst, int index) { /*empty */ }

// The following provide specializations for each of the integral types of
// operand values, both signed and unsigned.
template <>
inline bool GetInstructionSource<bool>(const Instruction *inst, int index) {
  return inst->Source(index)->AsBool(0);
}
template <>
inline uint8_t GetInstructionSource<uint8_t>(const Instruction *inst,
                                             int index) {
  return inst->Source(index)->AsUint8(0);
}
template <>
inline int8_t GetInstructionSource<int8_t>(const Instruction *inst, int index) {
  return inst->Source(index)->AsInt8(0);
}
template <>
inline uint16_t GetInstructionSource<uint16_t>(const Instruction *inst,
                                               int index) {
  return inst->Source(index)->AsUint16(0);
}
template <>
inline int16_t GetInstructionSource<int16_t>(const Instruction *inst,
                                             int index) {
  return inst->Source(index)->AsInt16(0);
}
template <>
inline uint32_t GetInstructionSource<uint32_t>(const Instruction *inst,
                                               int index) {
  return inst->Source(index)->AsUint32(0);
}
template <>
inline int32_t GetInstructionSource<int32_t>(const Instruction *inst,
                                             int index) {
  return inst->Source(index)->AsInt32(0);
}
template <>
inline float GetInstructionSource<float>(const Instruction *inst, int index) {
  auto value = inst->Source(index)->AsUint32(0);
  return *reinterpret_cast<float *>(&value);
}
template <>
inline uint64_t GetInstructionSource<uint64_t>(const Instruction *inst,
                                               int index) {
  return inst->Source(index)->AsUint64(0);
}
template <>
inline int64_t GetInstructionSource<int64_t>(const Instruction *inst,
                                             int index) {
  return inst->Source(index)->AsInt64(0);
}
template <>
inline double GetInstructionSource<double>(const Instruction *inst, int index) {
  auto value = inst->Source(index)->AsUint64(0);
  return *reinterpret_cast<double *>(&value);
}
template <>
inline absl::uint128 GetInstructionSource<absl::uint128>(
    const Instruction *inst, int index) {
  return static_cast<absl::uint128>(inst->Source(index)->AsUint64(0));
}
template <>
inline absl::int128 GetInstructionSource<absl::int128>(const Instruction *inst,
                                                       int index) {
  return static_cast<absl::int128>(inst->Source(index)->AsInt64(0));
}

// The base case shouldn't be matched. No return statement is provided, so it
// will generate a compile time error if no other case is matched.
template <typename T>
inline T GetInstructionSource(const Instruction *inst, int index,
                              int element) { /*empty */ }
// The following provide specializations for each of the integral types of
// operand values, both signed and unsigned.
template <>
inline bool GetInstructionSource<bool>(const Instruction *inst, int index,
                                       int element) {
  return inst->Source(index)->AsBool(element);
}
template <>
inline uint8_t GetInstructionSource<uint8_t>(const Instruction *inst, int index,
                                             int element) {
  return inst->Source(index)->AsUint8(element);
}
template <>
inline int8_t GetInstructionSource<int8_t>(const Instruction *inst, int index,
                                           int element) {
  return inst->Source(index)->AsInt8(element);
}
template <>
inline uint16_t GetInstructionSource<uint16_t>(const Instruction *inst,
                                               int index, int element) {
  return inst->Source(index)->AsUint16(element);
}
template <>
inline int16_t GetInstructionSource<int16_t>(const Instruction *inst, int index,
                                             int element) {
  return inst->Source(index)->AsInt16(element);
}
template <>
inline uint32_t GetInstructionSource<uint32_t>(const Instruction *inst,
                                               int index, int element) {
  return inst->Source(index)->AsUint32(element);
}
template <>
inline int32_t GetInstructionSource<int32_t>(const Instruction *inst, int index,
                                             int element) {
  return inst->Source(index)->AsInt32(element);
}
template <>
inline float GetInstructionSource<float>(const Instruction *inst, int index,
                                         int element) {
  auto value = inst->Source(index)->AsUint32(element);
  return *reinterpret_cast<float *>(&value);
}
template <>
inline uint64_t GetInstructionSource<uint64_t>(const Instruction *inst,
                                               int index, int element) {
  return inst->Source(index)->AsUint64(element);
}
template <>
inline int64_t GetInstructionSource<int64_t>(const Instruction *inst, int index,
                                             int element) {
  return inst->Source(index)->AsInt64(element);
}
template <>
inline double GetInstructionSource<double>(const Instruction *inst, int index,
                                           int element) {
  auto value = inst->Source(index)->AsUint64(element);
  return *reinterpret_cast<double *>(&value);
}

}  // namespace generic
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_GENERIC_INSTRUCTION_H_
