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