xref: /openbmc/qemu/host/include/generic/host/atomic128-cas.h (revision f78ea7ddb0e18766ece9fdfe02061744a7afc41b)
1  /*
2   * SPDX-License-Identifier: GPL-2.0-or-later
3   * Compare-and-swap for 128-bit atomic operations, generic version.
4   *
5   * Copyright (C) 2018, 2023 Linaro, Ltd.
6   *
7   * See docs/devel/atomics.rst for discussion about the guarantees each
8   * atomic primitive is meant to provide.
9   */
10  
11  #ifndef HOST_ATOMIC128_CAS_H
12  #define HOST_ATOMIC128_CAS_H
13  
14  #if defined(CONFIG_ATOMIC128)
15  static inline Int128 ATTRIBUTE_ATOMIC128_OPT
atomic16_cmpxchg(Int128 * ptr,Int128 cmp,Int128 new)16  atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
17  {
18      __int128_t *ptr_align = __builtin_assume_aligned(ptr, 16);
19      Int128Alias r, c, n;
20  
21      c.s = cmp;
22      n.s = new;
23      r.i = qatomic_cmpxchg__nocheck(ptr_align, c.i, n.i);
24      return r.s;
25  }
26  # define HAVE_CMPXCHG128 1
27  #elif defined(CONFIG_CMPXCHG128)
28  static inline Int128 ATTRIBUTE_ATOMIC128_OPT
atomic16_cmpxchg(Int128 * ptr,Int128 cmp,Int128 new)29  atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new)
30  {
31      Int128Aligned *ptr_align = __builtin_assume_aligned(ptr, 16);
32      Int128Alias r, c, n;
33  
34      c.s = cmp;
35      n.s = new;
36      r.i = __sync_val_compare_and_swap_16(ptr_align, c.i, n.i);
37      return r.s;
38  }
39  # define HAVE_CMPXCHG128 1
40  #else
41  /* Fallback definition that must be optimized away, or error.  */
42  Int128 QEMU_ERROR("unsupported atomic")
43      atomic16_cmpxchg(Int128 *ptr, Int128 cmp, Int128 new);
44  # define HAVE_CMPXCHG128 0
45  #endif
46  
47  #endif /* HOST_ATOMIC128_CAS_H */
48