// 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 <algorithm>
#include <cctype>
#include <cstddef>
#include <cstdlib>
#include <map>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

#include "absl/container/btree_set.h"
#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' || locator.type == 't') {
    absl::StrAppend(&code, "Source(", locator.instance, ")");
  } else if (locator.type == 'd' || locator.type == 'e') {
    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, ' '); }

// Generates a string that is a unique key for the attributes to determine which
// instructions can share attribute setter functions.
std::string Slot::CreateAttributeLookupKey(const Instruction *inst) const {
  std::string key;
  for (auto const &[name, expr] : inst->attribute_map()) {
    std::string value;
    auto result = expr->GetValue();
    if (!result.ok()) {
      absl::StrAppend(&key, name, "[e1]:");
      continue;
    }
    auto *value_ptr = std::get_if<int>(&result.value());
    if (value_ptr == nullptr) {
      absl::StrAppend(&key, name, "[e2]:");
      continue;
    }
    absl::StrAppend(&key, name, "[", *value_ptr, "]:");
  }
  return key;
}

// Generate the attribute setter function that matches the "key" of the given
// instruction.
std::string Slot::GenerateAttributeSetterFcn(absl::string_view name,
                                             const Instruction *inst) const {
  std::string output;
  absl::StrAppend(&output, "void ", name, "(Instruction *inst) {\n");
  if (!attribute_map_.empty()) {
    // Allocate the array and initialize to zero.
    absl::StrAppend(&output, "  int *attrs = new int[", attribute_map_.size(),
                    "];\n"
                    "  attrs = {");
    std::string sep = "";
    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, sep, "*value");
      sep = ", ";
    }
    absl::StrAppend(&output, "};\n");
    absl::StrAppend(&output,
                    "  inst->SetAttributes(absl::Span<int>(attrs, size));\n");
  }
  absl::StrAppend(&output, "}\n");
  return output;
}

// Return a function call string that will set the attributes for the given
// instruction. If no such appropriate function exists, create one.
std::string Slot::GenerateAttributeSetter(const Instruction *inst) {
  auto key = CreateAttributeLookupKey(inst);
  auto iter = attribute_setter_name_map_.find(key);
  if (iter == attribute_setter_name_map_.end()) {
    auto index = attribute_setter_name_map_.size();
    std::string func_name =
        absl::StrCat(pascal_name(), "Slot", "SetAttributes", index);
    iter = attribute_setter_name_map_.emplace(key, func_name).first;
    absl::StrAppend(&setter_functions_,
                    GenerateAttributeSetterFcn(func_name, inst));
  }
  return iter->second;
}

namespace {

std::string EscapeRegexCharacters(const std::string &str) {
  std::string output;
  if (str.empty()) return output;
  auto pos = str.find_last_not_of(' ');
  if (pos == std::string::npos) {
    return "\\s+";
  }
  std::string input(str.substr(pos));
  bool in_space = false;
  char p;
  for (auto c : str) {
    if (isspace(c)) {
      if (!in_space) {
        if (ispunct(p)) {
          absl::StrAppend(&output, "\\s*");
        } else {
          absl::StrAppend(&output, "\\s+");
        }
      }
      in_space = true;
      continue;
    }
    p = c;
    in_space = false;
    switch (c) {
      case '.':
        absl::StrAppend(&output, "\\.");
        break;
      case '(':
        absl::StrAppend(&output, "\\(");
        break;
      case ')':
        absl::StrAppend(&output, "\\)");
        break;
      case '[':
        absl::StrAppend(&output, "\\[");
        break;
      case ']':
        absl::StrAppend(&output, "\\]");
        break;
      case '*':
        absl::StrAppend(&output, "\\*");
        break;
      case '+':
        absl::StrAppend(&output, "\\+");
        break;
      case '?':
        absl::StrAppend(&output, "\\?");
        break;
      case '|':
        absl::StrAppend(&output, "\\|");
        break;
      case '{':
        absl::StrAppend(&output, "\\{");
        break;
      case '}':
        absl::StrAppend(&output, "\\}");
        break;
      case '^':
        absl::StrAppend(&output, "\\^");
        break;
      case '$':
        absl::StrAppend(&output, "\\$");
        break;
      case '!':
        absl::StrAppend(&output, "\\!");
        break;
      case '\\':
        absl::StrAppend(&output, "\\\\");
        break;
      default:
        absl::StrAppend(&output, std::string(1, c));
        break;
    }
  }
  return output;
}

}  // namespace

