xref: /freebsd/sys/contrib/ck/include/ck_pr.h (revision 29fc4075e69fd27de0cded313ac6000165d99f8b)
1 /*
2  * Copyright 2009-2015 Samy Al Bahra.
3  * Copyright 2011 David Joseph.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #ifndef CK_PR_H
29 #define CK_PR_H
30 
31 #include <ck_cc.h>
32 #include <ck_limits.h>
33 #include <ck_md.h>
34 #include <ck_stdint.h>
35 #include <ck_stdbool.h>
36 
37 /*
38  * Default to using builtins for clang analyzer, coverity, and sparse:
39  * inline assembly is often too opaque for useful analysis.  Override
40  * the defaults by defining CK_USE_CC_BUILTINS=0 or 1.
41  */
42 #if !defined(CK_USE_CC_BUILTINS)
43 #if defined(__clang_analyzer__) || defined(__COVERITY__) || defined(__CHECKER__)
44 #define CK_USE_CC_BUILTINS 1
45 #else
46 #define CK_USE_CC_BUILTINS 0
47 #endif
48 #endif
49 
50 #if !CK_USE_CC_BUILTINS
51 #if defined(__x86_64__)
52 #include "gcc/x86_64/ck_pr.h"
53 #elif defined(__x86__)
54 #include "gcc/x86/ck_pr.h"
55 #elif defined(__sparcv9__)
56 #include "gcc/sparcv9/ck_pr.h"
57 #elif defined(__ppc64__)
58 #include "gcc/ppc64/ck_pr.h"
59 #elif defined(__s390x__)
60 #include "gcc/s390x/ck_pr.h"
61 #elif defined(__ppc__)
62 #include "gcc/ppc/ck_pr.h"
63 #elif defined(__arm__)
64 #include "gcc/arm/ck_pr.h"
65 #elif defined(__aarch64__)
66 #include "gcc/aarch64/ck_pr.h"
67 #elif !defined(__GNUC__)
68 #error Your platform is unsupported
69 #endif
70 #endif /* !CK_USE_CC_BUILTINS */
71 
72 #if defined(__GNUC__)
73 #include "gcc/ck_pr.h"
74 #endif
75 
76 #define CK_PR_FENCE_EMIT(T)			\
77 	CK_CC_INLINE static void		\
78 	ck_pr_fence_##T(void)			\
79 	{					\
80 		ck_pr_fence_strict_##T();	\
81 		return;				\
82 	}
83 #define CK_PR_FENCE_NOOP(T)			\
84 	CK_CC_INLINE static void		\
85 	ck_pr_fence_##T(void)			\
86 	{					\
87 		ck_pr_barrier();		\
88 		return;				\
89 	}
90 
91 /*
92  * None of the currently supported platforms allow for data-dependent
93  * load ordering.
94  */
95 CK_PR_FENCE_NOOP(load_depends)
96 #define ck_pr_fence_strict_load_depends ck_pr_fence_load_depends
97 
98 /*
99  * In memory models where atomic operations do not have serializing
100  * effects, atomic read-modify-write operations are modeled as stores.
101  */
102 #if defined(CK_MD_RMO)
103 /*
104  * Only stores to the same location have a global
105  * ordering.
106  */
107 CK_PR_FENCE_EMIT(atomic)
108 CK_PR_FENCE_EMIT(atomic_load)
109 CK_PR_FENCE_EMIT(atomic_store)
110 CK_PR_FENCE_EMIT(store_atomic)
111 CK_PR_FENCE_EMIT(load_atomic)
112 CK_PR_FENCE_EMIT(load_store)
113 CK_PR_FENCE_EMIT(store_load)
114 CK_PR_FENCE_EMIT(load)
115 CK_PR_FENCE_EMIT(store)
116 CK_PR_FENCE_EMIT(memory)
117 CK_PR_FENCE_EMIT(acquire)
118 CK_PR_FENCE_EMIT(release)
119 CK_PR_FENCE_EMIT(acqrel)
120 CK_PR_FENCE_EMIT(lock)
121 CK_PR_FENCE_EMIT(unlock)
122 #elif defined(CK_MD_PSO)
123 /*
124  * Anything can be re-ordered with respect to stores.
125  * Otherwise, loads are executed in-order.
126  */
127 CK_PR_FENCE_EMIT(atomic)
128 CK_PR_FENCE_NOOP(atomic_load)
129 CK_PR_FENCE_EMIT(atomic_store)
130 CK_PR_FENCE_EMIT(store_atomic)
131 CK_PR_FENCE_NOOP(load_atomic)
132 CK_PR_FENCE_EMIT(load_store)
133 CK_PR_FENCE_EMIT(store_load)
134 CK_PR_FENCE_NOOP(load)
135 CK_PR_FENCE_EMIT(store)
136 CK_PR_FENCE_EMIT(memory)
137 CK_PR_FENCE_EMIT(acquire)
138 CK_PR_FENCE_EMIT(release)
139 CK_PR_FENCE_EMIT(acqrel)
140 CK_PR_FENCE_EMIT(lock)
141 CK_PR_FENCE_EMIT(unlock)
142 #elif defined(CK_MD_TSO)
143 /*
144  * Only loads are re-ordered and only with respect to
145  * prior stores. Atomic operations are serializing.
146  */
147 CK_PR_FENCE_NOOP(atomic)
148 CK_PR_FENCE_NOOP(atomic_load)
149 CK_PR_FENCE_NOOP(atomic_store)
150 CK_PR_FENCE_NOOP(store_atomic)
151 CK_PR_FENCE_NOOP(load_atomic)
152 CK_PR_FENCE_NOOP(load_store)
153 CK_PR_FENCE_EMIT(store_load)
154 CK_PR_FENCE_NOOP(load)
155 CK_PR_FENCE_NOOP(store)
156 CK_PR_FENCE_EMIT(memory)
157 CK_PR_FENCE_NOOP(acquire)
158 CK_PR_FENCE_NOOP(release)
159 CK_PR_FENCE_NOOP(acqrel)
160 CK_PR_FENCE_NOOP(lock)
161 CK_PR_FENCE_NOOP(unlock)
162 #else
163 #error "No memory model has been defined."
164 #endif /* CK_MD_TSO */
165 
166 #undef CK_PR_FENCE_EMIT
167 #undef CK_PR_FENCE_NOOP
168 
169 #ifndef CK_F_PR_RFO
170 #define CK_F_PR_RFO
171 CK_CC_INLINE static void
172 ck_pr_rfo(const void *m)
173 {
174 
175 	(void)m;
176 	return;
177 }
178 #endif /* CK_F_PR_RFO */
179 
180 #define CK_PR_STORE_SAFE(DST, VAL, TYPE)			\
181     ck_pr_md_store_##TYPE(					\
182         ((void)sizeof(*(DST) = (VAL)), (DST)),			\
183         (VAL))
184 
185 #define ck_pr_store_ptr(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), ptr)
186 #define ck_pr_store_char(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), char)
187 #ifndef CK_PR_DISABLE_DOUBLE
188 #define ck_pr_store_double(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), double)
189 #endif
190 #define ck_pr_store_uint(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), uint)
191 #define ck_pr_store_int(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), int)
192 #define ck_pr_store_32(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 32)
193 #define ck_pr_store_16(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 16)
194 #define ck_pr_store_8(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 8)
195 
196 #define ck_pr_store_ptr_unsafe(DST, VAL) ck_pr_md_store_ptr((DST), (VAL))
197 
198 #ifdef CK_F_PR_LOAD_64
199 #define ck_pr_store_64(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 64)
200 #endif /* CK_F_PR_LOAD_64 */
201 
202 #define CK_PR_LOAD_PTR_SAFE(SRC) (CK_CC_TYPEOF(*(SRC), (void *)))ck_pr_md_load_ptr((SRC))
203 #define ck_pr_load_ptr(SRC) CK_PR_LOAD_PTR_SAFE((SRC))
204 
205 #define CK_PR_LOAD_SAFE(SRC, TYPE) ck_pr_md_load_##TYPE((SRC))
206 #define ck_pr_load_char(SRC) CK_PR_LOAD_SAFE((SRC), char)
207 #ifndef CK_PR_DISABLE_DOUBLE
208 #define ck_pr_load_double(SRC) CK_PR_LOAD_SAFE((SRC), double)
209 #endif
210 #define ck_pr_load_uint(SRC) CK_PR_LOAD_SAFE((SRC), uint)
211 #define ck_pr_load_int(SRC) CK_PR_LOAD_SAFE((SRC), int)
212 #define ck_pr_load_32(SRC) CK_PR_LOAD_SAFE((SRC), 32)
213 #define ck_pr_load_16(SRC) CK_PR_LOAD_SAFE((SRC), 16)
214 #define ck_pr_load_8(SRC) CK_PR_LOAD_SAFE((SRC), 8)
215 
216 #ifdef CK_F_PR_LOAD_64
217 #define ck_pr_load_64(SRC) CK_PR_LOAD_SAFE((SRC), 64)
218 #endif /* CK_F_PR_LOAD_64 */
219 
220 #define CK_PR_BIN(K, S, M, T, P, C)					\
221 	CK_CC_INLINE static void					\
222 	ck_pr_##K##_##S(M *target, T value)				\
223 	{								\
224 		T previous;						\
225 		C punt;							\
226 		punt = ck_pr_md_load_##S(target);			\
227 		previous = (T)punt;					\
228 		while (ck_pr_cas_##S##_value(target,			\
229 					     (C)previous,		\
230 					     (C)(previous P value),	\
231 					     &previous) == false)	\
232 			ck_pr_stall();					\
233 									\
234 		return;							\
235 	}
236 
237 #define CK_PR_BIN_S(K, S, T, P) CK_PR_BIN(K, S, T, T, P, T)
238 
239 #if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)
240 
241 #ifndef CK_F_PR_ADD_CHAR
242 #define CK_F_PR_ADD_CHAR
243 CK_PR_BIN_S(add, char, char, +)
244 #endif /* CK_F_PR_ADD_CHAR */
245 
246 #ifndef CK_F_PR_SUB_CHAR
247 #define CK_F_PR_SUB_CHAR
248 CK_PR_BIN_S(sub, char, char, -)
249 #endif /* CK_F_PR_SUB_CHAR */
250 
251 #ifndef CK_F_PR_AND_CHAR
252 #define CK_F_PR_AND_CHAR
253 CK_PR_BIN_S(and, char, char, &)
254 #endif /* CK_F_PR_AND_CHAR */
255 
256 #ifndef CK_F_PR_XOR_CHAR
257 #define CK_F_PR_XOR_CHAR
258 CK_PR_BIN_S(xor, char, char, ^)
259 #endif /* CK_F_PR_XOR_CHAR */
260 
261 #ifndef CK_F_PR_OR_CHAR
262 #define CK_F_PR_OR_CHAR
263 CK_PR_BIN_S(or, char, char, |)
264 #endif /* CK_F_PR_OR_CHAR */
265 
266 #endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */
267 
268 #if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)
269 
270 #ifndef CK_F_PR_ADD_INT
271 #define CK_F_PR_ADD_INT
272 CK_PR_BIN_S(add, int, int, +)
273 #endif /* CK_F_PR_ADD_INT */
274 
275 #ifndef CK_F_PR_SUB_INT
276 #define CK_F_PR_SUB_INT
277 CK_PR_BIN_S(sub, int, int, -)
278 #endif /* CK_F_PR_SUB_INT */
279 
280 #ifndef CK_F_PR_AND_INT
281 #define CK_F_PR_AND_INT
282 CK_PR_BIN_S(and, int, int, &)
283 #endif /* CK_F_PR_AND_INT */
284 
285 #ifndef CK_F_PR_XOR_INT
286 #define CK_F_PR_XOR_INT
287 CK_PR_BIN_S(xor, int, int, ^)
288 #endif /* CK_F_PR_XOR_INT */
289 
290 #ifndef CK_F_PR_OR_INT
291 #define CK_F_PR_OR_INT
292 CK_PR_BIN_S(or, int, int, |)
293 #endif /* CK_F_PR_OR_INT */
294 
295 #endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */
296 
297 #if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \
298 	    !defined(CK_PR_DISABLE_DOUBLE)
299 
300 #ifndef CK_F_PR_ADD_DOUBLE
301 #define CK_F_PR_ADD_DOUBLE
302 CK_PR_BIN_S(add, double, double, +)
303 #endif /* CK_F_PR_ADD_DOUBLE */
304 
305 #ifndef CK_F_PR_SUB_DOUBLE
306 #define CK_F_PR_SUB_DOUBLE
307 CK_PR_BIN_S(sub, double, double, -)
308 #endif /* CK_F_PR_SUB_DOUBLE */
309 
310 #endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */
311 
312 #if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)
313 
314 #ifndef CK_F_PR_ADD_UINT
315 #define CK_F_PR_ADD_UINT
316 CK_PR_BIN_S(add, uint, unsigned int, +)
317 #endif /* CK_F_PR_ADD_UINT */
318 
319 #ifndef CK_F_PR_SUB_UINT
320 #define CK_F_PR_SUB_UINT
321 CK_PR_BIN_S(sub, uint, unsigned int, -)
322 #endif /* CK_F_PR_SUB_UINT */
323 
324 #ifndef CK_F_PR_AND_UINT
325 #define CK_F_PR_AND_UINT
326 CK_PR_BIN_S(and, uint, unsigned int, &)
327 #endif /* CK_F_PR_AND_UINT */
328 
329 #ifndef CK_F_PR_XOR_UINT
330 #define CK_F_PR_XOR_UINT
331 CK_PR_BIN_S(xor, uint, unsigned int, ^)
332 #endif /* CK_F_PR_XOR_UINT */
333 
334 #ifndef CK_F_PR_OR_UINT
335 #define CK_F_PR_OR_UINT
336 CK_PR_BIN_S(or, uint, unsigned int, |)
337 #endif /* CK_F_PR_OR_UINT */
338 
339 #endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */
340 
341 #if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)
342 
343 #ifndef CK_F_PR_ADD_PTR
344 #define CK_F_PR_ADD_PTR
345 CK_PR_BIN(add, ptr, void, uintptr_t, +, void *)
346 #endif /* CK_F_PR_ADD_PTR */
347 
348 #ifndef CK_F_PR_SUB_PTR
349 #define CK_F_PR_SUB_PTR
350 CK_PR_BIN(sub, ptr, void, uintptr_t, -, void *)
351 #endif /* CK_F_PR_SUB_PTR */
352 
353 #ifndef CK_F_PR_AND_PTR
354 #define CK_F_PR_AND_PTR
355 CK_PR_BIN(and, ptr, void, uintptr_t, &, void *)
356 #endif /* CK_F_PR_AND_PTR */
357 
358 #ifndef CK_F_PR_XOR_PTR
359 #define CK_F_PR_XOR_PTR
360 CK_PR_BIN(xor, ptr, void, uintptr_t, ^, void *)
361 #endif /* CK_F_PR_XOR_PTR */
362 
363 #ifndef CK_F_PR_OR_PTR
364 #define CK_F_PR_OR_PTR
365 CK_PR_BIN(or, ptr, void, uintptr_t, |, void *)
366 #endif /* CK_F_PR_OR_PTR */
367 
368 #endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */
369 
370 #if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)
371 
372 #ifndef CK_F_PR_ADD_64
373 #define CK_F_PR_ADD_64
374 CK_PR_BIN_S(add, 64, uint64_t, +)
375 #endif /* CK_F_PR_ADD_64 */
376 
377 #ifndef CK_F_PR_SUB_64
378 #define CK_F_PR_SUB_64
379 CK_PR_BIN_S(sub, 64, uint64_t, -)
380 #endif /* CK_F_PR_SUB_64 */
381 
382 #ifndef CK_F_PR_AND_64
383 #define CK_F_PR_AND_64
384 CK_PR_BIN_S(and, 64, uint64_t, &)
385 #endif /* CK_F_PR_AND_64 */
386 
387 #ifndef CK_F_PR_XOR_64
388 #define CK_F_PR_XOR_64
389 CK_PR_BIN_S(xor, 64, uint64_t, ^)
390 #endif /* CK_F_PR_XOR_64 */
391 
392 #ifndef CK_F_PR_OR_64
393 #define CK_F_PR_OR_64
394 CK_PR_BIN_S(or, 64, uint64_t, |)
395 #endif /* CK_F_PR_OR_64 */
396 
397 #endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */
398 
399 #if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)
400 
401 #ifndef CK_F_PR_ADD_32
402 #define CK_F_PR_ADD_32
403 CK_PR_BIN_S(add, 32, uint32_t, +)
404 #endif /* CK_F_PR_ADD_32 */
405 
406 #ifndef CK_F_PR_SUB_32
407 #define CK_F_PR_SUB_32
408 CK_PR_BIN_S(sub, 32, uint32_t, -)
409 #endif /* CK_F_PR_SUB_32 */
410 
411 #ifndef CK_F_PR_AND_32
412 #define CK_F_PR_AND_32
413 CK_PR_BIN_S(and, 32, uint32_t, &)
414 #endif /* CK_F_PR_AND_32 */
415 
416 #ifndef CK_F_PR_XOR_32
417 #define CK_F_PR_XOR_32
418 CK_PR_BIN_S(xor, 32, uint32_t, ^)
419 #endif /* CK_F_PR_XOR_32 */
420 
421 #ifndef CK_F_PR_OR_32
422 #define CK_F_PR_OR_32
423 CK_PR_BIN_S(or, 32, uint32_t, |)
424 #endif /* CK_F_PR_OR_32 */
425 
426 #endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */
427 
428 #if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)
429 
430 #ifndef CK_F_PR_ADD_16
431 #define CK_F_PR_ADD_16
432 CK_PR_BIN_S(add, 16, uint16_t, +)
433 #endif /* CK_F_PR_ADD_16 */
434 
435 #ifndef CK_F_PR_SUB_16
436 #define CK_F_PR_SUB_16
437 CK_PR_BIN_S(sub, 16, uint16_t, -)
438 #endif /* CK_F_PR_SUB_16 */
439 
440 #ifndef CK_F_PR_AND_16
441 #define CK_F_PR_AND_16
442 CK_PR_BIN_S(and, 16, uint16_t, &)
443 #endif /* CK_F_PR_AND_16 */
444 
445 #ifndef CK_F_PR_XOR_16
446 #define CK_F_PR_XOR_16
447 CK_PR_BIN_S(xor, 16, uint16_t, ^)
448 #endif /* CK_F_PR_XOR_16 */
449 
450 #ifndef CK_F_PR_OR_16
451 #define CK_F_PR_OR_16
452 CK_PR_BIN_S(or, 16, uint16_t, |)
453 #endif /* CK_F_PR_OR_16 */
454 
455 #endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */
456 
457 #if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)
458 
459 #ifndef CK_F_PR_ADD_8
460 #define CK_F_PR_ADD_8
461 CK_PR_BIN_S(add, 8, uint8_t, +)
462 #endif /* CK_F_PR_ADD_8 */
463 
464 #ifndef CK_F_PR_SUB_8
465 #define CK_F_PR_SUB_8
466 CK_PR_BIN_S(sub, 8, uint8_t, -)
467 #endif /* CK_F_PR_SUB_8 */
468 
469 #ifndef CK_F_PR_AND_8
470 #define CK_F_PR_AND_8
471 CK_PR_BIN_S(and, 8, uint8_t, &)
472 #endif /* CK_F_PR_AND_8 */
473 
474 #ifndef CK_F_PR_XOR_8
475 #define CK_F_PR_XOR_8
476 CK_PR_BIN_S(xor, 8, uint8_t, ^)
477 #endif /* CK_F_PR_XOR_8 */
478 
479 #ifndef CK_F_PR_OR_8
480 #define CK_F_PR_OR_8
481 CK_PR_BIN_S(or, 8, uint8_t, |)
482 #endif /* CK_F_PR_OR_8 */
483 
484 #endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */
485 
486 #undef CK_PR_BIN_S
487 #undef CK_PR_BIN
488 
489 #define CK_PR_BTX(K, S, M, T, P, C, R)						   \
490 	CK_CC_INLINE static bool						   \
491 	ck_pr_##K##_##S(M *target, unsigned int offset)				   \
492 	{									   \
493 		T previous;							   \
494 		C punt;								   \
495 		punt = ck_pr_md_load_##S(target);				   \
496 		previous = (T)punt;						   \
497 		while (ck_pr_cas_##S##_value(target, (C)previous,		   \
498 			(C)(previous P (R ((T)1 << offset))), &previous) == false) \
499 				ck_pr_stall();					   \
500 		return ((previous >> offset) & 1);				   \
501 	}
502 
503 #define CK_PR_BTX_S(K, S, T, P, R) CK_PR_BTX(K, S, T, T, P, T, R)
504 
505 #if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)
506 
507 #ifndef CK_F_PR_BTC_INT
508 #define CK_F_PR_BTC_INT
509 CK_PR_BTX_S(btc, int, int, ^,)
510 #endif /* CK_F_PR_BTC_INT */
511 
512 #ifndef CK_F_PR_BTR_INT
513 #define CK_F_PR_BTR_INT
514 CK_PR_BTX_S(btr, int, int, &, ~)
515 #endif /* CK_F_PR_BTR_INT */
516 
517 #ifndef CK_F_PR_BTS_INT
518 #define CK_F_PR_BTS_INT
519 CK_PR_BTX_S(bts, int, int, |,)
520 #endif /* CK_F_PR_BTS_INT */
521 
522 #endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */
523 
524 #if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)
525 
526 #ifndef CK_F_PR_BTC_UINT
527 #define CK_F_PR_BTC_UINT
528 CK_PR_BTX_S(btc, uint, unsigned int, ^,)
529 #endif /* CK_F_PR_BTC_UINT */
530 
531 #ifndef CK_F_PR_BTR_UINT
532 #define CK_F_PR_BTR_UINT
533 CK_PR_BTX_S(btr, uint, unsigned int, &, ~)
534 #endif /* CK_F_PR_BTR_UINT */
535 
536 #ifndef CK_F_PR_BTS_UINT
537 #define CK_F_PR_BTS_UINT
538 CK_PR_BTX_S(bts, uint, unsigned int, |,)
539 #endif /* CK_F_PR_BTS_UINT */
540 
541 #endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */
542 
543 #if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)
544 
545 #ifndef CK_F_PR_BTC_PTR
546 #define CK_F_PR_BTC_PTR
547 CK_PR_BTX(btc, ptr, void, uintptr_t, ^, void *,)
548 #endif /* CK_F_PR_BTC_PTR */
549 
550 #ifndef CK_F_PR_BTR_PTR
551 #define CK_F_PR_BTR_PTR
552 CK_PR_BTX(btr, ptr, void, uintptr_t, &, void *, ~)
553 #endif /* CK_F_PR_BTR_PTR */
554 
555 #ifndef CK_F_PR_BTS_PTR
556 #define CK_F_PR_BTS_PTR
557 CK_PR_BTX(bts, ptr, void, uintptr_t, |, void *,)
558 #endif /* CK_F_PR_BTS_PTR */
559 
560 #endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */
561 
562 #if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)
563 
564 #ifndef CK_F_PR_BTC_64
565 #define CK_F_PR_BTC_64
566 CK_PR_BTX_S(btc, 64, uint64_t, ^,)
567 #endif /* CK_F_PR_BTC_64 */
568 
569 #ifndef CK_F_PR_BTR_64
570 #define CK_F_PR_BTR_64
571 CK_PR_BTX_S(btr, 64, uint64_t, &, ~)
572 #endif /* CK_F_PR_BTR_64 */
573 
574 #ifndef CK_F_PR_BTS_64
575 #define CK_F_PR_BTS_64
576 CK_PR_BTX_S(bts, 64, uint64_t, |,)
577 #endif /* CK_F_PR_BTS_64 */
578 
579 #endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */
580 
581 #if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)
582 
583 #ifndef CK_F_PR_BTC_32
584 #define CK_F_PR_BTC_32
585 CK_PR_BTX_S(btc, 32, uint32_t, ^,)
586 #endif /* CK_F_PR_BTC_32 */
587 
588 #ifndef CK_F_PR_BTR_32
589 #define CK_F_PR_BTR_32
590 CK_PR_BTX_S(btr, 32, uint32_t, &, ~)
591 #endif /* CK_F_PR_BTR_32 */
592 
593 #ifndef CK_F_PR_BTS_32
594 #define CK_F_PR_BTS_32
595 CK_PR_BTX_S(bts, 32, uint32_t, |,)
596 #endif /* CK_F_PR_BTS_32 */
597 
598 #endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */
599 
600 #if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)
601 
602 #ifndef CK_F_PR_BTC_16
603 #define CK_F_PR_BTC_16
604 CK_PR_BTX_S(btc, 16, uint16_t, ^,)
605 #endif /* CK_F_PR_BTC_16 */
606 
607 #ifndef CK_F_PR_BTR_16
608 #define CK_F_PR_BTR_16
609 CK_PR_BTX_S(btr, 16, uint16_t, &, ~)
610 #endif /* CK_F_PR_BTR_16 */
611 
612 #ifndef CK_F_PR_BTS_16
613 #define CK_F_PR_BTS_16
614 CK_PR_BTX_S(bts, 16, uint16_t, |,)
615 #endif /* CK_F_PR_BTS_16 */
616 
617 #endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */
618 
619 #undef CK_PR_BTX_S
620 #undef CK_PR_BTX
621 
622 #define CK_PR_UNARY(K, X, S, M, T)					\
623 	CK_CC_INLINE static void					\
624 	ck_pr_##K##_##S(M *target)					\
625 	{								\
626 		ck_pr_##X##_##S(target, (T)1);				\
627 		return;							\
628 	}
629 
630 #define CK_PR_UNARY_Z(K, S, M, T, P, C, Z)				\
631 	CK_CC_INLINE static bool					\
632 	ck_pr_##K##_##S##_is_zero(M *target)				\
633 	{								\
634 		T previous;						\
635 		C punt;							\
636 		punt = (C)ck_pr_md_load_##S(target);			\
637 		previous = (T)punt;					\
638 		while (ck_pr_cas_##S##_value(target,			\
639 					     (C)previous,		\
640 					     (C)(previous P 1),		\
641 					     &previous) == false)	\
642 			ck_pr_stall();					\
643 		return previous == (T)Z;				\
644         }
645 
646 #define CK_PR_UNARY_Z_STUB(K, S, M)					\
647 	CK_CC_INLINE static void					\
648 	ck_pr_##K##_##S##_zero(M *target, bool *zero)			\
649 	{								\
650 		*zero = ck_pr_##K##_##S##_is_zero(target);		\
651 		return;							\
652 	}
653 
654 #define CK_PR_UNARY_S(K, X, S, M) CK_PR_UNARY(K, X, S, M, M)
655 #define CK_PR_UNARY_Z_S(K, S, M, P, Z)          \
656         CK_PR_UNARY_Z(K, S, M, M, P, M, Z)      \
657         CK_PR_UNARY_Z_STUB(K, S, M)
658 
659 #if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)
660 
661 #ifndef CK_F_PR_INC_CHAR
662 #define CK_F_PR_INC_CHAR
663 CK_PR_UNARY_S(inc, add, char, char)
664 #endif /* CK_F_PR_INC_CHAR */
665 
666 #ifndef CK_F_PR_INC_CHAR_ZERO
667 #define CK_F_PR_INC_CHAR_ZERO
668 CK_PR_UNARY_Z_S(inc, char, char, +, -1)
669 #else
670 CK_PR_UNARY_Z_STUB(inc, char, char)
671 #endif /* CK_F_PR_INC_CHAR_ZERO */
672 
673 #ifndef CK_F_PR_DEC_CHAR
674 #define CK_F_PR_DEC_CHAR
675 CK_PR_UNARY_S(dec, sub, char, char)
676 #endif /* CK_F_PR_DEC_CHAR */
677 
678 #ifndef CK_F_PR_DEC_CHAR_ZERO
679 #define CK_F_PR_DEC_CHAR_ZERO
680 CK_PR_UNARY_Z_S(dec, char, char, -, 1)
681 #else
682 CK_PR_UNARY_Z_STUB(dec, char, char)
683 #endif /* CK_F_PR_DEC_CHAR_ZERO */
684 
685 #endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */
686 
687 #if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)
688 
689 #ifndef CK_F_PR_INC_INT
690 #define CK_F_PR_INC_INT
691 CK_PR_UNARY_S(inc, add, int, int)
692 #endif /* CK_F_PR_INC_INT */
693 
694 #ifndef CK_F_PR_INC_INT_ZERO
695 #define CK_F_PR_INC_INT_ZERO
696 CK_PR_UNARY_Z_S(inc, int, int, +, -1)
697 #else
698 CK_PR_UNARY_Z_STUB(inc, int, int)
699 #endif /* CK_F_PR_INC_INT_ZERO */
700 
701 #ifndef CK_F_PR_DEC_INT
702 #define CK_F_PR_DEC_INT
703 CK_PR_UNARY_S(dec, sub, int, int)
704 #endif /* CK_F_PR_DEC_INT */
705 
706 #ifndef CK_F_PR_DEC_INT_ZERO
707 #define CK_F_PR_DEC_INT_ZERO
708 CK_PR_UNARY_Z_S(dec, int, int, -, 1)
709 #else
710 CK_PR_UNARY_Z_STUB(dec, int, int)
711 #endif /* CK_F_PR_DEC_INT_ZERO */
712 
713 #endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */
714 
715 #if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \
716 	    !defined(CK_PR_DISABLE_DOUBLE)
717 
718 #ifndef CK_F_PR_INC_DOUBLE
719 #define CK_F_PR_INC_DOUBLE
720 CK_PR_UNARY_S(inc, add, double, double)
721 #endif /* CK_F_PR_INC_DOUBLE */
722 
723 #ifndef CK_F_PR_DEC_DOUBLE
724 #define CK_F_PR_DEC_DOUBLE
725 CK_PR_UNARY_S(dec, sub, double, double)
726 #endif /* CK_F_PR_DEC_DOUBLE */
727 
728 #endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */
729 
730 #if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)
731 
732 #ifndef CK_F_PR_INC_UINT
733 #define CK_F_PR_INC_UINT
734 CK_PR_UNARY_S(inc, add, uint, unsigned int)
735 #endif /* CK_F_PR_INC_UINT */
736 
737 #ifndef CK_F_PR_INC_UINT_ZERO
738 #define CK_F_PR_INC_UINT_ZERO
739 CK_PR_UNARY_Z_S(inc, uint, unsigned int, +, UINT_MAX)
740 #else
741 CK_PR_UNARY_Z_STUB(inc, uint, unsigned int)
742 #endif /* CK_F_PR_INC_UINT_ZERO */
743 
744 #ifndef CK_F_PR_DEC_UINT
745 #define CK_F_PR_DEC_UINT
746 CK_PR_UNARY_S(dec, sub, uint, unsigned int)
747 #endif /* CK_F_PR_DEC_UINT */
748 
749 #ifndef CK_F_PR_DEC_UINT_ZERO
750 #define CK_F_PR_DEC_UINT_ZERO
751 CK_PR_UNARY_Z_S(dec, uint, unsigned int, -, 1)
752 #else
753 CK_PR_UNARY_Z_STUB(dec, uint, unsigned int)
754 #endif /* CK_F_PR_DEC_UINT_ZERO */
755 
756 #endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */
757 
758 #if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)
759 
760 #ifndef CK_F_PR_INC_PTR
761 #define CK_F_PR_INC_PTR
762 CK_PR_UNARY(inc, add, ptr, void, uintptr_t)
763 #endif /* CK_F_PR_INC_PTR */
764 
765 #ifndef CK_F_PR_INC_PTR_ZERO
766 #define CK_F_PR_INC_PTR_ZERO
767 CK_PR_UNARY_Z(inc, ptr, void, uintptr_t, +, void *, UINT_MAX)
768 #else
769 CK_PR_UNARY_Z_STUB(inc, ptr, void)
770 #endif /* CK_F_PR_INC_PTR_ZERO */
771 
772 #ifndef CK_F_PR_DEC_PTR
773 #define CK_F_PR_DEC_PTR
774 CK_PR_UNARY(dec, sub, ptr, void, uintptr_t)
775 #endif /* CK_F_PR_DEC_PTR */
776 
777 #ifndef CK_F_PR_DEC_PTR_ZERO
778 #define CK_F_PR_DEC_PTR_ZERO
779 CK_PR_UNARY_Z(dec, ptr, void, uintptr_t, -, void *, 1)
780 #else
781 CK_PR_UNARY_Z_STUB(dec, ptr, void)
782 #endif /* CK_F_PR_DEC_PTR_ZERO */
783 
784 #endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */
785 
786 #if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)
787 
788 #ifndef CK_F_PR_INC_64
789 #define CK_F_PR_INC_64
790 CK_PR_UNARY_S(inc, add, 64, uint64_t)
791 #endif /* CK_F_PR_INC_64 */
792 
793 #ifndef CK_F_PR_INC_64_ZERO
794 #define CK_F_PR_INC_64_ZERO
795 CK_PR_UNARY_Z_S(inc, 64, uint64_t, +, UINT64_MAX)
796 #else
797 CK_PR_UNARY_Z_STUB(inc, 64, uint64_t)
798 #endif /* CK_F_PR_INC_64_ZERO */
799 
800 #ifndef CK_F_PR_DEC_64
801 #define CK_F_PR_DEC_64
802 CK_PR_UNARY_S(dec, sub, 64, uint64_t)
803 #endif /* CK_F_PR_DEC_64 */
804 
805 #ifndef CK_F_PR_DEC_64_ZERO
806 #define CK_F_PR_DEC_64_ZERO
807 CK_PR_UNARY_Z_S(dec, 64, uint64_t, -, 1)
808 #else
809 CK_PR_UNARY_Z_STUB(dec, 64, uint64_t)
810 #endif /* CK_F_PR_DEC_64_ZERO */
811 
812 #endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */
813 
814 #if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)
815 
816 #ifndef CK_F_PR_INC_32
817 #define CK_F_PR_INC_32
818 CK_PR_UNARY_S(inc, add, 32, uint32_t)
819 #endif /* CK_F_PR_INC_32 */
820 
821 #ifndef CK_F_PR_INC_32_ZERO
822 #define CK_F_PR_INC_32_ZERO
823 CK_PR_UNARY_Z_S(inc, 32, uint32_t, +, UINT32_MAX)
824 #else
825 CK_PR_UNARY_Z_STUB(inc, 32, uint32_t)
826 #endif /* CK_F_PR_INC_32_ZERO */
827 
828 #ifndef CK_F_PR_DEC_32
829 #define CK_F_PR_DEC_32
830 CK_PR_UNARY_S(dec, sub, 32, uint32_t)
831 #endif /* CK_F_PR_DEC_32 */
832 
833 #ifndef CK_F_PR_DEC_32_ZERO
834 #define CK_F_PR_DEC_32_ZERO
835 CK_PR_UNARY_Z_S(dec, 32, uint32_t, -, 1)
836 #else
837 CK_PR_UNARY_Z_STUB(dec, 32, uint32_t)
838 #endif /* CK_F_PR_DEC_32_ZERO */
839 
840 #endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */
841 
842 #if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)
843 
844 #ifndef CK_F_PR_INC_16
845 #define CK_F_PR_INC_16
846 CK_PR_UNARY_S(inc, add, 16, uint16_t)
847 #endif /* CK_F_PR_INC_16 */
848 
849 #ifndef CK_F_PR_INC_16_ZERO
850 #define CK_F_PR_INC_16_ZERO
851 CK_PR_UNARY_Z_S(inc, 16, uint16_t, +, UINT16_MAX)
852 #else
853 CK_PR_UNARY_Z_STUB(inc, 16, uint16_t)
854 #endif /* CK_F_PR_INC_16_ZERO */
855 
856 #ifndef CK_F_PR_DEC_16
857 #define CK_F_PR_DEC_16
858 CK_PR_UNARY_S(dec, sub, 16, uint16_t)
859 #endif /* CK_F_PR_DEC_16 */
860 
861 #ifndef CK_F_PR_DEC_16_ZERO
862 #define CK_F_PR_DEC_16_ZERO
863 CK_PR_UNARY_Z_S(dec, 16, uint16_t, -, 1)
864 #else
865 CK_PR_UNARY_Z_STUB(dec, 16, uint16_t)
866 #endif /* CK_F_PR_DEC_16_ZERO */
867 
868 #endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */
869 
870 #if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)
871 
872 #ifndef CK_F_PR_INC_8
873 #define CK_F_PR_INC_8
874 CK_PR_UNARY_S(inc, add, 8, uint8_t)
875 #endif /* CK_F_PR_INC_8 */
876 
877 #ifndef CK_F_PR_INC_8_ZERO
878 #define CK_F_PR_INC_8_ZERO
879 CK_PR_UNARY_Z_S(inc, 8, uint8_t, +, UINT8_MAX)
880 #else
881 CK_PR_UNARY_Z_STUB(inc, 8, uint8_t)
882 #endif /* CK_F_PR_INC_8_ZERO */
883 
884 #ifndef CK_F_PR_DEC_8
885 #define CK_F_PR_DEC_8
886 CK_PR_UNARY_S(dec, sub, 8, uint8_t)
887 #endif /* CK_F_PR_DEC_8 */
888 
889 #ifndef CK_F_PR_DEC_8_ZERO
890 #define CK_F_PR_DEC_8_ZERO
891 CK_PR_UNARY_Z_S(dec, 8, uint8_t, -, 1)
892 #else
893 CK_PR_UNARY_Z_STUB(dec, 8, uint8_t)
894 #endif /* CK_F_PR_DEC_8_ZERO */
895 
896 #endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */
897 
898 #undef CK_PR_UNARY_Z_S
899 #undef CK_PR_UNARY_S
900 #undef CK_PR_UNARY_Z
901 #undef CK_PR_UNARY
902 
903 #define CK_PR_N(K, S, M, T, P, C)					\
904 	CK_CC_INLINE static void					\
905 	ck_pr_##K##_##S(M *target)					\
906 	{								\
907 		T previous;						\
908 		C punt;							\
909 		punt = (C)ck_pr_md_load_##S(target);			\
910 		previous = (T)punt;					\
911 		while (ck_pr_cas_##S##_value(target,			\
912 					     (C)previous,		\
913 					     (C)(P previous),		\
914 					     &previous) == false)	\
915 			ck_pr_stall();					\
916 									\
917 		return;							\
918 	}
919 
920 #define CK_PR_N_Z(S, M, T, C)						\
921 	CK_CC_INLINE static void					\
922 	ck_pr_neg_##S##_zero(M *target, bool *zero)			\
923 	{								\
924 		T previous;						\
925 		C punt;							\
926 		punt = (C)ck_pr_md_load_##S(target);			\
927 		previous = (T)punt;					\
928 		while (ck_pr_cas_##S##_value(target,			\
929 					     (C)previous,		\
930 					     (C)(-previous),		\
931 					     &previous) == false)	\
932 			ck_pr_stall();					\
933 									\
934 		*zero = previous == 0;					\
935 		return;							\
936 	}
937 
938 #define CK_PR_N_S(K, S, M, P)	CK_PR_N(K, S, M, M, P, M)
939 #define CK_PR_N_Z_S(S, M) 	CK_PR_N_Z(S, M, M, M)
940 
941 #if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)
942 
943 #ifndef CK_F_PR_NOT_CHAR
944 #define CK_F_PR_NOT_CHAR
945 CK_PR_N_S(not, char, char, ~)
946 #endif /* CK_F_PR_NOT_CHAR */
947 
948 #ifndef CK_F_PR_NEG_CHAR
949 #define CK_F_PR_NEG_CHAR
950 CK_PR_N_S(neg, char, char, -)
951 #endif /* CK_F_PR_NEG_CHAR */
952 
953 #ifndef CK_F_PR_NEG_CHAR_ZERO
954 #define CK_F_PR_NEG_CHAR_ZERO
955 CK_PR_N_Z_S(char, char)
956 #endif /* CK_F_PR_NEG_CHAR_ZERO */
957 
958 #endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */
959 
960 #if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)
961 
962 #ifndef CK_F_PR_NOT_INT
963 #define CK_F_PR_NOT_INT
964 CK_PR_N_S(not, int, int, ~)
965 #endif /* CK_F_PR_NOT_INT */
966 
967 #ifndef CK_F_PR_NEG_INT
968 #define CK_F_PR_NEG_INT
969 CK_PR_N_S(neg, int, int, -)
970 #endif /* CK_F_PR_NEG_INT */
971 
972 #ifndef CK_F_PR_NEG_INT_ZERO
973 #define CK_F_PR_NEG_INT_ZERO
974 CK_PR_N_Z_S(int, int)
975 #endif /* CK_F_PR_NEG_INT_ZERO */
976 
977 #endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */
978 
979 #if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \
980 	    !defined(CK_PR_DISABLE_DOUBLE)
981 
982 #ifndef CK_F_PR_NEG_DOUBLE
983 #define CK_F_PR_NEG_DOUBLE
984 CK_PR_N_S(neg, double, double, -)
985 #endif /* CK_F_PR_NEG_DOUBLE */
986 
987 #endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */
988 
989 #if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)
990 
991 #ifndef CK_F_PR_NOT_UINT
992 #define CK_F_PR_NOT_UINT
993 CK_PR_N_S(not, uint, unsigned int, ~)
994 #endif /* CK_F_PR_NOT_UINT */
995 
996 #ifndef CK_F_PR_NEG_UINT
997 #define CK_F_PR_NEG_UINT
998 CK_PR_N_S(neg, uint, unsigned int, -)
999 #endif /* CK_F_PR_NEG_UINT */
1000 
1001 #ifndef CK_F_PR_NEG_UINT_ZERO
1002 #define CK_F_PR_NEG_UINT_ZERO
1003 CK_PR_N_Z_S(uint, unsigned int)
1004 #endif /* CK_F_PR_NEG_UINT_ZERO */
1005 
1006 #endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */
1007 
1008 #if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)
1009 
1010 #ifndef CK_F_PR_NOT_PTR
1011 #define CK_F_PR_NOT_PTR
1012 CK_PR_N(not, ptr, void, uintptr_t, ~, void *)
1013 #endif /* CK_F_PR_NOT_PTR */
1014 
1015 #ifndef CK_F_PR_NEG_PTR
1016 #define CK_F_PR_NEG_PTR
1017 CK_PR_N(neg, ptr, void, uintptr_t, -, void *)
1018 #endif /* CK_F_PR_NEG_PTR */
1019 
1020 #ifndef CK_F_PR_NEG_PTR_ZERO
1021 #define CK_F_PR_NEG_PTR_ZERO
1022 CK_PR_N_Z(ptr, void, uintptr_t, void *)
1023 #endif /* CK_F_PR_NEG_PTR_ZERO */
1024 
1025 #endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */
1026 
1027 #if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)
1028 
1029 #ifndef CK_F_PR_NOT_64
1030 #define CK_F_PR_NOT_64
1031 CK_PR_N_S(not, 64, uint64_t, ~)
1032 #endif /* CK_F_PR_NOT_64 */
1033 
1034 #ifndef CK_F_PR_NEG_64
1035 #define CK_F_PR_NEG_64
1036 CK_PR_N_S(neg, 64, uint64_t, -)
1037 #endif /* CK_F_PR_NEG_64 */
1038 
1039 #ifndef CK_F_PR_NEG_64_ZERO
1040 #define CK_F_PR_NEG_64_ZERO
1041 CK_PR_N_Z_S(64, uint64_t)
1042 #endif /* CK_F_PR_NEG_64_ZERO */
1043 
1044 #endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */
1045 
1046 #if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)
1047 
1048 #ifndef CK_F_PR_NOT_32
1049 #define CK_F_PR_NOT_32
1050 CK_PR_N_S(not, 32, uint32_t, ~)
1051 #endif /* CK_F_PR_NOT_32 */
1052 
1053 #ifndef CK_F_PR_NEG_32
1054 #define CK_F_PR_NEG_32
1055 CK_PR_N_S(neg, 32, uint32_t, -)
1056 #endif /* CK_F_PR_NEG_32 */
1057 
1058 #ifndef CK_F_PR_NEG_32_ZERO
1059 #define CK_F_PR_NEG_32_ZERO
1060 CK_PR_N_Z_S(32, uint32_t)
1061 #endif /* CK_F_PR_NEG_32_ZERO */
1062 
1063 #endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */
1064 
1065 #if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)
1066 
1067 #ifndef CK_F_PR_NOT_16
1068 #define CK_F_PR_NOT_16
1069 CK_PR_N_S(not, 16, uint16_t, ~)
1070 #endif /* CK_F_PR_NOT_16 */
1071 
1072 #ifndef CK_F_PR_NEG_16
1073 #define CK_F_PR_NEG_16
1074 CK_PR_N_S(neg, 16, uint16_t, -)
1075 #endif /* CK_F_PR_NEG_16 */
1076 
1077 #ifndef CK_F_PR_NEG_16_ZERO
1078 #define CK_F_PR_NEG_16_ZERO
1079 CK_PR_N_Z_S(16, uint16_t)
1080 #endif /* CK_F_PR_NEG_16_ZERO */
1081 
1082 #endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */
1083 
1084 #if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)
1085 
1086 #ifndef CK_F_PR_NOT_8
1087 #define CK_F_PR_NOT_8
1088 CK_PR_N_S(not, 8, uint8_t, ~)
1089 #endif /* CK_F_PR_NOT_8 */
1090 
1091 #ifndef CK_F_PR_NEG_8
1092 #define CK_F_PR_NEG_8
1093 CK_PR_N_S(neg, 8, uint8_t, -)
1094 #endif /* CK_F_PR_NEG_8 */
1095 
1096 #ifndef CK_F_PR_NEG_8_ZERO
1097 #define CK_F_PR_NEG_8_ZERO
1098 CK_PR_N_Z_S(8, uint8_t)
1099 #endif /* CK_F_PR_NEG_8_ZERO */
1100 
1101 #endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */
1102 
1103 #undef CK_PR_N_Z_S
1104 #undef CK_PR_N_S
1105 #undef CK_PR_N_Z
1106 #undef CK_PR_N
1107 
1108 #define CK_PR_FAA(S, M, T, C)						\
1109 	CK_CC_INLINE static C						\
1110 	ck_pr_faa_##S(M *target, T delta)				\
1111 	{								\
1112 		T previous;						\
1113 		C punt;							\
1114 		punt = (C)ck_pr_md_load_##S(target);			\
1115 		previous = (T)punt;					\
1116 		while (ck_pr_cas_##S##_value(target,			\
1117 					     (C)previous,		\
1118 					     (C)(previous + delta),	\
1119 					     &previous) == false)	\
1120 			ck_pr_stall();					\
1121 									\
1122 		return ((C)previous);					\
1123 	}
1124 
1125 #define CK_PR_FAS(S, M, C)						\
1126 	CK_CC_INLINE static C						\
1127 	ck_pr_fas_##S(M *target, C update)				\
1128 	{								\
1129 		C previous;						\
1130 		previous = ck_pr_md_load_##S(target);			\
1131 		while (ck_pr_cas_##S##_value(target,			\
1132 					     previous,			\
1133 					     update,			\
1134 					     &previous) == false)	\
1135 			ck_pr_stall();					\
1136 									\
1137 		return (previous);					\
1138 	}
1139 
1140 #define CK_PR_FAA_S(S, M) CK_PR_FAA(S, M, M, M)
1141 #define CK_PR_FAS_S(S, M) CK_PR_FAS(S, M, M)
1142 
1143 #if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)
1144 
1145 #ifndef CK_F_PR_FAA_CHAR
1146 #define CK_F_PR_FAA_CHAR
1147 CK_PR_FAA_S(char, char)
1148 #endif /* CK_F_PR_FAA_CHAR */
1149 
1150 #ifndef CK_F_PR_FAS_CHAR
1151 #define CK_F_PR_FAS_CHAR
1152 CK_PR_FAS_S(char, char)
1153 #endif /* CK_F_PR_FAS_CHAR */
1154 
1155 #endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */
1156 
1157 #if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)
1158 
1159 #ifndef CK_F_PR_FAA_INT
1160 #define CK_F_PR_FAA_INT
1161 CK_PR_FAA_S(int, int)
1162 #endif /* CK_F_PR_FAA_INT */
1163 
1164 #ifndef CK_F_PR_FAS_INT
1165 #define CK_F_PR_FAS_INT
1166 CK_PR_FAS_S(int, int)
1167 #endif /* CK_F_PR_FAS_INT */
1168 
1169 #endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */
1170 
1171 #if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \
1172 	    !defined(CK_PR_DISABLE_DOUBLE)
1173 
1174 #ifndef CK_F_PR_FAA_DOUBLE
1175 #define CK_F_PR_FAA_DOUBLE
1176 CK_PR_FAA_S(double, double)
1177 #endif /* CK_F_PR_FAA_DOUBLE */
1178 
1179 #ifndef CK_F_PR_FAS_DOUBLE
1180 #define CK_F_PR_FAS_DOUBLE
1181 CK_PR_FAS_S(double, double)
1182 #endif /* CK_F_PR_FAS_DOUBLE */
1183 
1184 #endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */
1185 
1186 #if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)
1187 
1188 #ifndef CK_F_PR_FAA_UINT
1189 #define CK_F_PR_FAA_UINT
1190 CK_PR_FAA_S(uint, unsigned int)
1191 #endif /* CK_F_PR_FAA_UINT */
1192 
1193 #ifndef CK_F_PR_FAS_UINT
1194 #define CK_F_PR_FAS_UINT
1195 CK_PR_FAS_S(uint, unsigned int)
1196 #endif /* CK_F_PR_FAS_UINT */
1197 
1198 #endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */
1199 
1200 #if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)
1201 
1202 #ifndef CK_F_PR_FAA_PTR
1203 #define CK_F_PR_FAA_PTR
1204 CK_PR_FAA(ptr, void, uintptr_t, void *)
1205 #endif /* CK_F_PR_FAA_PTR */
1206 
1207 #ifndef CK_F_PR_FAS_PTR
1208 #define CK_F_PR_FAS_PTR
1209 CK_PR_FAS(ptr, void, void *)
1210 #endif /* CK_F_PR_FAS_PTR */
1211 
1212 #endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */
1213 
1214 #if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)
1215 
1216 #ifndef CK_F_PR_FAA_64
1217 #define CK_F_PR_FAA_64
1218 CK_PR_FAA_S(64, uint64_t)
1219 #endif /* CK_F_PR_FAA_64 */
1220 
1221 #ifndef CK_F_PR_FAS_64
1222 #define CK_F_PR_FAS_64
1223 CK_PR_FAS_S(64, uint64_t)
1224 #endif /* CK_F_PR_FAS_64 */
1225 
1226 #endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */
1227 
1228 #if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)
1229 
1230 #ifndef CK_F_PR_FAA_32
1231 #define CK_F_PR_FAA_32
1232 CK_PR_FAA_S(32, uint32_t)
1233 #endif /* CK_F_PR_FAA_32 */
1234 
1235 #ifndef CK_F_PR_FAS_32
1236 #define CK_F_PR_FAS_32
1237 CK_PR_FAS_S(32, uint32_t)
1238 #endif /* CK_F_PR_FAS_32 */
1239 
1240 #endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */
1241 
1242 #if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)
1243 
1244 #ifndef CK_F_PR_FAA_16
1245 #define CK_F_PR_FAA_16
1246 CK_PR_FAA_S(16, uint16_t)
1247 #endif /* CK_F_PR_FAA_16 */
1248 
1249 #ifndef CK_F_PR_FAS_16
1250 #define CK_F_PR_FAS_16
1251 CK_PR_FAS_S(16, uint16_t)
1252 #endif /* CK_F_PR_FAS_16 */
1253 
1254 #endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */
1255 
1256 #if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)
1257 
1258 #ifndef CK_F_PR_FAA_8
1259 #define CK_F_PR_FAA_8
1260 CK_PR_FAA_S(8, uint8_t)
1261 #endif /* CK_F_PR_FAA_8 */
1262 
1263 #ifndef CK_F_PR_FAS_8
1264 #define CK_F_PR_FAS_8
1265 CK_PR_FAS_S(8, uint8_t)
1266 #endif /* CK_F_PR_FAS_8 */
1267 
1268 #endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */
1269 
1270 #undef CK_PR_FAA_S
1271 #undef CK_PR_FAS_S
1272 #undef CK_PR_FAA
1273 #undef CK_PR_FAS
1274 
1275 #endif /* CK_PR_H */
1276