shift_ndep.c revision 8f943afc22a6a683b78271836c8ddc462b4824a9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tests/asm.h" 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Test whether a shift by zero properly preserves the CC_NDEP thunk. */ 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Check whether the carry flag is properly preserved by a variable 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shift when the shift amount happens to be zero. */ 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int shift_ndep( void ) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char shift_amt = 0; 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x = -2; 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* First we set the carry flag. Then we increment %x, which sets 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CC_OP to X86G_CC_OP_INCL and stores the carry (1) in 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CC_NDEP. Then we left shift %x by a variable amount that happens 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) to be zero, which should leave both %x and all the flags 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unchanged. Then we add-with-carry 0 to %x, which (assuming the 17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) carry is still set as it should be) increments %x again. Thus the 18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) expected final value for x is -2 + 1 + 1 = 0. 19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) If instead the shift clears CC_NDEP (as it would legally do if 21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) the shift amount were non-zero), this will be interpeted as 22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) clearing the carry bit, so the adc will be a no-op and the final 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) value of %x will instead be -1. 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) */ 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) asm ( 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "stc" "\n\t" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "inc %[x]" "\n\t" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "shl %[shift_amt], %[x]" "\n\t" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "adc $0, %[x]" "\n\t" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : [x] "+r" (x) : [shift_amt] "c" (shift_amt)); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochint main ( void ) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int r = shift_ndep(); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r == 0) 38 printf("Passed (%d).\n", r); 39 else 40 printf("Failed (%d).\n", r); 41 return 0; 42} 43