Unverified Commit 1d7f6932 authored by Guo Ren's avatar Guo Ren Committed by Palmer Dabbelt
Browse files

riscv: atomic: Optimize dec_if_positive functions



Current implementation wastes another register to pass the
argument, but we only need addi to calculate the result. Optimize
the code with minimize the usage of registers.

Signed-off-by: default avatarGuo Ren <guoren@linux.alibaba.com>
Signed-off-by: default avatarGuo Ren <guoren@kernel.org>
Link: https://lore.kernel.org/r/20220505035526.2974382-3-guoren@kernel.org


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent dd8437cd
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -310,47 +310,47 @@ ATOMIC_OPS()
#undef ATOMIC_OPS
#undef ATOMIC_OP

static __always_inline int arch_atomic_sub_if_positive(atomic_t *v, int offset)
static __always_inline int arch_atomic_dec_if_positive(atomic_t *v)
{
       int prev, rc;

	__asm__ __volatile__ (
		"0:	lr.w     %[p],  %[c]\n"
		"	sub      %[rc], %[p], %[o]\n"
		"	addi     %[rc], %[p], -1\n"
		"	bltz     %[rc], 1f\n"
		"	sc.w.rl  %[rc], %[rc], %[c]\n"
		"	bnez     %[rc], 0b\n"
		"	fence    rw, rw\n"
		"1:\n"
		: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
		: [o]"r" (offset)
		:
		: "memory");
	return prev - offset;
	return prev - 1;
}

#define arch_atomic_dec_if_positive(v)	arch_atomic_sub_if_positive(v, 1)
#define arch_atomic_dec_if_positive arch_atomic_dec_if_positive

#ifndef CONFIG_GENERIC_ATOMIC64
static __always_inline s64 arch_atomic64_sub_if_positive(atomic64_t *v, s64 offset)
static __always_inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
{
       s64 prev;
       long rc;

	__asm__ __volatile__ (
		"0:	lr.d     %[p],  %[c]\n"
		"	sub      %[rc], %[p], %[o]\n"
		"	addi      %[rc], %[p], -1\n"
		"	bltz     %[rc], 1f\n"
		"	sc.d.rl  %[rc], %[rc], %[c]\n"
		"	bnez     %[rc], 0b\n"
		"	fence    rw, rw\n"
		"1:\n"
		: [p]"=&r" (prev), [rc]"=&r" (rc), [c]"+A" (v->counter)
		: [o]"r" (offset)
		:
		: "memory");
	return prev - offset;
	return prev - 1;
}

#define arch_atomic64_dec_if_positive(v)	arch_atomic64_sub_if_positive(v, 1)
#define arch_atomic64_dec_if_positive	arch_atomic64_dec_if_positive
#endif

#endif /* _ASM_RISCV_ATOMIC_H */