1 /*
2  * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
3  */
4 
5 #ifndef _PT_MACHINE_H
6 #define _PT_MACHINE_H   1
7 #include <features.h>
8 
9 #ifndef PT_EI
10 # define PT_EI __extern_always_inline
11 #endif
12 
13 #define HAS_COMPARE_AND_SWAP
14 PT_EI int
__compare_and_swap(long int * p,long int oldval,long int newval)15 __compare_and_swap (long int *p, long int oldval, long int newval)
16 {
17   long int ret, temp;
18 
19   __asm__ __volatile__
20     ("/* Inline compare & swap */\n"
21      "1:\n\t"
22      "lr.w      %1,%2\n\t"
23      "li        %0,0\n\t"
24      "bne       %1,%3,2f\n\t"
25      "li        %0,1\n\t"
26      "sc.w      %1,%4,%2\n\t"
27      "bnez      %1,1b\n"
28      "2:\n\t"
29      "/* End compare & swap */"
30      : "=&r" (ret), "=&r" (temp), "+A" (*p)
31      : "r" (oldval), "r" (newval)
32      : "memory");
33 
34   return ret;
35 }
36 
37 extern long int testandset (int *spinlock);
38 
39 PT_EI long int
testandset(int * spinlock)40 testandset (int *spinlock)
41 {
42         unsigned int old = 1;
43         int tmp = 1;
44 
45         __asm__ __volatile__ (
46         "amoswap.w %0, %2, %1"
47         : "=r" (old), "+A" (*spinlock)
48         : "r" (tmp)
49         : "memory");
50 
51         return old;
52 }
53 
54 /* Get some notion of the current stack.  Need not be exactly the top
55    of the stack, just something somewhere in the current frame.  */
56 #define CURRENT_STACK_FRAME  stack_pointer
57 register char * stack_pointer __asm__ ("sp");
58 
59 #else
60 #error PT_MACHINE already defined
61 #endif /* pt-machine.h */
62