summaryrefslogtreecommitdiffstats
path: root/arch/sparc/lib/bitops.S
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2009-01-08 13:22:55 +1100
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2009-01-08 13:22:55 +1100
commit6206aa8b2b9a45b4cf3ee31b7209b014be349fd9 (patch)
tree72c4223a2cc21bf055948eadb3b314ed0568ae9d /arch/sparc/lib/bitops.S
parent95f8e302c04c0b0c6de35ab399a5551605eeb006 (diff)
parent9e42d0cf5020aaf217433cad1a224745241d212a (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/sparc/lib/bitops.S')
-rw-r--r--arch/sparc/lib/bitops.S141
1 files changed, 141 insertions, 0 deletions
diff --git a/arch/sparc/lib/bitops.S b/arch/sparc/lib/bitops.S
new file mode 100644
index 00000000000..2b7228cb8c2
--- /dev/null
+++ b/arch/sparc/lib/bitops.S
@@ -0,0 +1,141 @@
+/* bitops.S: Sparc64 atomic bit operations.
+ *
+ * Copyright (C) 2000, 2007 David S. Miller (davem@davemloft.net)
+ */
+
+#include <asm/asi.h>
+#include <asm/backoff.h>
+
+ .text
+
+ .globl test_and_set_bit
+ .type test_and_set_bit,#function
+test_and_set_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
+ srlx %o0, 6, %g1
+ mov 1, %o2
+ sllx %g1, 3, %g3
+ and %o0, 63, %g2
+ sllx %o2, %g2, %o2
+ add %o1, %g3, %o1
+1: ldx [%o1], %g7
+ or %g7, %o2, %g1
+ casx [%o1], %g7, %g1
+ cmp %g7, %g1
+ bne,pn %xcc, 2f
+ and %g7, %o2, %g2
+ clr %o0
+ movrne %g2, 1, %o0
+ retl
+ nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
+ .size test_and_set_bit, .-test_and_set_bit
+
+ .globl test_and_clear_bit
+ .type test_and_clear_bit,#function
+test_and_clear_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
+ srlx %o0, 6, %g1
+ mov 1, %o2
+ sllx %g1, 3, %g3
+ and %o0, 63, %g2
+ sllx %o2, %g2, %o2
+ add %o1, %g3, %o1
+1: ldx [%o1], %g7
+ andn %g7, %o2, %g1
+ casx [%o1], %g7, %g1
+ cmp %g7, %g1
+ bne,pn %xcc, 2f
+ and %g7, %o2, %g2
+ clr %o0
+ movrne %g2, 1, %o0
+ retl
+ nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
+ .size test_and_clear_bit, .-test_and_clear_bit
+
+ .globl test_and_change_bit
+ .type test_and_change_bit,#function
+test_and_change_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
+ srlx %o0, 6, %g1
+ mov 1, %o2
+ sllx %g1, 3, %g3
+ and %o0, 63, %g2
+ sllx %o2, %g2, %o2
+ add %o1, %g3, %o1
+1: ldx [%o1], %g7
+ xor %g7, %o2, %g1
+ casx [%o1], %g7, %g1
+ cmp %g7, %g1
+ bne,pn %xcc, 2f
+ and %g7, %o2, %g2
+ clr %o0
+ movrne %g2, 1, %o0
+ retl
+ nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
+ .size test_and_change_bit, .-test_and_change_bit
+
+ .globl set_bit
+ .type set_bit,#function
+set_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
+ srlx %o0, 6, %g1
+ mov 1, %o2
+ sllx %g1, 3, %g3
+ and %o0, 63, %g2
+ sllx %o2, %g2, %o2
+ add %o1, %g3, %o1
+1: ldx [%o1], %g7
+ or %g7, %o2, %g1
+ casx [%o1], %g7, %g1
+ cmp %g7, %g1
+ bne,pn %xcc, 2f
+ nop
+ retl
+ nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
+ .size set_bit, .-set_bit
+
+ .globl clear_bit
+ .type clear_bit,#function
+clear_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
+ srlx %o0, 6, %g1
+ mov 1, %o2
+ sllx %g1, 3, %g3
+ and %o0, 63, %g2
+ sllx %o2, %g2, %o2
+ add %o1, %g3, %o1
+1: ldx [%o1], %g7
+ andn %g7, %o2, %g1
+ casx [%o1], %g7, %g1
+ cmp %g7, %g1
+ bne,pn %xcc, 2f
+ nop
+ retl
+ nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
+ .size clear_bit, .-clear_bit
+
+ .globl change_bit
+ .type change_bit,#function
+change_bit: /* %o0=nr, %o1=addr */
+ BACKOFF_SETUP(%o3)
+ srlx %o0, 6, %g1
+ mov 1, %o2
+ sllx %g1, 3, %g3
+ and %o0, 63, %g2
+ sllx %o2, %g2, %o2
+ add %o1, %g3, %o1
+1: ldx [%o1], %g7
+ xor %g7, %o2, %g1
+ casx [%o1], %g7, %g1
+ cmp %g7, %g1
+ bne,pn %xcc, 2f
+ nop
+ retl
+ nop
+2: BACKOFF_SPIN(%o3, %o4, 1b)
+ .size change_bit, .-change_bit