std::tuple<std::string, std::vector<OperandLocator>> Slot::GenerateRegEx(
    const Instruction *inst, std::vector<std::string> &formats) const {
  std::string output = "R\"(";
  std::string sep = "^";
  std::vector<OperandLocator> opnd_locators;
  // Iterate over the vector of disasm formats. These will end up concatenated
  // with \s+ separators.
  for (auto const *disasm_fmt : inst->disasm_format_vec()) {
    absl::StrAppend(&output, sep);
    sep = "\\s+";
    // The fragments are the text part (not part of operands), that occur
    // between the operand of the format. E.g., the commas in "r1, r2, r3".
    auto fragment_iter = disasm_fmt->format_fragment_vec.begin();
    auto fragment_end = disasm_fmt->format_fragment_vec.end();
    // The formats are the instruction formats, E.g., the register names in
    // "r1, r2, r3".
    auto format_iter = disasm_fmt->format_info_vec.begin();
    auto format_end = disasm_fmt->format_info_vec.end();
    char prev = '\0';
    // Iterate over the format fragments.
    while (fragment_iter != fragment_end) {
      auto fragment = *fragment_iter;
      if (!fragment.empty()) {
        auto str = EscapeRegexCharacters(fragment);
        absl::StrAppend(&output, str);
        prev = str.back();
      } else {
        prev = '\0';
      }
      fragment_iter++;
      if (format_iter != format_end) {
        // If the trailling part of output is not '\\s*', and prev is
        // punctuation, but not '.' or '_', add a space separator.
        auto len = output.size();
        if (output.substr(len - 3) != "\\s*") {
          if ((prev != '\0') &&
              !(isalnum(prev) || (prev == '_') || (prev == '.'))) {
            absl::StrAppend(&output, "\\s*");
          }
        }
        std::string op_name = (*format_iter)->op_name;
        absl::StrAppend(&output, "(\\S*?)");
        opnd_locators.push_back(inst->opcode()->op_locator_map().at(op_name));
        if ((fragment_iter != fragment_end) && (!(*fragment_iter).empty())) {
          char c = (*fragment_iter)[0];
          // If the next fragment is not alnum or underscore, add a space
          // separator.
          if (!isalnum(c) || (c != '_')) {
            absl::StrAppend(&output, "\\s*");
          }
        }
        format_iter++;
      }
    }
  }
  absl::StrAppend(&output, "$)\"");
  return {output, opnd_locators};
}

