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

#include "mpact/sim/decoder/slot.h"

#include <cctype>
#include <cstddef>
#include <cstdlib>
#include <map>
#include <stack>
#include <string>
#include <utility>
#include <variant>
#include <vector>

#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/format_name.h"
#include "mpact/sim/decoder/instruction.h"
#include "mpact/sim/decoder/instruction_set.h"
#include "mpact/sim/decoder/instruction_set_contexts.h"
#include "mpact/sim/decoder/opcode.h"
#include "mpact/sim/decoder/resource.h"
#include "mpact/sim/decoder/template_expression.h"

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

// This function translates the location specification into a set of '->'
// references starting with 'inst->' to get to the operand that is implied.
static absl::StatusOr<std::string> TranslateLocator(
    const OperandLocator &locator) {
  std::string code;
  absl::StrAppend(&code, "inst->");
  if (locator.op_spec_number > 0) {
    absl::StrAppend(&code, "child()->");
  }
  for (int i = 1; i < locator.op_spec_number; i++) {
    absl::StrAppend(&code, "next()->");
  }
  if (locator.type == 'p') {
    absl::StrAppend(&code, "Predicate()");
  } else if (locator.type == 's') {
    absl::StrAppend(&code, "Source(", locator.instance, ")");
  } else if (locator.type == 'd') {
    absl::StrAppend(&code, "Destination(", locator.instance, ")");
  } else {
    return absl::InternalError(absl::StrCat("Unknown locator type '",
                                            std::string(locator.type, 1), "'"));
  }
  return code;
}

// This is a helper function that generates the code snippet to extract the
// right sized value based on the length specifier in the print format
// specification. E.g., %08x, %04d, etc.
static std::string GetExtractor(const std::string &format) {
  int size = 0;
  int pos = 0;
  int len = 1;
  for (int i = 0; i < format.size(); i++) {
    if (!isdigit(format[i])) continue;
    pos = i;
    break;
  }
  while (isdigit(format[pos + len])) len++;
  if (!absl::SimpleAtoi(format.substr(pos, len), &size)) size = 0;
  if (size == 0) return "->AsInt64(0)";
  if (size <= 2) return "->AsInt8(0)";
  if (size <= 4) return "->AsInt16(0)";
  if (size <= 8) return "->AsInt32(0)";
  return "->AsInt64(0)";
}

// Small helper function to just expand the expression specified by the
// FormatInfo from parsing the disassembly specifier.
static std::string ExpandExpression(const FormatInfo &format,
                                    const std::string &locator) {
  // Handle the case when it's just an '@' - i.e., just the address.
  if (format.use_address && format.operation.empty()) {
    return absl::StrCat("(inst->address())");
  }
  if (format.operation.empty()) {
    // No +/- for the @ sign, i.e., @ <</>> amount.
    if (locator.empty()) return absl::StrCat("#error missing field locator");
    if (format.shift_amount == 0) {
      return absl::StrCat(locator, GetExtractor(format.number_format));
    }
    return absl::StrCat("(", locator, GetExtractor(format.number_format),
                        format.do_left_shift ? " << " : " >> ",
                        format.shift_amount, ")");
  }
  // (@ +/- operand) <</>> shift amount
  if (locator.empty()) return absl::StrCat("#error missing field locator");

  return absl::StrCat("(", format.use_address ? "inst->address() " : "0 ",
                      format.operation, "(", locator,
                      GetExtractor(format.number_format),
                      format.shift_amount != 0
                          ? absl::StrCat(format.do_left_shift ? " << " : " >> ",
                                         format.shift_amount, "))")
                          : "))");
}

Slot::Slot(absl::string_view name, InstructionSet *instruction_set,
           bool is_templated, SlotDeclCtx *ctx)
    : instruction_set_(instruction_set),
      ctx_(ctx),
      is_templated_(is_templated),
      name_(name),
      pascal_name_(ToPascalCase(name)) {}

