From: Joel Stanley <[email protected]>

A C userspace program to perform vector loads and stores that cross page
boundaries, and check the result.

Signed-off-by: Joel Stanley <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
Message-ID: <[email protected]>
---
 tests/tcg/riscv64/test-rvv-ldst-intrinsics.c | 66 ++++++++++++++++++++
 tests/tcg/riscv64/Makefile.target            | 12 +++-
 2 files changed, 75 insertions(+), 3 deletions(-)
 create mode 100644 tests/tcg/riscv64/test-rvv-ldst-intrinsics.c

diff --git a/tests/tcg/riscv64/test-rvv-ldst-intrinsics.c 
b/tests/tcg/riscv64/test-rvv-ldst-intrinsics.c
new file mode 100644
index 0000000000..3dbc862470
--- /dev/null
+++ b/tests/tcg/riscv64/test-rvv-ldst-intrinsics.c
@@ -0,0 +1,66 @@
+/*
+ * RISC-V vector load/store test, including accesses that cross a page
+ * boundary. Intrinsics version of test-rvv-ldst.S.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <riscv_vector.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX_PAGE_SIZE 65536
+#define NUM_BYTES 16
+
+struct cross_page {
+    uint8_t pad[MAX_PAGE_SIZE - NUM_BYTES / 2];
+    uint8_t data[NUM_BYTES];
+};
+
+/* Page aligned so the within-page cases never cross a boundary */
+static const uint8_t src_data[NUM_BYTES]
+    __attribute__((aligned(MAX_PAGE_SIZE))) = {
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+};
+
+static const struct cross_page src_cross
+    __attribute__((aligned(MAX_PAGE_SIZE))) = {
+    .data = {
+        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+        0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+    },
+};
+
+static uint8_t dst_data[NUM_BYTES] __attribute__((aligned(MAX_PAGE_SIZE)));
+static struct cross_page dst_cross __attribute__((aligned(MAX_PAGE_SIZE)));
+
+static void vec_copy(uint8_t *dst, const uint8_t *src, int code)
+{
+    size_t vl = __riscv_vsetvl_e8m1(NUM_BYTES);
+    if (vl != NUM_BYTES) {
+        exit(code);
+    }
+
+    vuint8m1_t v = __riscv_vle8_v_u8m1(src, vl);
+    __riscv_vse8_v_u8m1(dst, v, vl);
+
+    if (memcmp(dst, src, NUM_BYTES)) {
+        exit(code);
+    }
+}
+
+int main(void)
+{
+    /* Case 1: load/store within a page */
+    vec_copy(dst_data, src_data, 1);
+
+    /* Case 2: the load straddles a page boundary */
+    vec_copy(dst_data, src_cross.data, 2);
+
+    /* Case 3: the store straddles a page boundary */
+    vec_copy(dst_cross.data, src_data, 3);
+
+    return 0;
+}
diff --git a/tests/tcg/riscv64/Makefile.target 
b/tests/tcg/riscv64/Makefile.target
index 68a5ec5255..3c6cd4937c 100644
--- a/tests/tcg/riscv64/Makefile.target
+++ b/tests/tcg/riscv64/Makefile.target
@@ -14,10 +14,11 @@ TESTS += test-aes
 run-test-aes: QEMU_OPTS += -cpu rv64,zk=on
 
 # Vector load test
-TESTS += test-rvv-ldst
-test-rvv-ldst: CFLAGS += -march=rv64gcv
+TESTS += test-rvv-ldst test-rvv-ldst-intrinsics
+test-rvv-ldst-intrinsics test-rvv-ldst: CFLAGS += -march=rv64gcv
 test-rvv-ldst: LDFLAGS = -nostdlib -static
-run-test-rvv-ldst: QEMU_OPTS += -cpu max
+test-rvv-ldst-intrinsics: LDFLAGS = -static
+run-test-rvv-ldst-intrinsics run-test-rvv-ldst: QEMU_OPTS += -cpu max
 
 # Re-run the vector tests at each supported VLEN
 TEST_RVV_VLENS = 128 256 512 1024
@@ -26,6 +27,11 @@ run-test-rvv-ldst-vlen%: test-rvv-ldst
        $(call run-test, $@, env QEMU=$(QEMU) $(QEMU) $(QEMU_OPTS) -cpu 
max$(COMMA)vlen=$* $<, \
                test-rvv-ldst with vlen=$*)
 
+EXTRA_RUNS += $(patsubst 
%,run-test-rvv-ldst-intrinsics-vlen%,$(TEST_RVV_VLENS))
+run-test-rvv-ldst-intrinsics-vlen%: test-rvv-ldst-intrinsics
+       $(call run-test, $@, env QEMU=$(QEMU) $(QEMU) $(QEMU_OPTS) -cpu 
max$(COMMA)vlen=$* $<, \
+               test-rvv-ldst-intrinsics with vlen=$*)
+
 # Test for fcvtmod
 TESTS += test-fcvtmod
 test-fcvtmod: CFLAGS += -march=rv64imafdc
-- 
2.43.0


Reply via email to