Chromium Code Reviews| Index: crosstest/mem_intrin.c |
| diff --git a/crosstest/mem_intrin.c b/crosstest/mem_intrin.c |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bce0db296451b3a41f8ff62c25017dfdca18d255 |
| --- /dev/null |
| +++ b/crosstest/mem_intrin.c |
| @@ -0,0 +1,78 @@ |
| +/* Simple sanity test of memcpy, memmove, and memset intrinsics. */ |
| + |
| +#include <stdint.h> |
| +#include <stdlib.h> |
| +#include <string.h> |
| + |
| +typedef int elem_t; |
| +#define NWORDS 32 |
| +#define BYTE_LENGTH (32 * sizeof(elem_t)) |
| + |
| +/* |
| + * Reset buf to the sequence of bytes: n, n+1, n+2 ... length - 1 |
| + */ |
| +void __attribute__((noinline)) reset_buf(uint8_t *buf, |
| + uint8_t n, |
| + size_t length) { |
| + size_t i; |
| + for (i = n; i < length; ++i) |
| + buf[i] = i; |
| +} |
| + |
| +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; |
| +} |
| + |
| +/* |
| + * Workaround: There seems to be a mis-alignment of parameters |
| + * when you stack allocate two buffers. So, instead of allocating |
|
Jim Stichnoth
2014/06/12 20:52:07
Hmm. I guess we need some better alloca tests...
jvoung (off chromium)
2014/06/16 20:51:59
After the fix landed this works!
Removed workaroun
|
| + * both buf and buf2 in the same function, only allocate buf, |
| + * then call this helper, which allocates buf2, then use both. |
| + */ |
| +int __attribute__((noinline)) memcpy_helper2(uint8_t *buf, |
| + uint8_t *buf2, |
| + uint8_t n) { |
| + reset_buf((uint8_t *)buf, n, BYTE_LENGTH); |
| + memcpy((void *)buf2, (void *)buf, BYTE_LENGTH); |
| + return sum_buf((uint8_t*)buf2, BYTE_LENGTH); |
| +} |
| + |
| +int __attribute__((noinline)) memcpy_helper(uint8_t *buf, |
| + uint8_t n) { |
| + elem_t buf2[NWORDS]; |
| + return memcpy_helper2(buf, buf2, n); |
| +} |
| + |
| +int memcpy_test(uint8_t n) { |
| + elem_t buf[NWORDS]; |
| + return memcpy_helper(buf, n); |
| +} |
| + |
| +int memmove_test(uint8_t n) { |
| + elem_t buf[NWORDS]; |
| + reset_buf((uint8_t *)buf, n, BYTE_LENGTH); |
| + memmove((void *)(buf + 4), (void *)buf, BYTE_LENGTH - (4 * sizeof(elem_t))); |
| + return sum_buf((uint8_t*)buf + 4, BYTE_LENGTH - 4); |
| +} |
| + |
| +/* Broken: invalid push byte for the memset 'n'. |
| + Probably Subzero assumes that all parameters |
| + are at least i32, so the fact that the intrinsic |
| + violates that breaks it. Otherwise, we should widen |
| + the parameter ourselves before doing the call. |
| + |
| +Output/mem_intrin.sz.s:257:16: error: invalid operand for instruction |
| + push byte ptr [ebp] |
| + ^~~~ |
| + |
| +int memset_test(uint8_t n) { |
| + elem_t buf[NWORDS]; |
| + memset((void *)buf, n, BYTE_LENGTH); |
| + return sum_buf((uint8_t*)buf, BYTE_LENGTH); |
| +} |
| +*/ |