Added strings to access enum names of generated Op and Resource enums.
Added tests to verify that each encoding class covers all the enums.
PiperOrigin-RevId: 694634449
Change-Id: Ie2ed3764755df436ad9d68c925c45b6f01086dd7
diff --git a/cheriot/riscv_cheriot_encoding.h b/cheriot/riscv_cheriot_encoding.h
index b5af035..7bcaa72 100644
--- a/cheriot/riscv_cheriot_encoding.h
+++ b/cheriot/riscv_cheriot_encoding.h
@@ -42,6 +42,11 @@
class RiscVCheriotEncoding : public RiscVCheriotEncodingCommon,
public RiscVCheriotEncodingBase {
public:
+ using SourceOpGetterMap =
+ absl::flat_hash_map<int, absl::AnyInvocable<SourceOperandInterface *()>>;
+ using DestOpGetterMap = absl::flat_hash_map<
+ int, absl::AnyInvocable<DestinationOperandInterface *(int)>>;
+
explicit RiscVCheriotEncoding(CheriotState *state);
// Parses an instruction and determines the opcode.
@@ -92,12 +97,10 @@
return 0;
}
- private:
- using SourceOpGetterMap =
- absl::flat_hash_map<int, absl::AnyInvocable<SourceOperandInterface *()>>;
- using DestOpGetterMap = absl::flat_hash_map<
- int, absl::AnyInvocable<DestinationOperandInterface *(int)>>;
+ const SourceOpGetterMap &source_op_getters() { return source_op_getters_; }
+ const DestOpGetterMap &dest_op_getters() { return dest_op_getters_; }
+ private:
SourceOpGetterMap source_op_getters_;
DestOpGetterMap dest_op_getters_;
OpcodeEnum opcode_;
diff --git a/cheriot/riscv_cheriot_rvv_encoding.h b/cheriot/riscv_cheriot_rvv_encoding.h
index 2ac1bde..1aa0907 100644
--- a/cheriot/riscv_cheriot_rvv_encoding.h
+++ b/cheriot/riscv_cheriot_rvv_encoding.h
@@ -42,6 +42,11 @@
class RiscVCheriotRVVEncoding : public RiscVCheriotEncodingCommon,
public RiscVCheriotRVVEncodingBase {
public:
+ using SourceOpGetterMap =
+ absl::flat_hash_map<int, absl::AnyInvocable<SourceOperandInterface *()>>;
+ using DestOpGetterMap = absl::flat_hash_map<
+ int, absl::AnyInvocable<DestinationOperandInterface *(int)>>;
+
explicit RiscVCheriotRVVEncoding(CheriotState *state);
// Parses an instruction and determines the opcode.
@@ -92,12 +97,10 @@
return 0;
}
- private:
- using SourceOpGetterMap =
- absl::flat_hash_map<int, absl::AnyInvocable<SourceOperandInterface *()>>;
- using DestOpGetterMap = absl::flat_hash_map<
- int, absl::AnyInvocable<DestinationOperandInterface *(int)>>;
+ const SourceOpGetterMap &source_op_getters() { return source_op_getters_; }
+ const DestOpGetterMap &dest_op_getters() { return dest_op_getters_; }
+ private:
SourceOpGetterMap source_op_getters_;
DestOpGetterMap dest_op_getters_;
OpcodeEnum opcode_;
diff --git a/cheriot/test/BUILD b/cheriot/test/BUILD
index 4912d0a..3616d1d 100644
--- a/cheriot/test/BUILD
+++ b/cheriot/test/BUILD
@@ -148,6 +148,22 @@
)
cc_test(
+ name = "riscv_cheriot_rvv_encoding_test",
+ size = "small",
+ srcs = [
+ "riscv_cheriot_rvv_encoding_test.cc",
+ ],
+ deps = [
+ "//cheriot:cheriot_state",
+ "//cheriot:riscv_cheriot_rvv_decoder",
+ "//cheriot:riscv_cheriot_rvv_isa",
+ "@com_google_googletest//:gtest_main",
+ "@com_google_mpact-sim//mpact/sim/generic:type_helpers",
+ "@com_google_mpact-sim//mpact/sim/util/memory",
+ ],
+)
+
+cc_test(
name = "riscv_cheriot_a_instructions_test",
size = "small",
srcs = [
diff --git a/cheriot/test/riscv_cheriot_encoding_test.cc b/cheriot/test/riscv_cheriot_encoding_test.cc
index 4226c71..4cc6346 100644
--- a/cheriot/test/riscv_cheriot_encoding_test.cc
+++ b/cheriot/test/riscv_cheriot_encoding_test.cc
@@ -28,6 +28,10 @@
using ::mpact::sim::cheriot::isa32::kOpcodeNames;
using ::mpact::sim::cheriot::isa32::RiscVCheriotEncoding;
using ::mpact::sim::generic::operator*; // NOLINT: is used below (clang error).
+using ::mpact::sim::cheriot::isa32::DestOpEnum;
+using ::mpact::sim::cheriot::isa32::kDestOpNames;
+using ::mpact::sim::cheriot::isa32::kSourceOpNames;
+using ::mpact::sim::cheriot::isa32::SourceOpEnum;
using ::mpact::sim::util::TaggedFlatDemandMemory;
using SlotEnum = mpact::sim::cheriot::isa32::SlotEnum;
using OpcodeEnum = mpact::sim::cheriot::isa32::OpcodeEnum;
@@ -223,6 +227,22 @@
return (iword | ((val & 0x1f) << 2));
}
+TEST_F(RiscVCheriotEncodingTest, SourceOperands) {
+ auto &getters = enc_->source_op_getters();
+ for (int i = *SourceOpEnum::kNone; i < *SourceOpEnum::kPastMaxValue; ++i) {
+ EXPECT_TRUE(getters.contains(i)) << "No source operand for enum value " << i
+ << " (" << kSourceOpNames[i] << ")";
+ }
+}
+
+TEST_F(RiscVCheriotEncodingTest, DestOperands) {
+ auto &getters = enc_->dest_op_getters();
+ for (int i = *DestOpEnum::kNone; i < *DestOpEnum::kPastMaxValue; ++i) {
+ EXPECT_TRUE(getters.contains(i)) << "No dest operand for enum value " << i
+ << " (" << kDestOpNames[i] << ")";
+ }
+}
+
TEST_F(RiscVCheriotEncodingTest, RV32IOpcodes) {
enc_->ParseInstruction(SetRd(kLui, kRdValue));
EXPECT_EQ(enc_->GetOpcode(SlotEnum::kRiscv32Cheriot, 0), OpcodeEnum::kLui);
diff --git a/cheriot/test/riscv_cheriot_rvv_encoding_test.cc b/cheriot/test/riscv_cheriot_rvv_encoding_test.cc
new file mode 100644
index 0000000..4f38e72
--- /dev/null
+++ b/cheriot/test/riscv_cheriot_rvv_encoding_test.cc
@@ -0,0 +1,70 @@
+// 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
+//
+// http://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 "cheriot/riscv_cheriot_rvv_encoding.h"
+
+#include "cheriot/cheriot_state.h"
+#include "cheriot/riscv_cheriot_rvv_enums.h"
+#include "googlemock/include/gmock/gmock.h"
+#include "mpact/sim/generic/type_helpers.h"
+#include "mpact/sim/util/memory/tagged_flat_demand_memory.h"
+
+namespace {
+
+using ::mpact::sim::cheriot::CheriotState;
+using ::mpact::sim::cheriot::isa32_rvv::RiscVCheriotRVVEncoding;
+using ::mpact::sim::generic::operator*; // NOLINT: is used below (clang error).
+using ::mpact::sim::cheriot::isa32_rvv::DestOpEnum;
+using ::mpact::sim::cheriot::isa32_rvv::kDestOpNames;
+using ::mpact::sim::cheriot::isa32_rvv::kSourceOpNames;
+using ::mpact::sim::cheriot::isa32_rvv::SourceOpEnum;
+using ::mpact::sim::util::TaggedFlatDemandMemory;
+using SlotEnum = mpact::sim::cheriot::isa32_rvv::SlotEnum;
+using OpcodeEnum = mpact::sim::cheriot::isa32_rvv::OpcodeEnum;
+
+class RiscVCheriotRVVEncodingTest : public testing::Test {
+ protected:
+ RiscVCheriotRVVEncodingTest() {
+ mem_ = new TaggedFlatDemandMemory(8);
+ state_ = new CheriotState("test", mem_, nullptr);
+ enc_ = new RiscVCheriotRVVEncoding(state_);
+ }
+ ~RiscVCheriotRVVEncodingTest() override {
+ delete enc_;
+ delete mem_;
+ delete state_;
+ }
+
+ TaggedFlatDemandMemory *mem_;
+ CheriotState *state_;
+ RiscVCheriotRVVEncoding *enc_;
+};
+
+TEST_F(RiscVCheriotRVVEncodingTest, SourceOperands) {
+ auto &getters = enc_->source_op_getters();
+ for (int i = *SourceOpEnum::kNone; i < *SourceOpEnum::kPastMaxValue; ++i) {
+ EXPECT_TRUE(getters.contains(i)) << "No source operand for enum value " << i
+ << " (" << kSourceOpNames[i] << ")";
+ }
+}
+
+TEST_F(RiscVCheriotRVVEncodingTest, DestOperands) {
+ auto &getters = enc_->dest_op_getters();
+ for (int i = *DestOpEnum::kNone; i < *DestOpEnum::kPastMaxValue; ++i) {
+ EXPECT_TRUE(getters.contains(i)) << "No dest operand for enum value " << i
+ << " (" << kDestOpNames[i] << ")";
+ }
+}
+
+} // namespace