Add support for vrem/vremu.

* Add softrvv vrem implementations and tests.
* Add vrem and vremu vector instruction tests.

Change-Id: I3b75935eeba3bdec91d8b8592739cec7993c8aaa
diff --git a/softrvv/include/softrvv.h b/softrvv/include/softrvv.h
index d779c8e..e46af99 100644
--- a/softrvv/include/softrvv.h
+++ b/softrvv/include/softrvv.h
@@ -8,6 +8,7 @@
 #include "softrvv_vdiv.h"
 #include "softrvv_vmin.h"
 #include "softrvv_vmul_vmulh.h"
+#include "softrvv_vrem.h"
 #include "softrvv_vsext_vzext.h"
 #include "softrvv_vsub.h"
 #include "softrvv_vwadd.h"
diff --git a/softrvv/include/softrvv_vrem.h b/softrvv/include/softrvv_vrem.h
new file mode 100644
index 0000000..1a2b00e
--- /dev/null
+++ b/softrvv/include/softrvv_vrem.h
@@ -0,0 +1,24 @@
+#ifndef SOFTRVV_VREM_H
+#define SOFTRVV_VREM_H
+
+#include <stddef.h>
+
+namespace softrvv {
+
+template <typename T>
+void vrem_vx(T *dest, T *src1, const T *src2, int32_t avl) {
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[idx] = src1[idx] % *src2;
+  }
+}
+
+template <typename T>
+void vrem_vv(T *dest, T *src1, T *src2, int32_t avl) {
+  for (int32_t idx = 0; idx < avl; idx++) {
+    dest[idx] = src1[idx] % src2[idx];
+  }
+}
+
+}  // namespace softrvv
+
+#endif  // SOFTRVV_VREM_H
diff --git a/softrvv/tests/CMakeLists.txt b/softrvv/tests/CMakeLists.txt
index 59f7d21..565b508 100644
--- a/softrvv/tests/CMakeLists.txt
+++ b/softrvv/tests/CMakeLists.txt
@@ -135,3 +135,12 @@
   LINKOPTS
    -Xlinker --defsym=__itcm_length__=128K
 )
+
+softrvv_vec_cc_generated_test(
+  NAME
+    vrem
+  TEMPLATE
+    softrvv_vrem_test.tpl.cpp
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
diff --git a/softrvv/tests/templates/softrvv_vrem_test.tpl.cpp b/softrvv/tests/templates/softrvv_vrem_test.tpl.cpp
new file mode 100644
index 0000000..e4eefd7
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vrem_test.tpl.cpp
@@ -0,0 +1,25 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+# Generate test vectors using python
+N = 5
+ii32 = np.iinfo(np.int32)
+src1_data = np.random.random_integers(0, ii32.max, N).astype(np.int32)
+src2_data = np.random.random_integers(0, ii32.max, N).astype(np.int32)
+# Don't allow zero
+src2_data[src2_data==0] = 1
+ref_vv_data = np.mod(src1_data,src2_data).astype(np.int32)
+rs1 = np.int32(np.random.randint(0, ii32.max))
+# Don't allow divide by zero
+if rs1 == 0:
+  rs1 = 1
+ref_vx_data = np.mod(src1_data, rs1).astype(np.int32)
+
+# Convert test vectors to strings for array initialization
+src1 = parent.module.to_carr_str(src1_data)
+src2 = parent.module.to_carr_str(src2_data)
+ref_vv = parent.module.to_carr_str(ref_vv_data)
+ref_vx = parent.module.to_carr_str(ref_vx_data)
+%>\
+${tests.test_opivv_opivx("int32_t", op, src1, src2, rs1, ref_vv, ref_vx)}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 4e001f1..308fb22 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -114,6 +114,26 @@
 
 vec_cc_generated_test(
   NAME
+    vrem
+  OPFMT
+    OPIVV
+    OPIVX
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_generated_test(
+  NAME
+    vremu
+  OPFMT
+    OPIVV
+    OPIVX
+  LINKOPTS
+   -Xlinker --defsym=__itcm_length__=128K
+)
+
+vec_cc_generated_test(
+  NAME
     vwadd
   OPFMT
     OPIVV