Slot::~Slot() {
  delete default_latency_;
  default_latency_ = nullptr;
  delete default_instruction_;
  default_instruction_ = nullptr;
  for (auto *param : template_parameters_) {
    delete param;
  }
  template_parameters_.clear();
  for (auto &base : base_slots_) {
    if (base.arguments != nullptr) {
      for (auto *expr : *(base.arguments)) {
        delete expr;
      }
      delete base.arguments;
    }
  }
  base_slots_.clear();
  for (auto &[unused, inst_ptr] : instruction_map_) {
    delete inst_ptr;
  }
  instruction_map_.clear();
  for (auto &[unused, element_ptr] : constant_map_) {
    delete element_ptr;
  }
  constant_map_.clear();
  // The ctx objects stored in resource_spec_map_ are owned by the Antlr4
  // parser, so just clear the map (don't delete those objects).
  resource_spec_map_.clear();
  for (auto &[ignored, expr] : attribute_map_) {
    delete expr;
  }
  attribute_map_.clear();
}

absl::Status Slot::AppendInstruction(Instruction *inst) {
  if (!is_templated()) {
    bool valid = inst->opcode()->ValidateDestLatencies(
        [](int l) -> bool { return l >= 0; });
    if (!valid) {
      return absl::InternalError(absl::StrCat("Invalid latency for opcode '",
                                              inst->opcode()->name(), "'"));
    }
  }
  std::string name = inst->opcode()->name();
  if (!instruction_map_.contains(name)) {
    instruction_map_.emplace(name, inst);
    return absl::OkStatus();
  }
  return absl::InternalError(absl::StrCat(
      "Opcode '", name, "' already added to slot '", this->name(), "'"));
}

absl::Status Slot::AppendInheritedInstruction(Instruction *inst,
                                              TemplateInstantiationArgs *args) {
  std::string name = inst->opcode()->name();
  if (!instruction_map_.contains(name)) {
    auto derived = inst->CreateDerivedInstruction(args);

    if (derived.ok()) {
      if (!is_templated()) {
        bool valid = derived.value()->opcode()->ValidateDestLatencies(
            [](int l) -> bool { return l >= 0; });
        if (!valid) {
          return absl::InternalError(absl::StrCat(
              "Invalid latency for opcode '", inst->opcode()->name(), "'"));
        }
      }
      instruction_map_.emplace(name, derived.value());
      return absl::OkStatus();
    }
    return derived.status();
  }
  return absl::InternalError(
      absl::StrCat("instruction already added: ", inst->opcode()->name()));
}

bool Slot::HasInstruction(const std::string &opcode_name) const {
  return instruction_map_.contains(opcode_name);
}

static std::string indent_string(int n) { return std::string(n, ' '); }

std::string Slot::GenerateAttributeSetter(const Instruction *inst) const {
  if (InstructionSet::attribute_names() == nullptr) {
    return "  info->attribute_setter = [](Instruction *inst) {};\n";
  }
  std::string output;
  absl::StrAppend(&output,
                  "  info->attribute_setter = [](Instruction *inst) {\n");

  // Allocate the array and initialize to zero.
  absl::StrAppend(
      &output,
      "    int size = static_cast<int>(AttributeEnum::kPastMaxValue);\n"
      "    int *attrs = new int[size];\n");
  for (auto const &[name, expr] : inst->attribute_map()) {
    auto result = expr->GetValue();
    if (!result.ok()) {
      absl::StrAppend(&output, "    #error Expression for '", name,
                      "' has no constant value\n");
      continue;
    }
    int *value = std::get_if<int>(&result.value());
    if (value == nullptr) {
      absl::StrAppend(&output, "    #error Expression for '", name,
                      "' does not have type int\n");
      continue;
    }
    absl::StrAppend(&output, "    attrs[static_cast<int>(AttributeEnum::k",
                    ToPascalCase(name), ")] = ", *value, ";\n");
  }
  absl::StrAppend(&output,
                  "    inst->SetAttributes(absl::Span<int>(attrs, size));\n"
                  "  };\n\n");
  return output;
}

