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 | |
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
| |
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_helper2(uint8_t *buf, | |
38 uint8_t *buf2, | |
39 uint8_t n) { | |
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 __attribute__((noinline)) memcpy_helper(uint8_t *buf, | |
46 uint8_t n) { | |
47 elem_t buf2[NWORDS]; | |
48 return memcpy_helper2(buf, buf2, n); | |
49 } | |
50 | |
51 int memcpy_test(uint8_t n) { | |
52 elem_t buf[NWORDS]; | |
53 return memcpy_helper(buf, n); | |
54 } | |
55 | |
56 int memmove_test(uint8_t n) { | |
57 elem_t buf[NWORDS]; | |
58 reset_buf((uint8_t *)buf, n, BYTE_LENGTH); | |
59 memmove((void *)(buf + 4), (void *)buf, BYTE_LENGTH - (4 * sizeof(elem_t))); | |
60 return sum_buf((uint8_t*)buf + 4, BYTE_LENGTH - 4); | |
61 } | |
62 | |
63 /* Broken: invalid push byte for the memset 'n'. | |
64 Probably Subzero assumes that all parameters | |
65 are at least i32, so the fact that the intrinsic | |
66 violates that breaks it. Otherwise, we should widen | |
67 the parameter ourselves before doing the call. | |
68 | |
69 Output/mem_intrin.sz.s:257:16: error: invalid operand for instruction | |
70 push byte ptr [ebp] | |
71 ^~~~ | |
72 | |
73 int memset_test(uint8_t n) { | |
74 elem_t buf[NWORDS]; | |
75 memset((void *)buf, n, BYTE_LENGTH); | |
76 return sum_buf((uint8_t*)buf, BYTE_LENGTH); | |
77 } | |
78 */ | |
OLD | NEW |