1/* $Id: rwsem.S,v 1.5 2000/05/09 17:40:13 davem Exp $
2 * Assembly part of rw semaphores.
3 *
4 * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
5 */
6
7#include <linux/config.h>
8#include <asm/ptrace.h>
9#include <asm/psr.h>
10
11	.text
12	.align	4
13
14	.globl		___down_read
15___down_read:
16	rd		%psr, %g3
17	nop
18	nop
19	nop
20	or		%g3, PSR_PIL, %g7
21	wr		%g7, 0, %psr
22	nop
23	nop
24	nop
25#ifdef CONFIG_SMP
261:	ldstub		[%g1 + 4], %g7
27	tst		%g7
28	bne		1b
29	 ld		[%g1], %g7
30	sub		%g7, 1, %g7
31	st		%g7, [%g1]
32	stb		%g0, [%g1 + 4]
33#else
34	ld		[%g1], %g7
35	sub		%g7, 1, %g7
36	st		%g7, [%g1]
37#endif
38	wr		%g3, 0, %psr
39	add		%g7, 1, %g7
40	nop
41	nop
42	subcc		%g7, 1, %g7
43	bneg		3f
44	 nop
452:	jmpl		%o7, %g0
46	 mov		%g4, %o7
473:	save		%sp, -64, %sp
48	mov		%g1, %l1
49	mov		%g4, %l4
50	bcs		4f
51	 mov		%g5, %l5
52	call		down_read_failed
53	 mov		%l1, %o0
54	mov		%l1, %g1
55	mov		%l4, %g4
56	ba		___down_read
57	 restore	%l5, %g0, %g5
584:	call		down_read_failed_biased
59	 mov		%l1, %o0
60	mov		%l1, %g1
61	mov		%l4, %g4
62	ba		2b
63	 restore	%l5, %g0, %g5
64
65	.globl		___down_write
66___down_write:
67	rd		%psr, %g3
68	nop
69	nop
70	nop
71	or		%g3, PSR_PIL, %g7
72	wr		%g7, 0, %psr
73	sethi		%hi(0x01000000), %g2
74	nop
75	nop
76#ifdef CONFIG_SMP
771:	ldstub		[%g1 + 4], %g7
78	tst		%g7
79	bne		1b
80	 ld		[%g1], %g7
81	sub		%g7, %g2, %g7
82	st		%g7, [%g1]
83	stb		%g0, [%g1 + 4]
84#else
85	ld		[%g1], %g7
86	sub		%g7, %g2, %g7
87	st		%g7, [%g1]
88#endif
89	wr		%g3, 0, %psr
90	add		%g7, %g2, %g7
91	nop
92	nop
93	subcc		%g7, %g2, %g7
94	bne		3f
95	 nop
962:	jmpl		%o7, %g0
97	 mov		%g4, %o7
983:	save		%sp, -64, %sp
99	mov		%g1, %l1
100	mov		%g4, %l4
101	bcs		4f
102	 mov		%g5, %l5
103	call		down_write_failed
104	 mov		%l1, %o0
105	mov		%l1, %g1
106	mov		%l4, %g4
107	ba		___down_write
108	 restore	%l5, %g0, %g5
1094:	call		down_write_failed_biased
110	 mov		%l1, %o0
111	mov		%l1, %g1
112	mov		%l4, %g4
113	ba		2b
114	 restore	%l5, %g0, %g5
115
116	.globl		___up_read
117___up_read:
118	rd		%psr, %g3
119	nop
120	nop
121	nop
122	or		%g3, PSR_PIL, %g7
123	wr		%g7, 0, %psr
124	nop
125	nop
126	nop
127#ifdef CONFIG_SMP
1281:	ldstub		[%g1 + 4], %g7
129	tst		%g7
130	bne		1b
131	 ld		[%g1], %g7
132	add		%g7, 1, %g7
133	st		%g7, [%g1]
134	stb		%g0, [%g1 + 4]
135#else
136	ld		[%g1], %g7
137	add		%g7, 1, %g7
138	st		%g7, [%g1]
139#endif
140	wr		%g3, 0, %psr
141	nop
142	nop
143	nop
144	cmp		%g7, 0
145	be		3f
146	 nop
1472:	jmpl		%o7, %g0
148	 mov		%g4, %o7
1493:	save		%sp, -64, %sp
150	mov		%g1, %l1
151	mov		%g4, %l4
152	mov		%g5, %l5
153	clr		%o1
154	call		__rwsem_wake
155	 mov		%l1, %o0
156	mov		%l1, %g1
157	mov		%l4, %g4
158	ba		2b
159	 restore	%l5, %g0, %g5
160
161	.globl		___up_write
162___up_write:
163	rd		%psr, %g3
164	nop
165	nop
166	nop
167	or		%g3, PSR_PIL, %g7
168	wr		%g7, 0, %psr
169	sethi		%hi(0x01000000), %g2
170	nop
171	nop
172#ifdef CONFIG_SMP
1731:	ldstub		[%g1 + 4], %g7
174	tst		%g7
175	bne		1b
176	 ld		[%g1], %g7
177	add		%g7, %g2, %g7
178	st		%g7, [%g1]
179	stb		%g0, [%g1 + 4]
180#else
181	ld		[%g1], %g7
182	add		%g7, %g2, %g7
183	st		%g7, [%g1]
184#endif
185	wr		%g3, 0, %psr
186	sub		%g7, %g2, %g7
187	nop
188	nop
189	addcc		%g7, %g2, %g7
190	bcs		3f
191	 nop
1922:	jmpl		%o7, %g0
193	 mov		%g4, %o7
1943:	save		%sp, -64, %sp
195	mov		%g1, %l1
196	mov		%g4, %l4
197	mov		%g5, %l5
198	mov		%g7, %o1
199	call		__rwsem_wake
200	 mov		%l1, %o0
201	mov		%l1, %g1
202	mov		%l4, %g4
203	ba		2b
204	 restore	%l5, %g0, %g5
205