std::string GenerateEncodingFunctions(const std::string &encoder,
                                      InstructionSet instruction_set) {
  std::string output;
  absl::StrAppend(&output, "namespace {\n\n");
  absl::StrAppend(
      &output, "absl::StatusOr<std::tuple<uint64_t, int>> EncodeNone(", encoder,
      "*, SlotEnum, int, OpcodeEnum, uint64_t, const "
      "std::vector<std::string> &) {\n"
      "  return absl::NotFoundError(\"No such opcode\");\n"
      "}\n\n");
  return output;
}
// Generate a regex to match the assembly string for the instructions.
std::tuple<std::string, std::string> Slot::GenerateAsmRegexMatcher() const {
  std::string h_output;
  std::string cc_output;
  std::string class_name = pascal_name() + "SlotMatcher";
  size_t max_args = 0;

  // Generate the encoder function for each instruction.
  std::string encoder =
      absl::StrCat(instruction_set_->pascal_name(), "EncoderInterfaceBase");

  // Generate the matcher class.
  absl::StrAppend(
      &h_output,
      "// Assembly matcher.\n"
      "class ",
      class_name,
      " {\n"
      " public:\n"
      "  ",
      class_name, "(", instruction_set_->pascal_name(),
      "EncoderInterfaceBase *encoder);\n"
      "  ~",
      class_name,
      "();\n"
      "  absl::Status Initialize();\n"
      "absl::StatusOr<std::tuple<uint64_t, int>> "
      "  Encode(uint64_t address, absl::string_view text, int entry, "
      "ResolverInterface *resolver, std::vector<RelocationInfo> "
      "&relocations);\n\n"
      " private:\n"
      "  bool Match(absl::string_view text, std::vector<int> &matches);\n"
      "  bool Extract(absl::string_view text, int index, "
      "std::vector<std::string> &values);\n"
      "  ",
      encoder,
      " *encoder_;\n"
      "  std::vector<RE2 *> regex_vec_;\n"
      "  RE2::Set regex_set_;\n");
  absl::StrAppend(&cc_output, class_name, "::", class_name, "(",
                  instruction_set_->pascal_name(),
                  "EncoderInterfaceBase *encoder) :\n"
                  "  encoder_(encoder),\n"
                  "  regex_set_(RE2::Options(), RE2::ANCHOR_BOTH) {}\n"
                  "\n",
                  class_name, "::~", class_name,
                  "() {\n"
                  "  for (int i = 0; i < re2_args.size(); ++i) {\n"
                  "    delete re2_args[i];\n"
                  "  }\n"
                  "  for (auto *regex : regex_vec_) delete regex;\n"
                  "  regex_vec_.clear();\n"
                  "}\n\n"
                  "absl::Status ",
                  class_name,
                  "::Initialize() {\n"
                  "  int index;\n"
                  "  std::string error;\n"
                  "  index = regex_set_.Add(\"^$\", &error);\n"
                  "  regex_vec_.push_back(new RE2(\"^$\"));\n");
  std::vector<std::string> formats;
  for (auto const &[name, inst_ptr] : instruction_map_) {
    auto [regex, opnd_locators] = GenerateRegEx(inst_ptr, formats);
    max_args = std::max(max_args, opnd_locators.size());
    absl::StrAppend(&cc_output, "  regex_vec_.push_back(new RE2(", regex,
                    "));\n"
                    "  index = regex_set_.Add(",
                    regex,
                    ", &error);\n"
                    "  if (index == -1) return absl::InternalError(error);\n");
  }
  absl::StrAppend(&h_output, "  std::string args[", max_args,
                  "];\n"
                  "  std::array<RE2::Arg*, ",
                  max_args, "> re2_args = {");
  for (int i = 0; i < max_args; ++i) absl::StrAppend(&h_output, "nullptr, ");
  absl::StrAppend(&h_output, "  };\n");
  // Construct the RE2::Arg objects.
  absl::StrAppend(&cc_output,
                  "  auto ok = regex_set_.Compile();\n"
                  "  if (!ok) return absl::InternalError(\"Failed to compile "
                  "regex set\");\n"
                  "  for (int i = 0; i < ",
                  max_args,
                  "; ++i) {\n"
                  "    re2_args[i] = new RE2::Arg(&args[i]);\n"
                  "  }\n");
  absl::StrAppend(
      &cc_output,
      "  return absl::OkStatus();\n"
      "}\n\n"
      "bool ",
      class_name,
      "::Match(absl::string_view text, std::vector<int> &matches) {\n"
      "  return regex_set_.Match(text, &matches);\n"
      "}\n\n"
      "bool ",
      class_name,
      "::Extract(absl::string_view text, int index, "
      "std::vector<std::string> &values) {\n"
      "  auto &regex = regex_vec_.at(index);\n"
      "  int arg_count = regex->NumberOfCapturingGroups();\n"
      "  if (!regex_vec_.at(index)->FullMatchN(text, *regex, "
      "re2_args.data(), "
      "arg_count))\n"
      "    return false;\n"
      "  for (int i = 0; i < arg_count; ++i) {\n"
      "    values.push_back(args[i]);\n"
      "  }\n"
      "  return true;\n"
      "}\n\n"
      "absl::StatusOr<std::tuple<uint64_t, int>> ",
      pascal_name(),
      "SlotMatcher::Encode(\n"
      R"(
    uint64_t address, absl::string_view text, int entry, ResolverInterface *resolver,
    std::vector<RelocationInfo> &relocations) {
  std::vector<int> matches;
  std::string error_message = absl::StrCat("Failed to encode '", text, "':");
  if (!Match(text, matches) || (matches.size() == 0)) {
    return absl::NotFoundError(error_message);
  }
  std::vector<std::tuple<uint64_t, int>> encodings;
  for (auto index : matches) {
    std::vector<std::string> values;
    if (!Extract(text, index, values)) continue;
)",
      "    auto result = encode_fcns[index](encoder_, SlotEnum::k",
      pascal_name(),
      ", entry, \n"
      "                                     "
      "static_cast<OpcodeEnum>(index), address, values, resolver, "
      "relocations);\n",
      R"(
    if (!result.status().ok()) {
      absl::StrAppend(&error_message, "\n    ", result.status().message());
      continue;
    }
    encodings.push_back(result.value());
  }
  if (encodings.empty()) return absl::NotFoundError(error_message);
  if (encodings.size() > 1) {
    return absl::NotFoundError(
        absl::StrCat("Failed to encode '", text, "': ambiguous"));
  }
  return encodings[0];
}

)");
  absl::StrAppend(&h_output, "};\n\n");
  return {h_output, cc_output};
}

