1 /*
2  * sysdeps/microblaze/pt-machine.h -- microblaze-specific pthread definitions
3  *
4  *  Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
5  *  Copyright (C) 2002  NEC Electronics Corporation
6  *  Copyright (C) 2002  Miles Bader <miles@gnu.org>
7  *
8  * This file is subject to the terms and conditions of the GNU Lesser
9  * General Public License.  See the file COPYING.LIB in the main
10  * directory of this archive for more details.
11  *
12  */
13 
14 #ifndef _PT_MACHINE_H
15 #define _PT_MACHINE_H   1
16 
17 #include <features.h>
18 
19 #ifndef PT_EI
20 # define PT_EI __extern_always_inline
21 #endif
22 
23 /* Get some notion of the current stack.  Need not be exactly the top
24    of the stack, just something somewhere in the current frame.  */
25 #define CURRENT_STACK_FRAME  __stack_pointer
26 register char *__stack_pointer __asm__ ("r1");
27 
28 #define HAS_COMPARE_AND_SWAP
29 #define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
30 #define MEMORY_BARRIER() __asm__ __volatile__("": : :"memory")
31 
32 /* Atomically:  If *PTR == OLD, set *PTR to NEW and return true,
33    otherwise do nothing and return false.  */
__compare_and_swap(long * ptr,long old,long new)34 PT_EI int __compare_and_swap (long *ptr, long old, long new)
35 {
36   long prev, cmp, retval;
37   __asm__ __volatile__ ("         addi    %2, r0, 0;"
38                         "1:       lwx     %0, %3, r0;"
39                         "         cmp     %1, %0, %4;"
40                         "         bnei    %1, 2f;"
41                         "         swx     %5, %3, r0;"
42                         "         addic   %1, r0, 0;"
43                         "         bnei    %1, 1b;"
44                         "         addi    %2, r0, 1;"
45                         "2:"
46                         : "=&r" (prev), "=&r" (cmp), "=&r" (retval)
47                         : "r" (ptr), "r" (old), "r" (new)
48                         : "cc", "memory");
49 
50   return retval;
51 }
52 
53 PT_EI int
__compare_and_swap_with_release_semantics(long * p,long oldval,long newval)54 __compare_and_swap_with_release_semantics (long *p,
55 					   long oldval, long newval)
56 {
57   MEMORY_BARRIER();
58   return __compare_and_swap (p, oldval, newval);
59 }
60 
61 /* Spinlock implementation; required.  */
testandset(int * spinlock)62 PT_EI long int testandset (int *spinlock)
63 {
64   long int retval;
65 
66   __asm__ __volatile__ ("1:       lwx     %0, %1, r0;"
67                         "         bnei    %0, 2f;"
68                         "         addik   %0, r0, 1;"
69                         "         swx     %0, %1, r0;"
70                         "         addic   %0, r0, 0;"
71                         "         bnei    %0, 1b;"
72                         "2:"
73                         : "=&r" (retval)
74                         : "r" (spinlock)
75                         : "cc", "memory");
76 
77   return retval;
78 }
79 
80 #endif /* pt-machine.h */
81