arm: Fix atomic_testand{set,clear}_32(). According to atomic (9), the bit position argument should be a modulo operand size. While I'm in, add missing implementation of atomic_testandclear_64(). For more details see https://reviews.freebsd.org/D27886
Discused with: rlibby MFC after: 3 weeks
This commit is contained in:
parent
80aa931900
commit
bd03acedb8
@ -881,7 +881,7 @@ atomic_testandclear_32(volatile uint32_t *ptr, u_int bit)
|
||||
[oldv] "=&r" (oldv),
|
||||
[newv] "=&r" (newv)
|
||||
: [ptr] "r" (ptr),
|
||||
"[bit]" (bit)
|
||||
"[bit]" (bit & 0x1f)
|
||||
: "cc", "ip", "memory");
|
||||
|
||||
return (result);
|
||||
@ -902,6 +902,23 @@ atomic_testandclear_long(volatile u_long *p, u_int v)
|
||||
}
|
||||
#define atomic_testandclear_long atomic_testandclear_long
|
||||
|
||||
|
||||
static __inline int
|
||||
atomic_testandclear_64(volatile uint64_t *p, u_int v)
|
||||
{
|
||||
volatile uint32_t *p32;
|
||||
|
||||
p32 = (volatile uint32_t *)p;
|
||||
/*
|
||||
* Assume little-endian,
|
||||
* atomic_testandclear_32() uses only last 5 bits of v
|
||||
*/
|
||||
if (v >= 32) {
|
||||
p32++;
|
||||
}
|
||||
return (atomic_testandclear_32(p32, v));
|
||||
}
|
||||
|
||||
static __inline int
|
||||
atomic_testandset_32(volatile uint32_t *ptr, u_int bit)
|
||||
{
|
||||
@ -925,7 +942,7 @@ atomic_testandset_32(volatile uint32_t *ptr, u_int bit)
|
||||
[oldv] "=&r" (oldv),
|
||||
[newv] "=&r" (newv)
|
||||
: [ptr] "r" (ptr),
|
||||
"[bit]" (bit)
|
||||
"[bit]" (bit & 0x1f)
|
||||
: "cc", "ip", "memory");
|
||||
|
||||
return (result);
|
||||
@ -952,9 +969,11 @@ atomic_testandset_64(volatile uint64_t *p, u_int v)
|
||||
volatile uint32_t *p32;
|
||||
|
||||
p32 = (volatile uint32_t *)p;
|
||||
/* Assume little-endian */
|
||||
/*
|
||||
* Assume little-endian,
|
||||
* atomic_testandset_32() uses only last 5 bits of v
|
||||
*/
|
||||
if (v >= 32) {
|
||||
v &= 0x1f;
|
||||
p32++;
|
||||
}
|
||||
return (atomic_testandset_32(p32, v));
|
||||
|
Loading…
Reference in New Issue
Block a user