1 /* https://bugs.kde.org/show_bug.cgi?id=308627 */
3 #include "../../memcheck.h"
7 typedef unsigned long ULong
;
10 ULong w64
[2]; /* Note: little-endian */
13 static int getMSBs16x8(V128 v
)
16 __asm__("movups %1,%%xmm6\n"
17 "\tpmovmskb %%xmm6,%0\n"
18 : "=r" (result
) : "m" (v
) : "xmm6");
22 /* Set the V bits on the data at "addr". Note the convention: A zero
23 bit means "defined"; 1 means "undefined". */
24 static void set_vbits(V128
*addr
, V128 vbits
)
27 for (i
=0 ; i
<2 ; ++i
) {
28 (void)VALGRIND_SET_VBITS(&addr
->w64
[i
], &vbits
.w64
[i
], sizeof(vbits
.w64
[i
]));
32 static void print(V128 vbits
, V128 val
, int bit
, int result
)
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],
39 /* Use a value that we know is invalid. */
40 static void use(int index
, int invalid
)
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
));
46 /* Create a conditional branch on which our output depends, so that
47 memcheck cannot possibly optimize it away, either. */
49 fprintf(stderr
, "%d: Invalid value is true\n", index
);
51 fprintf(stderr
, "%d: Invalid value is false\n", index
);
54 static void doit(ULong vbits_hi
, ULong vbits_lo
, ULong val_hi
, ULong val_lo
)
56 V128 vbits
= { { vbits_lo
, vbits_hi
} };
57 V128 val
= { { val_lo
, val_hi
} };
59 /* Since we are about to mark "val" partially undefined, make a
60 copy that we can use without generating a memcheck warning. */
63 set_vbits(&val
, vbits
);
65 int result
= getMSBs16x8(val
);
67 int vbits_mask
= getMSBs16x8(vbits
);
69 int bit
= 0; ULong mask
= (1UL << bit
);
70 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
71 else use(bit
, result
& mask
);
73 bit
= 1; mask
= (1UL << bit
);
74 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
75 else use(bit
, result
& mask
);
77 bit
= 2; mask
= (1UL << bit
);
78 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
79 else use(bit
, result
& mask
);
81 bit
= 3; mask
= (1UL << bit
);
82 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
83 else use(bit
, result
& mask
);
85 bit
= 4; mask
= (1UL << bit
);
86 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
87 else use(bit
, result
& mask
);
89 bit
= 5; mask
= (1UL << bit
);
90 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
91 else use(bit
, result
& mask
);
93 bit
= 6 ; mask
= (1UL << bit
);
94 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
95 else use(bit
, result
& mask
);
97 bit
= 7 ; mask
= (1UL << bit
);
98 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
99 else use(bit
, result
& mask
);
101 bit
= 8 ; mask
= (1UL << bit
);
102 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
103 else use(bit
, result
& mask
);
105 bit
= 9 ; mask
= (1UL << bit
);
106 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
107 else use(bit
, result
& mask
);
109 bit
= 10 ; mask
= (1UL << bit
);
110 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
111 else use(bit
, result
& mask
);
113 bit
= 11 ; mask
= (1UL << bit
);
114 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
115 else use(bit
, result
& mask
);
117 bit
= 12 ; mask
= (1UL << bit
);
118 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
119 else use(bit
, result
& mask
);
121 bit
= 13 ; mask
= (1UL << bit
);
122 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
123 else use(bit
, result
& mask
);
125 bit
= 14 ; mask
= (1UL << bit
);
126 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
127 else use(bit
, result
& mask
);
129 bit
= 15 ; mask
= (1UL << bit
);
130 if ((vbits_mask
& mask
) == 0) print(vbits
, val_copy
, bit
, result
& mask
);
131 else use(bit
, result
& mask
);
134 int main(int argc
, char *argv
[])
136 doit(0x0000000000000000, 0x0000000000000000,
137 0x0000000000000000, 0x0000000000000000);
139 doit(0x0707070707070707, 0x0707070707070707,
140 0x0000000000000000, 0x0000000000000000);
142 doit(0x8080808080808080, 0x8080808080808080,
143 0x0000000000000000, 0x0000000000000000);
145 doit(0x13579BDF02468ACE, 0xFEDCBA9876543210,
146 0xFEEDFACEDEADBEEF, 0xFEE1DEADDABBAD00);