/* atomic.S: Move this stuff here for better ICACHE hit rates. * * Copyright (C) 1996 David S. Miller (davem@caipfs.rutgers.edu) */ #include #include #include .text .align 4 #ifndef __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 ___atomic_add ___atomic_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 __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 atomic_t sra %g7, 8, %g7 ! Get signed 24-bit integer add %g7, %g2, %g2 ! Add in argument sll %g2, 8, %g7 ! Transpose back to atomic_t st %g7, [%g1] ! Clever: This releases the lock as well. #else ld [%g1], %g7 ! Load locked atomic_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 ___atomic_sub ___atomic_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 __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 atomic_t sra %g7, 8, %g7 ! Get signed 24-bit integer sub %g7, %g2, %g2 ! Subtract argument sll %g2, 8, %g7 ! Transpose back to atomic_t st %g7, [%g1] ! Clever: This releases the lock as well #else ld [%g1], %g7 ! Load locked atomic_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