Add comparison ops.
* Adds ops vmseq, vmsge, vmsgt, vmsle, vmslt, and vmsne.
* Add softrvv implementations and tests.
* Add vec-ext op tests.
* Implement mask destination register check.
Change-Id: I1ed289941e876d3069bbdb41a794d8fa7b4144a5
diff --git a/scripts/vec_test_helpers/__init__.py b/scripts/vec_test_helpers/__init__.py
index 7da121f..87f457e 100644
--- a/scripts/vec_test_helpers/__init__.py
+++ b/scripts/vec_test_helpers/__init__.py
@@ -87,6 +87,11 @@
"""Check if a particular op_code is a narrowing type."""
return self.op_code[1] == 'n'
+ def is_destination_mask_register(self):
+ """Check if a particular op_code has a mask output."""
+ int_comparison_ops = ('vmseq', 'vmsne', 'vmsltu', 'vmsleu', 'vmsle', 'vmsgtu', 'vmsgt')
+ return self.op_code in int_comparison_ops
+
def is_unsigned(self):
"""Check if a particular op_code is a unsigned type."""
return self.op_code[-1] == 'u'
@@ -211,6 +216,11 @@
rs1 = 1 if rs1 == 0 else rs1
return src2_data, src1_data, rs1
+ def pack_dest_mask(self, values):
+ """Pack values into a single destination register."""
+ dest_type = self.get_np_dest_type()
+ return np.packbits(dest_type(values), bitorder='little')
+
def cast_to_unsigned(arr):
"""Cast a signed array to an unsigned array."""
udtypes = {np.int8:np.uint8,
diff --git a/softrvv/include/softrvv.h b/softrvv/include/softrvv.h
index 75a4017..5595634 100644
--- a/softrvv/include/softrvv.h
+++ b/softrvv/include/softrvv.h
@@ -4,12 +4,19 @@
#include <stddef.h>
#include "encoding.h"
+#include "softrvv_internal.h"
#include "softrvv_vadd.h"
#include "softrvv_vand.h"
#include "softrvv_vdiv.h"
#include "softrvv_vmax.h"
#include "softrvv_vmin.h"
#include "softrvv_vmul_vmulh.h"
+#include "softrvv_vmseq.h"
+#include "softrvv_vmsgt.h"
+#include "softrvv_vmsge.h"
+#include "softrvv_vmsle.h"
+#include "softrvv_vmslt.h"
+#include "softrvv_vmsne.h"
#include "softrvv_vnsra.h"
#include "softrvv_vnsrl.h"
#include "softrvv_vor.h"
diff --git a/softrvv/include/softrvv_internal.h b/softrvv/include/softrvv_internal.h
new file mode 100644
index 0000000..e4475a5
--- /dev/null
+++ b/softrvv/include/softrvv_internal.h
@@ -0,0 +1,40 @@
+#ifndef SOFTRVV_INTERNAL_H
+#define SOFTRVV_INTERNAL_H
+
+#include <bit>
+#include <tuple>
+
+namespace softrvv {
+
+template <typename T>
+inline std::tuple<int, int>get_element_and_pos(unsigned int index) {
+ // bw_required is the number of bits required to store the value
+ const unsigned int bw_required = std::__bit_width(sizeof(T)* 8);
+ const unsigned int shift = bw_required - 1;
+ // shift is the number of bits required to store the value minus 1
+ // Example for T is int32_t:
+ // 32 requires 6 bits to store, the shift required to divide by 32 is 5 (6 - 1)
+ // Shift of the index is equivalent to a divide
+ unsigned int element_idx = index >> shift;
+ // Masked lowers bits are equivalent to remainder
+ unsigned int element_pos = index & ~(element_idx << shift);
+ return std::make_tuple(element_idx, element_pos);
+}
+
+template <typename T>
+inline void set_bit_in_dest_mask(unsigned int index, T *dest, bool set_bit) {
+ unsigned int element_idx;
+ unsigned int element_pos;
+ std::tie(element_idx, element_pos) = get_element_and_pos<T>(index);
+ T *dest_eptr = dest + element_idx;
+ if (set_bit) {
+ // Set the target bit
+ *dest_eptr |= (1 << element_pos);
+ } else {
+ // Clear the target bit
+ *dest_eptr &= ~(1 << element_pos);
+ }
+}
+
+} // namespace softrvv
+#endif // SOFTRVV_INTERNAL_H
diff --git a/softrvv/include/softrvv_vmseq.h b/softrvv/include/softrvv_vmseq.h
new file mode 100644
index 0000000..05bf2f3
--- /dev/null
+++ b/softrvv/include/softrvv_vmseq.h
@@ -0,0 +1,25 @@
+#ifndef SOFTRVV_VMSEQ_H
+#define SOFTRVV_VMSEQ_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace softrvv {
+
+template <typename T>
+void vmseq_vx(T *dest, T *src2, const T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] == *src1);
+ }
+}
+
+template <typename T>
+void vmseq_vv(T *dest, T *src2, T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] == src1[idx]);
+ }
+}
+
+} // namespace softrvv
+
+#endif // SOFTRVV_VMSEQ_H
diff --git a/softrvv/include/softrvv_vmsge.h b/softrvv/include/softrvv_vmsge.h
new file mode 100644
index 0000000..90738ee
--- /dev/null
+++ b/softrvv/include/softrvv_vmsge.h
@@ -0,0 +1,25 @@
+#ifndef SOFTRVV_VMSGE_H
+#define SOFTRVV_VMSGE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace softrvv {
+
+template <typename T>
+void vmsge_vx(T *dest, T *src2, const T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] >= *src1);
+ }
+}
+
+template <typename T>
+void vmsge_vv(T *dest, T *src2, T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] >= src1[idx]);
+ }
+}
+
+} // namespace softrvv
+
+#endif // SOFTRVV_VMSGE_H
diff --git a/softrvv/include/softrvv_vmsgt.h b/softrvv/include/softrvv_vmsgt.h
new file mode 100644
index 0000000..a3e7afe
--- /dev/null
+++ b/softrvv/include/softrvv_vmsgt.h
@@ -0,0 +1,25 @@
+#ifndef SOFTRVV_VMSGT_H
+#define SOFTRVV_VMSGT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace softrvv {
+
+template <typename T>
+void vmsgt_vx(T *dest, T *src2, const T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] > *src1);
+ }
+}
+
+template <typename T>
+void vmsgt_vv(T *dest, T *src2, T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] > src1[idx]);
+ }
+}
+
+} // namespace softrvv
+
+#endif // SOFTRVV_VMSGT_H
diff --git a/softrvv/include/softrvv_vmsle.h b/softrvv/include/softrvv_vmsle.h
new file mode 100644
index 0000000..a53c8d0
--- /dev/null
+++ b/softrvv/include/softrvv_vmsle.h
@@ -0,0 +1,25 @@
+#ifndef SOFTRVV_VMSLE_H
+#define SOFTRVV_VMSLE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace softrvv {
+
+template <typename T>
+void vmsle_vx(T *dest, T *src2, const T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] <= *src1);
+ }
+}
+
+template <typename T>
+void vmsle_vv(T *dest, T *src2, T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] <= src1[idx]);
+ }
+}
+
+} // namespace softrvv
+
+#endif // SOFTRVV_VMSLE_H
diff --git a/softrvv/include/softrvv_vmslt.h b/softrvv/include/softrvv_vmslt.h
new file mode 100644
index 0000000..070c66a
--- /dev/null
+++ b/softrvv/include/softrvv_vmslt.h
@@ -0,0 +1,25 @@
+#ifndef SOFTRVV_VMSLT_H
+#define SOFTRVV_VMSLT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace softrvv {
+
+template <typename T>
+void vmslt_vx(T *dest, T *src2, const T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] < *src1);
+ }
+}
+
+template <typename T>
+void vmslt_vv(T *dest, T *src2, T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] < src1[idx]);
+ }
+}
+
+} // namespace softrvv
+
+#endif // SOFTRVV_VMSLT_H
diff --git a/softrvv/include/softrvv_vmsne.h b/softrvv/include/softrvv_vmsne.h
new file mode 100644
index 0000000..68b8378
--- /dev/null
+++ b/softrvv/include/softrvv_vmsne.h
@@ -0,0 +1,25 @@
+#ifndef SOFTRVV_VMSNE_H
+#define SOFTRVV_VMSNE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+namespace softrvv {
+
+template <typename T>
+void vmsne_vx(T *dest, T *src2, const T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] != *src1);
+ }
+}
+
+template <typename T>
+void vmsne_vv(T *dest, T *src2, T *src1, int32_t avl) {
+ for (int32_t idx = 0; idx < avl; idx++) {
+ set_bit_in_dest_mask<T>(idx, dest, src2[idx] != src1[idx]);
+ }
+}
+
+} // namespace softrvv
+
+#endif // SOFTRVV_VMSNE_H
diff --git a/softrvv/tests/CMakeLists.txt b/softrvv/tests/CMakeLists.txt
index f788d8c..fd87980 100644
--- a/softrvv/tests/CMakeLists.txt
+++ b/softrvv/tests/CMakeLists.txt
@@ -206,6 +206,60 @@
-Xlinker --defsym=__itcm_length__=128K
)
+softrvv_vec_cc_generated_test(
+ NAME
+ vmseq
+ TEMPLATE
+ softrvv_vmseq_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
+
+softrvv_vec_cc_generated_test(
+ NAME
+ vmsne
+ TEMPLATE
+ softrvv_vmsne_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
+
+softrvv_vec_cc_generated_test(
+ NAME
+ vmslt
+ TEMPLATE
+ softrvv_vmslt_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
+
+softrvv_vec_cc_generated_test(
+ NAME
+ vmsle
+ TEMPLATE
+ softrvv_vmsle_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
+
+softrvv_vec_cc_generated_test(
+ NAME
+ vmsgt
+ TEMPLATE
+ softrvv_vmsgt_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
+
+softrvv_vec_cc_generated_test(
+ NAME
+ vmsge
+ TEMPLATE
+ softrvv_vmsge_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
+
vec_cc_test(
NAME
softrvv_vmax
diff --git a/softrvv/tests/templates/opivv_opivx_test.tpl.cpp b/softrvv/tests/templates/opivv_opivx_test.tpl.cpp
index 2a21200..1586eb6 100644
--- a/softrvv/tests/templates/opivv_opivx_test.tpl.cpp
+++ b/softrvv/tests/templates/opivv_opivx_test.tpl.cpp
@@ -1,19 +1,16 @@
<%!
import vec_test_helpers
-%>
-
+%>\
<%def name="test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)">
<%
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)
ref_vx = vec_test_helpers.to_carr_str(ref_vx)
-%>
+%>\
namespace softrvv_${template_helper.op_code}_test {
namespace {
-
${insert_variable_init(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
-
template <typename T>
void assert_vec_elem_eq(int avl, void *test_vector_1, void *test_vector_2) {
T *ptr_vec_1 = reinterpret_cast<T *>(test_vector_1);
@@ -22,16 +19,29 @@
ASSERT_EQ(ptr_vec_1[idx], ptr_vec_2[idx]);
}
}
+
+template <typename T>
+void assert_vec_mask_eq(int avl, void *test_vector_1, void *test_vector_2) {
+ uint32_t *ptr_vec_1 = reinterpret_cast<uint32_t *>(test_vector_1);
+ uint32_t *ptr_vec_2 = reinterpret_cast<uint32_t *>(test_vector_2);
+ for (int idx = 0; idx < avl; idx++) {
+ const int bits_in_element = sizeof(uint32_t) * 8;
+ int eidx = idx / bits_in_element;
+ int epos = idx % bits_in_element;
+ uint32_t *e1 = ptr_vec_1 + eidx;
+ uint32_t *e2 = ptr_vec_2 + eidx;
+ ASSERT_EQ(*e1 & (1 << epos), *e2 & (1 << epos));
+ }
+}
+
class SoftRvv${template_helper.op_code.capitalize()}Test : public ::testing::Test {
protected:
void SetUp() override { memset(dest, 0, sizeof(dest)); }
};
-
-${insert_test(template_helper)}
-
+${insert_test(template_helper)}\
} // namespace
-} // namespace softrvv_${op}_test
-</%def>
+} // namespace softrvv_${op}_test\
+</%def>\
<%def name="insert_variable_init(template_helper, src2, src1, rs1, ref_vv, ref_vx)">
<%
@@ -43,8 +53,8 @@
const int kAVL = sizeof(src1)/sizeof(src1[0]);
${var_types.dest_type} dest[kAVL];
-${var_types.dest_type} ref_vv[] = {${ref_vv}};
-${var_types.dest_type} ref_vx[] = {${ref_vx}};
+${var_types.dest_type} ref_vv[kAVL] = {${ref_vv}};
+${var_types.dest_type} ref_vx[kAVL] = {${ref_vx}};
</%def>\
<%def name="insert_test(template_helper)">
@@ -53,12 +63,20 @@
datatypes = template_helper.get_softrvv_template_data_type()
%>\
TEST_F(SoftRvv${template_helper.op_code.capitalize()}Test, VV) {
- softrvv::${template_helper.op_code}_vv<${datatypes}>(dest, src2, src1, kAVL);
- assert_vec_elem_eq<${var_types.dest_type}>(kAVL, dest, ref_vv);
+ softrvv::${template_helper.op_code}_vv<${datatypes}>(dest, src2, src1, kAVL);\
+${insert_check(template_helper, var_types.dest_type, "ref_vv")}\
}
TEST_F(SoftRvv${template_helper.op_code.capitalize()}Test, VX) {
- softrvv::${template_helper.op_code}_vx<${datatypes}>(dest, src2, &rs1, kAVL);
- assert_vec_elem_eq<${var_types.dest_type}>(kAVL, dest, ref_vx);
+ softrvv::${template_helper.op_code}_vx<${datatypes}>(dest, src2, &rs1, kAVL);\
+${insert_check(template_helper, var_types.dest_type, "ref_vx")}\
}
</%def>\
+
+<%def name="insert_check(template_helper, dest_type, ref_var)">
+% if template_helper.is_destination_mask_register():
+ assert_vec_mask_eq<${dest_type}>(kAVL, dest, ${ref_var});
+% else:
+ assert_vec_elem_eq<${dest_type}>(kAVL, dest, ${ref_var});
+% endif
+</%def>\
diff --git a/softrvv/tests/templates/softrvv_vmseq_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmseq_test.tpl.cpp
new file mode 100644
index 0000000..744d971
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vmseq_test.tpl.cpp
@@ -0,0 +1,16 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+N = 8
+M = 3
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=N)
+indices = np.random.choice(src2.shape[0], M, replace=False)
+src1[indices] = rs1
+src2[indices] = rs1
+ref_vv = template_helper.pack_dest_mask(src2 == src1)
+ref_vx = template_helper.pack_dest_mask(src2 == rs1)
+%>\
+${tests.test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
diff --git a/softrvv/tests/templates/softrvv_vmsge_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmsge_test.tpl.cpp
new file mode 100644
index 0000000..82bbe77
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vmsge_test.tpl.cpp
@@ -0,0 +1,16 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+N = 8
+M = 3
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=N)
+indices = np.random.choice(src2.shape[0], M, replace=False)
+src1[indices] = rs1
+src2[indices] = rs1
+ref_vv = template_helper.pack_dest_mask(src2 >= src1)
+ref_vx = template_helper.pack_dest_mask(src2 >= rs1)
+%>\
+${tests.test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
diff --git a/softrvv/tests/templates/softrvv_vmsgt_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmsgt_test.tpl.cpp
new file mode 100644
index 0000000..5deb454
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vmsgt_test.tpl.cpp
@@ -0,0 +1,12 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+N = 8
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=N)
+ref_vv = template_helper.pack_dest_mask(src2 > src1)
+ref_vx = template_helper.pack_dest_mask(src2 > rs1)
+%>\
+${tests.test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
diff --git a/softrvv/tests/templates/softrvv_vmsle_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmsle_test.tpl.cpp
new file mode 100644
index 0000000..07a1ab1
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vmsle_test.tpl.cpp
@@ -0,0 +1,16 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+N = 8
+M = 2
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=N)
+indices = np.random.choice(src2.shape[0], M, replace=False)
+src1[indices] = rs1
+src2[indices] = rs1
+ref_vv = template_helper.pack_dest_mask(src2 <= src1)
+ref_vx = template_helper.pack_dest_mask(src2 <= rs1)
+%>\
+${tests.test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
diff --git a/softrvv/tests/templates/softrvv_vmslt_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmslt_test.tpl.cpp
new file mode 100644
index 0000000..2b30b84
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vmslt_test.tpl.cpp
@@ -0,0 +1,13 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+N = 8
+M = 3
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=N)
+ref_vv = template_helper.pack_dest_mask(src2 < src1)
+ref_vx = template_helper.pack_dest_mask(src2 < rs1)
+%>\
+${tests.test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
diff --git a/softrvv/tests/templates/softrvv_vmsne_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmsne_test.tpl.cpp
new file mode 100644
index 0000000..5d560ac
--- /dev/null
+++ b/softrvv/tests/templates/softrvv_vmsne_test.tpl.cpp
@@ -0,0 +1,16 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests" file="opivv_opivx_test.tpl.cpp"/>
+<%
+import numpy as np
+import vec_test_helpers
+N = 8
+M = 3
+template_helper = vec_test_helpers.VecTemplateHelper(op, 32)
+src2, src1, rs1 = template_helper.get_test_inputs(n=N)
+indices = np.random.choice(src2.shape[0], M, replace=False)
+src1[indices] = rs1
+src2[indices] = rs1
+ref_vv = template_helper.pack_dest_mask(src2 != src1)
+ref_vx = template_helper.pack_dest_mask(src2 != rs1)
+%>\
+${tests.test_opivv_opivx(template_helper, src2, src1, rs1, ref_vv, ref_vx)}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 9564552..58a22df 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -264,6 +264,96 @@
-Xlinker --defsym=__itcm_length__=192K
)
+vec_cc_generated_test(
+ NAME
+ vmseq
+ TEMPLATE
+ opivv_opivx_opivi_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsne
+ TEMPLATE
+ opivv_opivx_opivi_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsltu
+ TEMPLATE
+ opivv_opivx_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmslt
+ TEMPLATE
+ opivv_opivx_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsleu
+ TEMPLATE
+ opivv_opivx_opivi_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsle
+ TEMPLATE
+ opivv_opivx_opivi_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsgtu
+ TEMPLATE
+ opivx_opivi_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsgt
+ TEMPLATE
+ opivx_opivi_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsgeu
+ TEMPLATE
+ opivx_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
+vec_cc_generated_test(
+ NAME
+ vmsge
+ TEMPLATE
+ opivx_test.tpl.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=192K
+)
+
vec_cc_test(
NAME
vsetvl_test
diff --git a/tests/templates/base_opivi_test.tpl.cpp b/tests/templates/base_opivi_test.tpl.cpp
index 64aa5e0..c1dcc32 100644
--- a/tests/templates/base_opivi_test.tpl.cpp
+++ b/tests/templates/base_opivi_test.tpl.cpp
@@ -90,7 +90,7 @@
memset(dest_vector, 0, MAXVL_BYTES);
memset(ref_dest_vector, 0, MAXVL_BYTES);
// Generate reference vector
- softrvv::${op_code}_vx<${datatypes}>(ptr_ref_dest_vec, ptr_vec_1, &test_val, avl);
+ softrvv::${ref_opcode}_vx<${datatypes}>(ptr_ref_dest_vec, ptr_vec_1, &test_val, avl);
// Load vector registers
__asm__ volatile("vle${src2_sew}.v v8, (%0)" : : "r"(ptr_vec_1));
diff --git a/tests/templates/opivx_test.tpl.cpp b/tests/templates/opivx_test.tpl.cpp
new file mode 100644
index 0000000..a63d525
--- /dev/null
+++ b/tests/templates/opivx_test.tpl.cpp
@@ -0,0 +1,4 @@
+<%inherit file="base.tpl.cpp"/>\
+<%namespace name="tests_vx" file="base_opivx_test.tpl.cpp"/>\
+<%namespace name="tests_vi" file="base_opivi_test.tpl.cpp"/>\
+${tests_vx.test_opivx(op)}