| // Copyright 2024 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_CHERIOT_CHERIOT_RVV_GETTERS_H_ |
| #define MPACT_CHERIOT_CHERIOT_RVV_GETTERS_H_ |
| |
| #include <cstdint> |
| |
| #include "absl/container/flat_hash_map.h" |
| #include "absl/functional/any_invocable.h" |
| #include "cheriot/cheriot_getter_helpers.h" |
| #include "cheriot/cheriot_state.h" |
| #include "cheriot/cheriot_vector_true_operand.h" |
| #include "cheriot/riscv_cheriot_encoding_common.h" |
| #include "mpact/sim/generic/immediate_operand.h" |
| #include "mpact/sim/generic/literal_operand.h" |
| #include "mpact/sim/generic/operand_interface.h" |
| #include "riscv//riscv_register.h" |
| |
| namespace mpact { |
| namespace sim { |
| namespace cheriot { |
| |
| using ::mpact::sim::cheriot::RiscVCheriotEncodingCommon; |
| using ::mpact::sim::generic::DestinationOperandInterface; |
| using ::mpact::sim::generic::ImmediateOperand; |
| using ::mpact::sim::generic::IntLiteralOperand; |
| using ::mpact::sim::generic::SourceOperandInterface; |
| using ::mpact::sim::riscv::RV32VectorTrueOperand; |
| using ::mpact::sim::riscv::RVVectorRegister; |
| |
| using SourceOpGetterMap = |
| absl::flat_hash_map<int, absl::AnyInvocable<SourceOperandInterface *()>>; |
| using DestOpGetterMap = |
| absl::flat_hash_map<int, |
| absl::AnyInvocable<DestinationOperandInterface *(int)>>; |
| |
| template <typename Enum, typename Extractors> |
| void AddCheriotRVVSourceGetters(SourceOpGetterMap &getter_map, |
| RiscVCheriotEncodingCommon *common) { |
| Insert(getter_map, *Enum::kConst1, []() -> SourceOperandInterface * { |
| return new IntLiteralOperand<1>(); |
| }); |
| Insert(getter_map, *Enum::kConst2, []() -> SourceOperandInterface * { |
| return new IntLiteralOperand<2>(); |
| }); |
| Insert(getter_map, *Enum::kConst4, []() -> SourceOperandInterface * { |
| return new IntLiteralOperand<4>(); |
| }); |
| Insert(getter_map, *Enum::kConst8, []() -> SourceOperandInterface * { |
| return new IntLiteralOperand<8>(); |
| }); |
| Insert(getter_map, *Enum::kNf, [common]() -> SourceOperandInterface * { |
| auto imm = Extractors::VMem::ExtractNf(common->inst_word()); |
| return new ImmediateOperand<uint32_t>(imm); |
| }); |
| Insert(getter_map, *Enum::kSimm5, [common]() -> SourceOperandInterface * { |
| auto imm = Extractors::VArith::ExtractSimm5(common->inst_word()); |
| return new ImmediateOperand<uint32_t>(imm); |
| }); |
| Insert(getter_map, *Enum::kUimm5, [common]() -> SourceOperandInterface * { |
| auto imm = Extractors::VArith::ExtractUimm5(common->inst_word()); |
| return new ImmediateOperand<int32_t>(imm); |
| }); |
| Insert(getter_map, *Enum::kVd, [common]() -> SourceOperandInterface * { |
| auto num = Extractors::VArith::ExtractVd(common->inst_word()); |
| return GetVectorRegisterSourceOp<RVVectorRegister>(common->state(), num); |
| }); |
| Insert(getter_map, *Enum::kVm, [common]() -> SourceOperandInterface * { |
| auto vm = Extractors::VArith::ExtractVm(common->inst_word()); |
| return new ImmediateOperand<uint32_t>(vm); |
| }); |
| Insert(getter_map, *Enum::kVmask, [common]() -> SourceOperandInterface * { |
| auto vm = Extractors::VArith::ExtractVm(common->inst_word()); |
| if (vm == 1) { |
| // Unmasked, return the True mask. |
| return new CheriotVectorTrueOperand(common->state()); |
| } |
| // Masked. Return the mask register. |
| return GetVectorMaskRegisterSourceOp<RVVectorRegister>(common->state(), 0); |
| }); |
| Insert(getter_map, *Enum::kVmaskTrue, [common]() -> SourceOperandInterface * { |
| return new CheriotVectorTrueOperand(common->state()); |
| }); |
| Insert(getter_map, *Enum::kVs1, [common]() -> SourceOperandInterface * { |
| auto num = Extractors::VArith::ExtractVs1(common->inst_word()); |
| return GetVectorRegisterSourceOp<RVVectorRegister>(common->state(), num); |
| }); |
| Insert(getter_map, *Enum::kVs2, [common]() -> SourceOperandInterface * { |
| auto num = Extractors::VArith::ExtractVs2(common->inst_word()); |
| return GetVectorRegisterSourceOp<RVVectorRegister>(common->state(), num); |
| }); |
| Insert(getter_map, *Enum::kVs3, [common]() -> SourceOperandInterface * { |
| auto num = Extractors::VMem::ExtractVs3(common->inst_word()); |
| return GetVectorRegisterSourceOp<RVVectorRegister>(common->state(), num); |
| }); |
| Insert(getter_map, *Enum::kZimm10, [common]() -> SourceOperandInterface * { |
| auto imm = Extractors::VConfig::ExtractZimm10(common->inst_word()); |
| return new ImmediateOperand<uint32_t>(imm); |
| }); |
| Insert(getter_map, *Enum::kZimm11, [common]() -> SourceOperandInterface * { |
| auto imm = Extractors::VConfig::ExtractZimm11(common->inst_word()); |
| return new ImmediateOperand<uint32_t>(imm); |
| }); |
| } |
| |
| template <typename Enum, typename Extractors> |
| void AddCheriotRVVDestGetters(DestOpGetterMap &getter_map, |
| RiscVCheriotEncodingCommon *common) { |
| Insert(getter_map, Enum::kVd, |
| [common](int latency) -> DestinationOperandInterface * { |
| auto num = Extractors::VArith::ExtractVd(common->inst_word()); |
| return GetVectorRegisterDestinationOp<RVVectorRegister>( |
| common->state(), latency, num); |
| }); |
| } |
| |
| } // namespace cheriot |
| } // namespace sim |
| } // namespace mpact |
| |
| #endif // MPACT_CHERIOT_CHERIOT_RVV_GETTERS_H_ |