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); |
+} |
+*/ |