1typedef unsigned long long uint64_t; 2void abort (void); 3 4#define BASE 0x1234567812345678ull 5 6#define DEF_BBIT_TAKEN(BRANCH_IF, BIT) \ 7 int bbit_is_taken_##BRANCH_IF##_##BIT (volatile uint64_t *p) \ 8 { \ 9 int ret; \ 10 asm (".set push \n\t" \ 11 ".set noreorder \n\t" \ 12 "bbit" #BRANCH_IF " %1, " #BIT ", 1f \n\t" \ 13 "nop \n\t" \ 14 "li %0, 0 \n\t" \ 15 "b 2f \n\t" \ 16 "nop \n\t" \ 17 "1: \n\t" \ 18 "li %0, 1 \n\t" \ 19 "2: \n\t" \ 20 ".set pop" \ 21 : "=r"(ret) : "r"(*p)); \ 22 return ret; \ 23 } \ 24 volatile uint64_t taken_##BRANCH_IF##_##BIT = \ 25 BASE & (~(1ull << BIT)) | ((uint64_t) BRANCH_IF << BIT); \ 26 volatile uint64_t not_taken_##BRANCH_IF##_##BIT = \ 27 BASE & (~(1ull << BIT)) | (((uint64_t) !BRANCH_IF) << BIT); 28 29DEF_BBIT_TAKEN (0, 10); 30DEF_BBIT_TAKEN (0, 36); 31DEF_BBIT_TAKEN (1, 20); 32DEF_BBIT_TAKEN (1, 49); 33 34#define EXPECT(X) if (!(X)) abort (); 35 36main () 37{ 38 EXPECT (bbit_is_taken_0_10 (&taken_0_10)); 39 EXPECT (!bbit_is_taken_0_10 (¬_taken_0_10)); 40 41 EXPECT (bbit_is_taken_0_36 (&taken_0_36)); 42 EXPECT (!bbit_is_taken_0_36 (¬_taken_0_36)); 43 44 EXPECT (bbit_is_taken_1_20 (&taken_1_20)); 45 EXPECT (!bbit_is_taken_1_20 (¬_taken_1_20)); 46 47 EXPECT (bbit_is_taken_1_49 (&taken_1_49)); 48 EXPECT (!bbit_is_taken_1_49 (¬_taken_1_49)); 49} 50