]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/none/tests/x86/shift_ndep.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / none / tests / x86 / shift_ndep.c
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 }