// 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_DECODER_SLOT_H_
#define MPACT_SIM_DECODER_SLOT_H_

#include <limits>
#include <string>
#include <tuple>
#include <vector>

#include "absl/base/no_destructor.h"
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/InstructionSetParser.h"
#include "mpact/sim/decoder/base_class.h"
#include "mpact/sim/decoder/instruction_set_contexts.h"
#include "mpact/sim/decoder/opcode.h"
#include "mpact/sim/decoder/template_expression.h"

namespace mpact {
namespace sim {
namespace machine_description {
namespace instruction_set {

class Instruction;
class InstructionSet;
class Resource;

// A structure that holds the resources specified by a named resource specifier.
struct ResourceSpec {
  std::string name;
  std::vector<ResourceReference *> use_vec;
  std::vector<ResourceReference *> acquire_vec;
};

// A slot class instance represents one or more identical instruction slots
// in an instruction word where a defined set of opcodes may be executed. A
// slot may inherit from a base slot to facilitate the factoring of common
// subsets of instruction opcodes into "base slots". These "base slots" need
// not be directly used in a bundle, in which case, they are not part of the
// instruction word encoding per se.
class Slot {
 public:
  using BaseSlot = BaseClass<Slot>;
  using ResourceDetailsCtx = ::sim::machine_description::instruction_set::
      generated::InstructionSetParser::Resource_detailsContext;

  // Constructor and destructor.
  Slot(absl::string_view name, InstructionSet *instruction_set,
       bool is_templated, SlotDeclCtx *ctx, unsigned generator_version);
  Slot(absl::string_view name, InstructionSet *instruction_set,
       bool is_templated, SlotDeclCtx *ctx)
      : Slot(name, instruction_set, is_templated, ctx, 1) {}
  ~Slot();

  // Add declared opcode to the current slot.
  absl::Status AppendInstruction(Instruction *inst);
  // Add an opcode inherited from a base slot to the current slot.
  absl::Status AppendInheritedInstruction(Instruction *inst,
                                          TemplateInstantiationArgs *args);
  // Add default instruction attribute.
  void AddInstructionAttribute(const std::string &name,
                               TemplateExpression *expr);
  bool HasInstruction(const std::string &opcode_name) const;
  // Return string for the header file declarations for this class.
  std::string GenerateClassDeclaration(absl::string_view encoding_type) const;
  // Return string for the .cc file definitions for this class.
  std::string GenerateClassDefinition(absl::string_view encoding_type);

  // Add a non-templated slot as a base.
  absl::Status AddBase(const Slot *base);
  // Add a templated slot as a base with the vector of expressions as the
  // template parameter values.
  absl::Status AddBase(const Slot *base, TemplateInstantiationArgs *arguments);
  // Add a declared constant (scoped to the slot).
  absl::Status AddConstant(const std::string &ident, const std::string &type,
                           TemplateExpression *expression);
  TemplateExpression *GetConstExpression(const std::string &ident) const;
  // When the current slot is templated, adds an identifier as a template
  // formal parameter.
  absl::Status AddTemplateFormal(const std::string &name);
  TemplateFormal *GetTemplateFormal(const std::string &name) const;

  // Generate the calls to encode the given operand.
  std::string GenerateOperandEncoder(int position, absl::string_view op_name,
                                     const OperandLocator &locator,
                                     const Opcode *opcode) const;
  // Generate regex for a given instruction.
  std::tuple<std::string, std::vector<OperandLocator>> GenerateRegEx(
      const Instruction *inst, std::vector<std::string> &formats) const;
  // Generate regexes to match the assembly string for the instructions.
  std::tuple<std::string, std::string> GenerateAsmRegexMatcher() const;
  // Generate assembler function for the given instruction.
  std::string GenerateAssemblerFcn(const Instruction *inst,
                                   absl::string_view encoder_type) const;

  // Resources
  Resource *GetOrInsertResource(const std::string &name);

  // Getters and setters.
  InstructionSet *instruction_set() const { return instruction_set_; }
  const SlotDeclCtx *ctx() const { return ctx_; }
  int default_instruction_size() const { return default_instruction_size_; }
  void set_default_instruction_size(int val) {
    default_instruction_size_ = val;
  }
  TemplateExpression *default_latency() const { return default_latency_; }
  void set_default_latency(TemplateExpression *latency_expr) {
    if (default_latency_ != nullptr) delete default_latency_;
    default_latency_ = latency_expr;
  }
  Instruction *default_instruction() const { return default_instruction_; }
  void set_default_instruction(Instruction *inst) {
    default_instruction_ = inst;
  }
  int size() const { return size_; }
  void set_size(int size) { size_ = size; }
  int min_instruction_size() const { return min_instruction_size_; }
  void set_min_instruction_size(int size) { min_instruction_size_ = size; }
  bool is_templated() const { return is_templated_; }
  bool is_marked() const { return is_marked_; }
  void set_is_marked(bool value) { is_marked_ = value; }
  void set_is_referenced(bool value) { is_referenced_ = value; }
  bool is_referenced() const { return is_referenced_; }
  const std::string &name() const { return name_; }
  const std::string &pascal_name() const { return pascal_name_; }
  const std::vector<BaseSlot> &base_slots() const { return base_slots_; }
  const absl::btree_map<std::string, Instruction *> &instruction_map() const {
    return instruction_map_;
  }
  const std::vector<TemplateFormal *> &template_parameters() const {
    return template_parameters_;
  }
  const absl::flat_hash_map<std::string, int> &template_parameter_map() const {
    return template_parameter_map_;
  }
  absl::btree_map<std::string, ResourceDetailsCtx *> &resource_spec_map() {
    return resource_spec_map_;
  }
  absl::btree_map<std::string, IdentListCtx *> &resource_array_ref_map() {
    return resource_array_ref_map_;
  }
  const absl::btree_map<std::string, TemplateExpression *> &attribute_map() {
    return attribute_map_;
  }

