121 lines · cpp
1// REQUIRES: aarch64-target-arch, aarch64-sme-available2// RUN: %clangxx_builtins %s %librt -o %t && %run %t3 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(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