summaryrefslogtreecommitdiff
path: root/arch/sparc/lib/bitops.S
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2009-01-09 03:39:43 -0500
committerLen Brown <len.brown@intel.com>2009-01-09 03:39:43 -0500
commitb2576e1d4408e134e2188c967b1f28af39cd79d4 (patch)
tree004f3c82faab760f304ce031d6d2f572e7746a50 /arch/sparc/lib/bitops.S
parent3cc8a5f4ba91f67bbdb81a43a99281a26aab8d77 (diff)
parent2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (diff)
Merge branch 'linus' into release
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 000000000000..2b7228cb8c22
--- /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