| // 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. |
| |
| #ifndef MPACT_SIM_DECODER_INSTRUCTION_GROUP_H_ |
| #define MPACT_SIM_DECODER_INSTRUCTION_GROUP_H_ |
| |
| #include <cstdint> |
| #include <string> |
| #include <tuple> |
| #include <vector> |
| |
| #include "absl/container/btree_map.h" |
| #include "absl/container/flat_hash_map.h" |
| #include "absl/status/status.h" |
| #include "antlr4-runtime/Token.h" |
| #include "mpact/sim/decoder/bin_encoding_info.h" |
| #include "mpact/sim/decoder/encoding_group.h" |
| |
| namespace mpact { |
| namespace sim { |
| namespace decoder { |
| namespace bin_format { |
| |
| class BinDecoder; |
| class InstructionEncoding; |
| class Format; |
| |
| // An instruction group corresponds to an instruction group in the input file. |
| // Each instruction group gets subdivided into one or more encoding groups that |
| // have constraints on overlapping bits in the instruction word. |
| class InstructionGroup { |
| public: |
| InstructionGroup() = default; |
| InstructionGroup(std::string name, int width, std::string format_name, |
| std::string opcode_enum, BinEncodingInfo* encoding_info); |
| ~InstructionGroup(); |
| |
| InstructionEncoding* AddInstructionEncoding(antlr4::Token* token, |
| 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 |
| // decoding tree. |
| void ProcessEncodings(); |
| // Check encodings for duplicates etc. |
| void CheckEncodings(); |
| // Generate and emit code for decoding this instruction group. |
| std::tuple<std::string, std::string> EmitDecoderCode(); |
| // Collect the encodings for these instructions. |
| void GetInstructionEncodings( |
| absl::btree_map<std::string, std::tuple<uint64_t, int>>& encodings); |
| // Return a string containing information about this instruction group and |
| // how it has been partitioned across encoding groups. |
| std::string WriteGroup(); |
| // Add a specialization to this instruction group. |
| absl::Status AddSpecialization(const std::string& name, |
| const std::string& parent_name, |
| InstructionEncoding* encoding); |
| |
| // Accessors. |
| const std::string& name() const { return name_; } |
| const std::string& format_name() const { return format_name_; } |
| const std::string& opcode_enum() const { return opcode_enum_; } |
| const std::vector<InstructionEncoding*>& encoding_vec() const { |
| return encoding_vec_; |
| } |
| int width() const { return width_; } |
| BinEncodingInfo* encoding_info() const { return encoding_info_; } |
| const absl::flat_hash_map<std::string, InstructionEncoding*>& |
| encoding_name_map() const { |
| return encoding_name_map_; |
| } |
| |
| Format* format() const { return format_; } |
| |
| private: |
| std::string name_; |
| int width_; |
| std::string format_name_; |
| Format* format_; |
| std::string opcode_enum_; |
| BinEncodingInfo* encoding_info_; |
| std::vector<InstructionEncoding*> encoding_vec_; |
| absl::flat_hash_map<std::string, InstructionEncoding*> encoding_name_map_; |
| absl::btree_multimap<uint64_t, InstructionEncoding*> encoding_map_; |
| std::vector<EncodingGroup*> encoding_group_vec_; |
| }; |
| |
| } // namespace bin_format |
| } // namespace decoder |
| } // namespace sim |
| } // namespace mpact |
| |
| #endif // MPACT_SIM_DECODER_INSTRUCTION_GROUP_H_ |