 private:
  // These functions generate the functions that are called by the decoder to
  // set the instruction operands.
  std::string CreateOperandLookupKey(const Opcode *opcode) const;
  std::string GenerateOperandSetterFcn(absl::string_view getter_name,
                                       absl::string_view encoding_type,
                                       const Opcode *opcode) const;
  // These functions generate the functions that are called by the decoder to
  // set the instruction resources.
  std::string CreateResourceKey(
      const std::vector<const ResourceReference *> &refs) const;
  std::string GenerateResourceSetter(const Instruction *inst,
                                     absl::string_view encoding_type);
  std::string GenerateResourceSetterFcn(absl::string_view name,
                                        const Instruction *inst,
                                        absl::string_view encoding_type) const;
  // These functions generate the functions that are called by the decoder to
  // set the instruction disassembly string.
  std::string GenerateDisassemblySetter(const Instruction *inst);
  std::string GenerateDisasmSetterFcn(absl::string_view name,
                                      const Instruction *inst) const;
  // These functions generate the functions that are called by the decoder to
  // set the instruction attributes.
  std::string GenerateAttributeSetter(const Instruction *inst);
  std::string GenerateAttributeSetterFcn(absl::string_view name,
                                         const Instruction *inst) const;
  std::string CreateAttributeLookupKey(const Instruction *inst) const;
  // Generates a string that is a unique key for the operands to determine which
  // instructions can share operand getter functions.
  // Build up a string containing the function getter initializers that are
  // stored in two flat hash maps with the opcode as the key. These functions
  // are lambda's that call the getters for the semantic functions as well as
  // operand getters for each instruction opcode.
  std::string ListFuncGetterInitializations(absl::string_view encoding_type);
  // Transitively check if base slot is in the predecessor set of the current
  // slot or any of its inheritance predecessors. Returns AlreadyExistsError
  // if the current slot or its predecessors already inherit from base or its
  // predecessors.
  absl::Status CheckPredecessors(const Slot *base) const;
  // Parent instruction_set class.
  InstructionSet *instruction_set_;
  // Parser context.
  SlotDeclCtx *ctx_ = nullptr;
  // The default and minimum opcode size specified for the slot.
  int default_instruction_size_ = 1;
  int min_instruction_size_ = std::numeric_limits<int>::max();
  // Default latency for destination operands.
  TemplateExpression *default_latency_ = nullptr;
  // Fallback opcode for failed decodes.
  Instruction *default_instruction_ = nullptr;
  // Number of instances of this slot in the instruction_set instruction word.
  int size_ = 1;
  unsigned generator_version_;
  // True if the slot is a templated slot.
  bool is_templated_;
  bool is_marked_ = false;
  // True if this slot is referenced in a bundle.
  bool is_referenced_ = false;
  // Name of slot.
  std::string name_;
  // Name of slot in PascalCase.
  std::string pascal_name_;
  // Pointer to slot it inherits from.
  std::vector<BaseSlot> base_slots_;
  absl::flat_hash_set<const Slot *> predecessor_set_;
  // Map from operand getter key to operand getter function name. These are
  // static so that they can be shared across different slots.
  static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>>
      operand_setter_name_map_;
  static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>>
      disasm_setter_name_map_;
  static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>>
      resource_setter_name_map_;
  static absl::NoDestructor<absl::flat_hash_map<std::string, std::string>>
      attribute_setter_name_map_;
  std::string setter_functions_;
  // Used to list the unique getters for the operands.
  absl::flat_hash_set<std::string> pred_operand_getters_;
  absl::flat_hash_set<std::string> src_operand_getters_;
  absl::flat_hash_set<std::string> dst_operand_getters_;
  // Map of instructions defined in this slot or inherited.
  absl::btree_map<std::string, Instruction *> instruction_map_;
  absl::flat_hash_set<std::string> operand_setters_;
  // Template parameter names.
  std::vector<TemplateFormal *> template_parameters_;
  absl::flat_hash_map<std::string, int> template_parameter_map_;
  absl::flat_hash_map<std::string, TemplateExpression *> constant_map_;
  // Named resource specifiers.
  absl::btree_map<std::string, ResourceDetailsCtx *> resource_spec_map_;
  absl::btree_map<std::string, IdentListCtx *> resource_array_ref_map_;
  // Default instruction attributes.
  absl::btree_map<std::string, TemplateExpression *> attribute_map_;
};

}  // namespace instruction_set
}  // namespace machine_description
}  // namespace sim
}  // namespace mpact

#endif  // MPACT_SIM_DECODER_SLOT_H_
