insn-pmovmskb.c revision 436e89c602e787e7a27dd6624b09beed41a0da8a
1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* https://bugs.kde.org/show_bug.cgi?id=308627 */ 2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "../../memcheck.h" 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include <stdio.h> 6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef unsigned long ULong; 8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef struct { 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong w64[2]; /* Note: little-endian */ 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} V128; 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic int getMSBs16x8(V128 v) 14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int result; 16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__("movups %1,%%xmm6\n" 17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "\tpmovmskb %%xmm6,%0\n" 18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : "=r" (result) : "m" (v) : "xmm6"); 19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return result; 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Set the V bits on the data at "addr". Note the convention: A zero 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit means "defined"; 1 means "undefined". */ 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void set_vbits(V128 *addr, V128 vbits) 25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int i; 27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov for (i=0 ; i<2 ; ++i) { 28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (void)VALGRIND_SET_VBITS(&addr->w64[i], &vbits.w64[i], sizeof(vbits.w64[i])); 29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void print(V128 vbits, V128 val, int bit, int result) 33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov printf("vbits=0x%016lx%016lx val=0x%016lx%016lx bit=%d result=%d\n", 35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vbits.w64[1], vbits.w64[0], val.w64[1], val.w64[0], 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit, result); 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Use a value that we know is invalid. */ 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void use(int index, int invalid) 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Convince GCC it does not know what is in "invalid" so it cannot 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov possibly optimize away the conditional branch below. */ 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __asm__ ("" : "=r" (invalid) : "0" (invalid)); 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Create a conditional branch on which our output depends, so that 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov memcheck cannot possibly optimize it away, either. */ 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fprintf(stderr, "%d: Invalid value is %s\n", 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov index, invalid ? "true" : "false"); 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void doit(ULong vbits_hi, ULong vbits_lo, ULong val_hi, ULong val_lo) 53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov V128 vbits = { { vbits_lo, vbits_hi } }; 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov V128 val = { { val_lo, val_hi } }; 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Since we are about to mark "val" partially undefined, make a 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov copy that we can use without generating a memcheck warning. */ 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov V128 val_copy = val; 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov set_vbits(&val, vbits); 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int result = getMSBs16x8(val); 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int vbits_mask = getMSBs16x8(vbits); 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov int bit = 0; ULong mask = (1UL << bit); 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 1; mask = (1UL << bit); 72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 2; mask = (1UL << bit); 76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 3; mask = (1UL << bit); 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 4; mask = (1UL << bit); 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 5; mask = (1UL << bit); 88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 6 ; mask = (1UL << bit); 92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 7 ; mask = (1UL << bit); 96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 8 ; mask = (1UL << bit); 100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 9 ; mask = (1UL << bit); 104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 10 ; mask = (1UL << bit); 108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 11 ; mask = (1UL << bit); 112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 12 ; mask = (1UL << bit); 116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 13 ; mask = (1UL << bit); 120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 14 ; mask = (1UL << bit); 124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov bit = 15 ; mask = (1UL << bit); 128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if ((vbits_mask & mask) == 0) print(vbits, val_copy, bit, result & mask); 129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else use(bit, result & mask); 130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovint main(int argc, char *argv[]) 133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov doit(0x0000000000000000, 0x0000000000000000, 135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 0x0000000000000000, 0x0000000000000000); 136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov doit(0x0707070707070707, 0x0707070707070707, 138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 0x0000000000000000, 0x0000000000000000); 139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov doit(0x8080808080808080, 0x8080808080808080, 141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 0x0000000000000000, 0x0000000000000000); 142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov doit(0x13579BDF02468ACE, 0xFEDCBA9876543210, 144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 0xFEEDFACEDEADBEEF, 0xFEE1DEADDABBAD00); 145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return 0; 147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 148