| /* | 
 |  * 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 */ |