diff options
Diffstat (limited to 'arch/sparc/lib/rwsem.S')
| -rw-r--r-- | arch/sparc/lib/rwsem.S | 205 | 
1 files changed, 205 insertions, 0 deletions
diff --git a/arch/sparc/lib/rwsem.S b/arch/sparc/lib/rwsem.S new file mode 100644 index 00000000000..e7578dc600b --- /dev/null +++ b/arch/sparc/lib/rwsem.S @@ -0,0 +1,205 @@ +/* $Id: rwsem.S,v 1.5 2000/05/09 17:40:13 davem Exp $ + * Assembly part of rw semaphores. + * + * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) + */ + +#include <linux/config.h> +#include <asm/ptrace.h> +#include <asm/psr.h> + +	.section .sched.text +	.align	4 + +	.globl		___down_read +___down_read: +	rd		%psr, %g3 +	nop +	nop +	nop +	or		%g3, PSR_PIL, %g7 +	wr		%g7, 0, %psr +	nop +	nop +	nop +#ifdef CONFIG_SMP +1:	ldstub		[%g1 + 4], %g7 +	tst		%g7 +	bne		1b +	 ld		[%g1], %g7 +	sub		%g7, 1, %g7 +	st		%g7, [%g1] +	stb		%g0, [%g1 + 4] +#else +	ld		[%g1], %g7 +	sub		%g7, 1, %g7 +	st		%g7, [%g1] +#endif +	wr		%g3, 0, %psr +	add		%g7, 1, %g7 +	nop +	nop +	subcc		%g7, 1, %g7 +	bneg		3f +	 nop +2:	jmpl		%o7, %g0 +	 mov		%g4, %o7 +3:	save		%sp, -64, %sp +	mov		%g1, %l1 +	mov		%g4, %l4 +	bcs		4f +	 mov		%g5, %l5 +	call		down_read_failed +	 mov		%l1, %o0 +	mov		%l1, %g1 +	mov		%l4, %g4 +	ba		___down_read +	 restore	%l5, %g0, %g5 +4:	call		down_read_failed_biased +	 mov		%l1, %o0 +	mov		%l1, %g1 +	mov		%l4, %g4 +	ba		2b +	 restore	%l5, %g0, %g5 + +	.globl		___down_write +___down_write: +	rd		%psr, %g3 +	nop +	nop +	nop +	or		%g3, PSR_PIL, %g7 +	wr		%g7, 0, %psr +	sethi		%hi(0x01000000), %g2 +	nop +	nop +#ifdef CONFIG_SMP +1:	ldstub		[%g1 + 4], %g7 +	tst		%g7 +	bne		1b +	 ld		[%g1], %g7 +	sub		%g7, %g2, %g7 +	st		%g7, [%g1] +	stb		%g0, [%g1 + 4] +#else +	ld		[%g1], %g7 +	sub		%g7, %g2, %g7 +	st		%g7, [%g1] +#endif +	wr		%g3, 0, %psr +	add		%g7, %g2, %g7 +	nop +	nop +	subcc		%g7, %g2, %g7 +	bne		3f +	 nop +2:	jmpl		%o7, %g0 +	 mov		%g4, %o7 +3:	save		%sp, -64, %sp +	mov		%g1, %l1 +	mov		%g4, %l4 +	bcs		4f +	 mov		%g5, %l5 +	call		down_write_failed +	 mov		%l1, %o0 +	mov		%l1, %g1 +	mov		%l4, %g4 +	ba		___down_write +	 restore	%l5, %g0, %g5 +4:	call		down_write_failed_biased +	 mov		%l1, %o0 +	mov		%l1, %g1 +	mov		%l4, %g4 +	ba		2b +	 restore	%l5, %g0, %g5 + +	.text +	.globl		___up_read +___up_read: +	rd		%psr, %g3 +	nop +	nop +	nop +	or		%g3, PSR_PIL, %g7 +	wr		%g7, 0, %psr +	nop +	nop +	nop +#ifdef CONFIG_SMP +1:	ldstub		[%g1 + 4], %g7 +	tst		%g7 +	bne		1b +	 ld		[%g1], %g7 +	add		%g7, 1, %g7 +	st		%g7, [%g1] +	stb		%g0, [%g1 + 4] +#else +	ld		[%g1], %g7 +	add		%g7, 1, %g7 +	st		%g7, [%g1] +#endif +	wr		%g3, 0, %psr +	nop +	nop +	nop +	cmp		%g7, 0 +	be		3f +	 nop +2:	jmpl		%o7, %g0 +	 mov		%g4, %o7 +3:	save		%sp, -64, %sp +	mov		%g1, %l1 +	mov		%g4, %l4 +	mov		%g5, %l5 +	clr		%o1 +	call		__rwsem_wake +	 mov		%l1, %o0 +	mov		%l1, %g1 +	mov		%l4, %g4 +	ba		2b +	 restore	%l5, %g0, %g5 + +	.globl		___up_write +___up_write: +	rd		%psr, %g3 +	nop +	nop +	nop +	or		%g3, PSR_PIL, %g7 +	wr		%g7, 0, %psr +	sethi		%hi(0x01000000), %g2 +	nop +	nop +#ifdef CONFIG_SMP +1:	ldstub		[%g1 + 4], %g7 +	tst		%g7 +	bne		1b +	 ld		[%g1], %g7 +	add		%g7, %g2, %g7 +	st		%g7, [%g1] +	stb		%g0, [%g1 + 4] +#else +	ld		[%g1], %g7 +	add		%g7, %g2, %g7 +	st		%g7, [%g1] +#endif +	wr		%g3, 0, %psr +	sub		%g7, %g2, %g7 +	nop +	nop +	addcc		%g7, %g2, %g7 +	bcs		3f +	 nop +2:	jmpl		%o7, %g0 +	 mov		%g4, %o7 +3:	save		%sp, -64, %sp +	mov		%g1, %l1 +	mov		%g4, %l4 +	mov		%g5, %l5 +	mov		%g7, %o1 +	call		__rwsem_wake +	 mov		%l1, %o0 +	mov		%l1, %g1 +	mov		%l4, %g4 +	ba		2b +	 restore	%l5, %g0, %g5  |