// Generate a function that will set the disassembly string for the given
// instruction.
std::string Slot::GenerateDisasmSetterFcn(absl::string_view name,
                                          const Instruction *inst) const {
  std::string output;
  std::string class_name = pascal_name() + "Slot";
  absl::StrAppend(&output, "void ", name, "(Instruction *inst) {\n");
  absl::StrAppend(&output, "  inst->SetDisassemblyString(");
  int indent = 2;
  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.
    std::string next_sep;
    for (auto const &frag : disasm_fmt->format_fragment_vec) {
      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.back() == 'x' ? "0x" : "",
                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.back() == 'x' ? "0x" : "",
                format_info->number_format, "\", ",
                ExpandExpression(*format_info, result.value()), ")");
          }
        }
      }
      next_sep = ", ";
      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;
}

// Generate a signature for the disassembly setter function required for the
// given instruction. If a matching one does not exist, call to create such a
// function.
std::string Slot::GenerateDisassemblySetter(const Instruction *inst) {
  std::string key;
  // First combine the disassembly fragments.
  for (auto const *format : inst->disasm_format_vec()) {
    for (auto const &frag : format->format_fragment_vec) {
      absl::StrAppend(&key, frag);
    }
  }
  // Then add the resources.
  absl::StrAppend(&key, ":", CreateOperandLookupKey(inst->opcode()));
  std::string func_name = absl::StrCat(
      pascal_name(), "Slot", inst->opcode()->pascal_name(), "SetDisasm");
  auto iter = disasm_setter_name_map_.find(key);
  if (iter == disasm_setter_name_map_.end()) {
    iter = disasm_setter_name_map_.emplace(key, func_name).first;
    absl::StrAppend(&setter_functions_,
                    GenerateDisasmSetterFcn(func_name, inst));
  }
  return absl::StrCat(iter->second);
}

