No public description

PiperOrigin-RevId: 727035909
Change-Id: Ia13b98e4c7057fb35e1c0bcd698cd80efd6f4aab
diff --git a/cheriot/test/riscv_cheriot_vector_fp_compare_instructions_test.cc b/cheriot/test/riscv_cheriot_vector_fp_compare_instructions_test.cc
index 1fd6a2b..f872142 100644
--- a/cheriot/test/riscv_cheriot_vector_fp_compare_instructions_test.cc
+++ b/cheriot/test/riscv_cheriot_vector_fp_compare_instructions_test.cc
@@ -196,7 +196,7 @@
 
   // Helper function for testing mask vector-scalar/immediate instructions that
   // use the mask bit.
-  template <typename Vs2, typename Fs1>
+  template <typename Vs2, typename Fs1, typename ScalarReg = CheriotRegister>
   void BinaryMaskFPOpWithMaskTestHelperVX(
       absl::string_view name, int sew, Instruction *inst,
       std::function<uint8_t(Vs2, Fs1, bool)> operation) {
@@ -213,7 +213,7 @@
     Vs2 vs2_value[vs2_size * 8];
     auto vs2_span = Span<Vs2>(vs2_value);
     AppendVectorRegisterOperands({kVs2}, {});
-    AppendRegisterOperands({kFs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kFs1Name}, {});
     AppendVectorRegisterOperands({kVmask}, {kVd});
     // Initialize input values.
     FillArrayWithRandomValues<Vs2>(vs2_span);
@@ -308,7 +308,7 @@
   void BinaryMaskFPOpTestHelperVX(absl::string_view name, int sew,
                                   Instruction *inst,
                                   std::function<uint8_t(Vs2, Fs1)> operation) {
-    BinaryMaskFPOpWithMaskTestHelperVX<Vs2, Fs1>(
+    BinaryMaskFPOpWithMaskTestHelperVX<Vs2, Fs1, RVFpRegister>(
         name, sew, inst,
         [operation](Vs2 vs2, Fs1 fs1, bool mask_value) -> uint8_t {
           if (mask_value) {
diff --git a/cheriot/test/riscv_cheriot_vector_fp_instructions_test.cc b/cheriot/test/riscv_cheriot_vector_fp_instructions_test.cc
index 11a17b1..c9f4d15 100644
--- a/cheriot/test/riscv_cheriot_vector_fp_instructions_test.cc
+++ b/cheriot/test/riscv_cheriot_vector_fp_instructions_test.cc
@@ -293,7 +293,8 @@
   // Floating point test needs to ensure to use the fp special values (inf, NaN
   // etc.) during testing, not just random values. This function handles vector
   // scalar instructions.
-  template <typename Vd, typename Vs2, typename Fs1>
+  template <typename Vd, typename Vs2, typename Fs1,
+            typename ScalarReg = CheriotRegister>
   void TernaryOpFPTestHelperVX(absl::string_view name, int sew,
                                Instruction *inst, int delta_position,
                                std::function<Vd(Vs2, Fs1, Vd)> operation) {
@@ -314,7 +315,7 @@
     auto vs2_span = Span<Vs2>(vs2_value);
     auto vd_span = Span<Vd>(vd_value);
     AppendVectorRegisterOperands({kVs2}, {kVd});
-    AppendRegisterOperands({kFs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kFs1Name}, {});
     AppendVectorRegisterOperands({kVd, kVmask}, {kVd});
     SetVectorRegisterValues<uint8_t>(
         {{kVmaskName, Span<const uint8_t>(kA5Mask)}});
@@ -499,12 +500,12 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfadd);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfadd_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float { return vs2 + vs1; });
   ResetInstruction();
   SetSemanticFunction(&Vfadd);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfadd_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double { return vs2 + vs1; });
 }
@@ -524,12 +525,12 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfsub);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfsub_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float { return vs2 - vs1; });
   ResetInstruction();
   SetSemanticFunction(&Vfsub);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfsub_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double { return vs2 - vs1; });
 }
