blob: 2f14e7581353a1ee13c7756ea9cc15e4fcc1ac62 [file] [log] [blame]
sewardj9b826d62012-11-19 15:12:07 +00001/* https://bugs.kde.org/show_bug.cgi?id=308627 */
2
3#include "../../memcheck.h"
4
5#include <stdio.h>
6
7typedef unsigned long ULong;
8
9typedef struct {
10 ULong w64[2]; /* Note: little-endian */
11} V128;
12
13static int getMSBs16x8(V128 v)
14{
15 int result;
16 __asm__("movups %1,%%xmm6\n"
17 "\tpmovmskb %%xmm6,%0\n"
18 : "=r" (result) : "m" (v) : "xmm6");
19 return result;
20}
21
22/* Set the V bits on the data at "addr". Note the convention: A zero
23 bit means "defined"; 1 means "undefined". */
24static void set_vbits(V128 *addr, V128 vbits)
25{
26 int i;
27 for (i=0 ; i<2 ; ++i) {
sewardje5932752012-12-06 23:11:19 +000028 (void)VALGRIND_SET_VBITS(&addr->w64[i], &vbits.w64[i], sizeof(vbits.w64[i]));
sewardj9b826d62012-11-19 15:12:07 +000029 }
30}
31
32static void print(V128 vbits, V128 val, int bit, int result)
33{
34 printf("vbits=0x%016lx%016lx val=0x%016lx%016lx bit=%d result=%d\n",
35 vbits.w64[1], vbits.w64[0], val.w64[1], val.w64[0],
36 bit, result);
37}
38
39/* Use a value that we know is invalid. */
40static void use(int index, int invalid)
41{
42 /* Convince GCC it does not know what is in "invalid" so it cannot
43 possibly optimize away the conditional branch below. */
44 __asm__ ("" : "=r" (invalid) : "0" (invalid));
45
46 /* Create a conditional branch on which our output depends, so that
47 memcheck cannot possibly optimize it away, either. */
48 fprintf(stderr, "%d: Invalid value is %s\n",
49 index, invalid ? "true" : "false");
50}
51
52static void doit(ULong vbits_hi, ULong vbits_lo, ULong val_hi, ULong val_lo)
53{
54 V128 vbits = { { vbits_lo, vbits_hi } };
55 V128 val = { { val_lo, val_hi } };
56
57 /* Since we are about to mark "val" partially undefined, make a
58 copy that we can use without generating a memcheck warning. */
59 V128 val_copy = val;
60
61 set_vbits(&val, vbits);
62
63 int result = getMSBs16x8(val);
64
65 int vbits_mask = getMSBs16x8(vbits);
66
67 int bit = 0; ULong mask = (1UL << bit);
68 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
69 else use(bit, result & mask);
70
71 bit = 1; mask = (1UL << bit);
72 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
73 else use(bit, result & mask);
74
75 bit = 2; mask = (1UL << bit);
76 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
77 else use(bit, result & mask);
78
79 bit = 3; mask = (1UL << bit);
80 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
81 else use(bit, result & mask);
82
83 bit = 4; mask = (1UL << bit);
84 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
85 else use(bit, result & mask);
86
87 bit = 5; mask = (1UL << bit);
88 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
89 else use(bit, result & mask);
90
91 bit = 6 ; mask = (1UL << bit);
92 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
93 else use(bit, result & mask);
94
95 bit = 7 ; mask = (1UL << bit);
96 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
97 else use(bit, result & mask);
98
99 bit = 8 ; mask = (1UL << bit);
100 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
101 else use(bit, result & mask);
102
103 bit = 9 ; mask = (1UL << bit);
104 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
105 else use(bit, result & mask);
106
107 bit = 10 ; mask = (1UL << bit);
108 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
109 else use(bit, result & mask);
110
111 bit = 11 ; mask = (1UL << bit);
112 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
113 else use(bit, result & mask);
114
115 bit = 12 ; mask = (1UL << bit);
116 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
117 else use(bit, result & mask);
118
119 bit = 13 ; mask = (1UL << bit);
120 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
121 else use(bit, result & mask);
122
123 bit = 14 ; mask = (1UL << bit);
124 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
125 else use(bit, result & mask);
126
127 bit = 15 ; mask = (1UL << bit);
128 if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask);
129 else use(bit, result & mask);
130}
131
132int main(int argc, char *argv[])
133{
134 doit(0x0000000000000000, 0x0000000000000000,
135 0x0000000000000000, 0x0000000000000000);
136
137 doit(0x0707070707070707, 0x0707070707070707,
138 0x0000000000000000, 0x0000000000000000);
139
140 doit(0x8080808080808080, 0x8080808080808080,
141 0x0000000000000000, 0x0000000000000000);
142
143 doit(0x13579BDF02468ACE, 0xFEDCBA9876543210,
144 0xFEEDFACEDEADBEEF, 0xFEE1DEADDABBAD00);
145
146 return 0;
147}