12 #include <linux/futex.h>
14 #include <asm/futex.h>
15 #include <asm/errno.h>
21 static inline int atomic_futex_op_xchg_set(
int oparg,
u32 __user *
uaddr,
int *_oldval)
26 " orcc gr0,gr0,gr0,icc3 \n"
29 " orcr cc7,cc7,cc3 \n"
30 "2: cst.p %3,%M0 ,cc3,#1 \n"
31 " corcc gr29,gr29,gr0 ,cc3,#1 \n"
39 ".section __ex_table,\"a\" \n"
44 :
"+U"(*uaddr),
"=&r"(oldval),
"=&r"(ret),
"=r"(oparg)
46 :
"memory",
"cc7",
"cc3",
"icc3"
53 static inline int atomic_futex_op_xchg_add(
int oparg,
u32 __user *uaddr,
int *_oldval)
58 " orcc gr0,gr0,gr0,icc3 \n"
61 " orcr cc7,cc7,cc3 \n"
63 "2: cst.p %3,%M0 ,cc3,#1 \n"
64 " corcc gr29,gr29,gr0 ,cc3,#1 \n"
72 ".section __ex_table,\"a\" \n"
77 :
"+U"(*uaddr),
"=&r"(oldval),
"=&r"(ret),
"=r"(oparg)
79 :
"memory",
"cc7",
"cc3",
"icc3"
86 static inline int atomic_futex_op_xchg_or(
int oparg,
u32 __user *uaddr,
int *_oldval)
91 " orcc gr0,gr0,gr0,icc3 \n"
94 " orcr cc7,cc7,cc3 \n"
96 "2: cst.p %3,%M0 ,cc3,#1 \n"
97 " corcc gr29,gr29,gr0 ,cc3,#1 \n"
105 ".section __ex_table,\"a\" \n"
110 :
"+U"(*uaddr),
"=&r"(oldval),
"=&r"(ret),
"=r"(oparg)
111 :
"3"(oparg),
"i"(-
EFAULT)
112 :
"memory",
"cc7",
"cc3",
"icc3"
119 static inline int atomic_futex_op_xchg_and(
int oparg,
u32 __user *uaddr,
int *_oldval)
124 " orcc gr0,gr0,gr0,icc3 \n"
127 " orcr cc7,cc7,cc3 \n"
129 "2: cst.p %3,%M0 ,cc3,#1 \n"
130 " corcc gr29,gr29,gr0 ,cc3,#1 \n"
138 ".section __ex_table,\"a\" \n"
143 :
"+U"(*uaddr),
"=&r"(oldval),
"=&r"(ret),
"=r"(oparg)
144 :
"3"(oparg),
"i"(-
EFAULT)
145 :
"memory",
"cc7",
"cc3",
"icc3"
152 static inline int atomic_futex_op_xchg_xor(
int oparg,
u32 __user *uaddr,
int *_oldval)
157 " orcc gr0,gr0,gr0,icc3 \n"
160 " orcr cc7,cc7,cc3 \n"
162 "2: cst.p %3,%M0 ,cc3,#1 \n"
163 " corcc gr29,gr29,gr0 ,cc3,#1 \n"
171 ".section __ex_table,\"a\" \n"
176 :
"+U"(*uaddr),
"=&r"(oldval),
"=&r"(ret),
"=r"(oparg)
177 :
"3"(oparg),
"i"(-
EFAULT)
178 :
"memory",
"cc7",
"cc3",
"icc3"
191 int op = (encoded_op >> 28) & 7;
192 int cmp = (encoded_op >> 24) & 15;
193 int oparg = (encoded_op << 8) >> 20;
194 int cmparg = (encoded_op << 20) >> 20;
207 ret = atomic_futex_op_xchg_set(oparg, uaddr, &oldval);
210 ret = atomic_futex_op_xchg_add(oparg, uaddr, &oldval);
213 ret = atomic_futex_op_xchg_or(oparg, uaddr, &oldval);
216 ret = atomic_futex_op_xchg_and(~oparg, uaddr, &oldval);
219 ret = atomic_futex_op_xchg_xor(oparg, uaddr, &oldval);
236 default: ret = -
ENOSYS;
break;