This fixes two issues: In the .isa parser, backslashes in disasm formats are filtered out as intended. In the .bin_fmt parser, warnings are given if binary constants in constraints are of different width than the field it is compared to. PiperOrigin-RevId: 671858831 Change-Id: Icf660504726eb02b64c54ad0111756d653122246
diff --git a/mpact/sim/decoder/bin_format_visitor.cc b/mpact/sim/decoder/bin_format_visitor.cc index dbaef12..605b0f5 100644 --- a/mpact/sim/decoder/bin_format_visitor.cc +++ b/mpact/sim/decoder/bin_format_visitor.cc
@@ -763,7 +763,7 @@ if (format == nullptr) return; // Add constraints to the instruction encoding. for (auto *constraint : ctx->field_constraint_list()->field_constraint()) { - VisitConstraint(constraint, inst_encoding); + VisitConstraint(format, constraint, inst_encoding); } } @@ -921,7 +921,7 @@ return generated; } -void BinFormatVisitor::VisitConstraint(FieldConstraintCtx *ctx, +void BinFormatVisitor::VisitConstraint(Format *format, FieldConstraintCtx *ctx, InstructionEncoding *inst_encoding) { if (ctx == nullptr) return; if (inst_encoding == nullptr) return; @@ -929,6 +929,29 @@ // Constraints are based on field names ==/!=/>/>=/</<= to a value. std::string field_name = ctx->field_name->getText(); std::string op = ctx->constraint_op()->getText(); + // If the number is binary, let's get its length too and check against the + // field width. + if (ctx->number()->BIN_NUMBER() != nullptr) { + int length = ParseBinaryNum(ctx->number()->BIN_NUMBER()).width; + auto *field = format->GetField(field_name); + auto *overlay = format->GetOverlay(field_name); + if (field != nullptr) { + if (field->width != length) { + error_listener_->semanticWarning( + ctx->start, + absl::StrCat("Field '", field_name, "' has width ", field->width, + " but constraint value is ", length, " bits")); + } + } else if (overlay != nullptr) { + if (overlay->computed_width() != length) { + error_listener_->semanticWarning( + ctx->start, + absl::StrCat("Overlay '", field_name, "' has width ", + overlay->computed_width(), " but constraint value is ", + length, " bits")); + } + } + } int value = ConvertToInt(ctx->number()); absl::Status status; if (op == "==") {
diff --git a/mpact/sim/decoder/bin_format_visitor.h b/mpact/sim/decoder/bin_format_visitor.h index fb41348..68ac713 100644 --- a/mpact/sim/decoder/bin_format_visitor.h +++ b/mpact/sim/decoder/bin_format_visitor.h
@@ -124,7 +124,7 @@ std::string GenerateInstructionDefList( const std::vector<RangeAssignmentInfo *> &range_info_vec, int index, const std::string &template_str_in) const; - void VisitConstraint(FieldConstraintCtx *ctx, + void VisitConstraint(Format *format, FieldConstraintCtx *ctx, InstructionEncoding *inst_encoding); // Accessors.
diff --git a/mpact/sim/decoder/instruction_set_visitor.cc b/mpact/sim/decoder/instruction_set_visitor.cc index c8acd80..31f9792 100644 --- a/mpact/sim/decoder/instruction_set_visitor.cc +++ b/mpact/sim/decoder/instruction_set_visitor.cc
@@ -16,11 +16,12 @@ #include <cctype> #include <cstddef> -#include <filesystem> +#include <filesystem> // NOLINT: third party. #include <fstream> #include <iostream> #include <istream> #include <memory> +#include <new> #include <optional> #include <string> #include <utility> @@ -214,7 +215,7 @@ PerformBundleReferenceChecks(instruction_set, bundle_ref); } // Verify that all the slot uses were declared. - for (auto [slot_name, instance_vec] : bundle->slot_uses()) { + for (auto &[slot_name, instance_vec] : bundle->slot_uses()) { Slot *slot = instruction_set->GetSlot(slot_name); // Verify that the instance number of the slot falls within valid range. for (auto &instance_number : instance_vec) { @@ -1701,8 +1702,13 @@ DisasmFormat *disasm_fmt = new DisasmFormat(); while ((pos != std::string::npos) && ((pos = format.find_first_of('%', pos)) != std::string::npos)) { - disasm_fmt->format_fragment_vec.push_back(format.substr(prev, pos - prev)); std::string text = format.substr(prev, pos - prev); + std::string new_text; + for (auto &c : text) { + if (c == '\\') continue; + new_text.push_back(c); + } + disasm_fmt->format_fragment_vec.push_back(new_text); pos++; if (pos >= length) break; @@ -1790,7 +1796,17 @@ absl::StrCat("Unexpected end of format string in '", format, "'")); } if (prev != std::string::npos) { - disasm_fmt->format_fragment_vec.push_back(format.substr(prev)); + std::string text = format.substr(prev); + std::string new_text; + for (auto &c : text) { + if (c == '\\') continue; + new_text.push_back(c); + } + disasm_fmt->format_fragment_vec.push_back(new_text); + } + std::string str; + for (auto &s : disasm_fmt->format_fragment_vec) { + absl::StrAppend(&str, s, ":"); } int width = 0; auto count = inst->disasm_format_vec().size();