Add softrvv vredsum instruction and test.

* Add softrvv implementation.
* Add sorfrvv test.

Change-Id: Ie5a0b838b30dc47da3a5b357dcfcca98b284c6fb
diff --git a/softrvv/include/softrvv.h b/softrvv/include/softrvv.h
index 18c2c21..bfc0f54 100644
--- a/softrvv/include/softrvv.h
+++ b/softrvv/include/softrvv.h
@@ -24,6 +24,7 @@
 #include "softrvv_vnsra.h"
 #include "softrvv_vnsrl.h"
 #include "softrvv_vor.h"
+#include "softrvv_vredsum.h"
 #include "softrvv_vrem.h"
 #include "softrvv_vsext_vzext.h"
 #include "softrvv_vsll.h"
diff --git a/softrvv/include/softrvv_vredsum.h b/softrvv/include/softrvv_vredsum.h
new file mode 100644
index 0000000..7f96886
--- /dev/null
+++ b/softrvv/include/softrvv_vredsum.h
@@ -0,0 +1,18 @@
+#ifndef SOFTRVV_VREDSUM_H
+#define SOFTRVV_VREDSUM_H
+
+#include <stddef.h>
+
+namespace softrvv {
+
+template <typename T>
+void vredsum_vs(T *dest, T *src2, T *src1, int32_t avl) {
+  dest[0] = src1[0];
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[0] += src2[idx];
+  }
+}
+
+}  // namespace softrvv
+
+#endif  // SOFTRVV_VREDSUM_H
diff --git a/softrvv/tests/CMakeLists.txt b/softrvv/tests/CMakeLists.txt
index 62cbc9a..9614eb4 100644
--- a/softrvv/tests/CMakeLists.txt
+++ b/softrvv/tests/CMakeLists.txt
@@ -260,6 +260,15 @@
    -Xlinker --defsym=__itcm_length__=128K
 )
 
+softrvv_vec_cc_generated_test(
+  NAME
+    vredsum
+  TEMPLATE
+    softrvv_vredsum_test.tpl.cpp
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
 vec_cc_test(
   NAME
     softrvv_vmax
diff --git a/softrvv/tests/templates/opmvv_vred_test.tpl.cpp b/softrvv/tests/templates/opmvv_vred_test.tpl.cpp
new file mode 100644
index 0000000..c40f1c1
--- /dev/null
+++ b/softrvv/tests/templates/opmvv_vred_test.tpl.cpp
@@ -0,0 +1,44 @@
+<%!
+import vec_test_helpers
+%>\
+<%def name="test_opmvv_vred(template_helper, src2, src1, ref_vv)">
+<%
+src1 = vec_test_helpers.to_carr_str(src1)
+src2 = vec_test_helpers.to_carr_str(src2)
+ref_vv = vec_test_helpers.to_carr_str(ref_vv)
+%>\
+namespace softrvv_${template_helper.op_code}_test {
+namespace {
+${insert_variable_init(template_helper, src2, src1, ref_vv)}
+
+class SoftRvv${template_helper.op_code.capitalize()}Test : public ::testing::Test {
+ protected:
+  void SetUp() override { memset(dest, 0, sizeof(dest)); }
+};
+${insert_test(template_helper)}\
+}  // namespace
+}  // namespace softrvv_${op}_test\
+</%def>\
+
+<%def name="insert_variable_init(template_helper, src2, src1, ref_vv)">
+<%
+  var_types = template_helper.get_var_types()
+%>\
+${var_types.src1_type} src1[] = {${src1}};
+${var_types.src2_type} src2[] = {${src2}};
+const int kAVL = sizeof(src1)/sizeof(src1[0]);
+${var_types.dest_type} dest[kAVL];
+
+${var_types.dest_type} ref_vv[kAVL] = {${ref_vv}};
+</%def>\
+
+<%def name="insert_test(template_helper)">
+<%
+var_types = template_helper.get_var_types()
+datatypes = template_helper.get_softrvv_template_data_type()
+%>\
+TEST_F(SoftRvv${template_helper.op_code.capitalize()}Test, VS) {
+  softrvv::${template_helper.op_code}_vs<${datatypes}>(dest, src2, src1, kAVL);\
+  assert_vec_elem_eq<${var_types.dest_type}>(kAVL, dest, ref_vv);
+}
+</%def>\
diff --git a/softrvv/tests/templates/softrvv_vredsum_test.tpl.cpp b/softrvv/tests/templates/softrvv_vredsum_test.tpl.cpp
new file mode 100644
index 0000000..7eced1a
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vredsum_test.tpl.cpp
@@ -0,0 +1,12 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opmvv_vred_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=5)
+dest_type = template_helper.get_np_dest_type()
+ref_vv = np.zeros(src2.shape, dtype=dest_type)
+ref_vv[0] = src2.sum() + src1[0]
+%>\
+${tests.test_opmvv_vred(template_helper, src2, src1, ref_vv)}