1 /* See if various BMI2 instructions give expected results */ 2 #include <assert.h> 3 #include <stdint.h> 4 #include <stdio.h> 5 6 #define CC_C 1 7 #define CC_O (1 << 11) 8 9 #ifdef __x86_64__ 10 #define REG uint64_t 11 #else 12 #define REG uint32_t 13 #endif 14 15 void test_adox_adcx(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_operand) 16 { 17 REG flags; 18 REG out_adcx, out_adox; 19 20 asm("pushf; pop %0" : "=r"(flags)); 21 flags &= ~(CC_C | CC_O); 22 flags |= (in_c ? CC_C : 0); 23 flags |= (in_o ? CC_O : 0); 24 25 out_adcx = adcx_operand; 26 out_adox = adox_operand; 27 asm("push %0; popf;" 28 "adox %3, %2;" 29 "adcx %3, %1;" 30 "pushf; pop %0" 31 : "+r" (flags), "+r" (out_adcx), "+r" (out_adox) 32 : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox)); 33 34 assert(out_adcx == in_c + adcx_operand - 1); 35 assert(out_adox == in_o + adox_operand - 1); 36 assert(!!(flags & CC_C) == (in_c || adcx_operand)); 37 assert(!!(flags & CC_O) == (in_o || adox_operand)); 38 } 39 40 void test_adcx_adox(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_operand) 41 { 42 REG flags; 43 REG out_adcx, out_adox; 44 45 asm("pushf; pop %0" : "=r"(flags)); 46 flags &= ~(CC_C | CC_O); 47 flags |= (in_c ? CC_C : 0); 48 flags |= (in_o ? CC_O : 0); 49 50 out_adcx = adcx_operand; 51 out_adox = adox_operand; 52 asm("push %0; popf;" 53 "adcx %3, %1;" 54 "adox %3, %2;" 55 "pushf; pop %0" 56 : "+r" (flags), "+r" (out_adcx), "+r" (out_adox) 57 : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox)); 58 59 assert(out_adcx == in_c + adcx_operand - 1); 60 assert(out_adox == in_o + adox_operand - 1); 61 assert(!!(flags & CC_C) == (in_c || adcx_operand)); 62 assert(!!(flags & CC_O) == (in_o || adox_operand)); 63 } 64 65 int main(int argc, char *argv[]) { 66 /* try all combinations of input CF, input OF, CF from op1+op2, OF from op2+op1 */ 67 int i; 68 for (i = 0; i <= 15; i++) { 69 printf("%d\n", i); 70 test_adcx_adox(!!(i & 1), !!(i & 2), !!(i & 4), !!(i & 8)); 71 test_adox_adcx(!!(i & 1), !!(i & 2), !!(i & 4), !!(i & 8)); 72 } 73 return 0; 74 } 75 76