// 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:
  // 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_;
  absl::btree_set<std::string> attribute_names_;
};

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

#endif  // MPACT_SIM_DECODER_SLOT_H_
