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
10extern "C" {
11void *__arm_sc_memcpy(void *, const void *, size_t);
12void *__arm_sc_memset(void *, int, size_t);
13void *__arm_sc_memmove(void *, const void *, size_t);
14void *__arm_sc_memchr(const void *, int, size_t);
15}
16
17template <unsigned N> class Memory {
18public:
19 uint8_t ptr[N];
20 unsigned size;
21
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
30 void assert_equal(const Memory &other) {
31 assert(N == other.size);
32 assert(memcmp(ptr, other.ptr, N) == 0);
33 }
34
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
42 void assert_elemt_equal_at(unsigned I, uint8_t elem) {
43 assert(ptr[I] == elem);
44 }
45};
46
47int 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(other: src);
56 dst.assert_equal(s: {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(s: {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(s: src.ptr, c: e, n: 8);
74 if (!elem)
75 abort();
76 src.assert_elemt_equal_at(I: elem - src.ptr, elem: *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(s: {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(s: {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(s: {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(s: {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(s: {0, 1, 2, 3, 4, 5, 5, 7});
117 }
118
119 return 0;
120}
121

source code of compiler-rt/test/builtins/Unit/sme-string-test.cpp