std::string Slot::GenerateDisassemblySetter(const Instruction *inst) const {
  std::string output;
  if (inst->disasm_format_vec().empty()) {
    return "  info->disassembly_setter = [](Instruction *) {};\n";
  }
  absl::StrAppend(&output,
                  "  info->disassembly_setter = [](Instruction *inst) {\n"
                  "    inst->SetDisassemblyString(");
  int indent = 6;
  int outer_paren = false;
  // This is used to keep track of whether the current code emitted is in
  // a call to strcat or not. It helps reduce the number of strcat calls made
  // in the generated code.
  std::stack<bool> in_strcat;
  absl::StrAppend(&output, "absl::StrCat(\n");
  in_strcat.push(true);
  outer_paren = true;
  std::string outer_sep;
  for (auto const *disasm_fmt : inst->disasm_format_vec()) {
    int inner_paren = 0;
    size_t index = 0;
    std::string inner_sep;
    // If the next string needs to be formatted within a certain width field,
    // start out with a StrFormat call.
    if (disasm_fmt->width != 0) {
      absl::StrAppend(&output, outer_sep, indent_string(indent),
                      "absl::StrFormat(\"%", disasm_fmt->width, "s\",\n");
      indent += 2;
      inner_paren++;
      in_strcat.push(false);
    } else if (!outer_sep.empty()) {
      absl::StrAppend(&output, ", ");
    }
    // If multiple strings will be generated, and we're not currently in a
    // StrCat, start a StrCat.
    if (!((disasm_fmt->format_fragment_vec.size() == 1) &&
          disasm_fmt->format_info_vec.empty()) &&
        !in_strcat.top()) {
      absl::StrAppend(&output, indent_string(indent), "absl::StrCat(\n");
      indent += 2;
      inner_paren++;
      in_strcat.push(true);
    }
    // Generate the strings from the format fragments and the format info.
    for (auto const &frag : disasm_fmt->format_fragment_vec) {
      std::string next_sep;
      if (!frag.empty()) {
        absl::StrAppend(&output, inner_sep, indent_string(indent), "\"", frag,
                        "\"");
        next_sep = ", ";
      }
      if (index < disasm_fmt->format_info_vec.size()) {
        auto *format_info = disasm_fmt->format_info_vec[index];
        if (format_info->op_name.empty()) {
          if (!format_info->is_formatted) {
            absl::StrAppend(&output, "\n#error Missing locator information");
          } else {
            absl::StrAppend(&output, next_sep, "absl::StrFormat(\"",
                            format_info->number_format, "\", ",
                            ExpandExpression(*format_info, ""), ")");
          }
        } else {
          auto key = format_info->op_name;
          auto iter = inst->opcode()->op_locator_map().find(key);
          if (iter == inst->opcode()->op_locator_map().end()) {
            absl::StrAppend(&output, "\n#error ", key,
                            " not found in instruction opcodes\n");
            continue;
          }
          auto result = TranslateLocator(iter->second);
          if (!result.status().ok()) {
            absl::StrAppend(&output, "\n#error ", result.status().message(),
                            "\n");
            continue;
          }
          if (!format_info->is_formatted) {
            absl::StrAppend(&output, next_sep, result.value(), "->AsString()");
          } else {
            absl::StrAppend(&output, next_sep, "absl::StrFormat(\"",
                            format_info->number_format, "\", ",
                            ExpandExpression(*format_info, result.value()),
                            ")");
          }
        }
      }
      index++;
      if (inner_sep.empty()) inner_sep = ",\n";
    }
    // Close up parentheses as required.
    for (int i = 0; i < inner_paren; i++) {
      absl::StrAppend(&output, ")");
      indent -= 2;
      if (!in_strcat.top()) {  // Finished a StrFormat.
        absl::StrAppend(&output, "\n", indent_string(indent));
      }
      in_strcat.pop();
    }
    if (outer_sep.empty()) outer_sep = ",\n";
  }
  if (outer_paren) {
    in_strcat.pop();
    absl::StrAppend(&output, ")");
  }

  absl::StrAppend(&output,
                  ");\n"
                  "  };\n\n");
  return output;
}

