xref: /kvm-unit-tests/lib/arm64/asm/bitops.h (revision 71a6a145226927f50d938b0f2befc24363a496bc)
1 #ifndef _ASMARM64_BITOPS_H_
2 #define _ASMARM64_BITOPS_H_
3 /*
4  * Adapted from
5  *   arch/arm64/lib/bitops.S
6  *
7  * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.
10  */
11 
12 #ifndef _BITOPS_H_
13 #error only <bitops.h> can be included directly
14 #endif
15 
16 #define BITS_PER_LONG	64
17 
18 #define HAVE_BUILTIN_FLS 1
19 
20 #define ATOMIC_BITOP(insn, mask, word)				\
21 ({								\
22 	unsigned long tmp1, tmp2;				\
23 	asm volatile(						\
24 	"1:	ldxr	%0, [%2]\n"				\
25 		insn"	%0, %0, %3\n"				\
26 	"	stxr	%w1, %0, [%2]\n"			\
27 	"	cbnz	%w1, 1b\n"				\
28 	: "=&r" (tmp1), "=&r" (tmp2)				\
29 	: "r" (word), "r" (mask)				\
30 	: "cc");						\
31 })
32 
33 #define ATOMIC_TESTOP(insn, mask, word, old)			\
34 ({								\
35 	unsigned long tmp1, tmp2;				\
36 	asm volatile(						\
37 	"1:	ldxr	%0, [%3]\n"				\
38 	"	and	%1, %0, %4\n"				\
39 		insn"	%0, %0, %4\n"				\
40 	"	stlxr	%w2, %0, [%3]\n"			\
41 	"	cbnz	%w2, 1b\n"				\
42 	: "=&r" (tmp1), "=&r" (old), "=&r" (tmp2)		\
43 	: "r" (word), "r" (mask)				\
44 	: "cc");						\
45 })
46 
47 extern void set_bit(int nr, volatile unsigned long *addr);
48 extern void clear_bit(int nr, volatile unsigned long *addr);
49 extern int test_bit(int nr, const volatile unsigned long *addr);
50 extern int test_and_set_bit(int nr, volatile unsigned long *addr);
51 extern int test_and_clear_bit(int nr, volatile unsigned long *addr);
52 
53 #endif /* _ASMARM64_BITOPS_H_ */
54