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