1/* 2 * SPDX-License-Identifier: GPL-2.0-or-later 3 * Atomic store insert into 128-bit, generic version. 4 * 5 * Copyright (C) 2023 Linaro, Ltd. 6 */ 7 8#ifndef HOST_STORE_INSERT_AL16_H 9#define HOST_STORE_INSERT_AL16_H 10 11/** 12 * store_atom_insert_al16: 13 * @p: host address 14 * @val: shifted value to store 15 * @msk: mask for value to store 16 * 17 * Atomically store @val to @p masked by @msk. 18 */ 19static inline void ATTRIBUTE_ATOMIC128_OPT 20store_atom_insert_al16(Int128 *ps, Int128 val, Int128 msk) 21{ 22#if defined(CONFIG_ATOMIC128) 23 __uint128_t *pu; 24 Int128Alias old, new; 25 26 /* With CONFIG_ATOMIC128, we can avoid the memory barriers. */ 27 pu = __builtin_assume_aligned(ps, 16); 28 old.u = *pu; 29 msk = int128_not(msk); 30 do { 31 new.s = int128_and(old.s, msk); 32 new.s = int128_or(new.s, val); 33 } while (!__atomic_compare_exchange_n(pu, &old.u, new.u, true, 34 __ATOMIC_RELAXED, __ATOMIC_RELAXED)); 35#else 36 Int128 old, new, cmp; 37 38 ps = __builtin_assume_aligned(ps, 16); 39 old = *ps; 40 msk = int128_not(msk); 41 do { 42 cmp = old; 43 new = int128_and(old, msk); 44 new = int128_or(new, val); 45 old = atomic16_cmpxchg(ps, cmp, new); 46 } while (int128_ne(cmp, old)); 47#endif 48} 49 50#endif /* HOST_STORE_INSERT_AL16_H */ 51