Add support for vmul and vmulh. * Add softrvv vmul, vmulh implementations and tests. * Add vmul, vmulh vector instruction tests. Change-Id: Ib07351314112e7670f969cac2cf626aee4408cbf
diff --git a/softrvv/include/softrvv.h b/softrvv/include/softrvv.h index 0edbf3c..596341f 100644 --- a/softrvv/include/softrvv.h +++ b/softrvv/include/softrvv.h
@@ -6,11 +6,11 @@ #include "encoding.h" #include "softrvv_vadd.h" #include "softrvv_vmin.h" +#include "softrvv_vmul_vmulh.h" +#include "softrvv_vsext_vzext.h" #include "softrvv_vsub.h" #include "softrvv_vwadd.h" #include "softrvv_vwsub.h" -#include "softrvv_vsext_vzext.h" - namespace softrvv {
diff --git a/softrvv/include/softrvv_vmul_vmulh.h b/softrvv/include/softrvv_vmul_vmulh.h new file mode 100644 index 0000000..1e5a816 --- /dev/null +++ b/softrvv/include/softrvv_vmul_vmulh.h
@@ -0,0 +1,44 @@ +#ifndef SOFTRVV_VMUL_H +#define SOFTRVV_VMUL_H + +#include <stddef.h> + +namespace softrvv { + +template <typename T> +void vmul_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 vmul_vv(T *dest, T *src1, T *src2, int32_t avl) { + for (int32_t idx = 0; idx < avl; idx++) { + dest[idx] = src1[idx] * src2[idx]; + } +} + +template <typename T> +void vmulh_vx(T *dest, T *src1, const T *src2, int32_t avl) { + for (int32_t idx = 0; idx < avl; idx++) { + // TODO(b/197705521) find a better way to promote T to larger type + int64_t temp = + static_cast<int64_t>(src1[idx]) * static_cast<int64_t>(*src2); + dest[idx] = static_cast<T>(temp >> (sizeof(T) * 8)); + } +} + +template <typename T> +void vmulh_vv(T *dest, T *src1, T *src2, int32_t avl) { + for (int32_t idx = 0; idx < avl; idx++) { + // TODO(b/197705521) find a better way to promote T to larger type + int64_t temp = + static_cast<int64_t>(src1[idx]) * static_cast<int64_t>(src2[idx]); + dest[idx] = static_cast<T>(temp >> (sizeof(T) * 8)); + } +} + +} // namespace softrvv + +#endif // SOFTRVV_VMUL_H
diff --git a/softrvv/tests/CMakeLists.txt b/softrvv/tests/CMakeLists.txt index edb6575..0638773 100644 --- a/softrvv/tests/CMakeLists.txt +++ b/softrvv/tests/CMakeLists.txt
@@ -108,3 +108,21 @@ LINKOPTS -Xlinker --defsym=__itcm_length__=128K ) + +softrvv_vec_cc_generated_test( + NAME + vmul + TEMPLATE + softrvv_vmul_test.tpl.cpp + LINKOPTS + -Xlinker --defsym=__itcm_length__=128K +) + +softrvv_vec_cc_generated_test( + NAME + vmulh + TEMPLATE + softrvv_vmulh_test.tpl.cpp + LINKOPTS + -Xlinker --defsym=__itcm_length__=128K +)
diff --git a/softrvv/tests/templates/softrvv_vmul_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmul_test.tpl.cpp new file mode 100644 index 0000000..e9a1832 --- /dev/null +++ b/softrvv/tests/templates/softrvv_vmul_test.tpl.cpp
@@ -0,0 +1,20 @@ +<%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.randint(ii32.min, ii32.max, N).astype(np.int32) +src2_data = np.random.randint(ii32.min, ii32.max, N).astype(np.int32) +rs1 = np.int32(np.random.randint(ii32.min, ii32.max)) +ref_vv_data = src1_data * src2_data +ref_vx_data = src1_data * rs1 + +# 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/softrvv/tests/templates/softrvv_vmulh_test.tpl.cpp b/softrvv/tests/templates/softrvv_vmulh_test.tpl.cpp new file mode 100644 index 0000000..c4d82a8 --- /dev/null +++ b/softrvv/tests/templates/softrvv_vmulh_test.tpl.cpp
@@ -0,0 +1,22 @@ +<%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.randint(ii32.min, ii32.max, N).astype(np.int32) +src2_data = np.random.randint(ii32.min, ii32.max, N).astype(np.int32) +rs1 = np.int32(np.random.randint(ii32.min, ii32.max)) +ref_vv_data = np.right_shift( + src1_data.astype(np.int64) * src2_data.astype(np.int64), 32).astype(np.int32) +ref_vx_data = np.right_shift( + src1_data.astype(np.int64) * rs1, 32).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 1ec4a36..effcafe 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt
@@ -64,6 +64,36 @@ vec_cc_generated_test( NAME + vmul + OPFMT + OPIVV + OPIVX + LINKOPTS + -Xlinker --defsym=__itcm_length__=128K +) + +vec_cc_generated_test( + NAME + vmulh + OPFMT + OPIVV + OPIVX + LINKOPTS + -Xlinker --defsym=__itcm_length__=128K +) + +vec_cc_generated_test( + NAME + vmulhu + OPFMT + OPIVV + OPIVX + LINKOPTS + -Xlinker --defsym=__itcm_length__=128K +) + +vec_cc_generated_test( + NAME vwadd OPFMT OPIVV