PAPI 7.1.0.0
Loading...
Searching...
No Matches
gcc/ia64.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23#include "../all_atomic_load_store.h"
24
25#include "../all_acquire_release_volatile.h"
26
27#include "../test_and_set_t_is_char.h"
28
29#ifdef _ILP32
30 /* 32-bit HP/UX code. */
31 /* This requires pointer "swizzling". Pointers need to be expanded */
32 /* to 64 bits using the addp4 instruction before use. This makes it */
33 /* hard to share code, but we try anyway. */
34# define AO_LEN "4"
35 /* We assume that addr always appears in argument position 1 in asm */
36 /* code. If it is clobbered due to swizzling, we also need it in */
37 /* second position. Any later arguments are referenced symbolically, */
38 /* so that we don't have to worry about their position. This requires*/
39 /* gcc 3.1, but you shouldn't be using anything older than that on */
40 /* IA64 anyway. */
41 /* The AO_MASK macro is a workaround for the fact that HP/UX gcc */
42 /* appears to otherwise store 64-bit pointers in ar.ccv, i.e. it */
43 /* doesn't appear to clear high bits in a pointer value we pass into */
44 /* assembly code, even if it is supposedly of type AO_t. */
45# define AO_IN_ADDR "1"(addr)
46# define AO_OUT_ADDR , "=r"(addr)
47# define AO_SWIZZLE "addp4 %1=0,%1;;\n"
48# define AO_MASK(ptr) __asm__ __volatile__("zxt4 %1=%1": "=r"(ptr) : "0"(ptr))
49#else
50# define AO_LEN "8"
51# define AO_IN_ADDR "r"(addr)
52# define AO_OUT_ADDR
53# define AO_SWIZZLE
54# define AO_MASK(ptr) /* empty */
55#endif /* !_ILP32 */
56
57AO_INLINE void
59{
60 __asm__ __volatile__("mf" : : : "memory");
61}
62#define AO_HAVE_nop_full
63
64#ifndef AO_PREFER_GENERALIZED
67{
69
70 __asm__ __volatile__ (AO_SWIZZLE
71 "fetchadd" AO_LEN ".acq %0=[%1],1":
72 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
73 return result;
74}
75#define AO_HAVE_fetch_and_add1_acquire
76
79{
81
82 __asm__ __volatile__ (AO_SWIZZLE
83 "fetchadd" AO_LEN ".rel %0=[%1],1":
84 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
85 return result;
86}
87#define AO_HAVE_fetch_and_add1_release
88
91{
93
94 __asm__ __volatile__ (AO_SWIZZLE
95 "fetchadd" AO_LEN ".acq %0=[%1],-1":
96 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
97 return result;
98}
99#define AO_HAVE_fetch_and_sub1_acquire
100
103{
104 AO_t result;
105
106 __asm__ __volatile__ (AO_SWIZZLE
107 "fetchadd" AO_LEN ".rel %0=[%1],-1":
108 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
109 return result;
110}
111#define AO_HAVE_fetch_and_sub1_release
112#endif /* !AO_PREFER_GENERALIZED */
113
115AO_fetch_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val)
116{
117 AO_t fetched_val;
118 AO_MASK(old);
119 __asm__ __volatile__(AO_SWIZZLE
120 "mov ar.ccv=%[old] ;; cmpxchg" AO_LEN
121 ".acq %0=[%1],%[new_val],ar.ccv"
122 : "=r"(fetched_val) AO_OUT_ADDR
123 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"(old)
124 : "memory");
125 return fetched_val;
126}
127#define AO_HAVE_fetch_compare_and_swap_acquire
128
130AO_fetch_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val)
131{
132 AO_t fetched_val;
133 AO_MASK(old);
134 __asm__ __volatile__(AO_SWIZZLE
135 "mov ar.ccv=%[old] ;; cmpxchg" AO_LEN
136 ".rel %0=[%1],%[new_val],ar.ccv"
137 : "=r"(fetched_val) AO_OUT_ADDR
138 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"(old)
139 : "memory");
140 return fetched_val;
141}
142#define AO_HAVE_fetch_compare_and_swap_release
143
144AO_INLINE unsigned char
145AO_char_fetch_compare_and_swap_acquire(volatile unsigned char *addr,
146 unsigned char old, unsigned char new_val)
147{
148 unsigned char fetched_val;
149 __asm__ __volatile__(AO_SWIZZLE
150 "mov ar.ccv=%[old] ;; cmpxchg1.acq %0=[%1],%[new_val],ar.ccv"
151 : "=r"(fetched_val) AO_OUT_ADDR
152 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
153 : "memory");
154 return fetched_val;
155}
156#define AO_HAVE_char_fetch_compare_and_swap_acquire
157
158AO_INLINE unsigned char
159AO_char_fetch_compare_and_swap_release(volatile unsigned char *addr,
160 unsigned char old, unsigned char new_val)
161{
162 unsigned char fetched_val;
163 __asm__ __volatile__(AO_SWIZZLE
164 "mov ar.ccv=%[old] ;; cmpxchg1.rel %0=[%1],%[new_val],ar.ccv"
165 : "=r"(fetched_val) AO_OUT_ADDR
166 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
167 : "memory");
168 return fetched_val;
169}
170#define AO_HAVE_char_fetch_compare_and_swap_release
171
172AO_INLINE unsigned short
173AO_short_fetch_compare_and_swap_acquire(volatile unsigned short *addr,
174 unsigned short old, unsigned short new_val)
175{
176 unsigned short fetched_val;
177 __asm__ __volatile__(AO_SWIZZLE
178 "mov ar.ccv=%[old] ;; cmpxchg2.acq %0=[%1],%[new_val],ar.ccv"
179 : "=r"(fetched_val) AO_OUT_ADDR
180 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
181 : "memory");
182 return fetched_val;
183}
184#define AO_HAVE_short_fetch_compare_and_swap_acquire
185
186AO_INLINE unsigned short
187AO_short_fetch_compare_and_swap_release(volatile unsigned short *addr,
188 unsigned short old, unsigned short new_val)
189{
190 unsigned short fetched_val;
191 __asm__ __volatile__(AO_SWIZZLE
192 "mov ar.ccv=%[old] ;; cmpxchg2.rel %0=[%1],%[new_val],ar.ccv"
193 : "=r"(fetched_val) AO_OUT_ADDR
194 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
195 : "memory");
196 return fetched_val;
197}
198#define AO_HAVE_short_fetch_compare_and_swap_release
199
200#ifdef _ILP32
201
202# define AO_T_IS_INT
203
204 /* TODO: Add compare_double_and_swap_double for the _ILP32 case. */
205#else
206
207# ifndef AO_PREFER_GENERALIZED
208 AO_INLINE unsigned int
209 AO_int_fetch_and_add1_acquire(volatile unsigned int *addr)
210 {
211 unsigned int result;
212 __asm__ __volatile__("fetchadd4.acq %0=[%1],1"
213 : "=r" (result) : AO_IN_ADDR
214 : "memory");
215 return result;
216 }
217# define AO_HAVE_int_fetch_and_add1_acquire
218
219 AO_INLINE unsigned int
220 AO_int_fetch_and_add1_release(volatile unsigned int *addr)
221 {
222 unsigned int result;
223 __asm__ __volatile__("fetchadd4.rel %0=[%1],1"
224 : "=r" (result) : AO_IN_ADDR
225 : "memory");
226 return result;
227 }
228# define AO_HAVE_int_fetch_and_add1_release
229
230 AO_INLINE unsigned int
231 AO_int_fetch_and_sub1_acquire(volatile unsigned int *addr)
232 {
233 unsigned int result;
234 __asm__ __volatile__("fetchadd4.acq %0=[%1],-1"
235 : "=r" (result) : AO_IN_ADDR
236 : "memory");
237 return result;
238 }
239# define AO_HAVE_int_fetch_and_sub1_acquire
240
241 AO_INLINE unsigned int
242 AO_int_fetch_and_sub1_release(volatile unsigned int *addr)
243 {
244 unsigned int result;
245 __asm__ __volatile__("fetchadd4.rel %0=[%1],-1"
246 : "=r" (result) : AO_IN_ADDR
247 : "memory");
248 return result;
249 }
250# define AO_HAVE_int_fetch_and_sub1_release
251# endif /* !AO_PREFER_GENERALIZED */
252
253 AO_INLINE unsigned int
254 AO_int_fetch_compare_and_swap_acquire(volatile unsigned int *addr,
255 unsigned int old, unsigned int new_val)
256 {
257 unsigned int fetched_val;
258 __asm__ __volatile__("mov ar.ccv=%3 ;; cmpxchg4.acq %0=[%1],%2,ar.ccv"
259 : "=r"(fetched_val)
260 : AO_IN_ADDR, "r"(new_val), "r"((AO_t)old)
261 : "memory");
262 return fetched_val;
263 }
264# define AO_HAVE_int_fetch_compare_and_swap_acquire
265
266 AO_INLINE unsigned int
267 AO_int_fetch_compare_and_swap_release(volatile unsigned int *addr,
268 unsigned int old, unsigned int new_val)
269 {
270 unsigned int fetched_val;
271 __asm__ __volatile__("mov ar.ccv=%3 ;; cmpxchg4.rel %0=[%1],%2,ar.ccv"
272 : "=r"(fetched_val)
273 : AO_IN_ADDR, "r"(new_val), "r"((AO_t)old)
274 : "memory");
275 return fetched_val;
276 }
277# define AO_HAVE_int_fetch_compare_and_swap_release
278#endif /* !_ILP32 */
279
280/* TODO: Add compare_and_swap_double as soon as there is widely */
281/* available hardware that implements it. */
282
283#undef AO_IN_ADDR
284#undef AO_LEN
285#undef AO_MASK
286#undef AO_OUT_ADDR
287#undef AO_SWIZZLE
volatile int result
#define AO_t
Definition: atomic_ops.h:156
#define AO_INLINE
Definition: atomic_ops.h:186
AO_INLINE unsigned short AO_short_fetch_compare_and_swap_acquire(volatile unsigned short *addr, unsigned short old, unsigned short new_val)
Definition: gcc/ia64.h:173
AO_INLINE unsigned char AO_char_fetch_compare_and_swap_acquire(volatile unsigned char *addr, unsigned char old, unsigned char new_val)
Definition: gcc/ia64.h:145
#define AO_SWIZZLE
Definition: gcc/ia64.h:53
AO_INLINE unsigned int AO_int_fetch_compare_and_swap_acquire(volatile unsigned int *addr, unsigned int old, unsigned int new_val)
Definition: gcc/ia64.h:254
AO_INLINE unsigned int AO_int_fetch_compare_and_swap_release(volatile unsigned int *addr, unsigned int old, unsigned int new_val)
Definition: gcc/ia64.h:267
#define AO_OUT_ADDR
Definition: gcc/ia64.h:52
AO_INLINE AO_t AO_fetch_and_add1_release(volatile AO_t *addr)
Definition: gcc/ia64.h:78
AO_INLINE unsigned int AO_int_fetch_and_sub1_release(volatile unsigned int *addr)
Definition: gcc/ia64.h:242
AO_INLINE unsigned int AO_int_fetch_and_add1_acquire(volatile unsigned int *addr)
Definition: gcc/ia64.h:209
AO_INLINE AO_t AO_fetch_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val)
Definition: gcc/ia64.h:130
#define AO_LEN
Definition: gcc/ia64.h:50
AO_INLINE unsigned int AO_int_fetch_and_add1_release(volatile unsigned int *addr)
Definition: gcc/ia64.h:220
AO_INLINE unsigned int AO_int_fetch_and_sub1_acquire(volatile unsigned int *addr)
Definition: gcc/ia64.h:231
AO_INLINE AO_t AO_fetch_and_sub1_acquire(volatile AO_t *addr)
Definition: gcc/ia64.h:90
#define AO_MASK(ptr)
Definition: gcc/ia64.h:54
AO_INLINE AO_t AO_fetch_and_add1_acquire(volatile AO_t *addr)
Definition: gcc/ia64.h:66
AO_INLINE unsigned short AO_short_fetch_compare_and_swap_release(volatile unsigned short *addr, unsigned short old, unsigned short new_val)
Definition: gcc/ia64.h:187
AO_INLINE unsigned char AO_char_fetch_compare_and_swap_release(volatile unsigned char *addr, unsigned char old, unsigned char new_val)
Definition: gcc/ia64.h:159
#define AO_IN_ADDR
Definition: gcc/ia64.h:51
AO_INLINE AO_t AO_fetch_and_sub1_release(volatile AO_t *addr)
Definition: gcc/ia64.h:102
AO_INLINE AO_t AO_fetch_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val)
Definition: gcc/ia64.h:115
AO_INLINE void AO_nop_full(void)
Definition: gcc/ia64.h:58