/* bitops.S: Low level assembler bit operations. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) */ #include #include #include .text .align 4 .globl __bitops_begin __bitops_begin: /* Take bits in %g2 and set them in word at %g1, * return whether bits were set in original value * in %g2. %g4 holds value to restore into %o7 * in delay slot of jmpl return, %g3 + %g5 + %g7 can be * used as temporaries and thus is considered clobbered * by all callers. */ .globl ___set_bit ___set_bit: rd %psr, %g3 nop; nop; nop; or %g3, PSR_PIL, %g5 wr %g5, 0x0, %psr nop; nop; nop #ifdef CONFIG_SMP set bitops_spinlock, %g5 2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP. orcc %g7, 0x0, %g0 ! Did we get it? bne 2b ! Nope... #endif ld [%g1], %g7 or %g7, %g2, %g5 and %g7, %g2, %g2 #ifdef CONFIG_SMP st %g5, [%g1] set bitops_spinlock, %g5 stb %g0, [%g5] #else st %g5, [%g1] #endif wr %g3, 0x0, %psr nop; nop; nop jmpl %o7, %g0 mov %g4, %o7 /* Same as above, but clears the bits from %g2 instead. */ .globl ___clear_bit ___clear_bit: rd %psr, %g3 nop; nop; nop or %g3, PSR_PIL, %g5 wr %g5, 0x0, %psr nop; nop; nop #ifdef CONFIG_SMP set bitops_spinlock, %g5 2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP. orcc %g7, 0x0, %g0 ! Did we get it? bne 2b ! Nope... #endif ld [%g1], %g7 andn %g7, %g2, %g5 and %g7, %g2, %g2 #ifdef CONFIG_SMP st %g5, [%g1] set bitops_spinlock, %g5 stb %g0, [%g5] #else st %g5, [%g1] #endif wr %g3, 0x0, %psr nop; nop; nop jmpl %o7, %g0 mov %g4, %o7 /* Same thing again, but this time toggles the bits from %g2. */ .globl ___change_bit ___change_bit: rd %psr, %g3 nop; nop; nop or %g3, PSR_PIL, %g5 wr %g5, 0x0, %psr nop; nop; nop #ifdef CONFIG_SMP set bitops_spinlock, %g5 2: ldstub [%g5], %g7 ! Spin on the byte lock for SMP. orcc %g7, 0x0, %g0 ! Did we get it? bne 2b ! Nope... #endif ld [%g1], %g7 xor %g7, %g2, %g5 and %g7, %g2, %g2 #ifdef CONFIG_SMP st %g5, [%g1] set bitops_spinlock, %g5 stb %g0, [%g5] #else st %g5, [%g1] #endif wr %g3, 0x0, %psr nop; nop; nop jmpl %o7, %g0 mov %g4, %o7 .globl __bitops_end __bitops_end: