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