// Generate the assembler function for the given instruction.
std::string Slot::GenerateAssemblerFcn(const Instruction *inst,
                                       absl::string_view encoder_type) const {
  std::string output;
  int num_values = inst->opcode()->source_op_vec().size() +
                   inst->opcode()->dest_op_vec().size();
  absl::StrAppend(
      &output, "absl::StatusOr<std::tuple<int, uint64_t>> ", pascal_name(),
      "Slot", "Assemble", inst->opcode()->pascal_name(), "(", encoder_type,
      " *enc, const std::vector<std::string> &values, SlotEnum "
      "slot, int entry) {\n",
      "  if (values.size() != ", num_values,
      ")\n"
      "    return absl::InvalidArgumentError(\"Wrong number of values\");\n"
      "  constexpr OpcodeEnum opcode = OpcodeEnum::k",
      inst->opcode()->pascal_name(),
      ";\n"
      "auto [inst_word, num_bits] = enc->GetOpEncoding(opcode, slot, "
      "entry);\n",
      "  absl::Status status;\n");
  auto const &source_op_vec = inst->opcode()->source_op_vec();
  for (int i = 0; i < source_op_vec.size(); ++i) {
    std::string op_name = ToPascalCase(source_op_vec[i].name);
    absl::StrAppend(&output, "  status = enc->SetSrcEncoding(values.at(", i,
                    "), slot, entry,\n"
                    "SourceOpEnum::k",
                    op_name, ", ", i,
                    ", opcode);\n"
                    "  if (!stats.ok()) return status;\n");
  }
  auto const &dest_op_vec = inst->opcode()->dest_op_vec();
  for (int i = 0; i < dest_op_vec.size(); ++i) {
    absl::StrAppend(&output, "  status = enc->SetDestEncoding(values.at(", i,
                    "), slot, entry,\n"
                    "DestOpEnum::k",
                    dest_op_vec[i]->pascal_case_name(), ", ", i,
                    ", opcode);\n"
                    "  if (!stats.ok()) return status;\n");
  }
  absl::StrAppend(
      &output,
      "  auto ok = enc->ValidateEncoding(opcode, slot, entry, inst_word);\n"
      "  if (!ok) return absl::InvalidArgumentError(\"Invalid "
      "encoding\");\n");
  absl::StrAppend(&output,
                  "return std::tie(num_bits, inst_word);\n"
                  "}\n\n");
  return output;
}

// Generate a string that is a unique identifier from the resources to
// determine which instructions can share resource setter functions.
std::string Slot::CreateResourceKey(
    const std::vector<const ResourceReference *> &refs) const {
  std::string key;
  std::vector<const ResourceReference *> complex_refs;
  std::vector<const ResourceReference *> simple_refs;
  absl::btree_set<std::string> names;
  // Iterate over use resources.
  for (auto const *ref : refs) {
    if (!ref->resource->is_simple()) {
      complex_refs.push_back(ref);
    } else {
      simple_refs.push_back(ref);
    }
  }
  // Simple use resources.
  for (auto const *ref : simple_refs) {
    std::string name = "S$";
    if (ref->is_array) {
      absl::StrAppend(&name, "[", ref->resource->pascal_name(), "]");
    } else {
      absl::StrAppend(&name, ref->resource->pascal_name());
    }
    names.insert(name);
  }
  std::string sep = "";
  for (auto const &name : names) {
    absl::StrAppend(&key, sep, name);
    sep = "/";
  }
  names.clear();
  absl::StrAppend(&key, ":");

  // Complex use resources.
  for (auto const *ref : complex_refs) {
    std::string name = "C$";
    if (ref->is_array) {
      absl::StrAppend(&name, "[", ref->resource->pascal_name(), "]");
    } else {
      absl::StrAppend(&name, ref->resource->pascal_name());
    }
    auto begin_value = ref->begin_expression->GetValue();
    if (!begin_value.ok()) {
      absl::StrAppend(&name, "(?)");
    } else {
      absl::StrAppend(&name, *std::get_if<int>(&begin_value.value()));
    }
    auto end_value = ref->end_expression->GetValue();
    if (!end_value.ok()) {
      absl::StrAppend(&name, "(?)");
    } else {
      absl::StrAppend(&name, *std::get_if<int>(&end_value.value()));
    }
    names.insert(name);
  }
  sep = "";
  for (auto const &name : names) {
    absl::StrAppend(&key, sep, name);
    sep = "/";
  }
  return key;
}