std::string Slot::GenerateResourceSetter(
    const Instruction *inst, absl::string_view encoding_type) const {
  std::string output;
  std::string opcode_name = inst->opcode()->pascal_name();
  std::string opcode_enum = absl::StrCat("OpcodeEnum::k", opcode_name);
  std::string signature = absl::StrCat("(Instruction *inst, ", encoding_type,
                                       " *enc, SlotEnum slot, int entry)");
  absl::StrAppend(&output, "  info->resource_setter = []", signature, " {\n");
  if (!inst->resource_use_vec().empty() ||
      !inst->resource_acquire_vec().empty()) {
    absl::StrAppend(&output, "    ResourceOperandInterface *res_op;\n");
  }
  // Get all the simple resources that need to be free, then all the complex
  // resources that need to be free in order to issue the instruction.
  std::vector<const ResourceReference *> complex_refs;
  std::vector<const ResourceReference *> simple_refs;
  for (auto const *ref : inst->resource_use_vec()) {
    // Do the complex refs last.
    if (!ref->resource->is_simple()) {
      complex_refs.push_back(ref);
    } else {
      simple_refs.push_back(ref);
    }
  }
  // Simple resources.
  if (!simple_refs.empty()) {
    // First gather the resource references into a single vector, then request
    // the resource operands for all the resource references in that vector.
    absl::StrAppend(&output,
                    "    std::vector<SimpleResourceEnum> hold_vec = {");
    for (auto const *simple : simple_refs) {
      std::string resource_name;
      if (simple->is_array) {
        resource_name = absl::StrCat("SimpleResourceEnum::k",
                                     simple->resource->pascal_name());
      } else {
        resource_name = absl::StrCat("SimpleResourceEnum::k",
                                     simple->resource->pascal_name());
      }
      absl::StrAppend(&output, "\n        ", resource_name, ", ");
    }
    absl::StrAppend(&output,
                    "};\n\n"
                    "    res_op = enc->GetSimpleResourceOperand(slot, entry, ",
                    opcode_enum, ", hold_vec, -1);\n",
                    "    if (res_op != nullptr) {\n"
                    "      inst->AppendResourceHold(res_op);\n"
                    "    }\n");
  }
  // Complex resources.
  for (auto const *complex : complex_refs) {
    // Get the expression values for the begin and end expressions.
    auto begin_value = complex->begin_expression->GetValue();
    auto end_value = complex->end_expression->GetValue();
    if (!begin_value.ok() || !end_value.ok()) {
      absl::StrAppend(&output,
                      "#error Unable to evaluate begin or end expression\n");
      continue;
    }
    // Get the integer values from the begin and end expression values.
    int *begin = std::get_if<int>(&begin_value.value());
    int *end = std::get_if<int>(&end_value.value());
    if ((begin == nullptr) || (end == nullptr)) {
      absl::StrAppend(
          &output, "#error Unable to get value of begin or end expression\n");
      continue;
    }
    if (complex->is_array) {
      absl::StrAppend(
          &output,
          "    auto res_op_vec = enc->GetComplexResourceOperands(slot, entry, ",
          opcode_enum, ", ListComplexResourceEnum::k",
          complex->resource->pascal_name(), *begin, ", ", *end, ");\n");
      absl::StrAppend(&output,
                      "    for (auto res_op : res_op_vec) {\n"
                      "      inst->AppendResourceHold(res_op);\n"
                      "    }\n");
    } else {
      absl::StrAppend(
          &output, "    res_op = enc->GetComplexResourceOperand(slot, entry, ",
          opcode_enum, ", ComplexResourceEnum::k",
          complex->resource->pascal_name(), ", ");
      absl::StrAppend(&output, *begin, ", ", *end, ");\n");
      absl::StrAppend(&output,
                      "    if (res_op != nullptr) {\n"
                      "      inst->AppendResourceHold(res_op);\n"
                      "    }\n");
    }
  }

  // Get all the simple resources that need to be reserved, then all the complex
  // resources that need to be reserved when issuing this instruction.
  complex_refs.clear();
  simple_refs.clear();
  for (auto const *ref : inst->resource_acquire_vec()) {
    // Do the complex refs last.
    if (!ref->resource->is_simple()) {
      complex_refs.push_back(ref);
    } else {
      simple_refs.push_back(ref);
    }
  }
  // Simple resources.
  if (!simple_refs.empty()) {
    // Compute the set of latencies. Insert each reference into a multi-map
    // keyed by the latency.
    std::multimap<int, const ResourceReference *> latency_map;
    absl::flat_hash_set<int> latencies;
    for (auto const *simple : simple_refs) {
      if (simple->end_expression == nullptr) {
        continue;
      }
      auto end_value = simple->end_expression->GetValue();
      if (!end_value.ok()) {
        absl::StrAppend(&output, "#error Unable to evaluate end expression\n");
        continue;
      }
      int *end = std::get_if<int>(&end_value.value());
      if (end == nullptr) {
        absl::StrAppend(&output,
                        "#error Unable to get value of  end expression\n");
        continue;
      }
      int latency = *end;
      latencies.insert(latency);
      latency_map.insert(std::make_pair(latency, simple));
    }
    // Process the resources by latencies.
    for (auto latency : latencies) {
      std::string sep = "";
      absl::StrAppend(&output,
                      "    std::vector<SimpleResourceEnum> acquire_vec",
                      latency, " = {");
      for (auto iter = latency_map.lower_bound(latency);
           iter != latency_map.upper_bound(latency); ++iter) {
        auto *simple = iter->second;
        std::string resource_name;
        if (simple->is_array) {
          resource_name = absl::StrCat("SimpleResourceEnum::k",
                                       simple->resource->pascal_name());
        } else {
          resource_name = absl::StrCat("SimpleResourceEnum::k",
                                       simple->resource->pascal_name());
        }
        absl::StrAppend(&output, sep, "\n        ", resource_name, ",");
      }
      absl::StrAppend(
          &output,
          "};\n\n"
          "    res_op = enc->GetSimpleResourceOperand(slot, entry, ",
          opcode_enum, ", acquire_vec", latency, ", ", latency,
          ");\n"
          "    if (res_op != nullptr) {\n"
          "      inst->AppendResourceAcquire(res_op);\n"
          "    }\n");
    }
  }

  // Complex resources.
  if (!complex_refs.empty()) {
    for (auto const *complex : complex_refs) {
      // Get the expression values for the begin and end expressions.
      if (complex->begin_expression == nullptr) continue;
      if (complex->end_expression == nullptr) continue;
      auto begin_value = complex->begin_expression->GetValue();
      auto end_value = complex->end_expression->GetValue();
      if (!begin_value.ok() || !end_value.ok()) {
        absl::StrAppend(&output,
                        "#error Unable to evaluate begin or end expression\n");
        continue;
      }
      // Get the integer values from the begin and end expression values.
      int *begin = std::get_if<int>(&begin_value.value());
      int *end = std::get_if<int>(&end_value.value());
      if (complex->is_array) {
        absl::StrAppend(&output,
                        "    auto res_op_vec = "
                        "enc->GetComplexResourceOperands(slot, entry, ",
                        opcode_enum, ", ListComplexResourceEnum::k",
                        complex->resource->pascal_name(), *begin, ", ", *end,
                        ");\n");
        absl::StrAppend(&output,
                        "    for (auto res_op : res_op_vec) {\n"
                        "      inst->AppendResourceHold(res_op);\n"
                        "    }\n");
      } else {
        absl::StrAppend(
            &output,
            "    res_op = enc->GetComplexResourceOperand(slot, entry, ",
            opcode_enum, ", ComplexResourceEnum::k",
            complex->resource->pascal_name(), ", ");
        absl::StrAppend(&output, *begin, ", ", *end, ");\n");
        absl::StrAppend(&output,
                        "    if (res_op != nullptr) {\n"
                        "      inst->AppendResourceHold(res_op);\n"
                        "    }\n");
      }
    }
  }
  absl::StrAppend(&output, "  };\n\n");
  return output;
}

