blob: 612edce481722e3cba8804d1e3a7b1ddec13bc43 [file] [log] [blame]
/*
* Simple sanity test of memcpy, memmove, and memset intrinsics.
* (fixed length buffers, variable length buffers, etc.)
*/
#include <stdint.h> /* cstdint requires -std=c++0x or higher */
#include <cstdlib>
#include <cstring>
#include "mem_intrin.h"
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++;
}
/* Do a fletcher-16 checksum so that the order of the values matter.
* (Not doing a fletcher-32 checksum, since we are working with
* smaller buffers, whose total won't approach 2**16).
*/
static int __attribute__((noinline))
fletcher_checksum(uint8_t *buf, size_t length) {
size_t i;
int sum = 0;
int sum_of_sums = 0;
const int kModulus = 255;
for (i = 0; i < length; ++i) {
sum = (sum + buf[i]) % kModulus;
sum_of_sums = (sum_of_sums + sum) % kModulus;
}
return (sum_of_sums << 8) | 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 fletcher_checksum((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 fletcher_checksum((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 fletcher_checksum((uint8_t *)buf, BYTE_LENGTH);
}
int memcpy_test(uint8_t *buf, uint8_t *buf2, uint8_t init, size_t length) {
reset_buf(buf, init, length);
memcpy((void *)buf2, (void *)buf, length);
return fletcher_checksum(buf2, length);
}
int memmove_test(uint8_t *buf, uint8_t *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 = fletcher_checksum(overlap_buf, reduced_length);
/* Test w/out overlap. */
memmove((void *)buf2, (void *)buf, length);
sum2 = fletcher_checksum(buf2, length);
return sum1 + sum2;
}
int memset_test(uint8_t *buf, uint8_t *buf2, uint8_t init, size_t length) {
memset((void *)buf, init, length);
memset((void *)buf2, init + 4, length);
return fletcher_checksum(buf, length) + fletcher_checksum(buf2, length);
}