1 // REQUIRES: aarch64-target-arch, aarch64-sme-available
2 // RUN: %clangxx_builtins %s %librt -o %t && %run %t
3
4 #include <cassert>
5 #include <initializer_list>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 extern "C" {
11 void *__arm_sc_memcpy(void *, const void *, size_t);
12 void *__arm_sc_memset(void *, int, size_t);
13 void *__arm_sc_memmove(void *, const void *, size_t);
14 void *__arm_sc_memchr(const void *, int, size_t);
15 }
16
17 template <unsigned N> class Memory {
18 public:
19 uint8_t ptr[N];
20 unsigned size;
21
Memory(unsigned stride=0)22 Memory(unsigned stride = 0) {
23 size = N;
24 if (stride == 0)
25 return;
26 for (unsigned i = 0; i < N; i++)
27 ptr[i] = i * stride;
28 }
29
assert_equal(const Memory & other)30 void assert_equal(const Memory &other) {
31 assert(N == other.size);
32 assert(memcmp(ptr, other.ptr, N) == 0);
33 }
34
assert_equal(std::initializer_list<uint8_t> s)35 void assert_equal(std::initializer_list<uint8_t> s) {
36 assert(N == s.size());
37 auto it = s.begin();
38 for (unsigned i = 0; i < N; ++i)
39 assert(ptr[i] == *it++);
40 }
41
assert_elemt_equal_at(unsigned I,uint8_t elem)42 void assert_elemt_equal_at(unsigned I, uint8_t elem) {
43 assert(ptr[I] == elem);
44 }
45 };
46
main()47 int main() {
48
49 // Testing memcpy from src to dst.
50 {
51 Memory<8> src(1);
52 Memory<8> dst;
53 if (!__arm_sc_memcpy(dst.ptr, src.ptr, 8))
54 abort();
55 dst.assert_equal(src);
56 dst.assert_equal({0, 1, 2, 3, 4, 5, 6, 7});
57 }
58
59 // Testing memcpy from src to dst with pointer offset.
60 {
61 Memory<8> src(1);
62 Memory<8> dst(1);
63 if (!__arm_sc_memcpy(dst.ptr + 1, src.ptr, 6))
64 abort();
65 dst.assert_equal({0, 0, 1, 2, 3, 4, 5, 7});
66 }
67
68 // Testing memchr.
69 {
70 Memory<8> src(4);
71 for (unsigned i = 0; i < 8; ++i) {
72 uint8_t e = src.ptr[i];
73 uint8_t *elem = (uint8_t *)memchr(src.ptr, e, 8);
74 if (!elem)
75 abort();
76 src.assert_elemt_equal_at(elem - src.ptr, *elem);
77 for (unsigned i = 0; i < 8; ++i)
78 assert(__arm_sc_memchr(src.ptr, src.ptr[i], 8) ==
79 memchr(src.ptr, src.ptr[i], 8));
80 }
81 }
82
83 // Testing memset.
84 {
85 Memory<8> array;
86 if (!__arm_sc_memset(array.ptr, 2, 8))
87 abort();
88 array.assert_equal({2, 2, 2, 2, 2, 2, 2, 2});
89 }
90
91 // Testing memset with pointer offset.
92 {
93 Memory<8> array(1);
94 if (!__arm_sc_memset(array.ptr + 1, 2, 6))
95 abort();
96 array.assert_equal({0, 2, 2, 2, 2, 2, 2, 7});
97 }
98
99 // Testing memmove with a simple non-overlap case.
100 {
101 Memory<8> src(1);
102 Memory<8> dst(1);
103 if (!__arm_sc_memmove(dst.ptr + 1, src.ptr, 6))
104 abort();
105 dst.assert_equal({0, 0, 1, 2, 3, 4, 5, 7});
106 }
107
108 // Testing memove with overlap pointers dst > src, dst < src.
109 {
110 Memory<8> srcdst(1);
111 if (!__arm_sc_memmove(srcdst.ptr + 1, srcdst.ptr, 6))
112 abort();
113 srcdst.assert_equal({0, 0, 1, 2, 3, 4, 5, 7});
114 if (!__arm_sc_memmove(srcdst.ptr, srcdst.ptr + 1, 6))
115 abort();
116 srcdst.assert_equal({0, 1, 2, 3, 4, 5, 5, 7});
117 }
118
119 return 0;
120 }
121