We can perform the cmpxchg comparison using eor and cbnz which avoids
the "cc" clobber for the ll/sc case and consequently for the LSE case
where we may have to fall-back on the ll/sc code at runtime.
Reviewed-by: Steve Capper <steve.capper@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
asm volatile("// atomic_cmpxchg\n"
"1: ldxr %w1, %2\n"
-" cmp %w1, %w3\n"
-" b.ne 2f\n"
+" eor %w0, %w1, %w3\n"
+" cbnz %w0, 2f\n"
" stxr %w0, %w4, %2\n"
" cbnz %w0, 1b\n"
"2:"
: "=&r" (tmp), "=&r" (oldval), "+Q" (ptr->counter)
- : "Ir" (old), "r" (new)
- : "cc");
+ : "Lr" (old), "r" (new));
smp_mb();
return oldval;
asm volatile("// atomic64_cmpxchg\n"
"1: ldxr %1, %2\n"
-" cmp %1, %3\n"
-" b.ne 2f\n"
+" eor %0, %1, %3\n"
+" cbnz %w0, 2f\n"
" stxr %w0, %4, %2\n"
" cbnz %w0, 1b\n"
"2:"
: "=&r" (res), "=&r" (oldval), "+Q" (ptr->counter)
- : "Ir" (old), "r" (new)
- : "cc");
+ : "Lr" (old), "r" (new));
smp_mb();
return oldval;
" mov %w[ret], w30")
: [ret] "+r" (x0), [v] "+Q" (ptr->counter)
: [old] "r" (w1), [new] "r" (w2)
- : "x30", "cc", "memory");
+ : "x30", "memory");
return x0;
}
" mov %[ret], x30")
: [ret] "+r" (x0), [v] "+Q" (ptr->counter)
: [old] "r" (x1), [new] "r" (x2)
- : "x30", "cc", "memory");
+ : "x30", "memory");
return x0;
}