Commit 3e5ee323 authored by Heiko Carstens's avatar Heiko Carstens

s390/atomic,cmpxchg: make constraints work with old compilers

Old gcc versions may fail with an internal compiler error if only the
T or S constraint is specified for an operand, and no displacement is
needed at all.

To fix this use RT and QS as constraints, which reflects the union of
both. Later gcc versions do the right thing and always accept single T
and S constraints.
See gcc commit 3e4be43f69da ("S/390: Memory constraint cleanup").

Fixes: ca897bb1 ("s390/atomic: use proper constraints")
Fixes: b23eb636 ("s390/atomic: get rid of gcc atomic builtins")
Fixes: d2b1f6d2 ("s390/cmpxchg: get rid of gcc atomic builtins")
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 5d8da695
...@@ -31,7 +31,7 @@ static inline s64 __atomic64_read(const atomic64_t *v) ...@@ -31,7 +31,7 @@ static inline s64 __atomic64_read(const atomic64_t *v)
asm volatile( asm volatile(
" lg %0,%1\n" " lg %0,%1\n"
: "=d" (c) : "T" (v->counter)); : "=d" (c) : "RT" (v->counter));
return c; return c;
} }
...@@ -39,7 +39,7 @@ static inline void __atomic64_set(atomic64_t *v, s64 i) ...@@ -39,7 +39,7 @@ static inline void __atomic64_set(atomic64_t *v, s64 i)
{ {
asm volatile( asm volatile(
" stg %1,%0\n" " stg %1,%0\n"
: "=T" (v->counter) : "d" (i)); : "=RT" (v->counter) : "d" (i));
} }
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
...@@ -52,7 +52,7 @@ static inline op_type op_name(op_type val, op_type *ptr) \ ...@@ -52,7 +52,7 @@ static inline op_type op_name(op_type val, op_type *ptr) \
asm volatile( \ asm volatile( \
op_string " %[old],%[val],%[ptr]\n" \ op_string " %[old],%[val],%[ptr]\n" \
op_barrier \ op_barrier \
: [old] "=d" (old), [ptr] "+S" (*ptr) \ : [old] "=d" (old), [ptr] "+QS" (*ptr) \
: [val] "d" (val) : "cc", "memory"); \ : [val] "d" (val) : "cc", "memory"); \
return old; \ return old; \
} \ } \
...@@ -80,7 +80,7 @@ static __always_inline void op_name(op_type val, op_type *ptr) \ ...@@ -80,7 +80,7 @@ static __always_inline void op_name(op_type val, op_type *ptr) \
asm volatile( \ asm volatile( \
op_string " %[ptr],%[val]\n" \ op_string " %[ptr],%[val]\n" \
op_barrier \ op_barrier \
: [ptr] "+S" (*ptr) : [val] "i" (val) : "cc", "memory");\ : [ptr] "+QS" (*ptr) : [val] "i" (val) : "cc", "memory");\
} }
#define __ATOMIC_CONST_OPS(op_name, op_type, op_string) \ #define __ATOMIC_CONST_OPS(op_name, op_type, op_string) \
...@@ -131,7 +131,7 @@ static inline long op_name(long val, long *ptr) \ ...@@ -131,7 +131,7 @@ static inline long op_name(long val, long *ptr) \
op_string " %[new],%[val]\n" \ op_string " %[new],%[val]\n" \
" csg %[old],%[new],%[ptr]\n" \ " csg %[old],%[new],%[ptr]\n" \
" jl 0b" \ " jl 0b" \
: [old] "=d" (old), [new] "=&d" (new), [ptr] "+S" (*ptr)\ : [old] "=d" (old), [new] "=&d" (new), [ptr] "+QS" (*ptr)\
: [val] "d" (val), "0" (*ptr) : "cc", "memory"); \ : [val] "d" (val), "0" (*ptr) : "cc", "memory"); \
return old; \ return old; \
} }
...@@ -180,7 +180,7 @@ static inline long __atomic64_cmpxchg(long *ptr, long old, long new) ...@@ -180,7 +180,7 @@ static inline long __atomic64_cmpxchg(long *ptr, long old, long new)
{ {
asm volatile( asm volatile(
" csg %[old],%[new],%[ptr]" " csg %[old],%[new],%[ptr]"
: [old] "+d" (old), [ptr] "+S" (*ptr) : [old] "+d" (old), [ptr] "+QS" (*ptr)
: [new] "d" (new) : [new] "d" (new)
: "cc", "memory"); : "cc", "memory");
return old; return old;
...@@ -192,7 +192,7 @@ static inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new) ...@@ -192,7 +192,7 @@ static inline bool __atomic64_cmpxchg_bool(long *ptr, long old, long new)
asm volatile( asm volatile(
" csg %[old],%[new],%[ptr]" " csg %[old],%[new],%[ptr]"
: [old] "+d" (old), [ptr] "+S" (*ptr) : [old] "+d" (old), [ptr] "+QS" (*ptr)
: [new] "d" (new) : [new] "d" (new)
: "cc", "memory"); : "cc", "memory");
return old == old_expected; return old == old_expected;
......
...@@ -62,7 +62,7 @@ static inline unsigned long __xchg(unsigned long x, unsigned long address, int s ...@@ -62,7 +62,7 @@ static inline unsigned long __xchg(unsigned long x, unsigned long address, int s
" lg %0,%1\n" " lg %0,%1\n"
"0: csg %0,%2,%1\n" "0: csg %0,%2,%1\n"
" jl 0b\n" " jl 0b\n"
: "=&d" (old), "+S" (*(long *) address) : "=&d" (old), "+QS" (*(long *) address)
: "d" (x) : "d" (x)
: "memory", "cc"); : "memory", "cc");
return old; return old;
...@@ -142,7 +142,7 @@ static inline unsigned long __cmpxchg(unsigned long address, unsigned long old, ...@@ -142,7 +142,7 @@ static inline unsigned long __cmpxchg(unsigned long address, unsigned long old,
case 8: case 8:
asm volatile( asm volatile(
" csg %0,%3,%1\n" " csg %0,%3,%1\n"
: "=&d" (prev), "+S" (*(long *) address) : "=&d" (prev), "+QS" (*(long *) address)
: "0" (old), "d" (new) : "0" (old), "d" (new)
: "memory", "cc"); : "memory", "cc");
return prev; return prev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment