7829c779e63b47b12ee15c64c3f6fe08c1c91eed
[kopensolaris-gnu/glibc.git] / linuxthreads / sysdeps / powerpc / pt-machine.h
1 /* Machine-dependent pthreads configuration and inline functions.
2    powerpc version.
3    Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If
18    not, write to the Free Software Foundation, Inc.,
19    59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* These routines are from Appendix G of the 'PowerPC 601 RISC Microprocessor
22    User's Manual', by IBM and Motorola.  */
23
24 /* For multiprocessor systems, we want to ensure all memory accesses
25    are completed before we reset a lock.  */
26 #if 0
27 /* on non multiprocessor systems, you can just: */
28 #define sync() /* nothing */
29 #else
30 #define sync() __asm__ __volatile__ ("sync")
31 #endif
32
33 /* Get some notion of the current stack.  Need not be exactly the top
34    of the stack, just something somewhere in the current frame.  */
35 #define CURRENT_STACK_FRAME  stack_pointer
36 register char * stack_pointer __asm__ ("r1");
37
38 /* Compare-and-swap for semaphores. */
39 /* note that test-and-set(x) is the same as compare-and-swap(x, 0, 1) */
40
41 #define HAS_COMPARE_AND_SWAP
42 #if BROKEN_PPC_ASM_CR0
43 static
44 #else
45 extern inline
46 #endif
47 int
48 __compare_and_swap (long *p, long oldval, long newval)
49 {
50   int ret;
51
52   sync();
53   __asm__ __volatile__(
54                        "0:    lwarx %0,0,%1 ;"
55                        "      xor. %0,%3,%0;"
56                        "      bne 1f;"
57                        "      stwcx. %2,0,%1;"
58                        "      bne- 0b;"
59                        "1:    "
60         : "=&r"(ret)
61         : "r"(p), "r"(newval), "r"(oldval)
62         : "cr0", "memory");
63   sync();
64   return ret == 0;
65 }