Skip to content

Commit

Permalink
MIPS: rework local_t operation on MIPS64
Browse files Browse the repository at this point in the history
+. Use daddu/dsubu for long int on MIPS64.

+. remove "asm/war.h" since R10000_LLSC_WAR became a config option

+. clean up, no function changed

Suggested-by:  "Maciej W. Rozycki" <macro@orcam.me.uk>
Signed-off-by: Huang Pei <huangpei@loongson.cn>
  • Loading branch information
mips-hp authored and intel-lab-lkp committed Nov 18, 2021
1 parent 42eb8fd commit e556d47
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 47 deletions.
18 changes: 18 additions & 0 deletions arch/mips/include/asm/asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include <asm/sgidefs.h>
#include <asm/asm-eva.h>
#include <asm/isa-rev.h>

#ifndef __VDSO__
/*
Expand Down Expand Up @@ -211,6 +212,8 @@ symbol = value
#define LONG_SUB sub
#define LONG_SUBU subu
#define LONG_L lw
#define LONG_LL ll
#define LONG_SC sc
#define LONG_S sw
#define LONG_SP swp
#define LONG_SLL sll
Expand All @@ -236,6 +239,8 @@ symbol = value
#define LONG_SUB dsub
#define LONG_SUBU dsubu
#define LONG_L ld
#define LONG_LL lld
#define LONG_SC scd
#define LONG_S sd
#define LONG_SP sdp
#define LONG_SLL dsll
Expand Down Expand Up @@ -320,6 +325,19 @@ symbol = value

#define SSNOP sll zero, zero, 1

/*
* Using a branch-likely instruction to check the result of an sc instruction
* works around a bug present in R10000 CPUs prior to revision 3.0 that could
* cause ll-sc sequences to execute non-atomically.
*/
#ifdef CONFIG_WAR_R10000_LLSC
# define SC_BEQZ beqzl
#elif MIPS_ISA_REV >= 6
# define SC_BEQZ beqzc
#else
# define SC_BEQZ beqz
#endif

#ifdef CONFIG_SGI_IP28
/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
#include <asm/cacheops.h>
Expand Down
62 changes: 15 additions & 47 deletions arch/mips/include/asm/local.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <linux/atomic.h>
#include <asm/cmpxchg.h>
#include <asm/compiler.h>
#include <asm/war.h>
#include <asm/asm.h>

typedef struct
{
Expand All @@ -31,34 +31,18 @@ static __inline__ long local_add_return(long i, local_t * l)
{
unsigned long result;

if (kernel_uses_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) {
unsigned long temp;

__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
__SYNC(full, loongson3_war) " \n"
"1:" __LL "%1, %2 # local_add_return \n"
" addu %0, %1, %3 \n"
__SC "%0, %2 \n"
" beqzl %0, 1b \n"
" addu %0, %1, %3 \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
: "Ir" (i), "m" (l->a.counter)
: "memory");
} else if (kernel_uses_llsc) {
if (kernel_uses_llsc) {
unsigned long temp;

__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
__SYNC(full, loongson3_war) " \n"
"1:" __LL "%1, %2 # local_add_return \n"
" addu %0, %1, %3 \n"
__SC "%0, %2 \n"
" beqz %0, 1b \n"
" addu %0, %1, %3 \n"
__SYNC(full, loongson3_war) " \n"
"1:" __stringify(LONG_LL) " %1, %2 \n"
" "__stringify(LONG_ADDU) " %0, %1, %3 \n"
" "__stringify(LONG_SC) " %0, %2 \n"
" "__stringify(SC_BEQZ) " %0, 1b \n"
" "__stringify(LONG_ADDU) " %0, %1, %3 \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
: "Ir" (i), "m" (l->a.counter)
Expand All @@ -80,34 +64,18 @@ static __inline__ long local_sub_return(long i, local_t * l)
{
unsigned long result;

if (kernel_uses_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) {
unsigned long temp;

__asm__ __volatile__(
" .set push \n"
" .set arch=r4000 \n"
__SYNC(full, loongson3_war) " \n"
"1:" __LL "%1, %2 # local_sub_return \n"
" subu %0, %1, %3 \n"
__SC "%0, %2 \n"
" beqzl %0, 1b \n"
" subu %0, %1, %3 \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
: "Ir" (i), "m" (l->a.counter)
: "memory");
} else if (kernel_uses_llsc) {
if (kernel_uses_llsc) {
unsigned long temp;

__asm__ __volatile__(
" .set push \n"
" .set "MIPS_ISA_ARCH_LEVEL" \n"
__SYNC(full, loongson3_war) " \n"
"1:" __LL "%1, %2 # local_sub_return \n"
" subu %0, %1, %3 \n"
__SC "%0, %2 \n"
" beqz %0, 1b \n"
" subu %0, %1, %3 \n"
__SYNC(full, loongson3_war) " \n"
"1:" __stringify(LONG_LL) " %1, %2 \n"
" "__stringify(LONG_SUBU) " %0, %1, %3 \n"
" "__stringify(LONG_SC) " %0, %2 \n"
" "__stringify(SC_BEQZ) " %0, 1b \n"
" "__stringify(LONG_SUBU) " %0, %1, %3 \n"
" .set pop \n"
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
: "Ir" (i), "m" (l->a.counter)
Expand Down

0 comments on commit e556d47

Please sign in to comment.