1 #include "tests/asm.h" 2 #include <stdio.h> 3 4 /* Test whether a shift by zero properly preserves the CC_NDEP thunk. */ 5 6 /* Check whether the carry flag is properly preserved by a variable 7 shift when the shift amount happens to be zero. */ 8 int shift_ndep( void ) 9 { 10 char shift_amt = 0; 11 int x = -2; 12 /* First we set the carry flag. Then we increment %x, which sets 13 CC_OP to X86G_CC_OP_INCL and stores the carry (1) in 14 CC_NDEP. Then we left shift %x by a variable amount that happens 15 to be zero, which should leave both %x and all the flags 16 unchanged. Then we add-with-carry 0 to %x, which (assuming the 17 carry is still set as it should be) increments %x again. Thus the 18 expected final value for x is -2 + 1 + 1 = 0. 19 20 If instead the shift clears CC_NDEP (as it would legally do if 21 the shift amount were non-zero), this will be interpeted as 22 clearing the carry bit, so the adc will be a no-op and the final 23 value of %x will instead be -1. 24 */ 25 asm ( 26 "stc" "\n\t" 27 "inc %[x]" "\n\t" 28 "shl %[shift_amt], %[x]" "\n\t" 29 "adc $0, %[x]" "\n\t" 30 : [x] "+r" (x) : [shift_amt] "c" (shift_amt)); 31 return x; 32 } 33 34 int main ( void ) 35 { 36 int r = shift_ndep(); 37 if (r == 0) 38 printf("Passed (%d).\n", r); 39 else 40 printf("Failed (%d).\n", r); 41 return 0; 42 } 43