Path: blob/main/contrib/arm-optimized-routines/string/test/memmove.c
39534 views
/*1* memmove test.2*3* Copyright (c) 2019-2023, Arm Limited.4* SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception5*/67#include <stdint.h>8#include <stdio.h>9#include <stdlib.h>10#include <string.h>11#include "mte.h"12#include "stringlib.h"13#include "stringtest.h"1415#define F(x, mte) {#x, x, mte},1617static const struct fun18{19const char *name;20void *(*fun) (void *, const void *, size_t);21int test_mte;22} funtab[] = {23// clang-format off24F(memmove, 0)25#if __aarch64__26F(__memmove_aarch64, 1)27F(__memmove_aarch64_simd, 1)28# if __ARM_FEATURE_SVE29F(__memmove_aarch64_sve, 1)30# endif31# if WANT_MOPS32F(__memmove_aarch64_mops, 1)33# endif34#endif35{0, 0, 0}36// clang-format on37};38#undef F3940#define A 3241#define LEN 25000042static unsigned char *dbuf;43static unsigned char *sbuf;44static unsigned char wbuf[LEN + 2 * A];4546static void *47alignup (void *p)48{49return (void *) (((uintptr_t) p + A - 1) & -A);50}5152static void53test (const struct fun *fun, int dalign, int salign, int len)54{55unsigned char *src = alignup (sbuf);56unsigned char *dst = alignup (dbuf);57unsigned char *want = wbuf;58unsigned char *s = src + salign;59unsigned char *d = dst + dalign;60unsigned char *w = want + dalign;61void *p;62int i;6364if (err_count >= ERR_LIMIT)65return;66if (len > LEN || dalign >= A || salign >= A)67abort ();68for (i = 0; i < len + A; i++)69{70src[i] = '?';71want[i] = dst[i] = '*';72}73for (i = 0; i < len; i++)74s[i] = w[i] = 'a' + i % 23;7576p = fun->fun (d, s, len);77if (p != d)78ERR ("%s(%p,..) returned %p\n", fun->name, d, p);79for (i = 0; i < len + A; i++)80{81if (dst[i] != want[i])82{83ERR ("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign,84len);85quoteat ("got", dst, len + A, i);86quoteat ("want", want, len + A, i);87break;88}89}90}9192static void93test_overlap (const struct fun *fun, int dalign, int salign, int len)94{95unsigned char *src = alignup (sbuf);96unsigned char *dst = src;97unsigned char *want = wbuf;98unsigned char *s = src + salign;99unsigned char *d = dst + dalign;100unsigned char *w = wbuf + dalign;101void *p;102103if (err_count >= ERR_LIMIT)104return;105if (len > LEN || dalign >= A || salign >= A)106abort ();107108for (int i = 0; i < len + A; i++)109src[i] = want[i] = '?';110111for (int i = 0; i < len; i++)112s[i] = want[salign + i] = 'a' + i % 23;113for (int i = 0; i < len; i++)114w[i] = s[i];115116s = tag_buffer (s, len, fun->test_mte);117d = tag_buffer (d, len, fun->test_mte);118p = fun->fun (d, s, len);119untag_buffer (s, len, fun->test_mte);120untag_buffer (d, len, fun->test_mte);121122if (p != d)123ERR ("%s(%p,..) returned %p\n", fun->name, d, p);124for (int i = 0; i < len + A; i++)125{126if (dst[i] != want[i])127{128ERR ("%s(align %d, align %d, %d) failed\n", fun->name, dalign, salign,129len);130quoteat ("got", dst, len + A, i);131quoteat ("want", want, len + A, i);132break;133}134}135}136137int138main ()139{140dbuf = mte_mmap (LEN + 2 * A);141sbuf = mte_mmap (LEN + 2 * A);142int r = 0;143for (int i = 0; funtab[i].name; i++)144{145err_count = 0;146for (int d = 0; d < A; d++)147for (int s = 0; s < A; s++)148{149int n;150for (n = 0; n < 100; n++)151{152test (funtab + i, d, s, n);153test_overlap (funtab + i, d, s, n);154}155for (; n < LEN; n *= 2)156{157test (funtab + i, d, s, n);158test_overlap (funtab + i, d, s, n);159}160}161char *pass = funtab[i].test_mte && mte_enabled () ? "MTE PASS" : "PASS";162printf ("%s %s\n", err_count ? "FAIL" : pass, funtab[i].name);163if (err_count)164r = -1;165}166return r;167}168169170