| Index: crosstest/mem_intrin.cpp
|
| diff --git a/crosstest/mem_intrin.cpp b/crosstest/mem_intrin.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e97ece69aef83ffd6a23ce3ff8b57e703b83f503
|
| --- /dev/null
|
| +++ b/crosstest/mem_intrin.cpp
|
| @@ -0,0 +1,88 @@
|
| +/*
|
| + * Simple sanity test of memcpy, memmove, and memset intrinsics.
|
| + * (fixed length buffers, variable length buffers, etc.)
|
| + */
|
| +
|
| +#include "mem_intrin.h"
|
| +
|
| +#include <stdint.h> /* cstdint requires -std=c++0x or higher */
|
| +#include <cstdlib>
|
| +#include <cstring>
|
| +
|
| +typedef int elem_t;
|
| +
|
| +/*
|
| + * Reset buf to the sequence of bytes: n, n+1, n+2 ... length - 1
|
| + */
|
| +static void __attribute__((noinline)) reset_buf(uint8_t *buf,
|
| + uint8_t init,
|
| + size_t length) {
|
| + size_t i;
|
| + size_t v = init;
|
| + for (i = 0; i < length; ++i)
|
| + buf[i] = v++;
|
| +}
|
| +
|
| +static int __attribute__((noinline)) sum_buf(uint8_t *buf,
|
| + size_t length) {
|
| + size_t i;
|
| + int sum = 0;
|
| + for (i = 0; i < length; ++i)
|
| + sum += buf[i];
|
| + return sum;
|
| +}
|
| +
|
| +#define NWORDS 32
|
| +#define BYTE_LENGTH (NWORDS * sizeof(elem_t))
|
| +
|
| +int memcpy_test_fixed_len(uint8_t init) {
|
| + elem_t buf[NWORDS];
|
| + elem_t buf2[NWORDS];
|
| + reset_buf((uint8_t *)buf, init, BYTE_LENGTH);
|
| + memcpy((void *)buf2, (void *)buf, BYTE_LENGTH);
|
| + return sum_buf((uint8_t*)buf2, BYTE_LENGTH);
|
| +}
|
| +
|
| +int memmove_test_fixed_len(uint8_t init) {
|
| + elem_t buf[NWORDS];
|
| + reset_buf((uint8_t *)buf, init, BYTE_LENGTH);
|
| + memmove((void *)(buf + 4), (void *)buf, BYTE_LENGTH - (4 * sizeof(elem_t)));
|
| + return sum_buf((uint8_t*)buf + 4, BYTE_LENGTH - 4);
|
| +}
|
| +
|
| +int memset_test_fixed_len(uint8_t init) {
|
| + elem_t buf[NWORDS];
|
| + memset((void *)buf, init, BYTE_LENGTH);
|
| + return sum_buf((uint8_t*)buf, BYTE_LENGTH);
|
| +}
|
| +
|
| +int memcpy_test(uint8_t *buf, void *buf2, uint8_t init, size_t length) {
|
| + reset_buf(buf, init, length);
|
| + memcpy(buf2, (void *)buf, length);
|
| + return sum_buf((uint8_t *)buf2, length);
|
| +}
|
| +
|
| +int memmove_test(uint8_t *buf, void *buf2, uint8_t init, size_t length) {
|
| + int sum1;
|
| + int sum2;
|
| + const int overlap_bytes = 4 * sizeof(elem_t);
|
| + if (length <= overlap_bytes)
|
| + return 0;
|
| + uint8_t *overlap_buf = buf + overlap_bytes;
|
| + size_t reduced_length = length - overlap_bytes;
|
| + reset_buf(buf, init, length);
|
| +
|
| + /* Test w/ overlap. */
|
| + memmove((void *)overlap_buf, (void *)buf, reduced_length);
|
| + sum1 = sum_buf(overlap_buf, reduced_length);
|
| + /* Test w/out overlap. */
|
| + memmove(buf2, (void *)buf, length);
|
| + sum2 = sum_buf((uint8_t *)buf2, length);
|
| + return sum1 + sum2;
|
| +}
|
| +
|
| +int memset_test(uint8_t *buf, void *buf2, uint8_t init, size_t length) {
|
| + memset((void *)buf, init, length);
|
| + memset(buf2, init + 4, length);
|
| + return sum_buf(buf, length) + sum_buf((uint8_t *)buf2, length);
|
| +}
|
|
|