@@ -549,12 +550,12 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfrsub);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfrsub_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float { return vs1 - vs2; });
   ResetInstruction();
   SetSemanticFunction(&Vfrsub);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfrsub_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double { return vs1 - vs2; });
 }
@@ -571,7 +572,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwadd);
-  BinaryOpFPTestHelperVX<double, float, float>(
+  BinaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwadd_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> double {
         return static_cast<double>(vs2) + static_cast<double>(vs1);
@@ -590,7 +591,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwsub);
-  BinaryOpFPTestHelperVX<double, float, float>(
+  BinaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwsub_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> double {
         return static_cast<double>(vs2) - static_cast<double>(vs1);
@@ -609,7 +610,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwaddw);
-  BinaryOpFPTestHelperVX<double, double, float>(
+  BinaryOpFPTestHelperVX<double, double, float, RVFpRegister>(
       "Vfwaddw_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](double vs2, float vs1) -> double {
         return vs2 + static_cast<double>(vs1);
@@ -628,7 +629,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwsubw);
-  BinaryOpFPTestHelperVX<double, double, float>(
+  BinaryOpFPTestHelperVX<double, double, float, RVFpRegister>(
       "Vfwsubw_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](double vs2, float vs1) -> double {
         return vs2 - static_cast<double>(vs1);
@@ -650,12 +651,12 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmul);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmul_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float { return vs2 * vs1; });
   ResetInstruction();
   SetSemanticFunction(&Vfmul);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmul_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double { return vs2 * vs1; });
 }
@@ -675,12 +676,12 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfdiv);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfdiv_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float { return vs2 / vs1; });
   ResetInstruction();
   SetSemanticFunction(&Vfdiv);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfdiv_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double { return vs2 / vs1; });
 }
@@ -700,12 +701,12 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfrdiv);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfrdiv_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float { return vs1 / vs2; });
   ResetInstruction();
   SetSemanticFunction(&Vfrdiv);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfrdiv_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double { return vs1 / vs2; });
 }
@@ -722,7 +723,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwmul);
-  BinaryOpFPTestHelperVX<double, float, float>(
+  BinaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwmul_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> double {
         return static_cast<double>(vs2) * static_cast<double>(vs1);
@@ -748,14 +749,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmadd);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmadd_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return std::fma(vs1, vd, vs2);
       });
   ResetInstruction();
   SetSemanticFunction(&Vfmadd);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmadd_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return std::fma(vs1, vd, vs2);
@@ -781,14 +782,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfnmadd);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfnmadd_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(-vs1, vd, -vs2));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfnmadd);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfnmadd_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(-vs1, vd, -vs2));
@@ -814,14 +815,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmsub);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmsub_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(vs1, vd, -vs2));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfmsub);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmsub_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(vs1, vd, -vs2));
@@ -847,14 +848,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfnmsub);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfnmsub_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(-vs1, vd, vs2));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfnmsub);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfnmsub_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(-vs1, vd, vs2));
@@ -880,14 +881,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmacc);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmacc_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(vs1, vs2, vd));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfmacc);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmacc_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(vs1, vs2, vd));
@@ -913,14 +914,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfnmacc);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfnmacc_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(-vs1, vs2, -vd));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfnmacc);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfnmacc_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(-vs1, vs2, -vd));
@@ -946,14 +947,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmsac);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmsac_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(vs1, vs2, -vd));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfmsac);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmsac_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(vs1, vs2, -vd));
@@ -979,14 +980,14 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfnmsac);
-  TernaryOpFPTestHelperVX<float, float, float>(
+  TernaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfnmsac_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1, float vd) -> float {
         return OptimizationBarrier(std::fma(-vs1, vs2, vd));
       });
   ResetInstruction();
   SetSemanticFunction(&Vfnmsac);
