No public description PiperOrigin-RevId: 875775834 Change-Id: Ia70363c8696757c613d3cd0ed7a844c3a68d4890
diff --git a/mpact/sim/decoder/BinFormat.g4 b/mpact/sim/decoder/BinFormat.g4 index 17d6480..af4437d 100644 --- a/mpact/sim/decoder/BinFormat.g4 +++ b/mpact/sim/decoder/BinFormat.g4
@@ -141,12 +141,15 @@ // An instruction encoding contains a name, the format it refers to, and a list // of binary field constraints. instruction_def - : name=IDENT ':' format_name=IDENT ':' field_constraint_list ';' + : duplicate? name=IDENT ':' format_name=IDENT ':' field_constraint_list ';' | generate=GENERATE '(' range_assignment (',' range_assignment)* ')' '{' generator_instruction_def_list '}' ';' | name=IDENT ':' SPECIALIZES parent=IDENT ':' field_constraint_list ';' ; +duplicate + : '!' + ; range_assignment : IDENT '=' '[' gen_value (',' gen_value)* ']'
diff --git a/mpact/sim/decoder/bin_format_visitor.cc b/mpact/sim/decoder/bin_format_visitor.cc index 0dbd7c5..03729b6 100644 --- a/mpact/sim/decoder/bin_format_visitor.cc +++ b/mpact/sim/decoder/bin_format_visitor.cc
@@ -1044,8 +1044,9 @@ ") differs from the declared width of the instruction group (", inst_group->width(), ")")); } - auto* inst_encoding = - inst_group->AddInstructionEncoding(ctx->format_name, name, format); + bool is_duplicate = ctx->duplicate() != nullptr; + auto* inst_encoding = inst_group->AddInstructionEncoding( + ctx->format_name, name, format, is_duplicate); if (format == nullptr) return; // Add constraints to the instruction encoding. for (auto* constraint : ctx->field_constraint_list()->field_constraint()) { @@ -1467,7 +1468,8 @@ if (iter != grp_ptr->encoding_name_map().end()) { auto* parent_encoding = iter->second; auto* format = parent_encoding->format(); - auto* inst_encoding = new InstructionEncoding(name, format); + auto* inst_encoding = + new InstructionEncoding(name, format, /*is_duplicate=*/false); for (auto* constraint : ctx->field_constraint_list()->field_constraint()) { context_file_map_.insert({constraint, file_index});
diff --git a/mpact/sim/decoder/instruction_encoding.cc b/mpact/sim/decoder/instruction_encoding.cc index c57afa9..4940273 100644 --- a/mpact/sim/decoder/instruction_encoding.cc +++ b/mpact/sim/decoder/instruction_encoding.cc
@@ -29,8 +29,9 @@ namespace decoder { namespace bin_format { -InstructionEncoding::InstructionEncoding(std::string name, Format* format) - : name_(name), format_(format) { +InstructionEncoding::InstructionEncoding(std::string name, Format* format, + bool is_duplicate) + : name_(name), format_(format), is_duplicate_(is_duplicate) { if (format) format_name_ = format->name(); } @@ -43,7 +44,8 @@ mask_(encoding.mask_), other_mask_(encoding.other_mask_), extracted_mask_(encoding.extracted_mask_), - value_(encoding.value_) { + value_(encoding.value_), + is_duplicate_(encoding.is_duplicate_) { // Copy construct each of the constraints. for (auto* constraint : encoding.equal_constraints_) { equal_constraints_.push_back(new Constraint(*constraint));
diff --git a/mpact/sim/decoder/instruction_encoding.h b/mpact/sim/decoder/instruction_encoding.h index 4dcda6e..2ee7079 100644 --- a/mpact/sim/decoder/instruction_encoding.h +++ b/mpact/sim/decoder/instruction_encoding.h
@@ -50,7 +50,7 @@ public: // Disable default constructor and assignment operator. InstructionEncoding() = delete; - InstructionEncoding(std::string name, Format* format); + InstructionEncoding(std::string name, Format* format, bool is_duplicate); InstructionEncoding(const InstructionEncoding& encoding); InstructionEncoding& operator=(const InstructionEncoding&) = delete; ~InstructionEncoding(); @@ -111,6 +111,9 @@ Format* format() const { return format_; } + void set_is_duplicate(bool is_duplicate) { is_duplicate_ = is_duplicate; } + bool is_duplicate() const { return is_duplicate_; } + private: // Internal helper to create and check a constraint. absl::StatusOr<Constraint*> CreateConstraint(ConstraintType type, @@ -135,6 +138,10 @@ uint64_t extracted_mask_ = 0; uint64_t value_ = 0; absl::btree_map<std::string, InstructionEncoding*> specializations_; + // True if this encoding is declared as using a duplicate of another opcode + // name. This is used to suppress warning messages for encodings which + // purposefully have the same opcode name as another encoding. + bool is_duplicate_ = false; }; } // namespace bin_format
diff --git a/mpact/sim/decoder/instruction_group.cc b/mpact/sim/decoder/instruction_group.cc index 294a5da..e3684ea 100644 --- a/mpact/sim/decoder/instruction_group.cc +++ b/mpact/sim/decoder/instruction_group.cc
@@ -67,7 +67,7 @@ // has the correct width, and that the format the encoding is defined in, or // derives from the format associated with the instruction group. InstructionEncoding* InstructionGroup::AddInstructionEncoding( - antlr4::Token* token, std::string name, Format* format) { + antlr4::Token* token, std::string name, Format* format, bool is_duplicate) { if ((format != nullptr) && ((format_ == nullptr) || (!format->IsDerivedFrom(format_)))) { encoding_info_->error_listener()->semanticError( @@ -83,19 +83,20 @@ // Warn if the instruction name has been seen before. It might be fully valid // that an instruction name has multiple encodings, but warn about it, in // case it is an error. - if (encoding_name_map_.contains(name)) { + if (encoding_name_map_.contains(name) && !is_duplicate) { encoding_info_->error_listener()->semanticWarning( token, absl::StrCat("Duplicate instruction opcode name '", name, "' in group '", this->name(), "'.")); } - auto* encoding = new InstructionEncoding(name, format); + auto* encoding = new InstructionEncoding(name, format, is_duplicate); encoding_vec_.push_back(encoding); encoding_name_map_.insert(std::make_pair(name, encoding)); return encoding; } void InstructionGroup::AddInstructionEncoding(InstructionEncoding* encoding) { - if (encoding_name_map_.contains(encoding->name())) { + if (encoding_name_map_.contains(encoding->name()) && + !encoding->is_duplicate()) { encoding_info_->error_listener()->semanticWarning( nullptr, absl::StrCat("Duplicate instruction opcode name '", encoding->name(), "' in group '", name(), "'."));
diff --git a/mpact/sim/decoder/instruction_group.h b/mpact/sim/decoder/instruction_group.h index 943c1f5..e7a7f46 100644 --- a/mpact/sim/decoder/instruction_group.h +++ b/mpact/sim/decoder/instruction_group.h
@@ -47,7 +47,8 @@ ~InstructionGroup(); InstructionEncoding* AddInstructionEncoding(antlr4::Token* token, - std::string name, Format* format); + std::string name, Format* format, + bool is_duplicate = false); void AddInstructionEncoding(InstructionEncoding* encoding); // Process the encodings in the group, partitioning them into subgroups // according to their opcode bits to make it easy to generate a hierarchical
diff --git a/mpact/sim/decoder/test/instruction_encoding_test.cc b/mpact/sim/decoder/test/instruction_encoding_test.cc index 42d935c..3380314 100644 --- a/mpact/sim/decoder/test/instruction_encoding_test.cc +++ b/mpact/sim/decoder/test/instruction_encoding_test.cc
@@ -60,7 +60,8 @@ (void)overlay->AddFieldReference("rs1"); (void)overlay->AddFieldReference("rd"); (void)i_type_fmt_->ComputeAndCheckFormatWidth(); - i_type_ = new InstructionEncoding(kITypeEncodingName, i_type_fmt_); + i_type_ = new InstructionEncoding(kITypeEncodingName, i_type_fmt_, + /*is_duplicate*/ false); (void)i_type_fmt_->AddFieldOverlay("extract", /*is_signed*/ false, 12); overlay = i_type_fmt_->GetOverlay("extract"); (void)overlay->AddFieldReference("rs1");