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 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)) 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 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