100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			100 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* atomic.S: Move this stuff here for better ICACHE hit rates.
 | |
|  *
 | |
|  * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu)
 | |
|  */
 | |
| 
 | |
| #include <asm/ptrace.h>
 | |
| #include <asm/psr.h>
 | |
| 
 | |
| 	.text
 | |
| 	.align	4
 | |
| 
 | |
| 	.globl  __atomic_begin
 | |
| __atomic_begin:
 | |
| 
 | |
| #ifndef CONFIG_SMP
 | |
| 	.globl	___xchg32_sun4c
 | |
| ___xchg32_sun4c:
 | |
| 	rd	%psr, %g3
 | |
| 	andcc	%g3, PSR_PIL, %g0
 | |
| 	bne	1f
 | |
| 	 nop
 | |
| 	wr	%g3, PSR_PIL, %psr
 | |
| 	nop; nop; nop
 | |
| 1:
 | |
| 	andcc	%g3, PSR_PIL, %g0
 | |
| 	ld	[%g1], %g7
 | |
| 	bne	1f
 | |
| 	 st	%g2, [%g1]
 | |
| 	wr	%g3, 0x0, %psr
 | |
| 	nop; nop; nop
 | |
| 1:
 | |
| 	mov	%g7, %g2
 | |
| 	jmpl	%o7 + 8, %g0
 | |
| 	 mov	%g4, %o7
 | |
| 
 | |
| 	.globl	___xchg32_sun4md
 | |
| ___xchg32_sun4md:
 | |
| 	swap	[%g1], %g2
 | |
| 	jmpl	%o7 + 8, %g0
 | |
| 	 mov	%g4, %o7
 | |
| #endif
 | |
| 
 | |
| 	/* Read asm-sparc/atomic.h carefully to understand how this works for SMP.
 | |
| 	 * Really, some things here for SMP are overly clever, go read the header.
 | |
| 	 */
 | |
| 	.globl	___atomic24_add
 | |
| ___atomic24_add:
 | |
| 	rd	%psr, %g3		! Keep the code small, old way was stupid
 | |
| 	nop; nop; nop;			! Let the bits set
 | |
| 	or	%g3, PSR_PIL, %g7	! Disable interrupts
 | |
| 	wr	%g7, 0x0, %psr		! Set %psr
 | |
| 	nop; nop; nop;			! Let the bits set
 | |
| #ifdef CONFIG_SMP
 | |
| 1:	ldstub	[%g1 + 3], %g7		! Spin on the byte lock for SMP.
 | |
| 	orcc	%g7, 0x0, %g0		! Did we get it?
 | |
| 	bne	1b			! Nope...
 | |
| 	 ld	[%g1], %g7		! Load locked atomic24_t
 | |
| 	sra	%g7, 8, %g7		! Get signed 24-bit integer
 | |
| 	add	%g7, %g2, %g2		! Add in argument
 | |
| 	sll	%g2, 8, %g7		! Transpose back to atomic24_t
 | |
| 	st	%g7, [%g1]		! Clever: This releases the lock as well.
 | |
| #else
 | |
| 	ld	[%g1], %g7		! Load locked atomic24_t
 | |
| 	add	%g7, %g2, %g2		! Add in argument
 | |
| 	st	%g2, [%g1]		! Store it back
 | |
| #endif
 | |
| 	wr	%g3, 0x0, %psr		! Restore original PSR_PIL
 | |
| 	nop; nop; nop;			! Let the bits set
 | |
| 	jmpl	%o7, %g0		! NOTE: not + 8, see callers in atomic.h
 | |
| 	 mov	%g4, %o7		! Restore %o7
 | |
| 
 | |
| 	.globl	___atomic24_sub
 | |
| ___atomic24_sub:
 | |
| 	rd	%psr, %g3		! Keep the code small, old way was stupid
 | |
| 	nop; nop; nop;			! Let the bits set
 | |
| 	or	%g3, PSR_PIL, %g7	! Disable interrupts
 | |
| 	wr	%g7, 0x0, %psr		! Set %psr
 | |
| 	nop; nop; nop;			! Let the bits set
 | |
| #ifdef CONFIG_SMP
 | |
| 1:	ldstub	[%g1 + 3], %g7		! Spin on the byte lock for SMP.
 | |
| 	orcc	%g7, 0x0, %g0		! Did we get it?
 | |
| 	bne	1b			! Nope...
 | |
| 	 ld	[%g1], %g7		! Load locked atomic24_t
 | |
| 	sra	%g7, 8, %g7		! Get signed 24-bit integer
 | |
| 	sub	%g7, %g2, %g2		! Subtract argument
 | |
| 	sll	%g2, 8, %g7		! Transpose back to atomic24_t
 | |
| 	st	%g7, [%g1]		! Clever: This releases the lock as well
 | |
| #else
 | |
| 	ld	[%g1], %g7		! Load locked atomic24_t
 | |
| 	sub	%g7, %g2, %g2		! Subtract argument
 | |
| 	st	%g2, [%g1]		! Store it back
 | |
| #endif
 | |
| 	wr	%g3, 0x0, %psr		! Restore original PSR_PIL
 | |
| 	nop; nop; nop;			! Let the bits set
 | |
| 	jmpl	%o7, %g0		! NOTE: not + 8, see callers in atomic.h
 | |
| 	 mov	%g4, %o7		! Restore %o7
 | |
| 
 | |
| 	.globl  __atomic_end
 | |
| __atomic_end:
 |