// 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/btree_set.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);

  // Attributes
  void AddAttributeName(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_;
  }

  const absl::btree_set<std::string>& attribute_names() const {
    return attribute_names_;
  }

 private:
  // Returns the name of the instruction array used for this slot. The
  // instruction array is a constexpr global array of instruction information,
  // keyed by the opcode.
  std::string GetInstructionArrayName() const;

  // 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 defines a global constexpr array of instruction
  // opcodes and instruction info structs. Also populates the setter function
  // string 'setter_functions_' with the setters.
  std::string CreateFuncGetterGlobalArray(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_;

  // Stores a string representation of the instruction array for this slot. This
  // is an array that is used to initialize the map within the decoder.
  std::string instruction_array_str_;
  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_;
  absl::btree_set<std::string> attribute_names_;
};

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

#endif  // MPACT_SIM_DECODER_SLOT_H_
