mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-11 03:24:58 -06:00

Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
50 lines
1.3 KiB
C
50 lines
1.3 KiB
C
/*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Atomic store insert into 128-bit, generic version.
|
|
*
|
|
* Copyright (C) 2023 Linaro, Ltd.
|
|
*/
|
|
|
|
#ifndef HOST_STORE_INSERT_AL16_H
|
|
#define HOST_STORE_INSERT_AL16_H
|
|
|
|
/**
|
|
* store_atom_insert_al16:
|
|
* @p: host address
|
|
* @val: shifted value to store
|
|
* @msk: mask for value to store
|
|
*
|
|
* Atomically store @val to @p masked by @msk.
|
|
*/
|
|
static inline void ATTRIBUTE_ATOMIC128_OPT
|
|
store_atom_insert_al16(Int128 *ps, Int128 val, Int128 msk)
|
|
{
|
|
#if defined(CONFIG_ATOMIC128)
|
|
__uint128_t *pu;
|
|
Int128Alias old, new;
|
|
|
|
/* With CONFIG_ATOMIC128, we can avoid the memory barriers. */
|
|
pu = __builtin_assume_aligned(ps, 16);
|
|
old.u = *pu;
|
|
msk = int128_not(msk);
|
|
do {
|
|
new.s = int128_and(old.s, msk);
|
|
new.s = int128_or(new.s, val);
|
|
} while (!__atomic_compare_exchange_n(pu, &old.u, new.u, true,
|
|
__ATOMIC_RELAXED, __ATOMIC_RELAXED));
|
|
#else
|
|
Int128 old, new, cmp;
|
|
|
|
ps = __builtin_assume_aligned(ps, 16);
|
|
old = *ps;
|
|
msk = int128_not(msk);
|
|
do {
|
|
cmp = old;
|
|
new = int128_and(old, msk);
|
|
new = int128_or(new, val);
|
|
old = atomic16_cmpxchg(ps, cmp, new);
|
|
} while (int128_ne(cmp, old));
|
|
#endif
|
|
}
|
|
|
|
#endif /* HOST_STORE_INSERT_AL16_H */
|