blob: 0722c3e31f7198332ee4c9843d2fc94b9dd4e8bf [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.
#ifndef THIRD_PARTY_MPACT_RISCV_TEST_RISCV_GETTERS_ZFH_H_
#define THIRD_PARTY_MPACT_RISCV_TEST_RISCV_GETTERS_ZFH_H_
#include <cstdint>
#include <string>
#include "absl/strings/str_cat.h"
#include "mpact/sim/generic/immediate_operand.h"
#include "mpact/sim/generic/literal_operand.h"
#include "mpact/sim/generic/type_helpers.h"
#include "riscv/riscv_encoding_common.h"
#include "riscv/riscv_getter_helpers.h"
#include "riscv/riscv_getters_vector.h"
#include "riscv/riscv_register.h"
#include "riscv/riscv_register_aliases.h"
namespace mpact {
namespace sim {
namespace riscv {
using ::mpact::sim::generic::operator*; // NOLINT: is used below (clang error).
template <typename Enum, typename Extractors, typename IntegerRegister>
void AddRiscVZfhSourceScalarGetters(SourceOpGetterMap &getter_map,
RiscVEncodingCommon *common) {
// Source operand getters.
Insert(getter_map, *Enum::kRs1, [common]() -> SourceOperandInterface * {
int num = Extractors::Inst32Format::ExtractRs1(common->inst_word());
if (num == 0) return new generic::IntLiteralOperand<0>({1});
return GetRegisterSourceOp<IntegerRegister>(
common->state(), absl::StrCat(RiscVState::kXregPrefix, num),
kXRegisterAliases[num]);
});
// I in IImm12 stands for IType instructions.
Insert(getter_map, *Enum::kIImm12, [common]() -> SourceOperandInterface * {
const auto num = Extractors::IType::ExtractImm12(common->inst_word());
return new generic::ImmediateOperand<int32_t>(num);
});
// S in SImm12 stands for SType instructions.
Insert(getter_map, *Enum::kSImm12, [common]() -> SourceOperandInterface * {
const auto num = Extractors::SType::ExtractSImm(common->inst_word());
return new generic::ImmediateOperand<int32_t>(num);
});
Insert(getter_map, *Enum::kRm, [common]() -> SourceOperandInterface * {
const auto num =
Extractors::Inst32Format::ExtractFunc3(common->inst_word());
return new generic::ImmediateOperand<uint8_t>(num);
});
}
template <typename Enum, typename Extractors, typename FloatRegister>
void AddRiscVZfhSourceFloatGetters(SourceOpGetterMap &getter_map,
RiscVEncodingCommon *common) {
// Source operand getters.
Insert(getter_map, *Enum::kFrs1, [common]() -> SourceOperandInterface * {
int num = Extractors::Inst32Format::ExtractRs1(common->inst_word());
return GetRegisterSourceOp<FloatRegister>(
common->state(), absl::StrCat(RiscVState::kFregPrefix, num),
kFRegisterAliases[num]);
});
Insert(getter_map, *Enum::kFrs2, [common]() -> SourceOperandInterface * {
int num = Extractors::Inst32Format::ExtractRs2(common->inst_word());
return GetRegisterSourceOp<FloatRegister>(
common->state(), absl::StrCat(RiscVState::kFregPrefix, num),
kFRegisterAliases[num]);
});
Insert(getter_map, *Enum::kFrs3, [common]() -> SourceOperandInterface * {
int num = Extractors::Inst32Format::ExtractRs3(common->inst_word());
return GetRegisterSourceOp<FloatRegister>(
common->state(), absl::StrCat(RiscVState::kFregPrefix, num),
kFRegisterAliases[num]);
});
}
template <typename Enum, typename Extractors, typename IntegerRegister>
void AddRiscVZfhDestScalarGetters(DestOpGetterMap &getter_map,
RiscVEncodingCommon *common) {
// Destination operand getters.
Insert(getter_map, *Enum::kRd,
[common](int latency) -> DestinationOperandInterface * {
auto num = Extractors::Inst32Format::ExtractRd(common->inst_word());
std::string name = absl::StrCat(RiscVState::kXregPrefix, num);
return mpact::sim::riscv::GetRegisterDestinationOp<IntegerRegister>(
common->state(), name, latency);
});
Insert(getter_map, *Enum::kFflags,
[common](int latency) -> DestinationOperandInterface * {
return GetCSRSetBitsDestinationOp<uint32_t>(common->state(),
"fflags", latency, "");
});
}
template <typename Enum, typename Extractors, typename FloatRegister>
void AddRiscVZfhDestFloatGetters(DestOpGetterMap &getter_map,
RiscVEncodingCommon *common) {
// Destination operand getters.
Insert(getter_map, *Enum::kFrd,
[common](int latency) -> DestinationOperandInterface * {
auto num = Extractors::Inst32Format::ExtractRd(common->inst_word());
std::string name = absl::StrCat(RiscVState::kFregPrefix, num);
return mpact::sim::riscv::GetRegisterDestinationOp<FloatRegister>(
common->state(), name, latency);
});
}
// This function is used to add the simple resource getters to the given
// "getter map". The function is templated on the enum type that defines the
// simple resource types, the Extractors type that defines the bit
// extraction functions, and the IntRegister and FpRegister types that are used
// to construct the register operand.
template <typename Enum, typename Extractors>
void AddRiscVZfhSimpleResourceGetters(SimpleResourceGetterMap &getter_map,
RiscVEncodingCommon *common) {
// TODO(julianmb): Add resource getters when appropriate.
}
} // namespace riscv
} // namespace sim
} // namespace mpact
#endif // THIRD_PARTY_MPACT_RISCV_TEST_RISCV_GETTERS_ZFH_H_