blob: 7e02c18c994cc1b1ea9c641e1b5199b266468670 [file]
// Copyright 2025 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.
#include "riscv/riscv64g_bin_encoder_interface.h"
#include <cstdint>
#include <tuple>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "mpact/sim/generic/type_helpers.h"
#include "mpact/sim/util/asm/resolver_interface.h"
#include "riscv/riscv64g_bin_encoder.h"
#include "riscv/riscv64g_encoder.h"
#include "riscv/riscv64g_enums.h"
#include "riscv/riscv_bin_setters.h"
namespace mpact {
namespace sim {
namespace riscv {
namespace isa64 {
using ::mpact::sim::generic::operator*; // NOLINT(misc-unused-using-decls)
using ::mpact::sim::util::assembler::ResolverInterface;
RiscV64GBinEncoderInterface::RiscV64GBinEncoderInterface() {
AddRiscvSourceOpBinSetters<SourceOpEnum, OpMap, encoding64::Encoder>(
source_op_map_);
AddRiscvDestOpBinSetters<DestOpEnum, OpMap, encoding64::Encoder>(
dest_op_map_);
AddRiscvSourceOpRelocationSetters<OpcodeEnum, SourceOpEnum, RelocationMap>(
relocation_source_op_map_);
}
absl::StatusOr<std::tuple<uint64_t, int>>
RiscV64GBinEncoderInterface::GetOpcodeEncoding(SlotEnum slot, int entry,
OpcodeEnum opcode,
ResolverInterface *resolver) {
return encoding64::kOpcodeEncodings->at(opcode);
}
absl::StatusOr<uint64_t> RiscV64GBinEncoderInterface::GetSrcOpEncoding(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, SourceOpEnum source_op, int source_num,
ResolverInterface *resolver) {
auto iter = source_op_map_.find(*source_op);
if (iter == source_op_map_.end()) {
return absl::NotFoundError(absl::StrCat(
"Source operand not found for op enum value ", *source_op));
}
return iter->second(address, text, resolver);
}
absl::Status RiscV64GBinEncoderInterface::AppendSrcOpRelocation(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, SourceOpEnum source_op, int source_num,
ResolverInterface *resolver, std::vector<RelocationInfo> &relocations) {
auto iter = relocation_source_op_map_.find(std::tie(opcode, source_op));
if (iter == relocation_source_op_map_.end()) return absl::OkStatus();
return iter->second(address, text, resolver, relocations);
}
absl::StatusOr<uint64_t> RiscV64GBinEncoderInterface::GetDestOpEncoding(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, DestOpEnum dest_op, int dest_num,
ResolverInterface *resolver) {
auto iter = dest_op_map_.find(*dest_op);
if (iter == dest_op_map_.end()) {
return absl::NotFoundError(
absl::StrCat("Dest operand not found for op enum value ", *dest_op));
}
return iter->second(address, text, resolver);
}
absl::StatusOr<uint64_t> RiscV64GBinEncoderInterface::GetListDestOpEncoding(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, ListDestOpEnum dest_op, int dest_num,
ResolverInterface *resolver) {
auto iter = list_dest_op_map_.find(*dest_op);
if (iter == list_dest_op_map_.end()) {
return absl::NotFoundError(absl::StrCat(
"List dest operand not found for op enum value ", *dest_op));
}
return iter->second(address, text, resolver);
}
absl::Status RiscV64GBinEncoderInterface::AppendDestOpRelocation(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, DestOpEnum dest_op, int dest_num,
ResolverInterface *resolver, std::vector<RelocationInfo> &relocations) {
// There are no destination operands that require relocation.
return absl::OkStatus();
}
absl::StatusOr<uint64_t> RiscV64GBinEncoderInterface::GetListSrcOpEncoding(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, ListSourceOpEnum source_op, int source_num,
ResolverInterface *resolver) {
auto iter = list_source_op_map_.find(*source_op);
if (iter == list_source_op_map_.end()) {
return absl::NotFoundError(absl::StrCat(
"List source operand not found for op enum value ", *source_op));
}
return iter->second(address, text, resolver);
}
absl::StatusOr<uint64_t> RiscV64GBinEncoderInterface::GetPredOpEncoding(
uint64_t address, absl::string_view text, SlotEnum slot, int entry,
OpcodeEnum opcode, PredOpEnum pred_op, ResolverInterface *resolver) {
auto iter = pred_op_map_.find(*pred_op);
if (iter == pred_op_map_.end()) {
return absl::NotFoundError(absl::StrCat(
"Predicate operand not found for op enum value ", *pred_op));
}
return iter->second(address, text, resolver);
}
} // namespace isa64
} // namespace riscv
} // namespace sim
} // namespace mpact