Commit 987bcdac authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Martin Schwidefsky
Browse files

[S390] use inline assembly contraints available with gcc 3.3.3



Drop support to compile the kernel with gcc versions older than 3.3.3.
This allows us to use the "Q" inline assembly contraint on some more
inline assemblies without duplicating a lot of complex code (e.g. __xchg
and __cmpxchg). The distinction for older gcc versions can be removed
which saves a few lines and simplifies the code.
Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent d1bf8590
......@@ -18,8 +18,6 @@
#define ATOMIC_INIT(i) { (i) }
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __CS_LOOP(ptr, op_val, op_string) ({ \
int old_val, new_val; \
asm volatile( \
......@@ -35,26 +33,6 @@
new_val; \
})
#else /* __GNUC__ */
#define __CS_LOOP(ptr, op_val, op_string) ({ \
int old_val, new_val; \
asm volatile( \
" l %0,0(%3)\n" \
"0: lr %1,%0\n" \
op_string " %1,%4\n" \
" cs %0,%1,0(%3)\n" \
" jl 0b" \
: "=&d" (old_val), "=&d" (new_val), \
"=m" (((atomic_t *)(ptr))->counter) \
: "a" (ptr), "d" (op_val), \
"m" (((atomic_t *)(ptr))->counter) \
: "cc", "memory"); \
new_val; \
})
#endif /* __GNUC__ */
static inline int atomic_read(const atomic_t *v)
{
barrier();
......@@ -101,19 +79,11 @@ static inline void atomic_set_mask(unsigned long mask, atomic_t *v)
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
asm volatile(
" cs %0,%2,%1"
: "+d" (old), "=Q" (v->counter)
: "d" (new), "Q" (v->counter)
: "cc", "memory");
#else /* __GNUC__ */
asm volatile(
" cs %0,%3,0(%2)"
: "+d" (old), "=m" (v->counter)
: "a" (v), "d" (new), "m" (v->counter)
: "cc", "memory");
#endif /* __GNUC__ */
return old;
}
......@@ -140,8 +110,6 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
#ifdef CONFIG_64BIT
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
long long old_val, new_val; \
asm volatile( \
......@@ -157,26 +125,6 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
new_val; \
})
#else /* __GNUC__ */
#define __CSG_LOOP(ptr, op_val, op_string) ({ \
long long old_val, new_val; \
asm volatile( \
" lg %0,0(%3)\n" \
"0: lgr %1,%0\n" \
op_string " %1,%4\n" \
" csg %0,%1,0(%3)\n" \
" jl 0b" \
: "=&d" (old_val), "=&d" (new_val), \
"=m" (((atomic_t *)(ptr))->counter) \
: "a" (ptr), "d" (op_val), \
"m" (((atomic_t *)(ptr))->counter) \
: "cc", "memory"); \
new_val; \
})
#endif /* __GNUC__ */
static inline long long atomic64_read(const atomic64_t *v)
{
barrier();
......@@ -214,19 +162,11 @@ static inline void atomic64_set_mask(unsigned long mask, atomic64_t *v)
static inline long long atomic64_cmpxchg(atomic64_t *v,
long long old, long long new)
{
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
asm volatile(
" csg %0,%2,%1"
: "+d" (old), "=Q" (v->counter)
: "d" (new), "Q" (v->counter)
: "cc", "memory");
#else /* __GNUC__ */
asm volatile(
" csg %0,%3,0(%2)"
: "+d" (old), "=m" (v->counter)
: "a" (v), "d" (new), "m" (v->counter)
: "cc", "memory");
#endif /* __GNUC__ */
return old;
}
......@@ -243,10 +183,8 @@ static inline long long atomic64_read(const atomic64_t *v)
register_pair rp;
asm volatile(
" lm %0,%N0,0(%1)"
: "=&d" (rp)
: "a" (&v->counter), "m" (v->counter)
);
" lm %0,%N0,%1"
: "=&d" (rp) : "Q" (v->counter) );
return rp.pair;
}
......@@ -255,10 +193,8 @@ static inline void atomic64_set(atomic64_t *v, long long i)
register_pair rp = {.pair = i};
asm volatile(
" stm %1,%N1,0(%2)"
: "=m" (v->counter)
: "d" (rp), "a" (&v->counter)
);
" stm %1,%N1,%0"
: "=Q" (v->counter) : "d" (rp) );
}
static inline long long atomic64_xchg(atomic64_t *v, long long new)
......@@ -267,11 +203,11 @@ static inline long long atomic64_xchg(atomic64_t *v, long long new)
register_pair rp_old;
asm volatile(
" lm %0,%N0,0(%2)\n"
"0: cds %0,%3,0(%2)\n"
" lm %0,%N0,%1\n"
"0: cds %0,%2,%1\n"
" jl 0b\n"
: "=&d" (rp_old), "+m" (v->counter)
: "a" (&v->counter), "d" (rp_new)
: "=&d" (rp_old), "=Q" (v->counter)
: "d" (rp_new), "Q" (v->counter)
: "cc");
return rp_old.pair;
}
......@@ -283,9 +219,9 @@ static inline long long atomic64_cmpxchg(atomic64_t *v,
register_pair rp_new = {.pair = new};
asm volatile(
" cds %0,%3,0(%2)"
: "+&d" (rp_old), "+m" (v->counter)
: "a" (&v->counter), "d" (rp_new)
" cds %0,%2,%1"
: "+&d" (rp_old), "=Q" (v->counter)
: "d" (rp_new), "Q" (v->counter)
: "cc");
return rp_old.pair;
}
......
......@@ -71,8 +71,6 @@ extern const char _sb_findmap[];
#define __BITOPS_AND "nr"
#define __BITOPS_XOR "xr"
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" l %0,%2\n" \
......@@ -85,22 +83,6 @@ extern const char _sb_findmap[];
: "d" (__val), "Q" (*(unsigned long *) __addr) \
: "cc");
#else /* __GNUC__ */
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" l %0,0(%4)\n" \
"0: lr %1,%0\n" \
__op_string " %1,%3\n" \
" cs %0,%1,0(%4)\n" \
" jl 0b" \
: "=&d" (__old), "=&d" (__new), \
"=m" (*(unsigned long *) __addr) \
: "d" (__val), "a" (__addr), \
"m" (*(unsigned long *) __addr) : "cc");
#endif /* __GNUC__ */
#else /* __s390x__ */
#define __BITOPS_ALIGN 7
......@@ -109,8 +91,6 @@ extern const char _sb_findmap[];
#define __BITOPS_AND "ngr"
#define __BITOPS_XOR "xgr"
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" lg %0,%2\n" \
......@@ -123,23 +103,6 @@ extern const char _sb_findmap[];
: "d" (__val), "Q" (*(unsigned long *) __addr) \
: "cc");
#else /* __GNUC__ */
#define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \
asm volatile( \
" lg %0,0(%4)\n" \
"0: lgr %1,%0\n" \
__op_string " %1,%3\n" \
" csg %0,%1,0(%4)\n" \
" jl 0b" \
: "=&d" (__old), "=&d" (__new), \
"=m" (*(unsigned long *) __addr) \
: "d" (__val), "a" (__addr), \
"m" (*(unsigned long *) __addr) : "cc");
#endif /* __GNUC__ */
#endif /* __s390x__ */
#define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE)
......@@ -261,9 +224,8 @@ static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
asm volatile(
" oc 0(1,%1),0(%2)"
: "=m" (*(char *) addr) : "a" (addr),
"a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
" oc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" );
}
static inline void
......@@ -290,9 +252,8 @@ __clear_bit(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
asm volatile(
" nc 0(1,%1),0(%2)"
: "=m" (*(char *) addr) : "a" (addr),
"a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc");
" nc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7]) : "cc" );
}
static inline void
......@@ -318,9 +279,8 @@ static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
asm volatile(
" xc 0(1,%1),0(%2)"
: "=m" (*(char *) addr) : "a" (addr),
"a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" );
" xc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7]) : "cc" );
}
static inline void
......@@ -349,10 +309,9 @@ test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
ch = *(unsigned char *) addr;
asm volatile(
" oc 0(1,%1),0(%2)"
: "=m" (*(char *) addr)
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
"m" (*(char *) addr) : "cc", "memory");
" oc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7])
: "cc", "memory");
return (ch >> (nr & 7)) & 1;
}
#define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y)
......@@ -369,10 +328,9 @@ test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
ch = *(unsigned char *) addr;
asm volatile(
" nc 0(1,%1),0(%2)"
: "=m" (*(char *) addr)
: "a" (addr), "a" (_ni_bitmap + (nr & 7)),
"m" (*(char *) addr) : "cc", "memory");
" nc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_ni_bitmap[nr & 7])
: "cc", "memory");
return (ch >> (nr & 7)) & 1;
}
#define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y)
......@@ -389,10 +347,9 @@ test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr)
addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3);
ch = *(unsigned char *) addr;
asm volatile(
" xc 0(1,%1),0(%2)"
: "=m" (*(char *) addr)
: "a" (addr), "a" (_oi_bitmap + (nr & 7)),
"m" (*(char *) addr) : "cc", "memory");
" xc %O0(1,%R0),%1"
: "=Q" (*(char *) addr) : "Q" (_oi_bitmap[nr & 7])
: "cc", "memory");
return (ch >> (nr & 7)) & 1;
}
#define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y)
......@@ -591,11 +548,11 @@ static inline unsigned long __load_ulong_le(const unsigned long *p,
p = (unsigned long *)((unsigned long) p + offset);
#ifndef __s390x__
asm volatile(
" ic %0,0(%1)\n"
" icm %0,2,1(%1)\n"
" icm %0,4,2(%1)\n"
" icm %0,8,3(%1)"
: "=&d" (word) : "a" (p), "m" (*p) : "cc");
" ic %0,%O1(%R1)\n"
" icm %0,2,%O1+1(%R1)\n"
" icm %0,4,%O1+2(%R1)\n"
" icm %0,8,%O1+3(%R1)"
: "=&d" (word) : "Q" (*p) : "cc");
#else
asm volatile(
" lrvg %0,%1"
......
......@@ -145,11 +145,11 @@ static inline int etr_setr(struct etr_eacr *ctrl)
int rc = -ENOSYS;
asm volatile(
" .insn s,0xb2160000,0(%2)\n"
" .insn s,0xb2160000,%1\n"
"0: la %0,0\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc) : "m" (*ctrl), "a" (ctrl));
: "+d" (rc) : "Q" (*ctrl));
return rc;
}
......@@ -159,11 +159,11 @@ static inline int etr_stetr(struct etr_aib *aib)
int rc = -ENOSYS;
asm volatile(
" .insn s,0xb2170000,0(%2)\n"
" .insn s,0xb2170000,%1\n"
"0: la %0,0\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc) : "m" (*aib), "a" (aib));
: "+d" (rc) : "Q" (*aib));
return rc;
}
......@@ -174,11 +174,11 @@ static inline int etr_steai(struct etr_aib *aib, unsigned int func)
int rc = -ENOSYS;
asm volatile(
" .insn s,0xb2b30000,0(%2)\n"
" .insn s,0xb2b30000,%1\n"
"0: la %0,0\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (rc) : "m" (*aib), "a" (aib), "d" (reg0));
: "+d" (rc) : "Q" (*aib), "d" (reg0));
return rc;
}
......
......@@ -8,8 +8,6 @@
#include <linux/types.h>
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
/* store then or system mask. */
#define __raw_local_irq_stosm(__or) \
({ \
......@@ -36,40 +34,6 @@
asm volatile("ssm %0" : : "Q" (__mask) : "memory"); \
})
#else /* __GNUC__ */
/* store then or system mask. */
#define __raw_local_irq_stosm(__or) \
({ \
unsigned long __mask; \
asm volatile( \
" stosm 0(%1),%2" \
: "=m" (__mask) \
: "a" (&__mask), "i" (__or) : "memory"); \
__mask; \
})
/* store then and system mask. */
#define __raw_local_irq_stnsm(__and) \
({ \
unsigned long __mask; \
asm volatile( \
" stnsm 0(%1),%2" \
: "=m" (__mask) \
: "a" (&__mask), "i" (__and) : "memory"); \
__mask; \
})
/* set system mask. */
#define __raw_local_irq_ssm(__mask) \
({ \
asm volatile( \
" ssm 0(%0)" \
: : "a" (&__mask), "m" (__mask) : "memory"); \
})
#endif /* __GNUC__ */
/* interrupt control.. */
static inline unsigned long raw_local_irq_enable(void)
{
......
......@@ -28,7 +28,7 @@
static inline void get_cpu_id(struct cpuid *ptr)
{
asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
asm volatile("stidp %0" : "=Q" (*ptr));
}
extern void s390_adjust_jiffies(void);
......@@ -184,9 +184,9 @@ static inline void psw_set_key(unsigned int key)
static inline void __load_psw(psw_t psw)
{
#ifndef __s390x__
asm volatile("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
asm volatile("lpsw %0" : : "Q" (psw) : "cc");
#else
asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc");
asm volatile("lpswe %0" : : "Q" (psw) : "cc");
#endif
}
......@@ -206,17 +206,17 @@ static inline void __load_psw_mask (unsigned long mask)
asm volatile(
" basr %0,0\n"
"0: ahi %0,1f-0b\n"
" st %0,4(%1)\n"
" lpsw 0(%1)\n"
" st %0,%O1+4(%R1)\n"
" lpsw %1\n"
"1:"
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
#else /* __s390x__ */
asm volatile(
" larl %0,1f\n"
" stg %0,8(%1)\n"
" lpswe 0(%1)\n"
" stg %0,%O1+8(%R1)\n"
" lpswe %1\n"
"1:"
: "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc");
: "=&d" (addr), "=Q" (psw) : "Q" (psw) : "memory", "cc");
#endif /* __s390x__ */
}
......
......@@ -124,21 +124,21 @@ static inline void __down_read(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" ahi %1,%5\n"
" cs %0,%1,0(%3)\n"
" ahi %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" aghi %1,%5\n"
" csg %0,%1,0(%3)\n"
" aghi %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
: "cc", "memory");
if (old < 0)
rwsem_down_read_failed(sem);
}
......@@ -152,25 +152,25 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: ltr %1,%0\n"
" jm 1f\n"
" ahi %1,%5\n"
" cs %0,%1,0(%3)\n"
" ahi %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b\n"
"1:"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: ltgr %1,%0\n"
" jm 1f\n"
" aghi %1,%5\n"
" csg %0,%1,0(%3)\n"
" aghi %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b\n"
"1:"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory");
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
: "cc", "memory");
return old >= 0 ? 1 : 0;
}
......@@ -184,20 +184,20 @@ static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
tmp = RWSEM_ACTIVE_WRITE_BIAS;
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" a %1,%5\n"
" cs %0,%1,0(%3)\n"
" a %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" ag %1,%5\n"
" csg %0,%1,0(%3)\n"
" ag %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count), "m" (tmp)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "m" (tmp)
: "cc", "memory");
if (old != 0)
rwsem_down_write_failed(sem);
......@@ -217,22 +217,22 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%2)\n"
" l %0,%1\n"
"0: ltr %0,%0\n"
" jnz 1f\n"
" cs %0,%4,0(%2)\n"
" cs %0,%3,%1\n"
" jl 0b\n"
#else /* __s390x__ */
" lg %0,0(%2)\n"
" lg %0,%1\n"
"0: ltgr %0,%0\n"
" jnz 1f\n"
" csg %0,%4,0(%2)\n"
" csg %0,%3,%1\n"
" jl 0b\n"
#endif /* __s390x__ */
"1:"
: "=&d" (old), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory");
: "=&d" (old), "=Q" (sem->count)
: "Q" (sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS)
: "cc", "memory");
return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
}
......@@ -245,21 +245,20 @@ static inline void __up_read(struct rw_semaphore *sem)
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" ahi %1,%5\n"
" cs %0,%1,0(%3)\n"
" ahi %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */
" lg %0,0(%3)\n"
" lg %0,%2\n"
"0: lgr %1,%0\n"
" aghi %1,%5\n"
" csg %0,%1,0(%3)\n"
" aghi %1,%4\n"
" csg %0,%1,%2\n"
" jl 0b"
#endif /* __s390x__ */
: "=&d" (old), "=&d" (new), "=m" (sem->count)
: "a" (&sem->count), "m" (sem->count),
"i" (-RWSEM_ACTIVE_READ_BIAS)
: "=&d" (old), "=&d" (new), "=Q" (sem->count)
: "Q" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS)
: "cc", "memory");
if (new < 0)
if ((new & RWSEM_ACTIVE_MASK) == 0)
......@@ -276,20 +275,20 @@ static inline void __up_write(struct rw_semaphore *sem)
tmp = -RWSEM_ACTIVE_WRITE_BIAS;
asm volatile(
#ifndef __s390x__
" l %0,0(%3)\n"
" l %0,%2\n"
"0: lr %1,%0\n"
" a %1,%5\n"
" cs %0,%1,0(%3)\n"
" a %1,%4\n"
" cs %0,%1,%2\n"
" jl 0b"
#else /* __s390x__ */