Add vwadd/vwaddu/vwsub/vwsubu to softrvv.

* Create subdirectory CMakeLists.txt

Change-Id: I5c2e61a4986e0f84f72f6b26195bde2ce44d32a8
diff --git a/softrvv/CMakeLists.txt b/softrvv/CMakeLists.txt
index 76a12e8..9672211 100644
--- a/softrvv/CMakeLists.txt
+++ b/softrvv/CMakeLists.txt
@@ -1,35 +1,4 @@
 add_library(softrvv INTERFACE)
 target_include_directories(softrvv INTERFACE include)
 
-vec_cc_test(
-  NAME
-    vec_disable_test
-  SRCS
-    tests/vec_disable_test.cpp
-  DEPS
-    softrvv
-  LINKOPTS
-   -Xlinker --defsym=__itcm_length__=256K
-)
-
-vec_cc_test(
-  NAME
-    softrvv_vadd
-  SRCS
-    tests/softrvv_vadd_test.cpp
-  DEPS
-    softrvv
-  LINKOPTS
-   -Xlinker --defsym=__itcm_length__=128K
-)
-
-vec_cc_test(
-  NAME
-    softrvv_vsub
-  SRCS
-    tests/softrvv_vsub_test.cpp
-  DEPS
-    softrvv
-  LINKOPTS
-   -Xlinker --defsym=__itcm_length__=128K
-)
\ No newline at end of file
+add_subdirectory(tests)
diff --git a/softrvv/include/softrvv.h b/softrvv/include/softrvv.h
index 18402a6..299fbb0 100644
--- a/softrvv/include/softrvv.h
+++ b/softrvv/include/softrvv.h
@@ -6,7 +6,8 @@
 #include "encoding.h"
 #include "softrvv_vadd.h"
 #include "softrvv_vsub.h"
