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