// 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_
