• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 #include <stdio.h>
3 #include <string.h>
4 
5 typedef  unsigned long long int  ULong;
6 typedef  unsigned int  UInt;
7 
8 #define CC_SHIFT_O   11
9 #define CC_SHIFT_S   7
10 #define CC_SHIFT_Z   6
11 #define CC_SHIFT_A   4
12 #define CC_SHIFT_C   0
13 #define CC_SHIFT_P   2
14 
15 #define CC_MASK_O    (1ULL << CC_SHIFT_O)
16 #define CC_MASK_S    (1ULL << CC_SHIFT_S)
17 #define CC_MASK_Z    (1ULL << CC_SHIFT_Z)
18 #define CC_MASK_A    (1ULL << CC_SHIFT_A)
19 #define CC_MASK_C    (1ULL << CC_SHIFT_C)
20 #define CC_MASK_P    (1ULL << CC_SHIFT_P)
21 
22 #define CC_MASK_OSZACP \
23    (CC_MASK_O | CC_MASK_S | CC_MASK_Z | CC_MASK_A | CC_MASK_C | CC_MASK_P)
24 
25 
showFlags(char * str,int nStr,ULong flags)26 void showFlags(/*OUT*/char* str, int nStr, ULong flags)
27 {
28    // Ignore everything except OSZACP, because V differs from real h/w in
29    // flags other than OSZACP, and we don't want that to confuse the
30    // results here
31    memset(str, 0, nStr);
32    sprintf(str, "%c%c%c%c%c%c",
33            (flags & CC_MASK_O) ? 'o' : '-',
34            (flags & CC_MASK_S) ? 's' : '-',
35            (flags & CC_MASK_Z) ? 'z' : '-',
36            (flags & CC_MASK_A) ? 'a' : '-',
37            (flags & CC_MASK_C) ? 'c' : '-',
38            (flags & CC_MASK_P) ? 'p' : '-');
39 }
40 
41 __attribute__((noinline))
do_test(ULong val,UInt ix)42 void do_test ( ULong val, UInt ix )
43 {
44   ULong o, s, z, a, c, p, flags_before;
45   for (o = 0; o < 2; o++) {
46   for (s = 0; s < 2; s++) {
47   for (z = 0; z < 2; z++) {
48   for (a = 0; a < 2; a++) {
49   for (c = 0; c < 2; c++) {
50   for (p = 0; p < 2; p++) {
51     flags_before = (o ? CC_MASK_O : 0)
52                  | (s ? CC_MASK_S : 0)
53                  | (z ? CC_MASK_Z : 0)
54                  | (a ? CC_MASK_A : 0)
55                  | (c ? CC_MASK_C : 0)
56                  | (p ? CC_MASK_P : 0);
57     ULong block[4] = { flags_before, val, ix, 0 };
58     __asm__ __volatile__(
59       "movq  0(%0),  %%r15"    "\n\t" // flags_before
60       "pushq %%r15"            "\n\t"
61       "popfq"                  "\n\t"
62       "movq  8(%0),  %%r14"    "\n\t" // val
63       "movq  16(%0), %%r13"    "\n\t" // ix
64       "bt    %%r13,  %%r14"    "\n\t"
65       "pushfq"                 "\n\t"
66       "popq %%r15"             "\n\t"
67       "movq %%r15,   24(%0)"   "\n" // block[3]
68       : : "r"(&block[0]) : "cc","memory","r13","r14","r15"
69     );
70     ULong flags_after = block[3];
71     flags_after &= CC_MASK_OSZACP;
72     char flags_after_str[100];
73     char flags_before_str[100];
74     showFlags(flags_before_str, 100, flags_before);
75     showFlags(flags_after_str, 100, flags_after);
76     printf("flags 0x%03llx(%s)  val 0x%llx  ix %d  ->  flags 0x%03llx(%s)\n",
77            flags_before, flags_before_str, val, ix,
78            flags_after, flags_after_str);
79   }}}}}}
80 }
81 
main(void)82 int main ( void )
83 {
84    do_test(0x8000, 14); // should always return C == 0
85    printf("\n");
86    do_test(0x8000, 15); // should always return C == 1
87    return 0;
88 }
89