xref: /kvm-unit-tests/lib/x86/asm/bitops.h (revision 9fb56fa18056dc0396a5d27c42215abc984f5c48)
1 #ifndef _ASMX86_BITOPS_H_
2 #define _ASMX86_BITOPS_H_
3 
4 #ifndef _BITOPS_H_
5 #error only <bitops.h> can be included directly
6 #endif
7 
8 #ifdef __x86_64__
9 #define BITS_PER_LONG	64
10 #else
11 #define BITS_PER_LONG	32
12 #endif
13 
14 #define HAVE_BUILTIN_FLS 1
15 
16 /*
17  * Macros to generate condition code outputs from inline assembly,
18  * The output operand must be type "bool".
19  */
20 #ifdef __GCC_ASM_FLAG_OUTPUTS__
21 # define CC_SET(c) "\n\t/* output condition code " #c "*/\n"
22 # define CC_OUT(c) "=@cc" #c
23 #else
24 # define CC_SET(c) "\n\tset" #c " %[_cc_" #c "]\n"
25 # define CC_OUT(c) [_cc_ ## c] "=qm"
26 #endif
27 
28 static inline void __clear_bit(int bit, void *__addr)
29 {
30 	unsigned long *addr = __addr;
31 
32 	__asm__ __volatile__("btr %1, %0"
33 			     : "+m" (*addr) : "Ir" (bit) : "cc", "memory");
34 }
35 
36 static inline void __set_bit(int bit, void *__addr)
37 {
38 	unsigned long *addr = __addr;
39 
40 	__asm__ __volatile__("bts %1, %0"
41 			     : "+m" (*addr) : "Ir" (bit) : "cc", "memory");
42 }
43 
44 static inline bool __test_and_clear_bit(int bit, void *__addr)
45 {
46 	unsigned long *addr = __addr;
47 	bool v;
48 
49 	__asm__ __volatile__("btr %2, %1" CC_SET(c)
50 			     : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit));
51 	return v;
52 }
53 
54 static inline bool __test_and_set_bit(int bit, void *__addr)
55 {
56 	unsigned long *addr = __addr;
57 	bool v;
58 
59 	__asm__ __volatile__("bts %2, %1" CC_SET(c)
60 			     : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit));
61 	return v;
62 }
63 
64 static inline void clear_bit(int bit, void *__addr)
65 {
66 	unsigned long *addr = __addr;
67 
68 	__asm__ __volatile__("lock; btr %1, %0"
69 			     : "+m" (*addr) : "Ir" (bit) : "cc", "memory");
70 }
71 
72 static inline void set_bit(int bit, void *__addr)
73 {
74 	unsigned long *addr = __addr;
75 
76 	__asm__ __volatile__("lock; bts %1, %0"
77 			     : "+m" (*addr) : "Ir" (bit) : "cc", "memory");
78 }
79 
80 static inline bool test_and_clear_bit(int bit, void *__addr)
81 {
82 	unsigned long *addr = __addr;
83 	bool v;
84 
85 	__asm__ __volatile__("lock; btr %2, %1" CC_SET(c)
86 			     : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit));
87 	return v;
88 }
89 
90 static inline bool test_and_set_bit(int bit, void *__addr)
91 {
92 	unsigned long *addr = __addr;
93 	bool v;
94 
95 	__asm__ __volatile__("lock; bts %2, %1" CC_SET(c)
96 			     : CC_OUT(c) (v), "+m" (*addr) : "Ir" (bit));
97 	return v;
98 }
99 
100 #endif
101