xref: /linux/arch/arm/lib/bitops.h (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 #include <linux/config.h>
2 
3 #if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_CPU_32v6K)
4 	.macro	bitop, instr
5 	mov	r2, #1
6 	and	r3, r0, #7		@ Get bit offset
7 	add	r1, r1, r0, lsr #3	@ Get byte offset
8 	mov	r3, r2, lsl r3
9 1:	ldrexb	r2, [r1]
10 	\instr	r2, r2, r3
11 	strexb	r0, r2, [r1]
12 	cmp	r0, #0
13 	bne	1b
14 	mov	pc, lr
15 	.endm
16 
17 	.macro	testop, instr, store
18 	and	r3, r0, #7		@ Get bit offset
19 	mov	r2, #1
20 	add	r1, r1, r0, lsr #3	@ Get byte offset
21 	mov	r3, r2, lsl r3		@ create mask
22 1:	ldrexb	r2, [r1]
23 	ands	r0, r2, r3		@ save old value of bit
24 	\instr	r2, r2, r3			@ toggle bit
25 	strexb	ip, r2, [r1]
26 	cmp	ip, #0
27 	bne	1b
28 	cmp	r0, #0
29 	movne	r0, #1
30 2:	mov	pc, lr
31 	.endm
32 #else
33 	.macro	bitop, instr
34 	and	r2, r0, #7
35 	mov	r3, #1
36 	mov	r3, r3, lsl r2
37 	save_and_disable_irqs ip
38 	ldrb	r2, [r1, r0, lsr #3]
39 	\instr	r2, r2, r3
40 	strb	r2, [r1, r0, lsr #3]
41 	restore_irqs ip
42 	mov	pc, lr
43 	.endm
44 
45 /**
46  * testop - implement a test_and_xxx_bit operation.
47  * @instr: operational instruction
48  * @store: store instruction
49  *
50  * Note: we can trivially conditionalise the store instruction
51  * to avoid dirting the data cache.
52  */
53 	.macro	testop, instr, store
54 	add	r1, r1, r0, lsr #3
55 	and	r3, r0, #7
56 	mov	r0, #1
57 	save_and_disable_irqs ip
58 	ldrb	r2, [r1]
59 	tst	r2, r0, lsl r3
60 	\instr	r2, r2, r0, lsl r3
61 	\store	r2, [r1]
62 	restore_irqs ip
63 	moveq	r0, #0
64 	mov	pc, lr
65 	.endm
66 #endif
67