// Generate a resource setter function call for the resource "key" of the
// given instruction. If a matching one does not exist, call to create such a
// function.
std::string Slot::GenerateResourceSetter(const Instruction *inst,
                                         absl::string_view encoding_type) {
  std::string key = CreateResourceKey(inst->resource_use_vec());
  absl::StrAppend(&key, ":", CreateResourceKey(inst->resource_acquire_vec()));
  auto iter = resource_setter_name_map_.find(key);
  if (iter == resource_setter_name_map_.end()) {
    auto index = resource_setter_name_map_.size();
    std::string func_name =
        absl::StrCat(pascal_name(), "Slot", "SetResources", index);
    iter = resource_setter_name_map_.emplace(key, func_name).first;
    absl::StrAppend(&setter_functions_,
                    GenerateResourceSetterFcn(func_name, inst, encoding_type));
  }
  return iter->second;
}

// Create a resource setter function for the resource "key" of the given
// instruction.
std::string Slot::GenerateResourceSetterFcn(
    absl::string_view name, const Instruction *inst,
    absl::string_view encoding_type) const {
  std::string output;
  absl::StrAppend(&output, "void ", name, "(Instruction *inst, ", encoding_type,
                  " *enc, SlotEnum slot, int entry) {\n");
  std::string opcode_name = inst->opcode()->pascal_name();
  std::string opcode_enum = absl::StrCat("OpcodeEnum::k", opcode_name);
  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"
                    "  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;
}

// Generates a string that is a unique identifier from the operands to
// determine which instructions can share operand getter functions.
std::string Slot::CreateOperandLookupKey(const Opcode *opcode) const {
  std::string key;
  // Generate identifier for the predicate operand, if the opcode has one.
  const std::string &op_name = opcode->predicate_op_name();
  if (!op_name.empty()) {
    absl::StrAppend(&key, op_name, ":");
  }
  // Generate key for the source operands.
  std::string sep = "";
  for (const auto &src_op : opcode->source_op_vec()) {
    if (src_op.is_array) {
      absl::StrAppend(&key, sep, "[", src_op.name, "]");
    } else {
      absl::StrAppend(&key, sep, src_op.name);
    }
    sep = "/";
  }
  absl::StrAppend(&key, ":");
  // Append identifier for destination operands.
  sep.clear();
  for (auto const *dst_op : opcode->dest_op_vec()) {
    std::string dest_op_enum;
    if (dst_op->is_array()) {
      absl::StrAppend(&key, sep, "[", dst_op->name(), "]");
    } else {
      absl::StrAppend(&key, sep, dst_op->name());
    }
    std::string latency;
    if (dst_op->expression() == nullptr) {
      absl::StrAppend(&latency, "(*)");
    } else {
      auto result = dst_op->GetLatency();
      if (!result.ok()) {
        absl::StrAppend(&latency, "(-1)");
        continue;
      }
      if (dst_op->is_array()) {
        absl::StrAppend(&latency, "({", result.value(), "})");
      } else {
        absl::StrAppend(&latency, "(", result.value(), ")");
      }
    }
    if (dst_op->is_array()) {
      absl::StrAppend(&key, sep, "[", dst_op->name(), "]", latency);
    } else {
      absl::StrAppend(&key, sep, dst_op->name(), latency);
    }
    sep = "/";
  }
  return key;
}

