1/*
2 * Based on linux/arch/arm64/lib/bitops.h which in turn is
3 * Based on arch/arm/lib/bitops.h
4 *
5 * Copyright (C) 2013 ARM Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/*
21 * x0: bits 4:0  bit offset
22 *     bits 31:5 word offset
23 * x1: address
24 */
25	.macro	bitop, name, instr
26ENTRY(	\name	)
27	and	w3, w0, #31		// Get bit offset
28	eor	w0, w0, w3		// Clear low bits
29	mov	x2, #1
30	add	x1, x1, x0, lsr #3	// Get word offset
31	lsl	x3, x2, x3		// Create mask
321:	ldxr	w2, [x1]
33	\instr	w2, w2, w3
34	stxr	w0, w2, [x1]
35	cbnz	w0, 1b
36	ret
37ENDPROC(\name	)
38	.endm
39
40	.macro	testop, name, instr
41ENTRY(	\name	)
42	and	w3, w0, #31		// Get bit offset
43	eor	w0, w0, w3		// Clear low bits
44	mov	x2, #1
45	add	x1, x1, x0, lsr #3	// Get word offset
46	lsl	x4, x2, x3		// Create mask
471:	ldxr	w2, [x1]
48	lsr	w0, w2, w3		// Save old value of bit
49	\instr	w2, w2, w4		// toggle bit
50	stlxr	w5, w2, [x1]
51	cbnz	w5, 1b
52	dmb	ish
53	and	w0, w0, #1
543:	ret
55ENDPROC(\name	)
56	.endm
57
58/*
59 * Atomic bit operations.
60 */
61	bitop	change_bit, eor
62	bitop	clear_bit, bic
63	bitop	set_bit, orr
64
65	testop	test_and_change_bit, eor
66	testop	test_and_clear_bit, bic
67	testop	test_and_set_bit, orr
68