// 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/encoding_group.h"

#include <algorithm>
#include <string>
#include <vector>

#include "absl/container/flat_hash_set.h"
#include "absl/functional/bind_front.h"
#include "absl/log/log.h"
#include "absl/numeric/bits.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/decoder/extract.h"
#include "mpact/sim/decoder/format_name.h"
#include "mpact/sim/decoder/instruction_encoding.h"
#include "mpact/sim/decoder/instruction_group.h"

namespace mpact {
namespace sim {
namespace decoder {
namespace bin_format {

using machine_description::instruction_set::ToPascalCase;

// Indexed by the members of the ConstraintType enum in instruction_encoding.h.
const char *kComparison[] = {
    /* kEq */ "==",
    /* kNe */ "!=",
    /* kLt */ "<",
    /* kLe */ "<=",
    /* kGt */ ">",
    /* kGe */ ">=",
};

// Helper function to provide a less than comparison of instruction encodings.
// This is used in call to std::sort.
static bool EncodingLess(uint64_t mask, InstructionEncoding *lhs,
                         InstructionEncoding *rhs) {
  uint64_t lhs_val = lhs->GetValue() & mask;
  uint64_t rhs_val = rhs->GetValue() & mask;
  return lhs_val < rhs_val;
}

EncodingGroup::EncodingGroup(InstructionGroup *inst_group, uint64_t ignore)
    : EncodingGroup(nullptr, inst_group, ignore) {}

EncodingGroup::EncodingGroup(EncodingGroup *parent,
                             InstructionGroup *inst_group, uint64_t ignore)
    : inst_group_(inst_group), parent_(parent), ignore_(ignore) {}

EncodingGroup::~EncodingGroup() {
  for (auto *group : encoding_group_vec_) {
    delete group;
  }
  encoding_group_vec_.clear();
}

// Adjust the masks and resort the encoding_vec.
void EncodingGroup::AdjustMask() {
  if (parent_ != nullptr) {
    uint64_t parent_mask = parent_->mask();
    constant_ &= ~parent_mask;
    mask_ &= ~parent_mask;
    varying_ &= ~parent_mask;
    value_ &= ~parent_mask;
  }
  std::sort(encoding_vec_.begin(), encoding_vec_.end(),
            absl::bind_front(&EncodingLess, mask_ & ~constant_ & ~ignore_));
}

// Adds an instruction encoding to the encoding group.
void EncodingGroup::AddEncoding(InstructionEncoding *enc) {
  if (encoding_vec_.empty()) {
    last_value_ = enc->GetValue();
    mask_ = enc->GetMask();
  }
  encoding_vec_.push_back(enc);
  mask_ &= enc->GetMask() & ~ignore_;
  uint64_t value = enc->GetValue();
  varying_ |= (value ^ last_value_);
  constant_ = ((~varying_) & mask_) & ~ignore_;
  last_value_ = value;
  value_ = encoding_vec_[0]->GetValue() & constant_;
}

// Returns true if there is overlap between the encoding and those already
// in the group. Returns false if it would clear the mask of common "fixed"
// bits.
bool EncodingGroup::CanAddEncoding(InstructionEncoding *enc) {
  if (encoding_vec_.empty()) return true;
  uint64_t new_mask = mask_ & enc->GetMask();
  if (new_mask == 0) return false;
  return true;
}

// Returns true if the decode can be done by simple opcode table lookup as
// opposed to a function that performs comparisons.
bool EncodingGroup::IsSimpleDecode() {
  if (!encoding_group_vec().empty()) return false;
  for (auto *enc : encoding_vec_) {
    if (!enc->other_constraints().empty()) return false;
    if (!enc->equal_extracted_constraints().empty()) return false;
  }
  return discriminator_ == varying_;
}

// This method takes the current group and seeks to break the encodings into
// subgroups based on the bits of the instructions that vary across the members
// of the group.
void EncodingGroup::AddSubGroups() {
  AdjustMask();
  discriminator_ = mask_ & ~constant_;
  simple_decoding_ = IsSimpleDecode();
  discriminator_recipe_ = GetExtractionRecipe(mask_ & ~constant_);
  discriminator_size_ =
      discriminator_ == 0 ? 0 : 1 << absl::popcount(discriminator_);
  unsigned shift =
      absl::bit_width(static_cast<unsigned>(inst_group_->width())) - 1;
  if (absl::popcount(static_cast<unsigned>(inst_group_->width())) > 1) {
    shift++;
  }
  shift = std::max(shift, 3U);
  if (shift > 6) {
    inst_word_type_ = "\n#error instruction word wider than 64 bits\n";
  } else {
    inst_word_type_ = absl::StrCat("uint", 1 << shift, "_t");
  }
  // Get the recipe for extracting only the varying bits that are part of the
  // mask into a compressed (i.e., bits are all adjacent) value.
  auto recipe = GetExtractionRecipe(discriminator_);
  // Iterate across the possible values of the compressed varying bits.
  for (int i = 0; i < (1 << absl::popcount(discriminator_)); i++) {
    // Create a new group for the current value 'i'.
    auto *encoding_group = new EncodingGroup(
        this, inst_group_, ignore_ | constant_ | discriminator_);
    for (auto *enc : encoding_vec_) {
      // Add all encodings that have value 'i' for the varying bits.
      if (ExtractValue(enc->GetValue(), recipe) != static_cast<unsigned>(i))
        continue;
      encoding_group->AddEncoding(enc);
    }
    // Avoid useless groups and infinite recursion by deleting any groups that
    // are empty and where the all the encodings ended up in the same subgroup.
    if (encoding_group->encoding_vec().empty()) {
      delete encoding_group;
      continue;
    }
    if (encoding_group->encoding_vec().size() == encoding_vec_.size()) {
      delete encoding_group;
      return;
    }
    // Remove the bits used to break up the current group from the mask of the
    // subgroup, as they have already been "used" on the path from the top to
    // the subgroup.
    encoding_group->AdjustMask();
    // If there are still bits that are part of the mask, try to recursively
    // break down the current group.
    if ((encoding_group->varying() | encoding_group->constant()) !=
        encoding_group->mask()) {
      simple_decoding_ = false;
      encoding_group->AddSubGroups();
      // But undo it if the max number of "varying" bits across the groups
      // is less than 2.
      int max = 0;
      for (auto *group : encoding_group->encoding_group_vec_) {
        max = std::max(max, absl::popcount(group->varying()));
      }
      if (max < 2) {
        for (auto *group : encoding_group->encoding_group_vec_) {
          delete group;
        }
        encoding_group->encoding_group_vec_.clear();
      }
    } else {
      encoding_group->discriminator_ =
          encoding_group->mask_ & ~encoding_group->constant_;
      encoding_group->discriminator_recipe_ = GetExtractionRecipe(
          encoding_group->mask_ & ~encoding_group->constant_);
      encoding_group->discriminator_size_ =
          1 << absl::popcount(encoding_group->discriminator_);
      encoding_group->simple_decoding_ = encoding_group->IsSimpleDecode();
      unsigned shift =
          absl::bit_width(static_cast<unsigned>(inst_group_->width())) - 1;
      if (absl::popcount(static_cast<unsigned>(inst_group_->width())) > 1) {
        shift++;
      }
      shift = std::max(shift, 3U);
      if (shift > 6) {
        encoding_group->inst_word_type_ =
            "\n#error instruction word wider than 64 bits\n";
      } else {
        encoding_group->inst_word_type_ =
            absl::StrCat("uint", 1 << shift, "_t");
      }
    }
    encoding_group_vec_.push_back(encoding_group);
  }
}

// Check for collisions of opcodes.
void EncodingGroup::CheckEncodings() const {
  if (encoding_group_vec_.empty() && simple_decoding_) {
    // The encodings are in order of discriminator value, so checking for
    // duplicates are easy.
    int prev_value = -1;
    InstructionEncoding *prev_enc = nullptr;
    for (auto *enc : encoding_vec_) {
      int value = ExtractValue(enc->GetValue(), discriminator_recipe_);
      if (value == prev_value) {
        inst_group_->encoding_info()->error_listener()->semanticError(
            nullptr, absl::StrCat("Duplicate encodings in instruction group ",
                                  inst_group_->name(), ": ", enc->name(),
                                  " and ", prev_enc->name()));
      }
      prev_enc = enc;
      prev_value = value;
    }
  }
  for (auto const *enc_grp : encoding_group_vec_) {
    enc_grp->CheckEncodings();
  }
}

// Emit the initializers of the decode function tables/opcode tables used
// by the decoding functions.
void EncodingGroup::EmitInitializers(absl::string_view name,
                                     std::string *initializers_ptr,
                                     const std::string &opcode_enum) const {
  if (discriminator_size_ == 0) return;
  absl::StrAppend(initializers_ptr, "constexpr int kParseGroup", name,
                  "_Size = ", discriminator_size_, ";\n\n");
  absl::StrAppend(initializers_ptr, "absl::AnyInvocable<", opcode_enum, "(",
                  inst_word_type_,
                  ")>"
                  " parse_group_",
                  name, "[kParseGroup", name, "_Size] = {\n");
  size_t encoding_index = 0;
  // Compute how many function names per line accounting for ',' and white
  // space.
  size_t per_line = 76 / (8 + name.size() + 1 + 2 + 2);
  for (uint64_t i = 0; i < discriminator_size_; i++) {
    uint64_t value = 0xffff'ffff'ffff'ffff;
    if (encoding_index < encoding_group_vec_.size()) {
      value = ExtractValue(
          encoding_group_vec_[encoding_index]->encoding_vec_[0]->GetValue(),
          discriminator_recipe_);
    }
    // Line start indent.
    if ((i % per_line) == 0) {
      absl::StrAppend(initializers_ptr, "   ");
    }
    if (i == value) {
      absl::StrAppend(initializers_ptr, " &Decode", name, "_", absl::Hex(i),
                      ",");
      encoding_index++;
    } else {
      absl::StrAppend(initializers_ptr, " &Decode", inst_group_->name(),
                      "None,");
    }

    // Break the line every 4 items.
    if ((i % per_line) == per_line - 1) {
      absl::StrAppend(initializers_ptr, "\n");
    }
  }
  absl::StrAppend(initializers_ptr, "};\n\n");
  for (auto const *enc_grp : encoding_group_vec_) {
    // Don't create initializers for leaf encoding groups. They don't need them.
    if (enc_grp->encoding_group_vec_.empty()) continue;
    std::string grp_name = absl::StrCat(
        name, "_",
        absl::Hex(ExtractValue(enc_grp->encoding_vec_[0]->GetValue(),
                               discriminator_recipe_)));
    enc_grp->EmitInitializers(grp_name, initializers_ptr, opcode_enum);
  }
}

// Generate the code for the decoders, both the declarations in the .h file as
// well as the definitions in the .cc file.
void EncodingGroup::EmitDecoders(absl::string_view name,
                                 std::string *declarations_ptr,
                                 std::string *definitions_ptr,
                                 const std::string &opcode_enum) const {
  // Generate the decode function signature.
  std::string signature = absl::StrCat(opcode_enum, " Decode", name, "(",
                                       inst_word_type_, " inst_word)");
  absl::StrAppend(declarations_ptr, signature, ";\n");
  absl::StrAppend(definitions_ptr, signature, " {\n");
  // Generate the index extraction code if the discriminator size is > 0.
  std::string index_extraction;
  if (!discriminator_recipe_.empty()) {
    index_extraction = absl::StrCat("  ", inst_word_type_, " index;\n");
    absl::StrAppend(
        &index_extraction,
        WriteExtraction(discriminator_recipe_, "inst_word", "index", "  "));
  }
  // If the encoding group has a constant value, generate that test.
  std::string constant_test;
  if (constant_) {
    uint64_t const_value = encoding_vec_[0]->GetValue() & constant_;
    absl::StrAppend(&constant_test, "  if ((inst_word & 0x",
                    absl::Hex(constant_), ") != 0x", absl::Hex(const_value),
                    ") return ", opcode_enum, "::kNone;\n");
  }
  if (!encoding_group_vec_.empty()) {
    // Create decoder for a non-leaf encoding group. Just extract the index
    // and call the next level decode.
    absl::StrAppend(definitions_ptr, constant_test, index_extraction);
    absl::StrAppend(definitions_ptr, "  return parse_group_", name,
                    "[index](inst_word);\n");
  } else {
    // Create decoder for a leaf encoding group.
    if (simple_decoding_) {
      // Simple decoding means that there are no special values in the opcodes
      // that have to be extracted and checked. A simple table lookup is
      // sufficient.
      if (encoding_vec_.size() == 1) {
        // If the table size is 1, no need to generate the table, just return
        // the opcode.
        absl::StrAppend(definitions_ptr, constant_test, "  return ",
                        opcode_enum, "::k",
                        ToPascalCase(encoding_vec_[0]->name()), ";\n");
      } else {
        // First generate the table of opcodes. The opcodes are in order of the
        // extracted discriminator value. If there are gaps, fill them in with
        // kNone values.
        int count = 1 << absl::popcount(discriminator_);
        absl::StrAppend(definitions_ptr, "  static constexpr ", opcode_enum,
                        " opcodes[", count, "] = {\n");
        int entry = 0;
        for (auto *enc : encoding_vec_) {
          int value = ExtractValue(enc->GetValue(), discriminator_recipe_);
          while (entry < value) {
            absl::StrAppend(definitions_ptr, "    ", opcode_enum, "::kNone,\n");
            entry++;
          }
          absl::StrAppend(definitions_ptr, "    ", opcode_enum, "::k",
                          ToPascalCase(enc->name()), ",\n");
          entry++;
        }
        while (entry < count) {
          absl::StrAppend(definitions_ptr, "    ", opcode_enum, "::kNone,\n");
          entry++;
        }
        absl::StrAppend(definitions_ptr, "  };\n");
        // Return the appropriate opcode.
        absl::StrAppend(definitions_ptr, constant_test, index_extraction);
        absl::StrAppend(definitions_ptr, "  return opcodes[index];\n");
      }
    } else {  // if (simple_decoding_)
      // Non simple decoding requires a sequence of if statements, as some
      // of the opcodes may have additional constraints == or != on bitfields
      // or overlays.
      absl::StrAppend(definitions_ptr, constant_test, index_extraction);
      EmitComplexDecoderBody(definitions_ptr, index_extraction, opcode_enum);
    }
  }

  absl::StrAppend(definitions_ptr, "}\n\n");

  if (encoding_group_vec_.empty()) return;

  for (auto const *enc_grp : encoding_group_vec_) {
    uint64_t value = ExtractValue(enc_grp->encoding_vec_[0]->GetValue(),
                                  discriminator_recipe_);
    std::string grp_name = absl::StrCat(name, "_", absl::Hex(value));
    enc_grp->EmitDecoders(grp_name, declarations_ptr, definitions_ptr,
                          opcode_enum);
  }
}

void EncodingGroup::EmitComplexDecoderBody(
    std::string *definitions_ptr, absl::string_view index_extraction,
    absl::string_view opcode_enum) const {
  // For each instruction in the encoding vec, generate the if statement
  // to see if the instruction is matched.
  absl::flat_hash_set<std::string> extracted;
  // For equal constraints, some can be ignored because those bits are wholly
  // considered by the parent groups or the discriminator.
  for (auto *encoding : encoding_vec_) {
    for (auto *constraint : encoding->equal_constraints()) {
      if (constraint->field != nullptr) {
        // Field constraint.
        Field *field = constraint->field;
        std::string name = absl::StrCat(field->name, "_value");
        if (extracted.contains(name)) continue;
        uint64_t mask = ((1ULL << field->width) - 1);
        // If the bits in the field are already handled by a parent or
        // the discriminator, ignore the field. There is no need to emit
        // a check for it.
        if (((mask << field->low) & ~(ignore_ | discriminator_)) == 0) {
          constraint->can_ignore = true;
        }
        continue;
      }

      // It's an overlay constraint.
      Overlay *overlay = constraint->overlay;
      std::string name = absl::StrCat(overlay->name(), "_value");
      uint64_t mask = 0;
      // Get the bits that correspond to the overlay.
      auto result = overlay->GetBitField((1 << overlay->declared_width()) - 1);
      if (result.ok()) {
        mask = result.value();
      } else {
        absl::StrAppend(definitions_ptr,
                        "#error Internal error: cannot extract value from ",
                        overlay->name());
        continue;
      }
      // If the bits in the overlay are already handled by a parent or
      // the discriminator, ignore the field. There is no need to emit
      // a check for it.
      if ((mask & ~(ignore_ | discriminator_)) == 0) {
        constraint->can_ignore = true;
      }
    }
    // Write any field/overlay extractions needed for the encoding (that
    // haven't already been extracted).
    EmitExtractions(encoding->equal_constraints(), extracted, definitions_ptr);
    EmitExtractions(encoding->equal_extracted_constraints(), extracted,
                    definitions_ptr);
    EmitExtractions(encoding->other_constraints(), extracted, definitions_ptr);

    // Get the discriminator value.
    uint64_t index_value =
        ExtractValue(encoding->GetValue(), discriminator_recipe_);
    // Construct the if statement. First the discriminator value (index).
    std::string condition;
    std::string connector;
    int count = 0;
    // Equal constraints.
    count += EmitConstraintConditions(encoding->equal_constraints(),
                                      "==", connector, &condition);
    count += EmitConstraintConditions(encoding->equal_extracted_constraints(),
                                      "==", connector, &condition);
    count += EmitConstraintConditions(encoding->other_constraints(),
                                      "!=", connector, &condition);
    // Write out the full if statement.
    if (!index_extraction.empty()) {
      // If there is an index extraction, then add that to the if statement.
      // Check to see how many additional conjunctions in the if statement and
      // adjust the number of parentheses required.
      if (count > 0) {
        absl::StrAppend(definitions_ptr, "  if ((index == 0x",
                        absl::Hex(index_value), ") &&\n      ", condition,
                        ")\n");
      } else {
        absl::StrAppend(definitions_ptr, "  if (index == 0x",
                        absl::Hex(index_value), ")\n");
      }
    } else {
      // There is no index extraction. Ensure the number of parentheses are
      // appropriate to the number of conjunctions in the if statement.
      if (count > 1) {
        absl::StrAppend(definitions_ptr, "  if (", condition, ")\n");
      } else {
        absl::StrAppend(definitions_ptr, "  if ", condition, "\n");
      }
    }
    absl::StrAppend(definitions_ptr, "    return ", opcode_enum, "::k",
                    ToPascalCase(encoding->name()), ";\n");
  }
  absl::StrAppend(definitions_ptr, "  return ", opcode_enum, "::kNone;\n");
}

void EncodingGroup::EmitExtractions(
    const std::vector<Constraint *> &constraints,
    absl::flat_hash_set<std::string> &extracted,
    std::string *definitions_ptr) const {
  // Write any field/overlay extractions needed for the constraints.
  // Note, the extractions may be wider than the instruction word width, due
  // to constant bits being added, so make sure to use appropriate type for each
  // extraction.
  for (auto const *constraint : constraints) {
    if (constraint->can_ignore) continue;
    if (constraint->field != nullptr) {
      Field *field = constraint->field;
      std::string name = absl::StrCat(field->name, "_value");
      if (!extracted.contains(name)) {
        std::string data_type;
        if (field->width > inst_group_->width()) {
          auto shift = absl::bit_width(static_cast<unsigned>(field->width)) - 1;
          if (absl::popcount(static_cast<unsigned>(field->width)) > 1) shift++;
          shift = std::max(shift, 3);
          if (shift > 6) {
            LOG(ERROR) << "Field '" << field->name
                       << "' width: " << field->width << " > 64 bits";
            data_type =
                absl::StrCat("#error field width ", field->width, " > 64 bits");
          } else {
            data_type = absl::StrCat("uint", 1 << shift, "_t");
          }
        } else {
          data_type = inst_word_type_;
        }
        uint64_t mask = ((1ULL << field->width) - 1);
        absl::StrAppend(definitions_ptr, "  ", data_type, " ", name,
                        " = (inst_word >> ", field->low, ") & 0x",
                        absl::Hex(mask), ";\n");
        extracted.insert(name);
      }
    } else {
      Overlay *overlay = constraint->overlay;
      std::string name = absl::StrCat(overlay->name(), "_value");
      if (!extracted.contains(name)) {
        auto ovl_width = overlay->declared_width();
        std::string data_type;
        if (ovl_width > inst_group_->width()) {
          auto shift = absl::bit_width(static_cast<unsigned>(ovl_width)) - 1;
          if (absl::popcount(static_cast<unsigned>(ovl_width)) > 1) shift++;
          shift = std::max(shift, 3);
          if (shift > 6) {
            LOG(ERROR) << "Field '" << overlay->name()
                       << "' width: " << ovl_width << " > 64 bits";
            data_type =
                absl::StrCat("#error overlay width ", ovl_width, " > 64 bits");
          } else {
            data_type = absl::StrCat("uint", 1 << shift, "_t");
          }
        } else {
          data_type = inst_word_type_;
        }
        absl::StrAppend(definitions_ptr, "  ", data_type, " ", name, ";\n");
        absl::StrAppend(definitions_ptr,
                        overlay->WriteSimpleValueExtractor("inst_word", name));
        extracted.insert(name);
      }
    }
  }
}

int EncodingGroup::EmitConstraintConditions(
    const std::vector<Constraint *> &constraints, absl::string_view comparison,
    std::string &connector, std::string *condition) const {
  int count = 0;
  for (auto const *constraint : constraints) {
    std::string comparison(kComparison[static_cast<int>(constraint->type)]);
    if (constraint->can_ignore) continue;
    std::string name = absl::StrCat((constraint->field != nullptr)
                                        ? constraint->field->name
                                        : constraint->overlay->name(),
                                    "_value");
    absl::StrAppend(condition, connector, "(", name, " ", comparison, " 0x",
                    absl::Hex(constraint->value), ")");
    connector = " &&\n      ";
    count++;
  }
  return count;
}

// This method dumps statistics about the group useful for development.
// TODO(torerik): remove when no longer needed.
std::string EncodingGroup::DumpGroup(std::string prefix, std::string indent) {
  std::string output;
  auto pad = absl::PadSpec::kZeroPad8;
  uint64_t grp_value;
  if (parent_ == nullptr) {
    auto grp_recipe = GetExtractionRecipe(constant_);
    grp_value = ExtractValue(encoding_vec_[0]->GetValue(), grp_recipe);
  } else {
    auto grp_recipe = GetExtractionRecipe(parent_->mask() & parent_->varying());
    grp_value = ExtractValue(encoding_vec_[0]->GetValue(), grp_recipe);
  }
  uint64_t const_value = encoding_vec_[0]->GetValue() & constant_;
  uint64_t discriminator = mask_ & ~constant_;
  absl::StrAppend(
      &output, "//", indent, prefix, "GROUP:\n//", indent,
      "  mask:          ", absl::Hex(mask_, pad), "\n//", indent,
      "  ignore:        ", absl::Hex(ignore_, pad), "\n//", indent,
      "  constant:      ", absl::Hex(constant_, pad), " : ",
      absl::Hex(const_value, pad), "\n//", indent, indent,
      "  varying:       ", absl::Hex(varying_, pad), "\n//", indent,
      "  value:         ", absl::Hex(grp_value, pad), "\n//", indent,
      "  discriminator: ", absl::Hex(discriminator, pad), "\n//", indent,
      "  simple:       ", simple_decoding_ ? "true\n//" : "false\n//", indent,
      "  leaf:         ",
      encoding_group_vec_.empty() ? "true\n//" : "false\n//",
      "  encodings:     ", encoding_vec_.size(), "\n");
  if (encoding_group_vec_.empty()) {
    auto recipe = GetExtractionRecipe(varying_ & mask_ & ~ignore_);
    for (auto *enc : encoding_vec_) {
      uint64_t value = ExtractValue(enc->GetValue(), recipe);
      absl::StrAppend(&output, "//", indent, "  ", enc->name(), ": ",
                      absl::Hex(enc->GetValue() & varying_ & mask_, pad), " : ",
                      absl::Hex(value, pad), ": ");
      uint64_t mask = enc->GetCombinedMask();  // ^ mask_;
      if (parent_ != nullptr) {
        mask &= ~(parent_->mask());
      }
      if (mask != 0) {
        mask &= ~ignore_;
        absl::StrAppend(&output, absl::Hex(mask, pad), ": ");
      }
      for (auto *constraint : enc->equal_extracted_constraints()) {
        std::string name = constraint->field == nullptr
                               ? constraint->overlay->name()
                               : constraint->field->name;
        absl::StrAppend(&output, " ", name, " == ",
                        absl::Hex(constraint->value, absl::PadSpec::kZeroPad8),
                        " ");
      }
      for (auto *constraint : enc->other_constraints()) {
        std::string name = constraint->field == nullptr
                               ? constraint->overlay->name()
                               : constraint->field->name;
        absl::StrAppend(&output, " ", name, " != ",
                        absl::Hex(constraint->value, absl::PadSpec::kZeroPad8),
                        " ");
      }
      absl::StrAppend(&output, "\n");
    }
  } else {
    for (auto *group : encoding_group_vec_) {
      absl::StrAppend(&output, group->DumpGroup("SUB" + prefix, indent + "  "));
    }
  }
  return output;
}

}  // namespace bin_format
}  // namespace decoder
}  // namespace sim
}  // namespace mpact
