blob: e7a7f46d83ce71f9bf4cc62d325959c837ee4533 [file]
// 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_