xref: /linux/arch/sparc/lib/bitops.S (revision 14b42963f64b98ab61fa9723c03d71aa5ef4f862)
1/* bitops.S: Low level assembler bit operations.
2 *
3 * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
4 */
5
6#include <asm/ptrace.h>
7#include <asm/psr.h>
8
9	.text
10	.align	4
11
12	.globl  __bitops_begin
13__bitops_begin:
14
15	/* Take bits in %g2 and set them in word at %g1,
16	 * return whether bits were set in original value
17	 * in %g2.  %g4 holds value to restore into %o7
18	 * in delay slot of jmpl return, %g3 + %g5 + %g7 can be
19	 * used as temporaries and thus is considered clobbered
20	 * by all callers.
21	 */
22	.globl	___set_bit
23___set_bit:
24	rd	%psr, %g3
25	nop; nop; nop;
26	or	%g3, PSR_PIL, %g5
27	wr	%g5, 0x0, %psr
28	nop; nop; nop
29#ifdef CONFIG_SMP
30	set	bitops_spinlock, %g5
312:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
32	orcc	%g7, 0x0, %g0		! Did we get it?
33	bne	2b			! Nope...
34#endif
35	 ld	[%g1], %g7
36	or	%g7, %g2, %g5
37	and	%g7, %g2, %g2
38#ifdef CONFIG_SMP
39	st	%g5, [%g1]
40	set	bitops_spinlock, %g5
41	stb	%g0, [%g5]
42#else
43	st	%g5, [%g1]
44#endif
45	wr	%g3, 0x0, %psr
46	nop; nop; nop
47	jmpl	%o7, %g0
48	 mov	%g4, %o7
49
50	/* Same as above, but clears the bits from %g2 instead. */
51	.globl	___clear_bit
52___clear_bit:
53	rd	%psr, %g3
54	nop; nop; nop
55	or	%g3, PSR_PIL, %g5
56	wr	%g5, 0x0, %psr
57	nop; nop; nop
58#ifdef CONFIG_SMP
59	set	bitops_spinlock, %g5
602:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
61	orcc	%g7, 0x0, %g0		! Did we get it?
62	bne	2b			! Nope...
63#endif
64	 ld	[%g1], %g7
65	andn	%g7, %g2, %g5
66	and	%g7, %g2, %g2
67#ifdef CONFIG_SMP
68	st	%g5, [%g1]
69	set	bitops_spinlock, %g5
70	stb	%g0, [%g5]
71#else
72	st	%g5, [%g1]
73#endif
74	wr	%g3, 0x0, %psr
75	nop; nop; nop
76	jmpl	%o7, %g0
77	 mov	%g4, %o7
78
79	/* Same thing again, but this time toggles the bits from %g2. */
80	.globl	___change_bit
81___change_bit:
82	rd	%psr, %g3
83	nop; nop; nop
84	or	%g3, PSR_PIL, %g5
85	wr	%g5, 0x0, %psr
86	nop; nop; nop
87#ifdef CONFIG_SMP
88	set	bitops_spinlock, %g5
892:	ldstub	[%g5], %g7		! Spin on the byte lock for SMP.
90	orcc	%g7, 0x0, %g0		! Did we get it?
91	bne	2b			! Nope...
92#endif
93	 ld	[%g1], %g7
94	xor	%g7, %g2, %g5
95	and	%g7, %g2, %g2
96#ifdef CONFIG_SMP
97	st	%g5, [%g1]
98	set	bitops_spinlock, %g5
99	stb	%g0, [%g5]
100#else
101	st	%g5, [%g1]
102#endif
103	wr	%g3, 0x0, %psr
104	nop; nop; nop
105	jmpl	%o7, %g0
106	 mov	%g4, %o7
107
108	.globl  __bitops_end
109__bitops_end:
110