-
+#include "softrvv_vwadd.h"
+#include "softrvv_vwsub.h"
 
 
 namespace softrvv {
diff --git a/softrvv/include/softrvv_vwadd.h b/softrvv/include/softrvv_vwadd.h
new file mode 100644
index 0000000..c420493
--- /dev/null
+++ b/softrvv/include/softrvv_vwadd.h
@@ -0,0 +1,26 @@
+#ifndef SOFTRVV_VWADD_H
+#define SOFTRVV_VWADD_H
+
+#include <stddef.h>
+
+namespace softrvv {
+
+template <typename T1, typename T2>
+void vwadd_vx(T1 *dest, T2 *src1, const T2 *src2, int32_t avl) {
+  static_assert(sizeof(T1) == 2 * sizeof(T2));
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[idx] = src1[idx] + *src2;
+  }
+}
+
+template <typename T1, typename T2>
+void vwadd_vv(T1 *dest, T2 *src1, T2 *src2, int32_t avl) {
+  static_assert(sizeof(T1) == 2 * sizeof(T2));
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[idx] = src1[idx] + src2[idx];
+  }
+}
+
+}  // namespace softrvv
+
+#endif  // SOFTRVV_VADD_H
diff --git a/softrvv/include/softrvv_vwsub.h b/softrvv/include/softrvv_vwsub.h
new file mode 100644
index 0000000..1d62761
--- /dev/null
+++ b/softrvv/include/softrvv_vwsub.h
@@ -0,0 +1,26 @@
+#ifndef SOFTRVV_VWSUB_H
+#define SOFTRVV_VWSUB_H
+
+#include <stddef.h>
+
+namespace softrvv {
+
+template <typename T1, typename T2>
+void vwsub_vx(T1 *dest, T2 *src1, const T2 *src2, int32_t avl) {
+  static_assert(sizeof(T1) == 2 * sizeof(T2));
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[idx] = src1[idx] - *src2;
+  }
+}
+
+template <typename T1, typename T2>
+void vwsub_vv(T1 *dest, T2 *src1, T2 *src2, int32_t avl) {
+  static_assert(sizeof(T1) == 2 * sizeof(T2));
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[idx] = src1[idx] - src2[idx];
+  }
+}
+
+}  // namespace softrvv
+
+#endif  // SOFTRVV_VSUB_H
diff --git a/softrvv/tests/CMakeLists.txt b/softrvv/tests/CMakeLists.txt
new file mode 100644
index 0000000..68c5364
--- /dev/null
+++ b/softrvv/tests/CMakeLists.txt
@@ -0,0 +1,77 @@
+
+vec_cc_test(
+  NAME
+    vec_disable_test
+  SRCS
+    vec_disable_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=256K
+)
+
+vec_cc_test(
+  NAME
+    softrvv_vadd
+  SRCS
+    softrvv_vadd_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_test(
+  NAME
+    softrvv_vsub
+  SRCS
+    softrvv_vsub_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_test(
+  NAME
+    softrvv_vwadd
+  SRCS
+    softrvv_vwadd_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_test(
+  NAME
+    softrvv_vwaddu
+  SRCS
+    softrvv_vwaddu_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_test(
+  NAME
+    softrvv_vwsub
+  SRCS
+    softrvv_vwsub_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_test(
+  NAME
+    softrvv_vwsubu
+  SRCS
+    softrvv_vwsubu_test.cpp
+  DEPS
+    softrvv
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
diff --git a/softrvv/tests/softrvv_vwadd_test.cpp b/softrvv/tests/softrvv_vwadd_test.cpp
new file mode 100644
index 0000000..6935a42
--- /dev/null
+++ b/softrvv/tests/softrvv_vwadd_test.cpp
@@ -0,0 +1,37 @@
+#include <riscv_vector.h>
+#include <springbok.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pw_unit_test/framework.h"
+#include "softrvv.h"
+
+namespace softrvv_vadd_test {
+namespace {
+
+int16_t src1[] = {1, 2, 3, -4, 5};
+int16_t src2[] = {1, 2, 3, 4, -6};
+int16_t rs1 = 3;
+const uint32_t AVL_CONST = sizeof(src1)/sizeof(src1[0]);
+int32_t dest[AVL_CONST];
+
+int32_t ref_vv[] = {2, 4, 6, 0, -1};
+int32_t ref_vx[] = {4, 5, 6, -1, 8};
+
+class SoftRvvVwaddTest : public ::testing::Test {
+ protected:
+  void SetUp() override { memset(dest, 0, sizeof(dest)); }
+};
+
+TEST_F(SoftRvvVwaddTest, VV) {
+  softrvv::vwadd_vv<int32_t, int16_t>(dest, src1, src2, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vv, sizeof(dest)), 0);
+}
+
+TEST_F(SoftRvvVwaddTest, VX) {
+  softrvv::vwadd_vx<int32_t, int16_t>(dest, src1, &rs1, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vx, sizeof(dest)), 0);
+}
+
+}  // namespace
+}  // namespace softrvv_vwadd_test
diff --git a/softrvv/tests/softrvv_vwaddu_test.cpp b/softrvv/tests/softrvv_vwaddu_test.cpp
new file mode 100644
index 0000000..871a62f
--- /dev/null
+++ b/softrvv/tests/softrvv_vwaddu_test.cpp
@@ -0,0 +1,37 @@
+#include <riscv_vector.h>
+#include <springbok.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pw_unit_test/framework.h"
+#include "softrvv.h"
+
+namespace softrvv_vaddu_test {
+namespace {
+
+uint16_t src1[] = {1, 2, 3, 4, 5};
+uint16_t src2[] = {1, 2, 3, 4, 5};
+uint16_t rs1 = 3;
+const uint32_t AVL_CONST = sizeof(src1)/sizeof(src1[0]);
+uint32_t dest[AVL_CONST];
+
+uint32_t ref_vv[] = {2, 4, 6, 8, 10};
+uint32_t ref_vx[] = {4, 5, 6, 7, 8};
+
+class SoftRvvVwaddTest : public ::testing::Test {
+ protected:
+  void SetUp() override { memset(dest, 0, sizeof(dest)); }
+};
+
+TEST_F(SoftRvvVwaddTest, UVV) {
+  softrvv::vwadd_vv<uint32_t, uint16_t>(dest, src1, src2, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vv, sizeof(dest)), 0);
+}
+
+TEST_F(SoftRvvVwaddTest, UVX) {
+  softrvv::vwadd_vx<uint32_t, uint16_t>(dest, src1, &rs1, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vx, sizeof(dest)), 0);
+}
+
+}  // namespace
+}  // namespace softrvv_vwaddu_test
diff --git a/softrvv/tests/softrvv_vwsub_test.cpp b/softrvv/tests/softrvv_vwsub_test.cpp
new file mode 100644
index 0000000..db44f4d
--- /dev/null
+++ b/softrvv/tests/softrvv_vwsub_test.cpp
@@ -0,0 +1,37 @@
+#include <riscv_vector.h>
+#include <springbok.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pw_unit_test/framework.h"
+#include "softrvv.h"
+
+namespace softrvv_vwsub_test {
+namespace {
+
+int16_t src1[] = {2, 4, -6, 8, 10};
+int16_t src2[] = {1, 2, 3, -4, 5};
+int16_t rs1 = 3;
+const uint32_t AVL_CONST = sizeof(src1)/sizeof(src1[0]);
+int32_t dest[AVL_CONST];
+
+int32_t ref_vv[] = {1, 2, -9, 12, 5};
+int32_t ref_vx[] = {-1, 1, -9, 5, 7};
+
+class SoftRvvVwsubTest : public ::testing::Test {
+ protected:
+  void SetUp() override { memset(dest, 0, sizeof(dest)); }
+};
+
+TEST_F(SoftRvvVwsubTest, VV) {
+  softrvv::vwsub_vv<int32_t, int16_t>(dest, src1, src2, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vv, sizeof(dest)), 0);
+}
+
+TEST_F(SoftRvvVwsubTest, VX) {
+  softrvv::vwsub_vx<int32_t, int16_t>(dest, src1, &rs1, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vx, sizeof(dest)), 0);
+}
+
+}  // namespace
+}  // namespace softrvv_vwsub_test
diff --git a/softrvv/tests/softrvv_vwsubu_test.cpp b/softrvv/tests/softrvv_vwsubu_test.cpp
new file mode 100644
index 0000000..c23d6c2
--- /dev/null
+++ b/softrvv/tests/softrvv_vwsubu_test.cpp
@@ -0,0 +1,37 @@
+#include <riscv_vector.h>
+#include <springbok.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "pw_unit_test/framework.h"
+#include "softrvv.h"
+
+namespace softrvv_vwsubu_test {
+namespace {
+
+uint16_t src1[] = {3, 4, 6, 8, 10};
+uint16_t src2[] = {1, 2, 3, 4, 5};
+uint16_t rs1 = 3;
+const uint32_t AVL_CONST = sizeof(src1)/sizeof(src1[0]);
+uint32_t dest[AVL_CONST];
+
+uint32_t ref_vv[] = {2, 2, 3, 4, 5};
+uint32_t ref_vx[] = {0, 1, 3, 5, 7};
+
+class SoftRvvVwsubuTest : public ::testing::Test {
+ protected:
+  void SetUp() override { memset(dest, 0, sizeof(dest)); }
+};
+
+TEST_F(SoftRvvVwsubuTest, VV) {
+  softrvv::vwsub_vv<uint32_t, uint16_t>(dest, src1, src2, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vv, sizeof(dest)), 0);
+}
+
+TEST_F(SoftRvvVwsubuTest, VX) {
+  softrvv::vwsub_vx<uint32_t, uint16_t>(dest, src1, &rs1, AVL_CONST);
+  ASSERT_EQ(memcmp(dest, ref_vx, sizeof(dest)), 0);
+}
+
+}  // namespace
+}  // namespace softrvv_vwsubu_test