Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Simple sanity test of memcpy, memmove, and memset intrinsics. |
| 3 | * (fixed length buffers, variable length buffers, etc.) |
| 4 | */ |
| 5 | |
| 6 | #include <stdint.h> /* cstdint requires -std=c++0x or higher */ |
| 7 | #include <cstdlib> |
| 8 | #include <cstring> |
| 9 | |
| 10 | #include "mem_intrin.h" |
| 11 | |
| 12 | typedef int elem_t; |
| 13 | |
| 14 | /* |
| 15 | * Reset buf to the sequence of bytes: n, n+1, n+2 ... length - 1 |
| 16 | */ |
| 17 | static void __attribute__((noinline)) reset_buf(uint8_t *buf, |
| 18 | uint8_t init, |
| 19 | size_t length) { |
| 20 | size_t i; |
| 21 | size_t v = init; |
| 22 | for (i = 0; i < length; ++i) |
| 23 | buf[i] = v++; |
| 24 | } |
| 25 | |
| 26 | /* Do a fletcher-16 checksum so that the order of the values matter. |
| 27 | * (Not doing a fletcher-32 checksum, since we are working with |
| 28 | * smaller buffers, whose total won't approach 2**16). |
| 29 | */ |
| 30 | static int __attribute__((noinline)) fletcher_checksum(uint8_t *buf, |
| 31 | size_t length) { |
| 32 | size_t i; |
| 33 | int sum = 0; |
| 34 | int sum_of_sums = 0; |
| 35 | const int kModulus = 255; |
| 36 | for (i = 0; i < length; ++i) { |
| 37 | sum = (sum + buf[i]) % kModulus; |
| 38 | sum_of_sums = (sum_of_sums + sum) % kModulus; |
| 39 | } |
| 40 | return (sum_of_sums << 8) | sum; |
| 41 | } |
| 42 | |
| 43 | #define NWORDS 32 |
| 44 | #define BYTE_LENGTH (NWORDS * sizeof(elem_t)) |
| 45 | |
| 46 | int memcpy_test_fixed_len(uint8_t init) { |
| 47 | elem_t buf[NWORDS]; |
| 48 | elem_t buf2[NWORDS]; |
| 49 | reset_buf((uint8_t *)buf, init, BYTE_LENGTH); |
| 50 | memcpy((void *)buf2, (void *)buf, BYTE_LENGTH); |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 51 | return fletcher_checksum((uint8_t *)buf2, BYTE_LENGTH); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 52 | } |
| 53 | |
| 54 | int memmove_test_fixed_len(uint8_t init) { |
| 55 | elem_t buf[NWORDS]; |
| 56 | reset_buf((uint8_t *)buf, init, BYTE_LENGTH); |
| 57 | memmove((void *)(buf + 4), (void *)buf, BYTE_LENGTH - (4 * sizeof(elem_t))); |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 58 | return fletcher_checksum((uint8_t *)buf + 4, BYTE_LENGTH - 4); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | int memset_test_fixed_len(uint8_t init) { |
| 62 | elem_t buf[NWORDS]; |
| 63 | memset((void *)buf, init, BYTE_LENGTH); |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 64 | return fletcher_checksum((uint8_t *)buf, BYTE_LENGTH); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 65 | } |
| 66 | |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 67 | int memcpy_test(uint8_t *buf, uint8_t *buf2, uint8_t init, size_t length) { |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 68 | reset_buf(buf, init, length); |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 69 | memcpy((void *)buf2, (void *)buf, length); |
| 70 | return fletcher_checksum(buf2, length); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 71 | } |
| 72 | |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 73 | int memmove_test(uint8_t *buf, uint8_t *buf2, uint8_t init, size_t length) { |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 74 | int sum1; |
| 75 | int sum2; |
| 76 | const int overlap_bytes = 4 * sizeof(elem_t); |
| 77 | if (length <= overlap_bytes) |
| 78 | return 0; |
| 79 | uint8_t *overlap_buf = buf + overlap_bytes; |
| 80 | size_t reduced_length = length - overlap_bytes; |
| 81 | reset_buf(buf, init, length); |
| 82 | |
| 83 | /* Test w/ overlap. */ |
| 84 | memmove((void *)overlap_buf, (void *)buf, reduced_length); |
| 85 | sum1 = fletcher_checksum(overlap_buf, reduced_length); |
| 86 | /* Test w/out overlap. */ |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 87 | memmove((void *)buf2, (void *)buf, length); |
| 88 | sum2 = fletcher_checksum(buf2, length); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 89 | return sum1 + sum2; |
| 90 | } |
| 91 | |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 92 | int memset_test(uint8_t *buf, uint8_t *buf2, uint8_t init, size_t length) { |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 93 | memset((void *)buf, init, length); |
Jan Voung | 140bb0d | 2014-07-14 11:51:44 -0700 | [diff] [blame] | 94 | memset((void *)buf2, init + 4, length); |
| 95 | return fletcher_checksum(buf, length) + fletcher_checksum(buf2, length); |
Jan Voung | 3bd9f1a | 2014-06-18 10:50:57 -0700 | [diff] [blame] | 96 | } |