blob: 4ba41077e42ad3a861b4a7b3b548e411fb7932ab [file] [log] [blame]
xf.libdd93d52023-05-12 07:10:14 -07001/* Copyright (C) 2003-2016 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19#include <stdint.h>
20
21typedef int8_t atomic8_t;
22typedef uint8_t uatomic8_t;
23typedef int_fast8_t atomic_fast8_t;
24typedef uint_fast8_t uatomic_fast8_t;
25
26typedef int16_t atomic16_t;
27typedef uint16_t uatomic16_t;
28typedef int_fast16_t atomic_fast16_t;
29typedef uint_fast16_t uatomic_fast16_t;
30
31typedef int32_t atomic32_t;
32typedef uint32_t uatomic32_t;
33typedef int_fast32_t atomic_fast32_t;
34typedef uint_fast32_t uatomic_fast32_t;
35
36typedef int64_t atomic64_t;
37typedef uint64_t uatomic64_t;
38typedef int_fast64_t atomic_fast64_t;
39typedef uint_fast64_t uatomic_fast64_t;
40
41typedef intptr_t atomicptr_t;
42typedef uintptr_t uatomicptr_t;
43typedef intmax_t atomic_max_t;
44typedef uintmax_t uatomic_max_t;
45
46#define USE_ATOMIC_COMPILER_BUILTINS 0
47
48
49#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
50 (abort (), (__typeof (*mem)) 0)
51
52#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
53 (abort (), (__typeof (*mem)) 0)
54
55#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
56 ({ __typeof (mem) __archmem = (mem); \
57 __typeof (*mem) __archold = (oldval); \
58 __asm__ __volatile__ ("cs %0,%2,%1" \
59 : "+d" (__archold), "=Q" (*__archmem) \
60 : "d" (newval), "m" (*__archmem) : "cc", "memory" ); \
61 __archold; })
62
63#ifdef __s390x__
64# define __HAVE_64B_ATOMICS 1
65# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
66 ({ __typeof (mem) __archmem = (mem); \
67 __typeof (*mem) __archold = (oldval); \
68 __asm__ __volatile__ ("csg %0,%2,%1" \
69 : "+d" (__archold), "=Q" (*__archmem) \
70 : "d" ((long) (newval)), "m" (*__archmem) : "cc", "memory" ); \
71 __archold; })
72#else
73# define __HAVE_64B_ATOMICS 0
74/* For 31 bit we do not really need 64-bit compare-and-exchange. We can
75 implement them by use of the csd instruction. The straightforward
76 implementation causes warnings so we skip the definition for now. */
77# define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
78 (abort (), (__typeof (*mem)) 0)
79#endif
80
81/* Store NEWVALUE in *MEM and return the old value. */
82/* On s390, the atomic_exchange_acq is different from generic implementation,
83 because the generic one does not use the condition-code of cs-instruction
84 to determine if looping is needed. Instead it saves the old-value and
85 compares it against old-value returned by cs-instruction. */
86#ifdef __s390x__
87# define atomic_exchange_acq(mem, newvalue) \
88 ({ __typeof (mem) __atg5_memp = (mem); \
89 __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \
90 __typeof (*(mem)) __atg5_value = (newvalue); \
91 if (sizeof (*mem) == 4) \
92 __asm__ __volatile__ ("0: cs %0,%2,%1\n" \
93 " jl 0b" \
94 : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \
95 : "d" (__atg5_value), "m" (*__atg5_memp) \
96 : "cc", "memory" ); \
97 else if (sizeof (*mem) == 8) \
98 __asm__ __volatile__ ("0: csg %0,%2,%1\n" \
99 " jl 0b" \
100 : "+d" ( __atg5_oldval), "=Q" (*__atg5_memp) \
101 : "d" ((long) __atg5_value), "m" (*__atg5_memp) \
102 : "cc", "memory" ); \
103 else \
104 abort (); \
105 __atg5_oldval; })
106#else
107# define atomic_exchange_acq(mem, newvalue) \
108 ({ __typeof (mem) __atg5_memp = (mem); \
109 __typeof (*(mem)) __atg5_oldval = *__atg5_memp; \
110 __typeof (*(mem)) __atg5_value = (newvalue); \
111 if (sizeof (*mem) == 4) \
112 __asm__ __volatile__ ("0: cs %0,%2,%1\n" \
113 " jl 0b" \
114 : "+d" (__atg5_oldval), "=Q" (*__atg5_memp) \
115 : "d" (__atg5_value), "m" (*__atg5_memp) \
116 : "cc", "memory" ); \
117 else \
118 abort (); \
119 __atg5_oldval; })
120#endif