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:
Michal Meloun 2021-01-02 20:30:00 +01:00
parent 80aa931900
commit bd03acedb8

View File

@ -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));