std::string Slot::ListFuncGetterInitializations(
    absl::string_view encoding_type) const {
  std::string output;
  if (instruction_map_.empty()) return output;
  std::string class_name = pascal_name() + "Slot";
  // For each instruction create two lambda functions. One that is used to
  // obtain the semantic function object for the instruction, the other a lambda
  // that sets the predicate, source and target operands. Both lambdas use calls
  // to virtual functions declared in the current class or a base class thereof.
  std::string signature = absl::StrCat("(Instruction *inst, ", encoding_type,
                                       " *enc, SlotEnum slot, int entry)");
  absl::StrAppend(&output,
                  "  int index;\n"
                  "  InstructionInfo *info;\n"
                  "  // For kNone - unknown instruction.\n"
                  "  index = static_cast<int>(OpcodeEnum::kNone);\n"
                  "  info = new InstructionInfo;\n"
                  "  info->instruction_size = ",
                  min_instruction_size(),
                  ";\n\n"
                  "  info->operand_setter.push_back([]",
                  signature,
                  "{});\n"
                  "  info->semfunc.push_back(",
                  default_instruction_->semfunc_code_string(), ");\n",
                  GenerateResourceSetter(default_instruction_, encoding_type),
                  GenerateDisassemblySetter(default_instruction_),
                  GenerateAttributeSetter(default_instruction_),
                  "  instruction_info_.insert({index, info});\n");
  for (auto const &[unused, inst_ptr] : instruction_map_) {
    auto *instruction = inst_ptr;
    std::string opcode_name = instruction->opcode()->pascal_name();
    std::string opcode_enum = absl::StrCat("OpcodeEnum::k", opcode_name);

    absl::StrAppend(&output, "\n  // ***   ", opcode_name, "   ***\n",
                    "  index = static_cast<int>(", opcode_enum,
                    ");\n"
                    "  info = new InstructionInfo;\n"
                    "  info->instruction_size = ",
                    instruction->opcode()->instruction_size(), ";\n");
    // For the opcode and any child opcodes, add the semantic function and
    // operand_setter_ lambda.
    for (auto const *inst = instruction; inst != nullptr;
         inst = inst->child()) {
      std::string code_str;
      if (inst->semfunc_code_string().empty()) {
        // If there is no code string, use the default one.
        code_str = default_instruction_->semfunc_code_string();
      } else {
        code_str = inst->semfunc_code_string();
      }
      absl::StrAppend(&output, "  info->semfunc.push_back(", code_str,
                      ");\n"
                      "  info->operand_setter.push_back([]",
                      signature, " {\n");
      // Generate code to set predicate operand, if the opcode has one.
      const std::string &op_name = inst->opcode()->predicate_op_name();
      if (!op_name.empty()) {
        std::string pred_op_enum =
            absl::StrCat("PredOpEnum::k", ToPascalCase(op_name));
        absl::StrAppend(&output, "        inst->SetPredicate(enc->GetPredicate",
                        "(slot_, entry, ", opcode_enum, ", ", pred_op_enum,
                        "));\n");
      }
      // Generate code to set the instruction's source operands.
      int source_no = 0;
      for (const auto &src_op : inst->opcode()->source_op_vec()) {
        // If the source operand is an array, then we need to iterate over the
        // vector of operands that GetSources returns.
        if (src_op.is_array) {
          std::string src_op_enum =
              absl::StrCat("ListSourceOpEnum::k", ToPascalCase(src_op.name));
          absl::StrAppend(
              &output,
              "      {\n"
              "         auto vec = enc->GetSources",
              "(slot_, entry, ", opcode_enum, ", ", src_op_enum, ", ",
              source_no,
              ");\n"
              "         for (auto *op : vec) inst->AppendSource(op);\n"
              "      }\n");
        } else {
          std::string src_op_enum =
              absl::StrCat("SourceOpEnum::k", ToPascalCase(src_op.name));
          absl::StrAppend(&output, "        inst->AppendSource(enc->GetSource",
                          "(slot_, entry, ", opcode_enum, ", ", src_op_enum,
                          ", ", source_no++, "));\n");
        }
      }
      // Generate code to set the instruction's destination operands.
      int dest_no = 0;
      for (auto const *dst_op : inst->opcode()->dest_op_vec()) {
        std::string dest_op_enum;
        if (dst_op->is_array()) {
          dest_op_enum =
              absl::StrCat("ListDestOpEnum::k", dst_op->pascal_case_name());
        } else {
          dest_op_enum =
              absl::StrCat("DestOpEnum::k", dst_op->pascal_case_name());
        }
        std::string latency;
        if (dst_op->expression() == nullptr) {
          latency = absl::StrCat("enc->GetLatency(slot_, entry, ", opcode_enum,
                                 ", ", dest_op_enum, ", ", dest_no, ")");
        } else {
          auto result = dst_op->GetLatency();
          if (!result.ok()) {
            absl::StrAppend(&output,
                            "#error \"Failed to get latency for operand '",
                            dst_op->name(), "'\"");
            dest_no++;
            continue;
          }
          latency = absl::StrCat(result.value());
          // If the operand is an array, then the latency is a vector.
          if (dst_op->is_array()) {
            latency = absl::StrCat("{", latency, "}");
          }
        }
        if (dst_op->is_array()) {
          absl::StrAppend(
              &output,
              "      {\n"
              "         auto vec = enc->GetDestinations",
              "(slot_, entry, ", opcode_enum, ", ", dest_op_enum, ", ", dest_no,
              ", ", latency,
              ");\n"
              "         for (auto *op : vec) inst->AppendDestination(op);\n"
              "      }");
        } else {
          absl::StrAppend(
              &output, "        inst->AppendDestination(enc->GetDestination(",
              "slot_, entry, ", opcode_enum, ", ", dest_op_enum, ", ", dest_no,
              ", ", latency, "));\n");
          dest_no++;
        }
        dest_no++;
      }
      absl::StrAppend(&output, "      });\n\n");
    }
    absl::StrAppend(&output, GenerateDisassemblySetter(instruction));
    absl::StrAppend(&output,
                    GenerateResourceSetter(instruction, encoding_type));
    absl::StrAppend(&output, GenerateAttributeSetter(instruction));
    absl::StrAppend(&output, "  instruction_info_.insert({index, info});\n");
  }
  return output;
}