// Generates a function that sets the operands for the operand "key" of the
// given opcode.
std::string Slot::GenerateOperandSetterFcn(absl::string_view getter_name,
                                           absl::string_view encoding_type,
                                           const Opcode *opcode) const {
  std::string output;
  absl::StrAppend(&output, "void ", getter_name, "(Instruction *inst, ",
                  encoding_type,
                  " *enc, OpcodeEnum opcode, SlotEnum slot, int entry) {\n");
  // Generate code to set predicate operand, if the opcode has one.
  const std::string &op_name = 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, ", pred_op_enum, "));\n");
  }
  // Generate code to set the instruction's source operands.
  int source_no = 0;
  for (const auto &src_op : 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, ", 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, ", src_op_enum, ", ", source_no++,
                      "));\n");
    }
  }
  // Generate code to set the instruction's destination operands.
  int dest_no = 0;
  for (auto const *dst_op : 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, ",
                             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, ", 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, ", dest_op_enum, ", ", dest_no,
                      ", ", latency, "));\n");
      dest_no++;
    }
    dest_no++;
  }
  absl::StrAppend(&output, "}\n\n");
  return output;
}

std::string Slot::ListFuncGetterInitializations(
    absl::string_view encoding_type) {
  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, OpcodeEnum opcode, SlotEnum slot, int entry)");
  absl::StrAppend(&setter_functions_,
                  GenerateOperandSetterFcn(
                      absl::StrCat(pascal_name(), "SlotSetOperandsNull"),
                      encoding_type, default_instruction_->opcode()));
  absl::StrAppend(
      &output, "    {OperandSetter{", pascal_name(),
      "SlotSetOperandsNull},\n"
      "    ",
      GenerateDisassemblySetter(default_instruction_), ",\n", "    ",
      GenerateResourceSetter(default_instruction_, encoding_type), ",\n",
      "    ", GenerateAttributeSetter(default_instruction_), ",\n",
      "    SemFuncSetter{", default_instruction_->semfunc_code_string(), "}, ",
      default_instruction_->opcode()->instruction_size(), "},\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  // ***   k", opcode_name, "   ***\n");
    // For the opcode and any child opcodes, add the semantic function and
    // operand_setter_ lambda.
    std::string code_str;
    std::string sep = "";
    std::string operands_str;
    for (auto const *inst = instruction; inst != nullptr;
         inst = inst->child()) {
      // Construct operand getter lookup key.
      std::string key = CreateOperandLookupKey(inst->opcode());
      auto iter = operand_setter_name_map_.find(key);
      // If the key is not found, create a new getter function, otherwise
      // reuse the existing one.
      if (iter == operand_setter_name_map_.end()) {
        auto index = operand_setter_name_map_.size();
        std::string setter_name =
            absl::StrCat(class_name, "SetOperands", index);
        absl::StrAppend(&setter_functions_,
                        GenerateOperandSetterFcn(setter_name, encoding_type,
                                                 inst->opcode()));
        iter = operand_setter_name_map_.insert(std::make_pair(key, setter_name))
                   .first;
      }
      absl::StrAppend(&operands_str, sep, iter->second);
      if (inst->semfunc_code_string().empty()) {
        // If there is no code string, use the default one.
        absl::StrAppend(&code_str, sep,
                        default_instruction_->semfunc_code_string());
      } else {
        absl::StrAppend(&code_str, sep, inst->semfunc_code_string());
      }
      sep = ", ";
    }
    absl::StrAppend(&output, "    {OperandSetter{", operands_str, "},\n",
                    "    ", GenerateDisassemblySetter(instruction), ",\n",
                    "    ", GenerateResourceSetter(instruction, encoding_type),
                    ",\n", "    ", GenerateAttributeSetter(instruction), ",\n",
                    "    SemFuncSetter{", code_str, "}, ",
                    instruction->opcode()->instruction_size(), "},\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");
  // 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"
                  "  std::array<InstructionInfo, ",
                  instruction_map_.size() + 1, "> 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) {
  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",
      "  instruction_info_{{\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"
      "  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, opcode, 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, opcode, 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");
  // Prepend the setter functions.
  std::string combined_output = absl::StrCat(
      "namespace {\n\n", setter_functions_, "}  // namespace\n\n", output);
  return combined_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
