aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/lib
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2005-09-15 00:47:01 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-15 00:47:01 -0400
commit4db2ce0199f04b6e99999f22e28ef9a0ae5f0d2f (patch)
tree87a00c97e02a77cdfec517398caa3f1d8f6a2f0d /arch/sparc64/lib
parent4a805e863d6b9466baf7084e1d6fdbe6e0628d8e (diff)
[LIB]: Consolidate _atomic_dec_and_lock()
Several implementations were essentialy a common piece of C code using the cmpxchg() macro. Put the implementation in one spot that everyone can share, and convert sparc64 over to using this. Alpha is the lone arch-specific implementation, which codes up a special fast path for the common case in order to avoid GP reloading which a pure C version would require. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/lib')
-rw-r--r--arch/sparc64/lib/Makefile2
-rw-r--r--arch/sparc64/lib/dec_and_lock.S80
2 files changed, 0 insertions, 82 deletions
diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile
index d968aebe83b2..c295806500f7 100644
--- a/arch/sparc64/lib/Makefile
+++ b/arch/sparc64/lib/Makefile
@@ -14,6 +14,4 @@ lib-y := PeeCeeI.o copy_page.o clear_page.o strlen.o strncmp.o \
14 copy_in_user.o user_fixup.o memmove.o \ 14 copy_in_user.o user_fixup.o memmove.o \
15 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o 15 mcount.o ipcsum.o rwsem.o xor.o find_bit.o delay.o
16 16
17lib-$(CONFIG_HAVE_DEC_LOCK) += dec_and_lock.o
18
19obj-y += iomap.o 17obj-y += iomap.o
diff --git a/arch/sparc64/lib/dec_and_lock.S b/arch/sparc64/lib/dec_and_lock.S
deleted file mode 100644
index 8ee288dd0afc..000000000000
--- a/arch/sparc64/lib/dec_and_lock.S
+++ /dev/null
@@ -1,80 +0,0 @@
1/* $Id: dec_and_lock.S,v 1.5 2001/11/18 00:12:56 davem Exp $
2 * dec_and_lock.S: Sparc64 version of "atomic_dec_and_lock()"
3 * using cas and ldstub instructions.
4 *
5 * Copyright (C) 2000 David S. Miller (davem@redhat.com)
6 */
7#include <linux/config.h>
8#include <asm/thread_info.h>
9
10 .text
11 .align 64
12
13 /* CAS basically works like this:
14 *
15 * void CAS(MEM, REG1, REG2)
16 * {
17 * START_ATOMIC();
18 * if (*(MEM) == REG1) {
19 * TMP = *(MEM);
20 * *(MEM) = REG2;
21 * REG2 = TMP;
22 * } else
23 * REG2 = *(MEM);
24 * END_ATOMIC();
25 * }
26 */
27
28 .globl _atomic_dec_and_lock
29_atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */
30loop1: lduw [%o0], %g2
31 subcc %g2, 1, %g7
32 be,pn %icc, start_to_zero
33 nop
34nzero: cas [%o0], %g2, %g7
35 cmp %g2, %g7
36 bne,pn %icc, loop1
37 mov 0, %g1
38
39out:
40 membar #StoreLoad | #StoreStore
41 retl
42 mov %g1, %o0
43start_to_zero:
44#ifdef CONFIG_PREEMPT
45 ldsw [%g6 + TI_PRE_COUNT], %g3
46 add %g3, 1, %g3
47 stw %g3, [%g6 + TI_PRE_COUNT]
48#endif
49to_zero:
50 ldstub [%o1], %g3
51 membar #StoreLoad | #StoreStore
52 brnz,pn %g3, spin_on_lock
53 nop
54loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */
55 cmp %g2, %g7
56
57 be,pt %icc, out
58 mov 1, %g1
59 lduw [%o0], %g2
60 subcc %g2, 1, %g7
61 be,pn %icc, loop2
62 nop
63 membar #StoreStore | #LoadStore
64 stb %g0, [%o1]
65#ifdef CONFIG_PREEMPT
66 ldsw [%g6 + TI_PRE_COUNT], %g3
67 sub %g3, 1, %g3
68 stw %g3, [%g6 + TI_PRE_COUNT]
69#endif
70
71 b,pt %xcc, nzero
72 nop
73spin_on_lock:
74 ldub [%o1], %g3
75 membar #LoadLoad
76 brnz,pt %g3, spin_on_lock
77 nop
78 ba,pt %xcc, to_zero
79 nop
80 nop