// Generate the class declaration, including all getter functions for semantic
// functions and operand initializers.
std::string Slot::GenerateClassDeclaration(
    absl::string_view encoding_type) const {
  std::string output;
  if (!is_referenced()) return output;
  std::string class_name = pascal_name() + "Slot";
  absl::StrAppend(&output, "class ", class_name,
                  " {\n"
                  " public:\n"
                  "  explicit ",
                  class_name,
                  "(ArchState *arch_state);\n"
                  "  virtual ~",
                  class_name, "();\n");
  // Emit Decode function generated that decodes the slot and creates and
  // initializes an instruction object, as well as private data members.
  absl::StrAppend(&output, "  Instruction *Decode(uint64_t address, ",
                  encoding_type, "* isa_encoding, SlotEnum, int entry);\n",
                  "\n"
                  " private:\n"
                  "  ArchState *arch_state_;\n"
                  "  InstructionInfoMap instruction_info_;\n",
                  "  static constexpr SlotEnum slot_ = SlotEnum::k",
                  pascal_name(),
                  ";\n"
                  "};\n"
                  "\n");
  return output;
}

// Write out the class definition for the Slot class including all initializer
// bodies.
std::string Slot::GenerateClassDefinition(
    absl::string_view encoding_type) const {
  if (!is_referenced()) return "";
  std::string class_name = pascal_name() + "Slot";
  std::string output;
  // Constructor.
  absl::StrAppend(
      &output, class_name, "::", class_name,
      "(ArchState *arch_state) :\n"
      "  arch_state_(arch_state)\n"
      "{\n",
      ListFuncGetterInitializations(encoding_type),
      "}\n"
      "\n"
      "Instruction *",
      class_name, "::Decode(uint64_t address, ", encoding_type,
      " *isa_encoding, SlotEnum slot, int entry) {\n"
      "  OpcodeEnum opcode = isa_encoding->GetOpcode(slot, entry);\n"
      "  int indx = static_cast<int>(opcode);\n"
      "  if (!instruction_info_.contains(indx)) indx = 0;\n"
      "  auto *inst_info = instruction_info_[indx];\n"
      "  Instruction *inst = new Instruction(address, arch_state_);\n"
      "  inst->set_size(inst_info->instruction_size);\n"
      "  inst->set_opcode(static_cast<int>(opcode));\n"
      "  inst->set_semantic_function(inst_info->semfunc[0]);\n"
      "  inst_info->operand_setter[0](inst, isa_encoding, slot, entry);\n"
      "  Instruction *parent = inst;\n"
      "  for (size_t i = 1; i < inst_info->operand_setter.size(); i++) {\n"
      "    Instruction *child = new Instruction(address, arch_state_);\n"
      "    child->set_semantic_function(inst_info->semfunc[i]);\n"
      "    inst_info->operand_setter[i](child, isa_encoding, slot, entry);\n"
      "    parent->AppendChild(child);\n"
      "    child->DecRef();\n"
      "    parent = child;\n"
      "  }\n"
      "  inst_info->resource_setter(inst, isa_encoding, slot, entry);\n"
      "  inst_info->disassembly_setter(inst);\n"
      "  inst_info->attribute_setter(inst);\n"
      "  return inst;\n"
      "}\n");
  // Destructor.
  absl::StrAppend(&output, class_name, "::~", class_name,
                  "() {\n"
                  "  for (auto &[unused, info_ptr] : instruction_info_) {\n"
                  "    delete info_ptr;\n"
                  "  };\n"
                  "  instruction_info_.clear();\n"
                  "}\n");
  return output;
}

