sw:vec:tests: Add multi-register load/store tests
Add v{l,s}{1,2,4,8}re{8,16,32} tests
Change-Id: Ifec16a55e43a898553ed97ef3a9699af283083f9
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 646c272..02a410c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -249,3 +249,12 @@
TIMEOUT
40
)
+
+vec_cc_test(
+ NAME
+ vlnr_vsnr_test
+ SRCS
+ vlnr_vsnr_test.cpp
+ LINKOPTS
+ -Xlinker --defsym=__itcm_length__=128K
+)
diff --git a/tests/vlnr_vsnr_test.cpp b/tests/vlnr_vsnr_test.cpp
new file mode 100644
index 0000000..a552600
--- /dev/null
+++ b/tests/vlnr_vsnr_test.cpp
@@ -0,0 +1,146 @@
+#include <stdlib.h>
+
+#include "pw_unit_test/framework.h"
+#include "test_v_helpers.h"
+
+// Test for vl{1,2,8}re{8,16,32}.v and vs{1,2,8}r{8,16,32}.v instructions.
+namespace vlnr_vsnr_test {
+namespace {
+
+using namespace test_v_helpers;
+
+uint8_t test_vector_1[MAXVL_BYTES];
+uint8_t reference_vector_1[MAXVL_BYTES];
+
+enum VNF { NF1 = 0, NF2 = 1, NF4 = 2, NF8 = 3 };
+
+class VlnrVsnrTest : public ::testing::Test {
+ public:
+ void vsr_test(VSEW sew, VNF nf);
+
+ protected:
+ void SetUp() override { zero_vector_registers(); }
+ void TearDown() override { zero_vector_registers(); }
+};
+
+void VlnrVsnrTest::vsr_test(VSEW sew, VNF nf) {
+ int avl = get_vsetvlmax_intrinsic(SEW_E8, LMUL_M1);
+ int vlmax;
+ int vl;
+ int nf_val = 1 << nf;
+
+ std::tie(vlmax, vl) = vector_test_setup<uint8_t>(
+ LMUL_M1, avl, {test_vector_1, reference_vector_1});
+ fill_random_vector<uint8_t>(reinterpret_cast<uint8_t *>(reference_vector_1),
+ avl * nf_val);
+ switch (nf) {
+ case NF1: {
+ switch (sew) {
+ case SEW_E8:
+ __asm__ volatile(
+ "vl1r.v v25, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E16:
+ __asm__ volatile(
+ "vl1re16.v v25, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E32:
+ __asm__ volatile(
+ "vl1re32.v v25, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ default:
+ break;
+ }
+ __asm__ volatile("vs1r.v v25, (%[REG])" ::[REG] "r"(test_vector_1));
+ break;
+ }
+ case NF2: {
+ switch (sew) {
+ case SEW_E8:
+ __asm__ volatile(
+ "vl2r.v v26, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E16:
+ __asm__ volatile(
+ "vl2re16.v v26, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E32:
+ __asm__ volatile(
+ "vl2re32.v v26, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ default:
+ break;
+ }
+ __asm__ volatile("vs2r.v v26, (%[REG])" ::[REG] "r"(test_vector_1));
+ break;
+ }
+ case NF4: {
+ switch (sew) {
+ case SEW_E8:
+ __asm__ volatile(
+ "vl4r.v v28, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E16:
+ __asm__ volatile(
+ "vl4re16.v v28, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E32:
+ __asm__ volatile(
+ "vl4re32.v v28, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ default:
+ break;
+ }
+ __asm__ volatile("vs4r.v v28, (%[REG])" ::[REG] "r"(test_vector_1));
+ break;
+ }
+ case NF8: {
+ switch (sew) {
+ case SEW_E8:
+ __asm__ volatile(
+ "vl8r.v v0, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E16:
+ __asm__ volatile(
+ "vl8re16.v v0, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ case SEW_E32:
+ __asm__ volatile(
+ "vl8re32.v v0, (%[REG])" ::[REG] "r"(reference_vector_1));
+ break;
+ default:
+ break;
+ }
+ __asm__ volatile("vs8r.v v0, (%[REG])" ::[REG] "r"(test_vector_1));
+ break;
+ }
+ }
+ assert_vec_elem_eq<uint8_t>(avl * nf_val, test_vector_1, reference_vector_1);
+}
+
+TEST_F(VlnrVsnrTest, vl1re8_vs1r) { vsr_test(SEW_E8, NF1); }
+
+TEST_F(VlnrVsnrTest, vl2re8_vs2r) { vsr_test(SEW_E8, NF2); }
+
+TEST_F(VlnrVsnrTest, vl4re8_vs4r) { vsr_test(SEW_E8, NF4); }
+
+TEST_F(VlnrVsnrTest, vl8re8_vs8r) { vsr_test(SEW_E8, NF8); }
+
+TEST_F(VlnrVsnrTest, vl1re16_vs1r) { vsr_test(SEW_E16, NF1); }
+
+TEST_F(VlnrVsnrTest, vl2re16_vs2r) { vsr_test(SEW_E16, NF2); }
+
+TEST_F(VlnrVsnrTest, vl4re16_vs4r) { vsr_test(SEW_E16, NF4); }
+
+TEST_F(VlnrVsnrTest, vl8re16_vs8r) { vsr_test(SEW_E16, NF8); }
+
+TEST_F(VlnrVsnrTest, vl1re32_vs1r) { vsr_test(SEW_E32, NF1); }
+
+TEST_F(VlnrVsnrTest, vl2re32_vs2r) { vsr_test(SEW_E32, NF2); }
+
+TEST_F(VlnrVsnrTest, vl4re32_vs4r) { vsr_test(SEW_E32, NF4); }
+
+TEST_F(VlnrVsnrTest, vl8re32_vs8r) { vsr_test(SEW_E32, NF8); }
+
+} // namespace
+} // namespace vlnr_vsnr_test