GNU Linux-libre 4.9.290-gnu1
[releases.git] / arch / sh / include / asm / futex-llsc.h
1 #ifndef __ASM_SH_FUTEX_LLSC_H
2 #define __ASM_SH_FUTEX_LLSC_H
3
4 static inline int atomic_futex_op_cmpxchg_inatomic(u32 *uval,
5                                                    u32 __user *uaddr,
6                                                    u32 oldval, u32 newval)
7 {
8         int err = 0;
9         __asm__ __volatile__(
10                 "synco\n"
11                 "1:\n\t"
12                 "movli.l        @%2, r0\n\t"
13                 "mov    r0, %1\n\t"
14                 "cmp/eq %1, %4\n\t"
15                 "bf     2f\n\t"
16                 "mov    %5, r0\n\t"
17                 "movco.l        r0, @%2\n\t"
18                 "bf     1b\n"
19                 "2:\n\t"
20                 "synco\n\t"
21 #ifdef CONFIG_MMU
22                 ".section       .fixup,\"ax\"\n"
23                 "3:\n\t"
24                 "mov.l  4f, %0\n\t"
25                 "jmp    @%0\n\t"
26                 " mov   %3, %0\n\t"
27                 ".balign        4\n"
28                 "4:     .long   2b\n\t"
29                 ".previous\n"
30                 ".section       __ex_table,\"a\"\n\t"
31                 ".long  1b, 3b\n\t"
32                 ".previous"
33 #endif
34                 :"+r" (err), "=&r" (*uval)
35                 :"r" (uaddr), "i" (-EFAULT), "r" (oldval), "r" (newval)
36                 :"t", "memory", "r0");
37         if (err) return err;
38         return 0;
39 }
40
41 #endif /* __ASM_SH_FUTEX_LLSC_H */