19b826d678462471e8112096c291d95cb61e99364sewardj/* https://bugs.kde.org/show_bug.cgi?id=308627 */ 29b826d678462471e8112096c291d95cb61e99364sewardj 39b826d678462471e8112096c291d95cb61e99364sewardj#include "../../memcheck.h" 49b826d678462471e8112096c291d95cb61e99364sewardj 59b826d678462471e8112096c291d95cb61e99364sewardj#include <stdio.h> 69b826d678462471e8112096c291d95cb61e99364sewardj 79b826d678462471e8112096c291d95cb61e99364sewardjtypedef unsigned long ULong; 89b826d678462471e8112096c291d95cb61e99364sewardj 99b826d678462471e8112096c291d95cb61e99364sewardjtypedef struct { 109b826d678462471e8112096c291d95cb61e99364sewardj ULong w64[2]; /* Note: little-endian */ 119b826d678462471e8112096c291d95cb61e99364sewardj} V128; 129b826d678462471e8112096c291d95cb61e99364sewardj 139b826d678462471e8112096c291d95cb61e99364sewardjstatic int getMSBs16x8(V128 v) 149b826d678462471e8112096c291d95cb61e99364sewardj{ 159b826d678462471e8112096c291d95cb61e99364sewardj int result; 169b826d678462471e8112096c291d95cb61e99364sewardj __asm__("movups %1,%%xmm6\n" 179b826d678462471e8112096c291d95cb61e99364sewardj "\tpmovmskb %%xmm6,%0\n" 189b826d678462471e8112096c291d95cb61e99364sewardj : "=r" (result) : "m" (v) : "xmm6"); 199b826d678462471e8112096c291d95cb61e99364sewardj return result; 209b826d678462471e8112096c291d95cb61e99364sewardj} 219b826d678462471e8112096c291d95cb61e99364sewardj 229b826d678462471e8112096c291d95cb61e99364sewardj/* Set the V bits on the data at "addr". Note the convention: A zero 239b826d678462471e8112096c291d95cb61e99364sewardj bit means "defined"; 1 means "undefined". */ 249b826d678462471e8112096c291d95cb61e99364sewardjstatic void set_vbits(V128 *addr, V128 vbits) 259b826d678462471e8112096c291d95cb61e99364sewardj{ 269b826d678462471e8112096c291d95cb61e99364sewardj int i; 279b826d678462471e8112096c291d95cb61e99364sewardj for (i=0 ; i<2 ; ++i) { 28e593275d41859efb73a2d0c7fc88473000f52c53sewardj (void)VALGRIND_SET_VBITS(&addr->w64[i], &vbits.w64[i], sizeof(vbits.w64[i])); 299b826d678462471e8112096c291d95cb61e99364sewardj } 309b826d678462471e8112096c291d95cb61e99364sewardj} 319b826d678462471e8112096c291d95cb61e99364sewardj 329b826d678462471e8112096c291d95cb61e99364sewardjstatic void print(V128 vbits, V128 val, int bit, int result) 339b826d678462471e8112096c291d95cb61e99364sewardj{ 349b826d678462471e8112096c291d95cb61e99364sewardj printf("vbits=0x%016lx%016lx val=0x%016lx%016lx bit=%d result=%d\n", 359b826d678462471e8112096c291d95cb61e99364sewardj vbits.w64[1], vbits.w64[0], val.w64[1], val.w64[0], 369b826d678462471e8112096c291d95cb61e99364sewardj bit, result); 379b826d678462471e8112096c291d95cb61e99364sewardj} 389b826d678462471e8112096c291d95cb61e99364sewardj 399b826d678462471e8112096c291d95cb61e99364sewardj/* Use a value that we know is invalid. */ 409b826d678462471e8112096c291d95cb61e99364sewardjstatic void use(int index, int invalid) 419b826d678462471e8112096c291d95cb61e99364sewardj{ 429b826d678462471e8112096c291d95cb61e99364sewardj /* Convince GCC it does not know what is in "invalid" so it cannot 439b826d678462471e8112096c291d95cb61e99364sewardj possibly optimize away the conditional branch below. */ 449b826d678462471e8112096c291d95cb61e99364sewardj __asm__ ("" : "=r" (invalid) : "0" (invalid)); 459b826d678462471e8112096c291d95cb61e99364sewardj 469b826d678462471e8112096c291d95cb61e99364sewardj /* Create a conditional branch on which our output depends, so that 479b826d678462471e8112096c291d95cb61e99364sewardj memcheck cannot possibly optimize it away, either. */ 489b826d678462471e8112096c291d95cb61e99364sewardj fprintf(stderr, "%d: Invalid value is %s\n", 499b826d678462471e8112096c291d95cb61e99364sewardj index, invalid ? "true" : "false"); 509b826d678462471e8112096c291d95cb61e99364sewardj} 519b826d678462471e8112096c291d95cb61e99364sewardj 529b826d678462471e8112096c291d95cb61e99364sewardjstatic void doit(ULong vbits_hi, ULong vbits_lo, ULong val_hi, ULong val_lo) 539b826d678462471e8112096c291d95cb61e99364sewardj{ 549b826d678462471e8112096c291d95cb61e99364sewardj V128 vbits = { { vbits_lo, vbits_hi } }; 559b826d678462471e8112096c291d95cb61e99364sewardj V128 val = { { val_lo, val_hi } }; 569b826d678462471e8112096c291d95cb61e99364sewardj 579b826d678462471e8112096c291d95cb61e99364sewardj /* Since we are about to mark "val" partially undefined, make a 589b826d678462471e8112096c291d95cb61e99364sewardj copy that we can use without generating a memcheck warning. */ 599b826d678462471e8112096c291d95cb61e99364sewardj V128 val_copy = val; 609b826d678462471e8112096c291d95cb61e99364sewardj 619b826d678462471e8112096c291d95cb61e99364sewardj set_vbits(&val, vbits); 629b826d678462471e8112096c291d95cb61e99364sewardj 639b826d678462471e8112096c291d95cb61e99364sewardj int result = getMSBs16x8(val); 649b826d678462471e8112096c291d95cb61e99364sewardj 659b826d678462471e8112096c291d95cb61e99364sewardj int vbits_mask = getMSBs16x8(vbits); 669b826d678462471e8112096c291d95cb61e99364sewardj 679b826d678462471e8112096c291d95cb61e99364sewardj int bit = 0; ULong mask = (1UL << bit); 689b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 699b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 709b826d678462471e8112096c291d95cb61e99364sewardj 719b826d678462471e8112096c291d95cb61e99364sewardj bit = 1; mask = (1UL << bit); 729b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 739b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 749b826d678462471e8112096c291d95cb61e99364sewardj 759b826d678462471e8112096c291d95cb61e99364sewardj bit = 2; mask = (1UL << bit); 769b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 779b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 789b826d678462471e8112096c291d95cb61e99364sewardj 799b826d678462471e8112096c291d95cb61e99364sewardj bit = 3; mask = (1UL << bit); 809b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 819b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 829b826d678462471e8112096c291d95cb61e99364sewardj 839b826d678462471e8112096c291d95cb61e99364sewardj bit = 4; mask = (1UL << bit); 849b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 859b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 869b826d678462471e8112096c291d95cb61e99364sewardj 879b826d678462471e8112096c291d95cb61e99364sewardj bit = 5; mask = (1UL << bit); 889b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 899b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 909b826d678462471e8112096c291d95cb61e99364sewardj 919b826d678462471e8112096c291d95cb61e99364sewardj bit = 6 ; mask = (1UL << bit); 929b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 939b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 949b826d678462471e8112096c291d95cb61e99364sewardj 959b826d678462471e8112096c291d95cb61e99364sewardj bit = 7 ; mask = (1UL << bit); 969b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 979b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 989b826d678462471e8112096c291d95cb61e99364sewardj 999b826d678462471e8112096c291d95cb61e99364sewardj bit = 8 ; mask = (1UL << bit); 1009b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1019b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1029b826d678462471e8112096c291d95cb61e99364sewardj 1039b826d678462471e8112096c291d95cb61e99364sewardj bit = 9 ; mask = (1UL << bit); 1049b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1059b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1069b826d678462471e8112096c291d95cb61e99364sewardj 1079b826d678462471e8112096c291d95cb61e99364sewardj bit = 10 ; mask = (1UL << bit); 1089b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1099b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1109b826d678462471e8112096c291d95cb61e99364sewardj 1119b826d678462471e8112096c291d95cb61e99364sewardj bit = 11 ; mask = (1UL << bit); 1129b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1139b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1149b826d678462471e8112096c291d95cb61e99364sewardj 1159b826d678462471e8112096c291d95cb61e99364sewardj bit = 12 ; mask = (1UL << bit); 1169b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1179b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1189b826d678462471e8112096c291d95cb61e99364sewardj 1199b826d678462471e8112096c291d95cb61e99364sewardj bit = 13 ; mask = (1UL << bit); 1209b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1219b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1229b826d678462471e8112096c291d95cb61e99364sewardj 1239b826d678462471e8112096c291d95cb61e99364sewardj bit = 14 ; mask = (1UL << bit); 1249b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1259b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1269b826d678462471e8112096c291d95cb61e99364sewardj 1279b826d678462471e8112096c291d95cb61e99364sewardj bit = 15 ; mask = (1UL << bit); 1289b826d678462471e8112096c291d95cb61e99364sewardj if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 1299b826d678462471e8112096c291d95cb61e99364sewardj else use(bit, result & mask); 1309b826d678462471e8112096c291d95cb61e99364sewardj} 1319b826d678462471e8112096c291d95cb61e99364sewardj 1329b826d678462471e8112096c291d95cb61e99364sewardjint main(int argc, char *argv[]) 1339b826d678462471e8112096c291d95cb61e99364sewardj{ 1349b826d678462471e8112096c291d95cb61e99364sewardj doit(0x0000000000000000, 0x0000000000000000, 1359b826d678462471e8112096c291d95cb61e99364sewardj 0x0000000000000000, 0x0000000000000000); 1369b826d678462471e8112096c291d95cb61e99364sewardj 1379b826d678462471e8112096c291d95cb61e99364sewardj doit(0x0707070707070707, 0x0707070707070707, 1389b826d678462471e8112096c291d95cb61e99364sewardj 0x0000000000000000, 0x0000000000000000); 1399b826d678462471e8112096c291d95cb61e99364sewardj 1409b826d678462471e8112096c291d95cb61e99364sewardj doit(0x8080808080808080, 0x8080808080808080, 1419b826d678462471e8112096c291d95cb61e99364sewardj 0x0000000000000000, 0x0000000000000000); 1429b826d678462471e8112096c291d95cb61e99364sewardj 1439b826d678462471e8112096c291d95cb61e99364sewardj doit(0x13579BDF02468ACE, 0xFEDCBA9876543210, 1449b826d678462471e8112096c291d95cb61e99364sewardj 0xFEEDFACEDEADBEEF, 0xFEE1DEADDABBAD00); 1459b826d678462471e8112096c291d95cb61e99364sewardj 1469b826d678462471e8112096c291d95cb61e99364sewardj return 0; 1479b826d678462471e8112096c291d95cb61e99364sewardj} 148