-  TernaryOpFPTestHelperVX<double, double, double>(
+  TernaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfnmsac_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1, double vd) -> double {
         return OptimizationBarrier(std::fma(-vs1, vs2, vd));
@@ -1007,7 +1008,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwmacc);
-  TernaryOpFPTestHelperVX<double, float, float>(
+  TernaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwmacc_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 64,
       [](float vs2, float vs1, double vd) -> double {
         double vs1d = static_cast<double>(vs1);
@@ -1030,7 +1031,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwnmacc);
-  TernaryOpFPTestHelperVX<double, float, float>(
+  TernaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwnmacc_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 64,
       [](float vs2, float vs1, double vd) -> double {
         double vs1d = static_cast<double>(vs1);
@@ -1053,7 +1054,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwmsac);
-  TernaryOpFPTestHelperVX<double, float, float>(
+  TernaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwmsac_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 64,
       [](float vs2, float vs1, double vd) -> double {
         double vs1d = static_cast<double>(vs1);
@@ -1076,7 +1077,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfwnmsac);
-  TernaryOpFPTestHelperVX<double, float, float>(
+  TernaryOpFPTestHelperVX<double, float, float, RVFpRegister>(
       "Vfwnmsac_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 64,
       [](float vs2, float vs1, double vd) -> double {
         double vs1d = static_cast<double>(vs1);
@@ -1130,7 +1131,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfsgnj);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfsgnj_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float {
         using Int = typename FPTypeInfo<float>::IntType;
@@ -1140,7 +1141,7 @@
       });
   ResetInstruction();
   SetSemanticFunction(&Vfsgnj);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfsgnj_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double {
         using Int = typename FPTypeInfo<double>::IntType;
@@ -1175,7 +1176,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfsgnjn);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfsgnjn_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float {
         using Int = typename FPTypeInfo<float>::IntType;
@@ -1185,7 +1186,7 @@
       });
   ResetInstruction();
   SetSemanticFunction(&Vfsgnjn);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfsgnjn_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double {
         using Int = typename FPTypeInfo<double>::IntType;
@@ -1220,7 +1221,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfsgnjx);
-  BinaryOpFPTestHelperVX<float, float, float>(
+  BinaryOpFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfsgnjx_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> float {
         using Int = typename FPTypeInfo<float>::IntType;
@@ -1230,7 +1231,7 @@
       });
   ResetInstruction();
   SetSemanticFunction(&Vfsgnjx);
-  BinaryOpFPTestHelperVX<double, double, double>(
+  BinaryOpFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfsgnjx_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> double {
         using Int = typename FPTypeInfo<double>::IntType;
@@ -1296,7 +1297,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmax);
-  BinaryOpWithFflagsFPTestHelperVX<float, float, float>(
+  BinaryOpWithFflagsFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmax_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> std::tuple<float, uint32_t> {
         using T = float;
@@ -1306,7 +1307,7 @@
       });
   ResetInstruction();
   SetSemanticFunction(&Vfmax);
-  BinaryOpWithFflagsFPTestHelperVX<double, double, double>(
+  BinaryOpWithFflagsFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmax_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> std::tuple<double, uint32_t> {
         using T = double;
@@ -1340,7 +1341,7 @@
   // Vector-scalar.
   ResetInstruction();
   SetSemanticFunction(&Vfmin);
-  BinaryOpWithFflagsFPTestHelperVX<float, float, float>(
+  BinaryOpWithFflagsFPTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmin_vx32", /*sew*/ 32, instruction_, /*delta_position*/ 32,
       [](float vs2, float vs1) -> std::tuple<float, uint32_t> {
         using T = float;
@@ -1350,7 +1351,7 @@
       });
   ResetInstruction();
   SetSemanticFunction(&Vfmin);
-  BinaryOpWithFflagsFPTestHelperVX<double, double, double>(
+  BinaryOpWithFflagsFPTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmin_vx64", /*sew*/ 64, instruction_, /*delta_position*/ 64,
       [](double vs2, double vs1) -> std::tuple<double, uint32_t> {
         using T = double;
@@ -1363,12 +1364,12 @@
 TEST_F(RiscVCheriotFPInstructionsTest, Vfmerge) {
   // Vector-scalar.
   SetSemanticFunction(&Vfmerge);
-  BinaryOpFPWithMaskTestHelperVX<float, float, float>(
+  BinaryOpFPWithMaskTestHelperVX<float, float, float, RVFpRegister>(
       "Vfmerge_vx32", /*sew*/ 32, instruction_, /*delta position*/ 32,
       [](float vs2, float vs1, bool mask) -> float {
         return mask ? vs1 : vs2;
       });
-  BinaryOpFPWithMaskTestHelperVX<double, double, double>(
+  BinaryOpFPWithMaskTestHelperVX<double, double, double, RVFpRegister>(
       "Vfmerge_vx64", /*sew*/ 64, instruction_, /*delta position*/ 64,
       [](double vs2, double vs1, bool mask) -> double {
         return mask ? vs1 : vs2;
diff --git a/cheriot/test/riscv_cheriot_vector_fp_test_utilities.h b/cheriot/test/riscv_cheriot_vector_fp_test_utilities.h
index 6aba98e..90f59b5 100644
--- a/cheriot/test/riscv_cheriot_vector_fp_test_utilities.h
+++ b/cheriot/test/riscv_cheriot_vector_fp_test_utilities.h
@@ -604,7 +604,8 @@
 
   // Floating point test needs to ensure to use the fp special values (inf,
   // NaN etc.) during testing, not just random values.
-  template <typename Vd, typename Vs2, typename Fs1>
+  template <typename Vd, typename Vs2, typename Fs1,
+            typename ScalarReg = CheriotRegister>
   void BinaryOpWithFflagsFPTestHelperVX(
       absl::string_view name, int sew, Instruction *inst, int delta_position,
       std::function<std::tuple<Vd, uint32_t>(Vs2, Fs1)> operation) {
@@ -625,7 +626,7 @@
     Vs2 vs2_value[vs2_size * 8];
     auto vs2_span = Span<Vs2>(vs2_value);
     AppendVectorRegisterOperands({kVs2}, {kVd});
-    AppendRegisterOperands({kFs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kFs1Name}, {});
     auto *flag_op = rv_fp_->fflags()->CreateSetDestinationOperand(0, "fflags");
     instruction_->AppendDestination(flag_op);
     AppendVectorRegisterOperands({kVmask}, {});
@@ -773,7 +774,8 @@
   // Floating point test needs to ensure to use the fp special values (inf,
   // NaN etc.) during testing, not just random values. This function handles
   // vector scalar instructions.
-  template <typename Vd, typename Vs2, typename Fs1>
+  template <typename Vd, typename Vs2, typename Fs1,
+            typename ScalarReg = CheriotRegister>
   void BinaryOpFPWithMaskTestHelperVX(
       absl::string_view name, int sew, Instruction *inst, int delta_position,
       std::function<Vd(Vs2, Fs1, bool)> operation) {
@@ -794,7 +796,7 @@
     Vs2 vs2_value[vs2_size * 8];
     auto vs2_span = Span<Vs2>(vs2_value);
     AppendVectorRegisterOperands({kVs2}, {kVd});
-    AppendRegisterOperands({kFs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kFs1Name}, {});
     AppendVectorRegisterOperands({kVmask}, {});
     SetVectorRegisterValues<uint8_t>(
         {{kVmaskName, Span<const uint8_t>(kA5Mask)}});
@@ -927,11 +929,12 @@
 
   // Templated helper function that tests FP vector-scalar instructions that do
   // not use the value of the mask bit.
-  template <typename Vd, typename Vs2, typename Vs1>
+  template <typename Vd, typename Vs2, typename Vs1,
+            typename ScalarReg = CheriotRegister>
   void BinaryOpFPTestHelperVX(absl::string_view name, int sew,
                               Instruction *inst, int delta_position,
                               std::function<Vd(Vs2, Vs1)> operation) {
-    BinaryOpFPWithMaskTestHelperVX<Vd, Vs2, Vs1>(
+    BinaryOpFPWithMaskTestHelperVX<Vd, Vs2, Vs1, ScalarReg>(
         name, sew, inst, delta_position,
         [operation](Vs2 vs2, Vs1 vs1, bool mask_value) -> Vd {
           if (mask_value) {
diff --git a/cheriot/test/riscv_cheriot_vector_fp_unary_instructions_test.cc b/cheriot/test/riscv_cheriot_vector_fp_unary_instructions_test.cc
index 94315d7..6d525a5 100644
--- a/cheriot/test/riscv_cheriot_vector_fp_unary_instructions_test.cc
+++ b/cheriot/test/riscv_cheriot_vector_fp_unary_instructions_test.cc
@@ -596,7 +596,7 @@
 // Test vfmv.f.s instruction - move element 0 to scalar fp register.
 TEST_F(RiscVCheriotFPUnaryInstructionsTest, VfmvToScalar) {
   SetSemanticFunction(&Vfmvfs);
-  AppendRegisterOperands({}, {kFs1Name});
+  AppendRegisterOperands<RVFpRegister>({}, {kFs1Name});
   AppendVectorRegisterOperands({kVs2}, {});
   for (int byte_sew : {1, 2, 4, 8}) {
     int vlen = kVectorLengthInBytes / byte_sew;
@@ -636,7 +636,7 @@
 // Test vfmv.f.s instruction - move scalar fp register to element 0.
 TEST_F(RiscVCheriotFPUnaryInstructionsTest, VfmvFromScalar) {
   SetSemanticFunction(&Vfmvsf);
-  AppendRegisterOperands({kFs1Name}, {});
+  AppendRegisterOperands<RVFpRegister>({kFs1Name}, {});
   AppendVectorRegisterOperands({}, {kVd});
   for (int byte_sew : {1, 2, 4, 8}) {
     int vlen = kVectorLengthInBytes / byte_sew;
diff --git a/cheriot/test/riscv_cheriot_vector_instructions_test_base.h b/cheriot/test/riscv_cheriot_vector_instructions_test_base.h
index fc074e1..4239658 100644
--- a/cheriot/test/riscv_cheriot_vector_instructions_test_base.h
+++ b/cheriot/test/riscv_cheriot_vector_instructions_test_base.h
@@ -179,28 +179,30 @@
 
   // Creates source and destination scalar register operands for the registers
   // named in the two vectors and append them to the given instruction.
+  template <typename T = CheriotRegister>
   void AppendRegisterOperands(Instruction *inst,
                               const std::vector<std::string> &sources,
                               const std::vector<std::string> &destinations) {
     for (auto &reg_name : sources) {
-      auto *reg = state_->GetRegister<CheriotRegister>(reg_name).first;
+      auto *reg = state_->GetRegister<T>(reg_name).first;
       inst->AppendSource(reg->CreateSourceOperand());
     }
     for (auto &reg_name : destinations) {
-      auto *reg = state_->GetRegister<CheriotRegister>(reg_name).first;
+      auto *reg = state_->GetRegister<T>(reg_name).first;
       inst->AppendDestination(reg->CreateDestinationOperand(0));
     }
   }
 
   // Creates source and destination scalar register operands for the registers
   // named in the two vectors and append them to the default instruction.
+  template <typename T = CheriotRegister>
   void AppendRegisterOperands(const std::vector<std::string> &sources,
                               const std::vector<std::string> &destinations) {
-    AppendRegisterOperands(instruction_, sources, destinations);
+    AppendRegisterOperands<T>(instruction_, sources, destinations);
   }
 
   // Returns the value of the named vector register.
-  template <typename T>
+  template <typename T, typename RegisterType = CheriotRegister>
   T GetRegisterValue(absl::string_view vreg_name) {
     auto *reg = state_->GetRegister<CheriotRegister>(vreg_name).first;
     return reg->data_buffer()->Get<T>();
@@ -545,7 +547,8 @@
 
   // Helper function for testing vector-scalar/immediate instructions that use
   // the value of the mask bit.
-  template <typename Vd, typename Vs2, typename Rs1>
+  template <typename Vd, typename Vs2, typename Rs1,
+            typename ScalarReg = CheriotRegister>
   void BinaryOpWithMaskTestHelperVX(
       absl::string_view name, int sew, Instruction *inst,
       std::function<Vd(Vs2, Rs1, bool)> operation) {
@@ -563,7 +566,7 @@
     Vs2 vs2_value[vs2_size * 8];
     auto vs2_span = Span<Vs2>(vs2_value);
     AppendVectorRegisterOperands({kVs2}, {});
-    AppendRegisterOperands({kRs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kRs1Name}, {});
     AppendVectorRegisterOperands({kVmask}, {kVd});
     // Initialize input values.
     FillArrayWithRandomValues<Vs2>(vs2_span);
@@ -659,10 +662,11 @@
 
   // Templated helper function that tests vector-scalar instructions that do
   // not use the value of the mask bit.
-  template <typename Vd, typename Vs2, typename Vs1>
+  template <typename Vd, typename Vs2, typename Vs1,
+            typename ScalarReg = CheriotRegister>
   void BinaryOpTestHelperVX(absl::string_view name, int sew, Instruction *inst,
                             std::function<Vd(Vs2, Vs1)> operation) {
-    BinaryOpWithMaskTestHelperVX<Vd, Vs2, Vs1>(
+    BinaryOpWithMaskTestHelperVX<Vd, Vs2, Vs1, ScalarReg>(
         name, sew, inst, [operation](Vs2 vs2, Vs1 vs1, bool mask_value) -> Vd {
           if (mask_value) {
             return operation(vs2, vs1);
@@ -810,7 +814,8 @@
 
   // Helper function for testing vector-scalar/immediate instructions that use
   // the value of the mask bit.
-  template <typename Vd, typename Vs2, typename Rs1>
+  template <typename Vd, typename Vs2, typename Rs1,
+            typename ScalarReg = CheriotRegister>
   void TernaryOpWithMaskTestHelperVX(
       absl::string_view name, int sew, Instruction *inst,
       std::function<Vd(Vs2, Rs1, Vd, bool)> operation) {
@@ -831,7 +836,7 @@
     Vs2 vs2_value[vs2_size * 8];
     auto vs2_span = Span<Vs2>(vs2_value);
     AppendVectorRegisterOperands({kVs2}, {});
-    AppendRegisterOperands({kRs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kRs1Name}, {});
     AppendVectorRegisterOperands({kVd, kVmask}, {kVd});
     // Initialize input values.
     FillArrayWithRandomValues<Vd>(vd_span);
@@ -940,10 +945,11 @@
 
   // Templated helper function that tests vector-scalar instructions that do
   // not use the value of the mask bit.
-  template <typename Vd, typename Vs2, typename Rs1>
+  template <typename Vd, typename Vs2, typename Rs1,
+            typename ScalarReg = CheriotRegister>
   void TernaryOpTestHelperVX(absl::string_view name, int sew, Instruction *inst,
                              std::function<Vd(Vs2, Rs1, Vd)> operation) {
-    TernaryOpWithMaskTestHelperVX<Vd, Vs2, Rs1>(
+    TernaryOpWithMaskTestHelperVX<Vd, Vs2, Rs1, ScalarReg>(
         name, sew, inst,
         [operation](Vs2 vs2, Rs1 rs1, Vd vd, bool mask_value) -> Vd {
           if (mask_value) {
@@ -1070,7 +1076,7 @@
 
   // Helper function for testing mask vector-scalar/immediate instructions that
   // use the mask bit.
-  template <typename Vs2, typename Rs1>
+  template <typename Vs2, typename Rs1, typename ScalarReg = CheriotRegister>
   void BinaryMaskOpWithMaskTestHelperVX(
       absl::string_view name, int sew, Instruction *inst,
       std::function<uint8_t(Vs2, Rs1, bool)> operation) {
@@ -1087,7 +1093,7 @@
     Vs2 vs2_value[vs2_size * 8];
     auto vs2_span = Span<Vs2>(vs2_value);
     AppendVectorRegisterOperands({kVs2}, {});
-    AppendRegisterOperands({kRs1Name}, {});
+    AppendRegisterOperands<ScalarReg>({kRs1Name}, {});
     AppendVectorRegisterOperands({kVmask}, {kVd});
     // Initialize input values.
     FillArrayWithRandomValues<Vs2>(vs2_span);