Add extra constraints to tell the compiler that the memory be modified

in the arm __swp() and sparc64 casa() and casax() functions is actually
being used as an input and output and not just the value of the register
that points to the memory location.  This was the underlying source of
the mbuf refcount problems on sparc64 a while back.  For arm this should be
a nop because __swp() has a constraint to clobber all memory which can
probably be removed now.

Reviewed by:	alc, cognet
MFC after:	1 week
This commit is contained in:
John Baldwin 2005-07-27 20:01:45 +00:00
parent e11fe02dfb
commit d9610574a2
2 changed files with 10 additions and 6 deletions

View File

@ -77,8 +77,10 @@
static __inline uint32_t
__swp(uint32_t val, volatile uint32_t *ptr)
{
__asm __volatile("swp %0, %1, [%2]"
: "=&r" (val) : "r" (val) , "r" (ptr) : "memory");
__asm __volatile("swp %0, %2, [%3]"
: "=&r" (val), "=m" (*ptr)
: "r" (val) , "r" (ptr), "m" (*ptr)
: "memory");
return (val);
}

View File

@ -62,15 +62,17 @@ struct thread;
#define casa(rs1, rs2, rd, asi) ({ \
u_int __rd = (uint32_t)(rd); \
__asm __volatile("casa [%1] %2, %3, %0" \
: "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2)); \
__asm __volatile("casa [%2] %3, %4, %0" \
: "+r" (__rd), "=m" (*rs1) \
: "r" (rs1), "n" (asi), "r" (rs2), "m" (*rs1)); \
__rd; \
})
#define casxa(rs1, rs2, rd, asi) ({ \
u_long __rd = (uint64_t)(rd); \
__asm __volatile("casxa [%1] %2, %3, %0" \
: "+r" (__rd) : "r" (rs1), "n" (asi), "r" (rs2)); \
__asm __volatile("casxa [%2] %3, %4, %0" \
: "+r" (__rd), "=m" (*rs1) \
: "r" (rs1), "n" (asi), "r" (rs2), "m" (*rs1)); \
__rd; \
})