absl::Status Slot::CheckPredecessors(const Slot *base) const {
  if (predecessor_set_.contains(base))
    return absl::AlreadyExistsError(
        absl::StrCat("'", base->name(),
                     "' is already in the predecessor set of '", name(), "'"));
  for (auto const *pred : predecessor_set_) {
    auto status = pred->CheckPredecessors(base);
    if (!status.ok()) return status;
  }
  for (auto const *base_pred : base->predecessor_set_) {
    auto status = CheckPredecessors(base_pred);
    if (!status.ok()) return status;
  }
  return absl::OkStatus();
}

absl::Status Slot::AddBase(const Slot *base) {
  // First need to check if the current slot already inherits from base, or
  // any of base's predecessors. Only tree-like inheritance is supported.
  auto status = CheckPredecessors(base);
  if (!status.ok()) return status;
  predecessor_set_.insert(base);
  base_slots_.emplace_back(base);
  return absl::OkStatus();
}

absl::Status Slot::AddBase(const Slot *base,
                           TemplateInstantiationArgs *arguments) {
  auto status = CheckPredecessors(base);
  if (!status.ok()) return status;
  predecessor_set_.insert(base);
  base_slots_.emplace_back(base, arguments);
  return absl::OkStatus();
}

absl::Status Slot::AddConstant(const std::string &ident,
                               const std::string &type,
                               TemplateExpression *expression) {
  // Ignore the type for now - there is only int.
  (void)type;
  // Check if the name already exists or matches a template formal parameter.
  if (template_parameter_map_.contains(ident)) {
    return absl::AlreadyExistsError(
        absl::StrCat("Slot constant '", ident,
                     "' conflicts with template formal with same name"));
  }
  if (constant_map_.contains(ident)) {
    return absl::AlreadyExistsError(
        absl::StrCat("Redefinition of slot constant '", ident, "'"));
  }
  constant_map_.insert(std::make_pair(ident, expression));
  return absl::OkStatus();
}

