Files
mkrtos-real/mkrtos_knl/arch/aarch64/atomics.c
2024-03-31 16:06:11 +00:00

124 lines
2.5 KiB
C

#include <types.h>
#include <atomics.h>
bool_t atomic_cmpxchg(umword_t *v, umword_t old, umword_t new)
{
umword_t oldval, res;
asm volatile(
"1:\n"
"ldxr %1, %2\n"
"eor %0, %1, %3\n"
"cbnz %0, 2f\n"
"stxr %w0, %4, %2\n"
"cbnz %w0, 1b\n"
"2:"
: "=&r"(res), "=&r"(oldval), "+Q"(*v)
: "r"(old), "r"(new)
: "cc");
return !res;
}
void atomic_and(umword_t *l, umword_t val)
{
umword_t tmp, ret;
asm volatile(
"1:\n"
"ldxr %0, %2\n"
"and %0, %0, %3\n"
"stxr %w1, %0, %2\n"
"cbnz %w1, 1b\n"
: "=&r"(tmp), "=&r"(ret), "+Q"(*l)
: "r"(val)
: "cc");
}
umword_t atomic_and_return(umword_t *l, umword_t val)
{
umword_t tmp, ret;
asm volatile(
"ldxr %0, %2\n"
"and %1, %0, %3\n"
: "=&r"(tmp), "=&r"(ret), "+Q"(*l)
: "r"(val)
: "cc");
return !!ret;
}
void atomic_or(umword_t *l, umword_t val)
{
umword_t tmp, ret;
asm volatile(
"1:\n"
"ldxr %0, %2\n"
"orr %0, %0, %3\n"
"stxr %w1, %0, %2\n"
"cbnz %w1, 1b\n"
: "=&r"(tmp), "=&r"(ret), "+Q"(*l)
: "r"(val)
: "cc");
}
umword_t atomic_sub_return(umword_t i, atomic64_t *v)
{
umword_t tmp;
umword_t ret;
asm volatile(
"1:\n"
"ldxr %0, %2\n"
"sub %0, %0, %3\n"
"stxr %w1, %0, %2\n"
"cbnz %w1, 1b\n"
: "=&r"(ret), "=&r"(tmp), "+Q"(v->counter)
: "r"(i));
return ret;
}
umword_t atomic_add_return(umword_t i, atomic64_t *v)
{
umword_t tmp;
umword_t ret;
asm volatile(
"1:\n"
"ldxr %0, %2\n"
"add %0, %0, %3\n"
"stxr %w1, %0, %2\n"
"cbnz %w1, 1b\n"
: "=&r"(ret), "=&r"(tmp), "+Q"(v->counter)
: "r"(i));
return ret;
}
umword_t atomic_fetch_and(umword_t i, atomic64_t *v)
{
umword_t tmp, ret;
umword_t old;
asm volatile(
"1:\n"
"ldxr %2, %3\n"
"and %0, %2, %4\n"
"stxr %w1, %0, %3\n"
"cbnz %w1, 1b\n"
: "=&r"(tmp), "=&r"(ret), "=&r"(old), "+Q"(v->counter)
: "r"(i)
: "cc");
return old;
}
umword_t atomic_fetch_or(umword_t i, atomic64_t *v)
{
umword_t tmp, ret;
umword_t old;
asm volatile(
"1:\n"
"ldxr %2, %3\n"
"orr %0, %2, %4\n"
"stxr %w1, %0, %3\n"
"cbnz %w1, 1b\n"
: "=&r"(tmp), "=&r"(ret), "=&r"(old), "+Q"(v->counter)
: "r"(i)
: "cc");
return old;
}