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