blob: 5d4da6b9f359cad179ae80c73c0935a2494136e5 [file] [log] [blame]
sewardjff620022012-03-27 09:39:22 +00001#include "tests/malloc.h"
sewardjda04f3e2012-03-08 14:51:01 +00002#include <stdio.h>
3#include <assert.h>
4
5typedef unsigned long long int ULong;
6typedef unsigned long int UWord;
7
8__attribute__((noinline))
9static int my_ffsll ( ULong x )
10{
11 int i;
12 for (i = 0; i < 64; i++) {
13 if ((x & 1ULL) == 1ULL)
14 break;
15 x >>= 1;
16 }
17 return i+1;
18}
19
20/* Find length of string, assuming it is aligned and shorter than 8
21 characters. Little-endian only. */
22__attribute__((noinline))
23static int aligned_strlen(char *s)
24{
25 /* This is for 64-bit platforms */
26 assert(sizeof(ULong) == 8);
27 /* ..and only works for aligned input */
28 assert(((unsigned long)s & 0x7) == 0);
29
30 /* read 8 bytes */
31 ULong val = *(ULong*)s;
32 /* Subtract one from each byte */
33 ULong val2 = val - 0x0101010101010101ULL;
34 /* Find lowest byte whose high bit changed */
35 val2 ^= val;
36 val2 &= 0x8080808080808080ULL;
37
38 return (my_ffsll(val2) / 8) - 1;
39}
40
41__attribute__((noinline)) void foo ( int x )
42{
43 __asm__ __volatile__("":::"memory");
44}
45
46int
47main(int argc, char *argv[])
48{
sewardjff620022012-03-27 09:39:22 +000049 char *buf = memalign16(5);
sewardjda04f3e2012-03-08 14:51:01 +000050 buf[0] = 'a';
51 buf[1] = 'b';
52 buf[2] = 'c';
53 buf[3] = 'd';
54 buf[4] = '\0';
55
56 /* --partial-loads-ok=no: expect addr error (here) */
57 /* --partial-loads-ok=yes: expect no error */
58 if (aligned_strlen(buf) == 4)
59 foo(44);
60
61 /* --partial-loads-ok=no: expect addr error (here) */
62 /* --partial-loads-ok=yes: expect value error (in my_ffsll) */
63 buf[4] = 'x';
64 if (aligned_strlen(buf) == 0)
65 foo(37);
66
67 free(buf);
68
69 /* Also, we need to check that a completely out-of-range,
70 word-sized load gives an addressing error regardless of the
71 start of --partial-loads-ok=. *And* that the resulting
72 value is completely defined. */
73 UWord* words = malloc(3 * sizeof(UWord));
74 free(words);
75
76 /* Should ALWAYS give an addr error. */
77 UWord w = words[1];
78
79 /* Should NEVER give an error (you might expect a value one, but no.) */
80 if (w == 0x31415927) {
81 fprintf(stderr,
82 "Elvis is alive and well and living in Milton Keynes.\n");
83 }
84
85 return 0;
86}