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