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.
5 * Copyright (C) 2000 David S. Miller (davem@redhat.com)
7 #include <linux/config.h>
8 #include <asm/thread_info.h>
13 /* CAS basically works like this:
15 * void CAS(MEM, REG1, REG2)
18 * if (*(MEM) == REG1) {
28 .globl _atomic_dec_and_lock
29 _atomic_dec_and_lock: /* %o0 = counter, %o1 = lock */
30 loop1: lduw [%o0], %g2
32 be,pn %icc, start_to_zero
34 nzero: cas [%o0], %g2, %g7
40 membar #StoreLoad | #StoreStore
45 ldsw [%g6 + TI_PRE_COUNT], %g3
47 stw %g3, [%g6 + TI_PRE_COUNT]
51 brnz,pn %g3, spin_on_lock
52 membar #StoreLoad | #StoreStore
53 loop2: cas [%o0], %g2, %g7 /* ASSERT(g7 == 0) */
62 membar #StoreStore | #LoadStore
65 ldsw [%g6 + TI_PRE_COUNT], %g3
67 stw %g3, [%g6 + TI_PRE_COUNT]
74 brnz,pt %g3, spin_on_lock