OLD | NEW |
(Empty) | |
| 1 /* Simple sanity test of memcpy, memmove, and memset intrinsics. */ |
| 2 |
| 3 #include <stdint.h> |
| 4 #include <stdlib.h> |
| 5 #include <string.h> |
| 6 |
| 7 typedef int elem_t; |
| 8 #define NWORDS 32 |
| 9 #define BYTE_LENGTH (32 * sizeof(elem_t)) |
| 10 |
| 11 /* |
| 12 * Reset buf to the sequence of bytes: n, n+1, n+2 ... length - 1 |
| 13 */ |
| 14 void __attribute__((noinline)) reset_buf(uint8_t *buf, |
| 15 uint8_t n, |
| 16 size_t length) { |
| 17 size_t i; |
| 18 for (i = n; i < length; ++i) |
| 19 buf[i] = i; |
| 20 } |
| 21 |
| 22 int __attribute__((noinline)) sum_buf(uint8_t *buf, |
| 23 size_t length) { |
| 24 size_t i; |
| 25 int sum = 0; |
| 26 for (i = 0; i < length; ++i) |
| 27 sum += buf[i]; |
| 28 return sum; |
| 29 } |
| 30 |
| 31 /* |
| 32 * Workaround: There seems to be a mis-alignment of parameters |
| 33 * when you stack allocate two buffers. So, instead of allocating |
| 34 * both buf and buf2 in the same function, only allocate buf, |
| 35 * then call this helper, which allocates buf2, then use both. |
| 36 */ |
| 37 int __attribute__((noinline)) memcpy_helper(uint8_t *buf, |
| 38 uint8_t n) { |
| 39 elem_t buf2[NWORDS]; |
| 40 reset_buf((uint8_t *)buf, n, BYTE_LENGTH); |
| 41 memcpy((void *)buf2, (void *)buf, BYTE_LENGTH); |
| 42 return sum_buf((uint8_t*)buf2, BYTE_LENGTH); |
| 43 } |
| 44 |
| 45 int memcpy_test(uint8_t n) { |
| 46 elem_t buf[NWORDS]; |
| 47 return memcpy_helper(buf, n); |
| 48 } |
| 49 |
| 50 int memmove_test(uint8_t n) { |
| 51 elem_t buf[NWORDS]; |
| 52 reset_buf((uint8_t *)buf, n, BYTE_LENGTH); |
| 53 memmove((void *)(buf + 4), (void *)buf, BYTE_LENGTH - (4 * sizeof(elem_t))); |
| 54 return sum_buf((uint8_t*)buf + 4, BYTE_LENGTH - 4); |
| 55 } |
| 56 |
| 57 /* Broken: invalid push byte for the memset 'n'. |
| 58 Probably Subzero assumes that all parameters |
| 59 are at least i32, so the fact that the intrinsic |
| 60 violates that breaks it. Otherwise, we should widen |
| 61 the parameter ourselves before doing the call. |
| 62 int memset_test(uint8_t n) { |
| 63 elem_t buf[NWORDS]; |
| 64 memset((void *)buf, n, BYTE_LENGTH); |
| 65 return sum_buf((uint8_t*)buf, BYTE_LENGTH); |
| 66 } |
| 67 */ |
OLD | NEW |