xref: /llvm-project/compiler-rt/test/builtins/Unit/sme-string-test.cpp (revision 3112578597c031e6f00c4b126182bd0d8582c729)
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