#include <linux/percpu.h>
 #include <linux/io.h>
 #include <asm/alternative.h>
+#include <asm/asm.h>
 
 int spin_retry = -1;
 
        return owner;
 }
 
-static inline int arch_cmpxchg_niai8(int *lock, int old, int new)
+#ifdef __HAVE_ASM_FLAG_OUTPUTS__
+
+static inline int arch_try_cmpxchg_niai8(int *lock, int old, int new)
+{
+       int cc;
+
+       asm_inline volatile(
+               ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", ALT_FACILITY(49)) /* NIAI 8 */
+               "       cs      %[old],%[new],%[lock]\n"
+               : [old] "+d" (old), [lock] "+Q" (*lock), "=@cc" (cc)
+               : [new] "d" (new)
+               : "memory");
+       return cc == 0;
+}
+
+#else /* __HAVE_ASM_FLAG_OUTPUTS__ */
+
+static inline int arch_try_cmpxchg_niai8(int *lock, int old, int new)
 {
        int expected = old;
 
        return expected == old;
 }
 
+#endif /* __HAVE_ASM_FLAG_OUTPUTS__ */
+
 static inline struct spin_wait *arch_spin_decode_tail(int lock)
 {
        int ix, cpu;
                /* Try to get the lock if it is free. */
                if (!owner) {
                        new = (old & _Q_TAIL_MASK) | lockval;
-                       if (arch_cmpxchg_niai8(&lp->lock, old, new)) {
+                       if (arch_try_cmpxchg_niai8(&lp->lock, old, new)) {
                                /* Got the lock */
                                return;
                        }