Merge "Vector extension test with floating point values"
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d15c4fd..05814ca 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,6 +1,15 @@
 
 vec_cc_generated_test(
   NAME
+    vfadd
+  TEMPLATE
+    opivv_opivf_test.tpl.cpp
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_generated_test(
+  NAME
     vsub
   TEMPLATE
     opivv_opivx_test.tpl.cpp
@@ -392,12 +401,3 @@
   LINKOPTS
     -Xlinker --defsym=__itcm_length__=128K
 )
-
-vec_cc_test(
-  NAME
-    vector_vfadd_test
-  SRCS
-    vector_vfadd_test.cpp
-  LINKOPTS
-   -Xlinker --defsym=__itcm_length__=128K
-)
diff --git a/tests/templates/base_opivf_test.tpl.cpp b/tests/templates/base_opivf_test.tpl.cpp
new file mode 100644
index 0000000..c3e7f09
--- /dev/null
+++ b/tests/templates/base_opivf_test.tpl.cpp
@@ -0,0 +1,83 @@
+<%!
+import vec_test_helpers
+%>\
+<%def name="test_opivf(op_code)">
+namespace ${op_code}_vf_test {
+namespace {
+
+using namespace test_v_helpers;
+
+float src_vector_2[MAXVL_BYTES];
+float dest_vector[MAXVL_BYTES];
+float ref_dest_vector[MAXVL_BYTES];
+
+class ${op_code.capitalize()}Test : public ::testing::Test {
+ protected:
+  void SetUp() override { zero_vector_registers(); }
+  void TearDown() override { zero_vector_registers(); }
+};
+<%
+template_helper = vec_test_helpers.VecTemplateHelper(op_code)
+sews = template_helper.get_sews()
+lmuls = template_helper.get_lmuls()
+%>\
+% for sew in sews:
+% for lmul in lmuls:
+<%
+template_helper.sew = sew
+%>\
+${insert_vf_test(template_helper, lmul)}
+%endfor
+%endfor
+
+}  // namespace
+}  // namespace ${op_code}_vf_test
+</%def>
+
+<%def name="insert_vf_test(template_helper, lmul)">
+<%
+# Initialize the variables for a given test config
+op_code = template_helper.op_code
+sew = template_helper.sew
+ref_opcode = template_helper.get_ref_opcode()
+dest_sew, src2_sew, _, __ = template_helper.get_sew_sizes()
+datatypes = template_helper.get_softrvv_template_data_type()
+var_types = template_helper.get_var_types()
+mnemonic = template_helper.get_mnemonic(
+  vec_test_helpers.VecTemplateHelper.OperandType.SCALAR)
+%>\
+TEST_F(${op_code.capitalize()}Test, ${mnemonic.lower().replace(".","_")}${sew}m${lmul}) {
+  for (int i = 0; i < AVL_COUNT; i++) {
+    int32_t avl = AVLS[i];
+    int vlmax;
+    int vl;
+
+    std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>(
+        VLMUL::LMUL_M${lmul}, avl,
+        {dest_vector, ref_dest_vector, src_vector_2});
+
+    if (avl > vlmax) {
+      continue;
+    }
+    ${var_types.src2_type} *ptr_vec_2 = reinterpret_cast<${var_types.src2_type} *>(src_vector_2);
+    ${var_types.imm_type} test_val = static_cast<${var_types.imm_type}>(rand());
+    ${var_types.dest_type} *ptr_dest_vec = reinterpret_cast<${var_types.dest_type} *>(dest_vector);
+    ${var_types.dest_type} *ptr_ref_dest_vec = reinterpret_cast<${var_types.dest_type} *>(ref_dest_vector);
+    // set up values to test up to index of the AVL
+    fill_random_vector<${var_types.src2_type}>(ptr_vec_2, avl);
+
+    // Generate reference vector
+    softrvv::${ref_opcode}_vf(ptr_ref_dest_vec, ptr_vec_2, &test_val, avl);
+    // Load vector registers
+    __asm__ volatile("vle${src2_sew}.v v8, (%0)" : : "r"(ptr_vec_2));
+
+    // Run target instruction
+    __asm__ volatile("${mnemonic} v24, v8, %[RS1]" ::[RS1] "f"(test_val));
+
+    // Store result vector register
+    __asm__ volatile("vse${dest_sew}.v v24, (%0)" : : "r"(ptr_dest_vec));
+    // Check vector elements
+    assert_vec_elem_eq<${var_types.dest_type}>(vlmax, dest_vector, ref_dest_vector);
+  }
+}
+</%def>
diff --git a/tests/templates/base_opivv_test.tpl.cpp b/tests/templates/base_opivv_test.tpl.cpp
index a7aba2f..9acb8a7 100644
--- a/tests/templates/base_opivv_test.tpl.cpp
+++ b/tests/templates/base_opivv_test.tpl.cpp
@@ -7,21 +7,29 @@
 
 using namespace test_v_helpers;
 
-uint8_t src_vector_1[MAXVL_BYTES];
-uint8_t src_vector_2[MAXVL_BYTES];
-uint8_t dest_vector[MAXVL_BYTES];
-uint8_t ref_dest_vector[MAXVL_BYTES];
+<%
+template_helper = vec_test_helpers.VecTemplateHelper(op_code)
+sews = template_helper.get_sews()
+lmuls = template_helper.get_lmuls()
+%>\
+
+% if template_helper.is_floating():
+  float src_vector_1[MAXVL_BYTES];
+  float src_vector_2[MAXVL_BYTES];
+  float dest_vector[MAXVL_BYTES];
+  float ref_dest_vector[MAXVL_BYTES];
+% else:
+  uint8_t src_vector_1[MAXVL_BYTES];
+  uint8_t src_vector_2[MAXVL_BYTES];
+  uint8_t dest_vector[MAXVL_BYTES];
+  uint8_t ref_dest_vector[MAXVL_BYTES];
+% endif
 
 class ${op_code.capitalize()}Test : public ::testing::Test {
  protected:
   void SetUp() override { zero_vector_registers(); }
   void TearDown() override { zero_vector_registers(); }
 };
-<%
-template_helper = vec_test_helpers.VecTemplateHelper(op_code)
-sews = template_helper.get_sews()
-lmuls = template_helper.get_lmuls()
-%>\
 % for sew in sews:
 % for lmul in lmuls:
 <%
@@ -46,15 +54,13 @@
 var_types = template_helper.get_var_types()
 mnemonic = template_helper.get_mnemonic(
   vec_test_helpers.VecTemplateHelper.OperandType.VECTOR)
-is_narrowing = template_helper.is_narrowing()
-is_widening = template_helper.is_widening()
 %>\
 TEST_F(${op_code.capitalize()}Test, ${mnemonic.lower().replace(".","_")}${sew}m${lmul}) {
   for (int i = 0; i < AVL_COUNT; i++) {
     int32_t avl = AVLS[i];
     int vlmax;
     int vl;
-% if is_narrowing:
+% if not template_helper.is_floating() and template_helper.is_narrowing():
     vector_test_setup<${var_types.src2_type}>(
         VLMUL::LMUL_M${lmul}, avl,
         {src_vector_2});
@@ -65,7 +71,7 @@
     std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>(
         VLMUL::LMUL_M${lmul}, avl,
         {dest_vector, ref_dest_vector});
-% elif is_widening:
+% elif not template_helper.is_floating() and template_helper.is_widening():
     /* When a widening instruction is used sew matches src2 size */
     vector_test_setup<${var_types.dest_type}>(
         VLMUL::LMUL_M${lmul}, avl,
@@ -80,7 +86,7 @@
     /* For non narrowing instructions all vectors have same type*/
     std::tie(vlmax, vl) = vector_test_setup<${var_types.dest_type}>(
         VLMUL::LMUL_M${lmul}, avl,
-        {dest_vector, ref_dest_vector, src_vector_1});
+        {dest_vector, ref_dest_vector, src_vector_1, src_vector_2});
 % endif
 
     if (avl > vlmax) {
@@ -98,7 +104,11 @@
     memset(ref_dest_vector, 0, MAXVL_BYTES);
 
     // Generate reference vector
-    softrvv::${ref_opcode}_vv<${datatypes}>(ptr_ref_dest_vec, ptr_vec_2, ptr_vec_1, avl);
+    % if template_helper.is_floating():
+      softrvv::${ref_opcode}_vv(ptr_ref_dest_vec, ptr_vec_2, ptr_vec_1, avl);
+    % else:
+      softrvv::${ref_opcode}_vv<${datatypes}>(ptr_ref_dest_vec, ptr_vec_2, ptr_vec_1, avl);
+    % endif
     // Load vector registers
     __asm__ volatile("vle${src1_sew}.v v8, (%0)" : : "r"(ptr_vec_1));
     __asm__ volatile("vle${src2_sew}.v v16, (%0)" : : "r"(ptr_vec_2));
diff --git a/tests/templates/opivf_test.tpl.cpp b/tests/templates/opivf_test.tpl.cpp
new file mode 100644
index 0000000..7c64120
--- /dev/null
+++ b/tests/templates/opivf_test.tpl.cpp
@@ -0,0 +1,3 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests_vf" file="base_opivf_test.tpl.cpp"/>\
+${tests_vf.test_opivf(op)}
diff --git a/tests/templates/opivv_opivf_test.tpl.cpp b/tests/templates/opivv_opivf_test.tpl.cpp
new file mode 100644
index 0000000..b1bf4c3
--- /dev/null
+++ b/tests/templates/opivv_opivf_test.tpl.cpp
@@ -0,0 +1,5 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests_vv" file="base_opivv_test.tpl.cpp"/>\
+<%namespace name="tests_vf" file="base_opivf_test.tpl.cpp"/>\
+${tests_vv.test_opivv(op)}
+${tests_vf.test_opivf(op)}
diff --git a/tests/templates/opivv_test.tpl.cpp b/tests/templates/opivv_test.tpl.cpp
new file mode 100644
index 0000000..428a65b
--- /dev/null
+++ b/tests/templates/opivv_test.tpl.cpp
@@ -0,0 +1,3 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests_vv" file="base_opivv_test.tpl.cpp"/>\
+${tests_vv.test_opivv(op)}
diff --git a/tests/vector_vfadd_test.cpp b/tests/vector_vfadd_test.cpp
deleted file mode 100644
index 208cb91..0000000
--- a/tests/vector_vfadd_test.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include <softrvv.h>
-#include <springbok.h>
-#include <stdio.h>
-
-#include <tuple>
-
-#include "pw_unit_test/framework.h"
-#include "test_v_helpers.h"
-
-namespace vfadd_vv_test
-{
-namespace
-{
-using namespace test_v_helpers;
-
-float src_vector_1[MAXVL_BYTES];
-float src_vector_2[MAXVL_BYTES];
-float dest_vector[MAXVL_BYTES];
-float ref_dest_vector[MAXVL_BYTES];
-
-class VfaddTest : public ::testing::Test {
- protected:
-  void SetUp() override { zero_vector_registers(); }
-  void TearDown() override { zero_vector_registers(); }
-};
-
-TEST_F(VfaddTest, vfadd_vv32m1) {
-  for (int i = 0; i < AVL_COUNT; i++) {
-    int32_t avl = AVLS[i];
-    int vlmax;
-    int vl;
-
-    /* For non narrowing instructions all vectors have same type*/
-    std::tie(vlmax, vl) = vector_test_setup<int32_t>(
-        VLMUL::LMUL_M1, avl,
-        {dest_vector, ref_dest_vector, src_vector_1, src_vector_2});
-
-    if (avl > vlmax) {
-      continue;
-    }
-
-    float *ptr_vec_1 = reinterpret_cast<float *>(src_vector_1);
-    float *ptr_vec_2 = reinterpret_cast<float *>(src_vector_2);
-    float *ptr_dest_vec = reinterpret_cast<float *>(dest_vector);
-    float *ptr_ref_dest_vec = reinterpret_cast<float *>(ref_dest_vector);
-
-    // set up values to test up to index of the AVL
-    fill_random_vector<float>(ptr_vec_1, avl);
-    fill_random_vector<float>(ptr_vec_2, avl);
-
-    // Generate reference vector
-    softrvv::vfadd_vv(ptr_ref_dest_vec, ptr_vec_2, ptr_vec_1, avl);
-    // Load vector registers
-    __asm__ volatile("vle32.v v8, (%0)" : : "r"(ptr_vec_1));
-    __asm__ volatile("vle32.v v16, (%0)" : : "r"(ptr_vec_2));
-
-    // Run target instruction
-    __asm__ volatile("vfadd.vv v24, v16, v8");
-
-    // Store result vector register
-    __asm__ volatile("vse32.v v24, (%0)" : : "r"(ptr_dest_vec));
-    // Check vector elements
-    assert_vec_elem_eq<float>(vlmax, dest_vector, ref_dest_vector);
-  }
-}
-}  // namespace
-}  // namespace vfadd_vv_test