| // 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_ENCODING_H_ |
| #define MPACT_SIM_DECODER_INSTRUCTION_ENCODING_H_ |
| |
| #include <cstdint> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/container/btree_map.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "mpact/sim/decoder/bin_format_visitor.h" |
| #include "mpact/sim/decoder/format.h" |
| #include "mpact/sim/decoder/overlay.h" |
| |
| namespace mpact { |
| namespace sim { |
| namespace decoder { |
| namespace bin_format { |
| |
| // Helper struct to group the information of a constraint (either == or !=). |
| struct Constraint { |
| ConstraintType type; |
| Field* field = nullptr; |
| Overlay* overlay = nullptr; |
| Field* rhs_field = nullptr; |
| Overlay* rhs_overlay = nullptr; |
| bool can_ignore = false; |
| uint64_t value; |
| }; |
| |
| // Class for an individual instruction encoding. The instruction encoding |
| // captures the constraints on field values in an instruction format that |
| // determines the encoding of a specific opcode/instruction. It computes the |
| // constant bit values and masks from these constraints |
| class InstructionEncoding { |
| public: |
| // Disable default constructor and assignment operator. |
| InstructionEncoding() = delete; |
| InstructionEncoding(std::string name, Format* format); |
| InstructionEncoding(const InstructionEncoding& encoding); |
| InstructionEncoding& operator=(const InstructionEncoding&) = delete; |
| ~InstructionEncoding(); |
| |
| // Add a constraint on a field/overlay (in the format associated with the |
| // instruction) needing to be equal to a value. |
| absl::Status AddEqualConstraint(std::string field_name, int64_t value); |
| // Add a constraint on a field/overlay (in the format associated with the |
| // instruction) needing a different comparison (ne, lt, le, etc.). |
| absl::Status AddOtherConstraint(ConstraintType type, std::string field_name, |
| int64_t value); |
| // Add a constraint on a field/overlay (in the format associated with the |
| // instruction) that compares against another field/overlay. |
| absl::Status AddOtherConstraint(ConstraintType type, |
| const std::string& lhs_name, |
| const std::string& rhs_name); |
| |
| // Get the value of the constant bits in the instruction (as defined by the |
| // equal constraints). |
| uint64_t GetValue(); |
| // Get the mask of the instruction word based on the bits that are specified |
| // in the equal constraints. |
| uint64_t GetMask(); |
| // Get the mask of the instruction word based on the bits in both equal and |
| // not equal constraints. |
| uint64_t GetCombinedMask(); |
| // Add specialization to this encoding. |
| absl::Status AddSpecialization(const std::string& name, |
| InstructionEncoding* encoding); |
| bool HasSpecialization() const { return !specializations_.empty(); } |
| |
| // Accessors. |
| const std::string& name() const { return name_; } |
| const std::string& format_name() const { return format_name_; } |
| // Return the vector of constraints on the values of this encoding. These |
| // constraints determine the value that a masked set of bits have to be equal |
| // to in order to match this encoding. |
| const std::vector<Constraint*>& equal_constraints() const { |
| return equal_constraints_; |
| } |
| // Additionally, overlays may add constant bits to field references. These |
| // constraints have to be compared one by one after performing an overlay |
| // extraction that adds in the bits as specified in the overlay. Thus, they |
| // cannot be used in a simple mask and compare. |
| const std::vector<Constraint*>& equal_extracted_constraints() const { |
| return equal_extracted_constraints_; |
| } |
| // The vector of not-equal, greater, less, etc., constraints that have to be |
| // satisfied for an instruction to match this encoding. |
| const std::vector<Constraint*>& other_constraints() const { |
| return other_constraints_; |
| } |
| |
| const absl::btree_map<std::string, InstructionEncoding*>& specializations() |
| const { |
| return specializations_; |
| } |
| |
| Format* format() const { return format_; } |
| |
| private: |
| // Internal helper to create and check a constraint. |
| absl::StatusOr<Constraint*> CreateConstraint(ConstraintType type, |
| std::string lhs_name, |
| std::string rhs_name); |
| |
| absl::StatusOr<Constraint*> CreateConstraint(ConstraintType type, |
| std::string field_name, |
| int64_t value); |
| // Recomputes the masks and values. |
| absl::Status ComputeMaskAndValue(); |
| |
| std::string name_; |
| std::string format_name_; |
| Format* format_ = nullptr; |
| std::vector<Constraint*> equal_constraints_; |
| std::vector<Constraint*> equal_extracted_constraints_; |
| std::vector<Constraint*> other_constraints_; |
| bool mask_set_ = false; |
| uint64_t mask_ = 0; |
| uint64_t other_mask_ = 0; |
| uint64_t extracted_mask_ = 0; |
| uint64_t value_ = 0; |
| absl::btree_map<std::string, InstructionEncoding*> specializations_; |
| }; |
| |
| } // namespace bin_format |
| } // namespace decoder |
| } // namespace sim |
| } // namespace mpact |
| |
| #endif // MPACT_SIM_DECODER_INSTRUCTION_ENCODING_H_ |