// 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/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);
  ~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;
  // 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.
  absl::flat_hash_map<std::string, std::string> operand_setter_name_map_;
  absl::flat_hash_map<std::string, std::string> disasm_setter_name_map_;
  absl::flat_hash_map<std::string, std::string> resource_setter_name_map_;
  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_