TemplateExpression *Slot::GetConstExpression(const std::string &ident) const {
  auto iter = constant_map_.find(ident);
  if (iter == constant_map_.end()) return nullptr;
  return iter->second;
}

absl::Status Slot::AddTemplateFormal(const std::string &par_name) {
  if (template_parameter_map_.contains(par_name)) {
    // Push it into the vector, but not the map. Have the formal name refer to
    // the previous index. Signal error. This allows us to properly match the
    // number of parameters in each use of the templated slot, even though there
    // is an error in the parameter names.
    int indx = template_parameter_map_.at(par_name);
    template_parameters_.push_back(new TemplateFormal(par_name, indx));
    return absl::InternalError(
        absl::StrCat("Duplicate parameter name '", par_name, "'"));
  }
  int indx = template_parameters_.size();
  template_parameters_.push_back(new TemplateFormal(par_name, indx));
  template_parameter_map_.insert(std::make_pair(par_name, indx));
  return absl::OkStatus();
}

TemplateFormal *Slot::GetTemplateFormal(const std::string &name) const {
  auto iter = template_parameter_map_.find(name);
  if (iter == template_parameter_map_.end()) return nullptr;
  return template_parameters_[iter->second];
}

void Slot::AddInstructionAttribute(const std::string &name,
                                   TemplateExpression *expr) {
  attribute_map_.emplace(name, expr);
}

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