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