16fc729afSOlivier Houchard /* $NetBSD: atomic.h,v 1.1 2002/10/19 12:22:34 bsh Exp $ */
26fc729afSOlivier Houchard
3d8315c79SWarner Losh /*-
4af3dc4a7SPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause
5af3dc4a7SPedro F. Giffuni *
66fc729afSOlivier Houchard * Copyright (C) 2003-2004 Olivier Houchard
76fc729afSOlivier Houchard * Copyright (C) 1994-1997 Mark Brinicombe
86fc729afSOlivier Houchard * Copyright (C) 1994 Brini
96fc729afSOlivier Houchard * All rights reserved.
106fc729afSOlivier Houchard *
116fc729afSOlivier Houchard * This code is derived from software written for Brini by Mark Brinicombe
126fc729afSOlivier Houchard *
136fc729afSOlivier Houchard * Redistribution and use in source and binary forms, with or without
146fc729afSOlivier Houchard * modification, are permitted provided that the following conditions
156fc729afSOlivier Houchard * are met:
166fc729afSOlivier Houchard * 1. Redistributions of source code must retain the above copyright
176fc729afSOlivier Houchard * notice, this list of conditions and the following disclaimer.
186fc729afSOlivier Houchard * 2. Redistributions in binary form must reproduce the above copyright
196fc729afSOlivier Houchard * notice, this list of conditions and the following disclaimer in the
206fc729afSOlivier Houchard * documentation and/or other materials provided with the distribution.
216fc729afSOlivier Houchard * 3. All advertising materials mentioning features or use of this software
226fc729afSOlivier Houchard * must display the following acknowledgement:
236fc729afSOlivier Houchard * This product includes software developed by Brini.
246fc729afSOlivier Houchard * 4. The name of Brini may not be used to endorse or promote products
256fc729afSOlivier Houchard * derived from this software without specific prior written permission.
266fc729afSOlivier Houchard *
276fc729afSOlivier Houchard * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
286fc729afSOlivier Houchard * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
296fc729afSOlivier Houchard * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
306fc729afSOlivier Houchard * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
316fc729afSOlivier Houchard * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
326fc729afSOlivier Houchard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
336fc729afSOlivier Houchard * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
346fc729afSOlivier Houchard * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
356fc729afSOlivier Houchard * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
366fc729afSOlivier Houchard * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
376fc729afSOlivier Houchard */
386fc729afSOlivier Houchard
396fc729afSOlivier Houchard #ifndef _MACHINE_ATOMIC_H_
406fc729afSOlivier Houchard #define _MACHINE_ATOMIC_H_
416fc729afSOlivier Houchard
4230d4f9e8SKonstantin Belousov #include <sys/atomic_common.h>
4330d4f9e8SKonstantin Belousov
4404b15329SAndrew Turner #define isb() __asm __volatile("isb" : : : "memory")
4504b15329SAndrew Turner #define dsb() __asm __volatile("dsb" : : : "memory")
4604b15329SAndrew Turner #define dmb() __asm __volatile("dmb" : : : "memory")
4704b15329SAndrew Turner
4804b15329SAndrew Turner #define mb() dmb()
4904b15329SAndrew Turner #define wmb() dmb()
5004b15329SAndrew Turner #define rmb() dmb()
5104b15329SAndrew Turner
5204b15329SAndrew Turner #define ARM_HAVE_ATOMIC64
5304b15329SAndrew Turner
5404b15329SAndrew Turner #define ATOMIC_ACQ_REL_LONG(NAME) \
5504b15329SAndrew Turner static __inline void \
5604b15329SAndrew Turner atomic_##NAME##_acq_long(__volatile u_long *p, u_long v) \
5704b15329SAndrew Turner { \
5804b15329SAndrew Turner atomic_##NAME##_long(p, v); \
5904b15329SAndrew Turner dmb(); \
6004b15329SAndrew Turner } \
6104b15329SAndrew Turner \
6204b15329SAndrew Turner static __inline void \
6304b15329SAndrew Turner atomic_##NAME##_rel_long(__volatile u_long *p, u_long v) \
6404b15329SAndrew Turner { \
6504b15329SAndrew Turner dmb(); \
6604b15329SAndrew Turner atomic_##NAME##_long(p, v); \
6704b15329SAndrew Turner }
6804b15329SAndrew Turner
6904b15329SAndrew Turner #define ATOMIC_ACQ_REL(NAME, WIDTH) \
7004b15329SAndrew Turner static __inline void \
7104b15329SAndrew Turner atomic_##NAME##_acq_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\
7204b15329SAndrew Turner { \
7304b15329SAndrew Turner atomic_##NAME##_##WIDTH(p, v); \
7404b15329SAndrew Turner dmb(); \
7504b15329SAndrew Turner } \
7604b15329SAndrew Turner \
7704b15329SAndrew Turner static __inline void \
7804b15329SAndrew Turner atomic_##NAME##_rel_##WIDTH(__volatile uint##WIDTH##_t *p, uint##WIDTH##_t v)\
7904b15329SAndrew Turner { \
8004b15329SAndrew Turner dmb(); \
8104b15329SAndrew Turner atomic_##NAME##_##WIDTH(p, v); \
8204b15329SAndrew Turner }
8304b15329SAndrew Turner
8404b15329SAndrew Turner static __inline void
atomic_add_32(volatile uint32_t * p,uint32_t val)8504b15329SAndrew Turner atomic_add_32(volatile uint32_t *p, uint32_t val)
8604b15329SAndrew Turner {
8704b15329SAndrew Turner uint32_t tmp = 0, tmp2 = 0;
8804b15329SAndrew Turner
8904b15329SAndrew Turner __asm __volatile(
9004b15329SAndrew Turner "1: ldrex %0, [%2] \n"
9104b15329SAndrew Turner " add %0, %0, %3 \n"
9204b15329SAndrew Turner " strex %1, %0, [%2] \n"
9304b15329SAndrew Turner " cmp %1, #0 \n"
9404b15329SAndrew Turner " it ne \n"
9504b15329SAndrew Turner " bne 1b \n"
9604b15329SAndrew Turner : "=&r" (tmp), "+r" (tmp2)
9704b15329SAndrew Turner ,"+r" (p), "+r" (val) : : "cc", "memory");
9804b15329SAndrew Turner }
9904b15329SAndrew Turner
10004b15329SAndrew Turner static __inline void
atomic_add_64(volatile uint64_t * p,uint64_t val)10104b15329SAndrew Turner atomic_add_64(volatile uint64_t *p, uint64_t val)
10204b15329SAndrew Turner {
10304b15329SAndrew Turner uint64_t tmp;
10404b15329SAndrew Turner uint32_t exflag;
10504b15329SAndrew Turner
10604b15329SAndrew Turner __asm __volatile(
10704b15329SAndrew Turner "1: \n"
10804b15329SAndrew Turner " ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n"
10904b15329SAndrew Turner " adds %Q[tmp], %Q[val] \n"
11004b15329SAndrew Turner " adc %R[tmp], %R[tmp], %R[val] \n"
11104b15329SAndrew Turner " strexd %[exf], %Q[tmp], %R[tmp], [%[ptr]] \n"
11204b15329SAndrew Turner " teq %[exf], #0 \n"
11304b15329SAndrew Turner " it ne \n"
11404b15329SAndrew Turner " bne 1b \n"
11504b15329SAndrew Turner : [exf] "=&r" (exflag),
11604b15329SAndrew Turner [tmp] "=&r" (tmp)
11704b15329SAndrew Turner : [ptr] "r" (p),
11804b15329SAndrew Turner [val] "r" (val)
11904b15329SAndrew Turner : "cc", "memory");
12004b15329SAndrew Turner }
12104b15329SAndrew Turner
12204b15329SAndrew Turner static __inline void
atomic_add_long(volatile u_long * p,u_long val)12304b15329SAndrew Turner atomic_add_long(volatile u_long *p, u_long val)
12404b15329SAndrew Turner {
12504b15329SAndrew Turner
12604b15329SAndrew Turner atomic_add_32((volatile uint32_t *)p, val);
12704b15329SAndrew Turner }
12804b15329SAndrew Turner
12904b15329SAndrew Turner ATOMIC_ACQ_REL(add, 32)
13004b15329SAndrew Turner ATOMIC_ACQ_REL(add, 64)
ATOMIC_ACQ_REL_LONG(add)13104b15329SAndrew Turner ATOMIC_ACQ_REL_LONG(add)
13204b15329SAndrew Turner
13304b15329SAndrew Turner static __inline void
13404b15329SAndrew Turner atomic_clear_32(volatile uint32_t *address, uint32_t setmask)
13504b15329SAndrew Turner {
13604b15329SAndrew Turner uint32_t tmp = 0, tmp2 = 0;
13704b15329SAndrew Turner
13804b15329SAndrew Turner __asm __volatile(
13904b15329SAndrew Turner "1: ldrex %0, [%2] \n"
14004b15329SAndrew Turner " bic %0, %0, %3 \n"
14104b15329SAndrew Turner " strex %1, %0, [%2] \n"
14204b15329SAndrew Turner " cmp %1, #0 \n"
14304b15329SAndrew Turner " it ne \n"
14404b15329SAndrew Turner " bne 1b \n"
14504b15329SAndrew Turner : "=&r" (tmp), "+r" (tmp2), "+r" (address), "+r" (setmask)
14604b15329SAndrew Turner : : "cc", "memory");
14704b15329SAndrew Turner }
14804b15329SAndrew Turner
14904b15329SAndrew Turner static __inline void
atomic_clear_64(volatile uint64_t * p,uint64_t val)15004b15329SAndrew Turner atomic_clear_64(volatile uint64_t *p, uint64_t val)
15104b15329SAndrew Turner {
15204b15329SAndrew Turner uint64_t tmp;
15304b15329SAndrew Turner uint32_t exflag;
15404b15329SAndrew Turner
15504b15329SAndrew Turner __asm __volatile(
15604b15329SAndrew Turner "1: \n"
15704b15329SAndrew Turner " ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n"
15804b15329SAndrew Turner " bic %Q[tmp], %Q[val] \n"
15904b15329SAndrew Turner " bic %R[tmp], %R[val] \n"
16004b15329SAndrew Turner " strexd %[exf], %Q[tmp], %R[tmp], [%[ptr]] \n"
16104b15329SAndrew Turner " teq %[exf], #0 \n"
16204b15329SAndrew Turner " it ne \n"
16304b15329SAndrew Turner " bne 1b \n"
16404b15329SAndrew Turner : [exf] "=&r" (exflag),
16504b15329SAndrew Turner [tmp] "=&r" (tmp)
16604b15329SAndrew Turner : [ptr] "r" (p),
16704b15329SAndrew Turner [val] "r" (val)
16804b15329SAndrew Turner : "cc", "memory");
16904b15329SAndrew Turner }
17004b15329SAndrew Turner
17104b15329SAndrew Turner static __inline void
atomic_clear_long(volatile u_long * address,u_long setmask)17204b15329SAndrew Turner atomic_clear_long(volatile u_long *address, u_long setmask)
17304b15329SAndrew Turner {
17404b15329SAndrew Turner
17504b15329SAndrew Turner atomic_clear_32((volatile uint32_t *)address, setmask);
17604b15329SAndrew Turner }
17704b15329SAndrew Turner
17804b15329SAndrew Turner ATOMIC_ACQ_REL(clear, 32)
17904b15329SAndrew Turner ATOMIC_ACQ_REL(clear, 64)
ATOMIC_ACQ_REL_LONG(clear)18004b15329SAndrew Turner ATOMIC_ACQ_REL_LONG(clear)
18104b15329SAndrew Turner
18204b15329SAndrew Turner #define ATOMIC_FCMPSET_CODE(RET, TYPE, SUF) \
18304b15329SAndrew Turner { \
18404b15329SAndrew Turner TYPE tmp; \
18504b15329SAndrew Turner \
18604b15329SAndrew Turner __asm __volatile( \
18704b15329SAndrew Turner "1: ldrex" SUF " %[tmp], [%[ptr]] \n" \
18804b15329SAndrew Turner " ldr" SUF " %[ret], [%[oldv]] \n" \
18904b15329SAndrew Turner " teq %[tmp], %[ret] \n" \
19004b15329SAndrew Turner " ittee ne \n" \
19104b15329SAndrew Turner " str" SUF "ne %[tmp], [%[oldv]] \n" \
19204b15329SAndrew Turner " movne %[ret], #0 \n" \
19304b15329SAndrew Turner " strex" SUF "eq %[ret], %[newv], [%[ptr]] \n" \
19404b15329SAndrew Turner " eorseq %[ret], #1 \n" \
19504b15329SAndrew Turner " beq 1b \n" \
19604b15329SAndrew Turner : [ret] "=&r" (RET), \
19704b15329SAndrew Turner [tmp] "=&r" (tmp) \
19804b15329SAndrew Turner : [ptr] "r" (_ptr), \
19904b15329SAndrew Turner [oldv] "r" (_old), \
20004b15329SAndrew Turner [newv] "r" (_new) \
20104b15329SAndrew Turner : "cc", "memory"); \
20204b15329SAndrew Turner }
20304b15329SAndrew Turner
20404b15329SAndrew Turner #define ATOMIC_FCMPSET_CODE64(RET) \
20504b15329SAndrew Turner { \
20604b15329SAndrew Turner uint64_t cmp, tmp; \
20704b15329SAndrew Turner \
20804b15329SAndrew Turner __asm __volatile( \
20904b15329SAndrew Turner "1: ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n" \
21004b15329SAndrew Turner " ldrd %Q[cmp], %R[cmp], [%[oldv]] \n" \
21104b15329SAndrew Turner " teq %Q[tmp], %Q[cmp] \n" \
21204b15329SAndrew Turner " it eq \n" \
21304b15329SAndrew Turner " teqeq %R[tmp], %R[cmp] \n" \
21404b15329SAndrew Turner " ittee ne \n" \
21504b15329SAndrew Turner " movne %[ret], #0 \n" \
21604b15329SAndrew Turner " strdne %[cmp], [%[oldv]] \n" \
21704b15329SAndrew Turner " strexdeq %[ret], %Q[newv], %R[newv], [%[ptr]] \n" \
21804b15329SAndrew Turner " eorseq %[ret], #1 \n" \
21904b15329SAndrew Turner " beq 1b \n" \
22004b15329SAndrew Turner : [ret] "=&r" (RET), \
22104b15329SAndrew Turner [cmp] "=&r" (cmp), \
22204b15329SAndrew Turner [tmp] "=&r" (tmp) \
22304b15329SAndrew Turner : [ptr] "r" (_ptr), \
22404b15329SAndrew Turner [oldv] "r" (_old), \
22504b15329SAndrew Turner [newv] "r" (_new) \
22604b15329SAndrew Turner : "cc", "memory"); \
22704b15329SAndrew Turner }
22804b15329SAndrew Turner
22904b15329SAndrew Turner static __inline int
23004b15329SAndrew Turner atomic_fcmpset_8(volatile uint8_t *_ptr, uint8_t *_old, uint8_t _new)
23104b15329SAndrew Turner {
23204b15329SAndrew Turner int ret;
23304b15329SAndrew Turner
23404b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint8_t, "b");
23504b15329SAndrew Turner return (ret);
23604b15329SAndrew Turner }
23704b15329SAndrew Turner #define atomic_fcmpset_8 atomic_fcmpset_8
23804b15329SAndrew Turner
23904b15329SAndrew Turner static __inline int
atomic_fcmpset_acq_8(volatile uint8_t * _ptr,uint8_t * _old,uint8_t _new)24004b15329SAndrew Turner atomic_fcmpset_acq_8(volatile uint8_t *_ptr, uint8_t *_old, uint8_t _new)
24104b15329SAndrew Turner {
24204b15329SAndrew Turner int ret;
24304b15329SAndrew Turner
24404b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint8_t, "b");
24504b15329SAndrew Turner dmb();
24604b15329SAndrew Turner return (ret);
24704b15329SAndrew Turner }
24804b15329SAndrew Turner
24904b15329SAndrew Turner static __inline int
atomic_fcmpset_rel_8(volatile uint8_t * _ptr,uint8_t * _old,uint8_t _new)25004b15329SAndrew Turner atomic_fcmpset_rel_8(volatile uint8_t *_ptr, uint8_t *_old, uint8_t _new)
25104b15329SAndrew Turner {
25204b15329SAndrew Turner int ret;
25304b15329SAndrew Turner
25404b15329SAndrew Turner dmb();
25504b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint8_t, "b");
25604b15329SAndrew Turner return (ret);
25704b15329SAndrew Turner }
25804b15329SAndrew Turner
25904b15329SAndrew Turner static __inline int
atomic_fcmpset_16(volatile uint16_t * _ptr,uint16_t * _old,uint16_t _new)26004b15329SAndrew Turner atomic_fcmpset_16(volatile uint16_t *_ptr, uint16_t *_old, uint16_t _new)
26104b15329SAndrew Turner {
26204b15329SAndrew Turner int ret;
26304b15329SAndrew Turner
26404b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint16_t, "h");
26504b15329SAndrew Turner return (ret);
26604b15329SAndrew Turner }
26704b15329SAndrew Turner #define atomic_fcmpset_16 atomic_fcmpset_16
26804b15329SAndrew Turner
26904b15329SAndrew Turner static __inline int
atomic_fcmpset_acq_16(volatile uint16_t * _ptr,uint16_t * _old,uint16_t _new)27004b15329SAndrew Turner atomic_fcmpset_acq_16(volatile uint16_t *_ptr, uint16_t *_old, uint16_t _new)
27104b15329SAndrew Turner {
27204b15329SAndrew Turner int ret;
27304b15329SAndrew Turner
27404b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint16_t, "h");
27504b15329SAndrew Turner dmb();
27604b15329SAndrew Turner return (ret);
27704b15329SAndrew Turner }
27804b15329SAndrew Turner
27904b15329SAndrew Turner static __inline int
atomic_fcmpset_rel_16(volatile uint16_t * _ptr,uint16_t * _old,uint16_t _new)28004b15329SAndrew Turner atomic_fcmpset_rel_16(volatile uint16_t *_ptr, uint16_t *_old, uint16_t _new)
28104b15329SAndrew Turner {
28204b15329SAndrew Turner int ret;
28304b15329SAndrew Turner
28404b15329SAndrew Turner dmb();
28504b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint16_t, "h");
28604b15329SAndrew Turner return (ret);
28704b15329SAndrew Turner }
28804b15329SAndrew Turner
28904b15329SAndrew Turner static __inline int
atomic_fcmpset_32(volatile uint32_t * _ptr,uint32_t * _old,uint32_t _new)29004b15329SAndrew Turner atomic_fcmpset_32(volatile uint32_t *_ptr, uint32_t *_old, uint32_t _new)
29104b15329SAndrew Turner {
29204b15329SAndrew Turner int ret;
29304b15329SAndrew Turner
29404b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint32_t, "");
29504b15329SAndrew Turner return (ret);
29604b15329SAndrew Turner }
29704b15329SAndrew Turner
29804b15329SAndrew Turner static __inline int
atomic_fcmpset_acq_32(volatile uint32_t * _ptr,uint32_t * _old,uint32_t _new)29904b15329SAndrew Turner atomic_fcmpset_acq_32(volatile uint32_t *_ptr, uint32_t *_old, uint32_t _new)
30004b15329SAndrew Turner {
30104b15329SAndrew Turner int ret;
30204b15329SAndrew Turner
30304b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint32_t, "");
30404b15329SAndrew Turner dmb();
30504b15329SAndrew Turner return (ret);
30604b15329SAndrew Turner }
30704b15329SAndrew Turner
30804b15329SAndrew Turner static __inline int
atomic_fcmpset_rel_32(volatile uint32_t * _ptr,uint32_t * _old,uint32_t _new)30904b15329SAndrew Turner atomic_fcmpset_rel_32(volatile uint32_t *_ptr, uint32_t *_old, uint32_t _new)
31004b15329SAndrew Turner {
31104b15329SAndrew Turner int ret;
31204b15329SAndrew Turner
31304b15329SAndrew Turner dmb();
31404b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, uint32_t, "");
31504b15329SAndrew Turner return (ret);
31604b15329SAndrew Turner }
31704b15329SAndrew Turner
31804b15329SAndrew Turner static __inline int
atomic_fcmpset_long(volatile u_long * _ptr,u_long * _old,u_long _new)31904b15329SAndrew Turner atomic_fcmpset_long(volatile u_long *_ptr, u_long *_old, u_long _new)
32004b15329SAndrew Turner {
32104b15329SAndrew Turner int ret;
32204b15329SAndrew Turner
32304b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, u_long, "");
32404b15329SAndrew Turner return (ret);
32504b15329SAndrew Turner }
32604b15329SAndrew Turner
32704b15329SAndrew Turner static __inline int
atomic_fcmpset_acq_long(volatile u_long * _ptr,u_long * _old,u_long _new)32804b15329SAndrew Turner atomic_fcmpset_acq_long(volatile u_long *_ptr, u_long *_old, u_long _new)
32904b15329SAndrew Turner {
33004b15329SAndrew Turner int ret;
33104b15329SAndrew Turner
33204b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, u_long, "");
33304b15329SAndrew Turner dmb();
33404b15329SAndrew Turner return (ret);
33504b15329SAndrew Turner }
33604b15329SAndrew Turner
33704b15329SAndrew Turner static __inline int
atomic_fcmpset_rel_long(volatile u_long * _ptr,u_long * _old,u_long _new)33804b15329SAndrew Turner atomic_fcmpset_rel_long(volatile u_long *_ptr, u_long *_old, u_long _new)
33904b15329SAndrew Turner {
34004b15329SAndrew Turner int ret;
34104b15329SAndrew Turner
34204b15329SAndrew Turner dmb();
34304b15329SAndrew Turner ATOMIC_FCMPSET_CODE(ret, u_long, "");
34404b15329SAndrew Turner return (ret);
34504b15329SAndrew Turner }
34604b15329SAndrew Turner
34704b15329SAndrew Turner static __inline int
atomic_fcmpset_64(volatile uint64_t * _ptr,uint64_t * _old,uint64_t _new)34804b15329SAndrew Turner atomic_fcmpset_64(volatile uint64_t *_ptr, uint64_t *_old, uint64_t _new)
34904b15329SAndrew Turner {
35004b15329SAndrew Turner int ret;
35104b15329SAndrew Turner
35204b15329SAndrew Turner ATOMIC_FCMPSET_CODE64(ret);
35304b15329SAndrew Turner return (ret);
35404b15329SAndrew Turner }
35504b15329SAndrew Turner
35604b15329SAndrew Turner static __inline int
atomic_fcmpset_acq_64(volatile uint64_t * _ptr,uint64_t * _old,uint64_t _new)35704b15329SAndrew Turner atomic_fcmpset_acq_64(volatile uint64_t *_ptr, uint64_t *_old, uint64_t _new)
35804b15329SAndrew Turner {
35904b15329SAndrew Turner int ret;
36004b15329SAndrew Turner
36104b15329SAndrew Turner ATOMIC_FCMPSET_CODE64(ret);
36204b15329SAndrew Turner dmb();
36304b15329SAndrew Turner return (ret);
36404b15329SAndrew Turner }
36504b15329SAndrew Turner
36604b15329SAndrew Turner static __inline int
atomic_fcmpset_rel_64(volatile uint64_t * _ptr,uint64_t * _old,uint64_t _new)36704b15329SAndrew Turner atomic_fcmpset_rel_64(volatile uint64_t *_ptr, uint64_t *_old, uint64_t _new)
36804b15329SAndrew Turner {
36904b15329SAndrew Turner int ret;
37004b15329SAndrew Turner
37104b15329SAndrew Turner dmb();
37204b15329SAndrew Turner ATOMIC_FCMPSET_CODE64(ret);
37304b15329SAndrew Turner return (ret);
37404b15329SAndrew Turner }
37504b15329SAndrew Turner
37604b15329SAndrew Turner #define ATOMIC_CMPSET_CODE(RET, SUF) \
37704b15329SAndrew Turner { \
37804b15329SAndrew Turner __asm __volatile( \
37904b15329SAndrew Turner "1: ldrex" SUF " %[ret], [%[ptr]] \n" \
38004b15329SAndrew Turner " teq %[ret], %[oldv] \n" \
38104b15329SAndrew Turner " itee ne \n" \
38204b15329SAndrew Turner " movne %[ret], #0 \n" \
38304b15329SAndrew Turner " strex" SUF "eq %[ret], %[newv], [%[ptr]] \n" \
38404b15329SAndrew Turner " eorseq %[ret], #1 \n" \
38504b15329SAndrew Turner " beq 1b \n" \
38604b15329SAndrew Turner : [ret] "=&r" (RET) \
38704b15329SAndrew Turner : [ptr] "r" (_ptr), \
38804b15329SAndrew Turner [oldv] "r" (_old), \
38904b15329SAndrew Turner [newv] "r" (_new) \
39004b15329SAndrew Turner : "cc", "memory"); \
39104b15329SAndrew Turner }
39204b15329SAndrew Turner
39304b15329SAndrew Turner #define ATOMIC_CMPSET_CODE64(RET) \
39404b15329SAndrew Turner { \
39504b15329SAndrew Turner uint64_t tmp; \
39604b15329SAndrew Turner \
39704b15329SAndrew Turner __asm __volatile( \
39804b15329SAndrew Turner "1: ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n" \
39904b15329SAndrew Turner " teq %Q[tmp], %Q[oldv] \n" \
40004b15329SAndrew Turner " it eq \n" \
40104b15329SAndrew Turner " teqeq %R[tmp], %R[oldv] \n" \
40204b15329SAndrew Turner " itee ne \n" \
40304b15329SAndrew Turner " movne %[ret], #0 \n" \
40404b15329SAndrew Turner " strexdeq %[ret], %Q[newv], %R[newv], [%[ptr]] \n" \
40504b15329SAndrew Turner " eorseq %[ret], #1 \n" \
40604b15329SAndrew Turner " beq 1b \n" \
40704b15329SAndrew Turner : [ret] "=&r" (RET), \
40804b15329SAndrew Turner [tmp] "=&r" (tmp) \
40904b15329SAndrew Turner : [ptr] "r" (_ptr), \
41004b15329SAndrew Turner [oldv] "r" (_old), \
41104b15329SAndrew Turner [newv] "r" (_new) \
41204b15329SAndrew Turner : "cc", "memory"); \
41304b15329SAndrew Turner }
41404b15329SAndrew Turner
41504b15329SAndrew Turner static __inline int
atomic_cmpset_8(volatile uint8_t * _ptr,uint8_t _old,uint8_t _new)41604b15329SAndrew Turner atomic_cmpset_8(volatile uint8_t *_ptr, uint8_t _old, uint8_t _new)
41704b15329SAndrew Turner {
41804b15329SAndrew Turner int ret;
41904b15329SAndrew Turner
42004b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "b");
42104b15329SAndrew Turner return (ret);
42204b15329SAndrew Turner }
42304b15329SAndrew Turner #define atomic_cmpset_8 atomic_cmpset_8
42404b15329SAndrew Turner
42504b15329SAndrew Turner static __inline int
atomic_cmpset_acq_8(volatile uint8_t * _ptr,uint8_t _old,uint8_t _new)42604b15329SAndrew Turner atomic_cmpset_acq_8(volatile uint8_t *_ptr, uint8_t _old, uint8_t _new)
42704b15329SAndrew Turner {
42804b15329SAndrew Turner int ret;
42904b15329SAndrew Turner
43004b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "b");
43104b15329SAndrew Turner dmb();
43204b15329SAndrew Turner return (ret);
43304b15329SAndrew Turner }
43404b15329SAndrew Turner
43504b15329SAndrew Turner static __inline int
atomic_cmpset_rel_8(volatile uint8_t * _ptr,uint8_t _old,uint8_t _new)43604b15329SAndrew Turner atomic_cmpset_rel_8(volatile uint8_t *_ptr, uint8_t _old, uint8_t _new)
43704b15329SAndrew Turner {
43804b15329SAndrew Turner int ret;
43904b15329SAndrew Turner
44004b15329SAndrew Turner dmb();
44104b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "b");
44204b15329SAndrew Turner return (ret);
44304b15329SAndrew Turner }
44404b15329SAndrew Turner
44504b15329SAndrew Turner static __inline int
atomic_cmpset_16(volatile uint16_t * _ptr,uint16_t _old,uint16_t _new)44604b15329SAndrew Turner atomic_cmpset_16(volatile uint16_t *_ptr, uint16_t _old, uint16_t _new)
44704b15329SAndrew Turner {
44804b15329SAndrew Turner int ret;
44904b15329SAndrew Turner
45004b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "h");
45104b15329SAndrew Turner return (ret);
45204b15329SAndrew Turner }
45304b15329SAndrew Turner #define atomic_cmpset_16 atomic_cmpset_16
45404b15329SAndrew Turner
45504b15329SAndrew Turner static __inline int
atomic_cmpset_acq_16(volatile uint16_t * _ptr,uint16_t _old,uint16_t _new)45604b15329SAndrew Turner atomic_cmpset_acq_16(volatile uint16_t *_ptr, uint16_t _old, uint16_t _new)
45704b15329SAndrew Turner {
45804b15329SAndrew Turner int ret;
45904b15329SAndrew Turner
46004b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "h");
46104b15329SAndrew Turner dmb();
46204b15329SAndrew Turner return (ret);
46304b15329SAndrew Turner }
46404b15329SAndrew Turner
46504b15329SAndrew Turner static __inline int
atomic_cmpset_rel_16(volatile uint16_t * _ptr,uint16_t _old,uint16_t _new)46604b15329SAndrew Turner atomic_cmpset_rel_16(volatile uint16_t *_ptr, uint16_t _old, uint16_t _new)
46704b15329SAndrew Turner {
46804b15329SAndrew Turner int ret;
46904b15329SAndrew Turner
47004b15329SAndrew Turner dmb();
47104b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "h");
47204b15329SAndrew Turner return (ret);
47304b15329SAndrew Turner }
47404b15329SAndrew Turner
47504b15329SAndrew Turner static __inline int
atomic_cmpset_32(volatile uint32_t * _ptr,uint32_t _old,uint32_t _new)47604b15329SAndrew Turner atomic_cmpset_32(volatile uint32_t *_ptr, uint32_t _old, uint32_t _new)
47704b15329SAndrew Turner {
47804b15329SAndrew Turner int ret;
47904b15329SAndrew Turner
48004b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "");
48104b15329SAndrew Turner return (ret);
48204b15329SAndrew Turner }
48304b15329SAndrew Turner
48404b15329SAndrew Turner static __inline int
atomic_cmpset_acq_32(volatile uint32_t * _ptr,uint32_t _old,uint32_t _new)48504b15329SAndrew Turner atomic_cmpset_acq_32(volatile uint32_t *_ptr, uint32_t _old, uint32_t _new)
48604b15329SAndrew Turner {
48704b15329SAndrew Turner int ret;
48804b15329SAndrew Turner
48904b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "");
49004b15329SAndrew Turner dmb();
49104b15329SAndrew Turner return (ret);
49204b15329SAndrew Turner }
49304b15329SAndrew Turner
49404b15329SAndrew Turner static __inline int
atomic_cmpset_rel_32(volatile uint32_t * _ptr,uint32_t _old,uint32_t _new)49504b15329SAndrew Turner atomic_cmpset_rel_32(volatile uint32_t *_ptr, uint32_t _old, uint32_t _new)
49604b15329SAndrew Turner {
49704b15329SAndrew Turner int ret;
49804b15329SAndrew Turner
49904b15329SAndrew Turner dmb();
50004b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "");
50104b15329SAndrew Turner return (ret);
50204b15329SAndrew Turner }
50304b15329SAndrew Turner
50404b15329SAndrew Turner static __inline int
atomic_cmpset_long(volatile u_long * _ptr,u_long _old,u_long _new)50504b15329SAndrew Turner atomic_cmpset_long(volatile u_long *_ptr, u_long _old, u_long _new)
50604b15329SAndrew Turner {
50704b15329SAndrew Turner int ret;
50804b15329SAndrew Turner
50904b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "");
51004b15329SAndrew Turner return (ret);
51104b15329SAndrew Turner }
51204b15329SAndrew Turner
51304b15329SAndrew Turner static __inline int
atomic_cmpset_acq_long(volatile u_long * _ptr,u_long _old,u_long _new)51404b15329SAndrew Turner atomic_cmpset_acq_long(volatile u_long *_ptr, u_long _old, u_long _new)
51504b15329SAndrew Turner {
51604b15329SAndrew Turner int ret;
51704b15329SAndrew Turner
51804b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "");
51904b15329SAndrew Turner dmb();
52004b15329SAndrew Turner return (ret);
52104b15329SAndrew Turner }
52204b15329SAndrew Turner
52304b15329SAndrew Turner static __inline int
atomic_cmpset_rel_long(volatile u_long * _ptr,u_long _old,u_long _new)52404b15329SAndrew Turner atomic_cmpset_rel_long(volatile u_long *_ptr, u_long _old, u_long _new)
52504b15329SAndrew Turner {
52604b15329SAndrew Turner int ret;
52704b15329SAndrew Turner
52804b15329SAndrew Turner dmb();
52904b15329SAndrew Turner ATOMIC_CMPSET_CODE(ret, "");
53004b15329SAndrew Turner return (ret);
53104b15329SAndrew Turner }
53204b15329SAndrew Turner
53304b15329SAndrew Turner static __inline int
atomic_cmpset_64(volatile uint64_t * _ptr,uint64_t _old,uint64_t _new)53404b15329SAndrew Turner atomic_cmpset_64(volatile uint64_t *_ptr, uint64_t _old, uint64_t _new)
53504b15329SAndrew Turner {
53604b15329SAndrew Turner int ret;
53704b15329SAndrew Turner
53804b15329SAndrew Turner ATOMIC_CMPSET_CODE64(ret);
53904b15329SAndrew Turner return (ret);
54004b15329SAndrew Turner }
54104b15329SAndrew Turner
54204b15329SAndrew Turner static __inline int
atomic_cmpset_acq_64(volatile uint64_t * _ptr,uint64_t _old,uint64_t _new)54304b15329SAndrew Turner atomic_cmpset_acq_64(volatile uint64_t *_ptr, uint64_t _old, uint64_t _new)
54404b15329SAndrew Turner {
54504b15329SAndrew Turner int ret;
54604b15329SAndrew Turner
54704b15329SAndrew Turner ATOMIC_CMPSET_CODE64(ret);
54804b15329SAndrew Turner dmb();
54904b15329SAndrew Turner return (ret);
55004b15329SAndrew Turner }
55104b15329SAndrew Turner
55204b15329SAndrew Turner static __inline int
atomic_cmpset_rel_64(volatile uint64_t * _ptr,uint64_t _old,uint64_t _new)55304b15329SAndrew Turner atomic_cmpset_rel_64(volatile uint64_t *_ptr, uint64_t _old, uint64_t _new)
55404b15329SAndrew Turner {
55504b15329SAndrew Turner int ret;
55604b15329SAndrew Turner
55704b15329SAndrew Turner dmb();
55804b15329SAndrew Turner ATOMIC_CMPSET_CODE64(ret);
55904b15329SAndrew Turner return (ret);
56004b15329SAndrew Turner }
56104b15329SAndrew Turner
56204b15329SAndrew Turner static __inline uint32_t
atomic_fetchadd_32(volatile uint32_t * p,uint32_t val)56304b15329SAndrew Turner atomic_fetchadd_32(volatile uint32_t *p, uint32_t val)
56404b15329SAndrew Turner {
56504b15329SAndrew Turner uint32_t tmp = 0, tmp2 = 0, ret = 0;
56604b15329SAndrew Turner
56704b15329SAndrew Turner __asm __volatile(
56804b15329SAndrew Turner "1: ldrex %0, [%3] \n"
56904b15329SAndrew Turner " add %1, %0, %4 \n"
57004b15329SAndrew Turner " strex %2, %1, [%3] \n"
57104b15329SAndrew Turner " cmp %2, #0 \n"
57204b15329SAndrew Turner " it ne \n"
57304b15329SAndrew Turner " bne 1b \n"
57404b15329SAndrew Turner : "+r" (ret), "=&r" (tmp), "+r" (tmp2), "+r" (p), "+r" (val)
57504b15329SAndrew Turner : : "cc", "memory");
57604b15329SAndrew Turner return (ret);
57704b15329SAndrew Turner }
57804b15329SAndrew Turner
57904b15329SAndrew Turner static __inline uint64_t
atomic_fetchadd_64(volatile uint64_t * p,uint64_t val)58004b15329SAndrew Turner atomic_fetchadd_64(volatile uint64_t *p, uint64_t val)
58104b15329SAndrew Turner {
58204b15329SAndrew Turner uint64_t ret, tmp;
58304b15329SAndrew Turner uint32_t exflag;
58404b15329SAndrew Turner
58504b15329SAndrew Turner __asm __volatile(
58604b15329SAndrew Turner "1: \n"
58704b15329SAndrew Turner " ldrexd %Q[ret], %R[ret], [%[ptr]] \n"
58804b15329SAndrew Turner " adds %Q[tmp], %Q[ret], %Q[val] \n"
58904b15329SAndrew Turner " adc %R[tmp], %R[ret], %R[val] \n"
59004b15329SAndrew Turner " strexd %[exf], %Q[tmp], %R[tmp], [%[ptr]] \n"
59104b15329SAndrew Turner " teq %[exf], #0 \n"
59204b15329SAndrew Turner " it ne \n"
59304b15329SAndrew Turner " bne 1b \n"
59404b15329SAndrew Turner : [ret] "=&r" (ret),
59504b15329SAndrew Turner [exf] "=&r" (exflag),
59604b15329SAndrew Turner [tmp] "=&r" (tmp)
59704b15329SAndrew Turner : [ptr] "r" (p),
59804b15329SAndrew Turner [val] "r" (val)
59904b15329SAndrew Turner : "cc", "memory");
60004b15329SAndrew Turner return (ret);
60104b15329SAndrew Turner }
60204b15329SAndrew Turner
60304b15329SAndrew Turner static __inline u_long
atomic_fetchadd_long(volatile u_long * p,u_long val)60404b15329SAndrew Turner atomic_fetchadd_long(volatile u_long *p, u_long val)
60504b15329SAndrew Turner {
60604b15329SAndrew Turner
60704b15329SAndrew Turner return (atomic_fetchadd_32((volatile uint32_t *)p, val));
60804b15329SAndrew Turner }
60904b15329SAndrew Turner
61004b15329SAndrew Turner static __inline uint32_t
atomic_load_acq_32(const volatile uint32_t * p)6115e9a82e8SOlivier Certner atomic_load_acq_32(const volatile uint32_t *p)
61204b15329SAndrew Turner {
61304b15329SAndrew Turner uint32_t v;
61404b15329SAndrew Turner
61504b15329SAndrew Turner v = *p;
61604b15329SAndrew Turner dmb();
61704b15329SAndrew Turner return (v);
61804b15329SAndrew Turner }
61904b15329SAndrew Turner
62004b15329SAndrew Turner static __inline uint64_t
atomic_load_64(const volatile uint64_t * p)6215e9a82e8SOlivier Certner atomic_load_64(const volatile uint64_t *p)
62204b15329SAndrew Turner {
62304b15329SAndrew Turner uint64_t ret;
62404b15329SAndrew Turner
62504b15329SAndrew Turner /*
62604b15329SAndrew Turner * The only way to atomically load 64 bits is with LDREXD which puts the
62704b15329SAndrew Turner * exclusive monitor into the exclusive state, so reset it to open state
62804b15329SAndrew Turner * with CLREX because we don't actually need to store anything.
62904b15329SAndrew Turner */
63004b15329SAndrew Turner __asm __volatile(
63104b15329SAndrew Turner "ldrexd %Q[ret], %R[ret], [%[ptr]] \n"
63204b15329SAndrew Turner "clrex \n"
63304b15329SAndrew Turner : [ret] "=&r" (ret)
63404b15329SAndrew Turner : [ptr] "r" (p)
63504b15329SAndrew Turner : "cc", "memory");
63604b15329SAndrew Turner return (ret);
63704b15329SAndrew Turner }
63804b15329SAndrew Turner
63904b15329SAndrew Turner static __inline uint64_t
atomic_load_acq_64(const volatile uint64_t * p)6405e9a82e8SOlivier Certner atomic_load_acq_64(const volatile uint64_t *p)
64104b15329SAndrew Turner {
64204b15329SAndrew Turner uint64_t ret;
64304b15329SAndrew Turner
64404b15329SAndrew Turner ret = atomic_load_64(p);
64504b15329SAndrew Turner dmb();
64604b15329SAndrew Turner return (ret);
64704b15329SAndrew Turner }
64804b15329SAndrew Turner
64904b15329SAndrew Turner static __inline u_long
atomic_load_acq_long(const volatile u_long * p)6505e9a82e8SOlivier Certner atomic_load_acq_long(const volatile u_long *p)
65104b15329SAndrew Turner {
65204b15329SAndrew Turner u_long v;
65304b15329SAndrew Turner
65404b15329SAndrew Turner v = *p;
65504b15329SAndrew Turner dmb();
65604b15329SAndrew Turner return (v);
65704b15329SAndrew Turner }
65804b15329SAndrew Turner
65904b15329SAndrew Turner static __inline uint32_t
atomic_readandclear_32(volatile uint32_t * p)66004b15329SAndrew Turner atomic_readandclear_32(volatile uint32_t *p)
66104b15329SAndrew Turner {
66204b15329SAndrew Turner uint32_t ret, tmp = 0, tmp2 = 0;
66304b15329SAndrew Turner
66404b15329SAndrew Turner __asm __volatile(
66504b15329SAndrew Turner "1: ldrex %0, [%3] \n"
66604b15329SAndrew Turner " mov %1, #0 \n"
66704b15329SAndrew Turner " strex %2, %1, [%3] \n"
66804b15329SAndrew Turner " cmp %2, #0 \n"
66904b15329SAndrew Turner " it ne \n"
67004b15329SAndrew Turner " bne 1b \n"
67104b15329SAndrew Turner : "=r" (ret), "=&r" (tmp), "+r" (tmp2), "+r" (p)
67204b15329SAndrew Turner : : "cc", "memory");
67304b15329SAndrew Turner return (ret);
67404b15329SAndrew Turner }
67504b15329SAndrew Turner
67604b15329SAndrew Turner static __inline uint64_t
atomic_readandclear_64(volatile uint64_t * p)67704b15329SAndrew Turner atomic_readandclear_64(volatile uint64_t *p)
67804b15329SAndrew Turner {
67904b15329SAndrew Turner uint64_t ret, tmp;
68004b15329SAndrew Turner uint32_t exflag;
68104b15329SAndrew Turner
68204b15329SAndrew Turner __asm __volatile(
68304b15329SAndrew Turner "1: \n"
68404b15329SAndrew Turner " ldrexd %Q[ret], %R[ret], [%[ptr]] \n"
68504b15329SAndrew Turner " mov %Q[tmp], #0 \n"
68604b15329SAndrew Turner " mov %R[tmp], #0 \n"
68704b15329SAndrew Turner " strexd %[exf], %Q[tmp], %R[tmp], [%[ptr]] \n"
68804b15329SAndrew Turner " teq %[exf], #0 \n"
68904b15329SAndrew Turner " it ne \n"
69004b15329SAndrew Turner " bne 1b \n"
69104b15329SAndrew Turner : [ret] "=&r" (ret),
69204b15329SAndrew Turner [exf] "=&r" (exflag),
69304b15329SAndrew Turner [tmp] "=&r" (tmp)
69404b15329SAndrew Turner : [ptr] "r" (p)
69504b15329SAndrew Turner : "cc", "memory");
69604b15329SAndrew Turner return (ret);
69704b15329SAndrew Turner }
69804b15329SAndrew Turner
69904b15329SAndrew Turner static __inline u_long
atomic_readandclear_long(volatile u_long * p)70004b15329SAndrew Turner atomic_readandclear_long(volatile u_long *p)
70104b15329SAndrew Turner {
70204b15329SAndrew Turner
70304b15329SAndrew Turner return (atomic_readandclear_32((volatile uint32_t *)p));
70404b15329SAndrew Turner }
70504b15329SAndrew Turner
70604b15329SAndrew Turner static __inline void
atomic_set_32(volatile uint32_t * address,uint32_t setmask)70704b15329SAndrew Turner atomic_set_32(volatile uint32_t *address, uint32_t setmask)
70804b15329SAndrew Turner {
70904b15329SAndrew Turner uint32_t tmp = 0, tmp2 = 0;
71004b15329SAndrew Turner
71104b15329SAndrew Turner __asm __volatile(
71204b15329SAndrew Turner "1: ldrex %0, [%2] \n"
71304b15329SAndrew Turner " orr %0, %0, %3 \n"
71404b15329SAndrew Turner " strex %1, %0, [%2] \n"
71504b15329SAndrew Turner " cmp %1, #0 \n"
71604b15329SAndrew Turner " it ne \n"
71704b15329SAndrew Turner " bne 1b \n"
71804b15329SAndrew Turner : "=&r" (tmp), "+r" (tmp2), "+r" (address), "+r" (setmask)
71904b15329SAndrew Turner : : "cc", "memory");
72004b15329SAndrew Turner }
72104b15329SAndrew Turner
72204b15329SAndrew Turner static __inline void
atomic_set_64(volatile uint64_t * p,uint64_t val)72304b15329SAndrew Turner atomic_set_64(volatile uint64_t *p, uint64_t val)
72404b15329SAndrew Turner {
72504b15329SAndrew Turner uint64_t tmp;
72604b15329SAndrew Turner uint32_t exflag;
72704b15329SAndrew Turner
72804b15329SAndrew Turner __asm __volatile(
72904b15329SAndrew Turner "1: \n"
73004b15329SAndrew Turner " ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n"
73104b15329SAndrew Turner " orr %Q[tmp], %Q[val] \n"
73204b15329SAndrew Turner " orr %R[tmp], %R[val] \n"
73304b15329SAndrew Turner " strexd %[exf], %Q[tmp], %R[tmp], [%[ptr]] \n"
73404b15329SAndrew Turner " teq %[exf], #0 \n"
73504b15329SAndrew Turner " it ne \n"
73604b15329SAndrew Turner " bne 1b \n"
73704b15329SAndrew Turner : [exf] "=&r" (exflag),
73804b15329SAndrew Turner [tmp] "=&r" (tmp)
73904b15329SAndrew Turner : [ptr] "r" (p),
74004b15329SAndrew Turner [val] "r" (val)
74104b15329SAndrew Turner : "cc", "memory");
74204b15329SAndrew Turner }
74304b15329SAndrew Turner
74404b15329SAndrew Turner static __inline void
atomic_set_long(volatile u_long * address,u_long setmask)74504b15329SAndrew Turner atomic_set_long(volatile u_long *address, u_long setmask)
74604b15329SAndrew Turner {
74704b15329SAndrew Turner
74804b15329SAndrew Turner atomic_set_32((volatile uint32_t *)address, setmask);
74904b15329SAndrew Turner }
75004b15329SAndrew Turner
75104b15329SAndrew Turner ATOMIC_ACQ_REL(set, 32)
75204b15329SAndrew Turner ATOMIC_ACQ_REL(set, 64)
ATOMIC_ACQ_REL_LONG(set)75304b15329SAndrew Turner ATOMIC_ACQ_REL_LONG(set)
75404b15329SAndrew Turner
75504b15329SAndrew Turner static __inline void
75604b15329SAndrew Turner atomic_subtract_32(volatile uint32_t *p, uint32_t val)
75704b15329SAndrew Turner {
75804b15329SAndrew Turner uint32_t tmp = 0, tmp2 = 0;
75904b15329SAndrew Turner
76004b15329SAndrew Turner __asm __volatile(
76104b15329SAndrew Turner "1: ldrex %0, [%2] \n"
76204b15329SAndrew Turner " sub %0, %0, %3 \n"
76304b15329SAndrew Turner " strex %1, %0, [%2] \n"
76404b15329SAndrew Turner " cmp %1, #0 \n"
76504b15329SAndrew Turner " it ne \n"
76604b15329SAndrew Turner " bne 1b \n"
76704b15329SAndrew Turner : "=&r" (tmp), "+r" (tmp2), "+r" (p), "+r" (val)
76804b15329SAndrew Turner : : "cc", "memory");
76904b15329SAndrew Turner }
77004b15329SAndrew Turner
77104b15329SAndrew Turner static __inline void
atomic_subtract_64(volatile uint64_t * p,uint64_t val)77204b15329SAndrew Turner atomic_subtract_64(volatile uint64_t *p, uint64_t val)
77304b15329SAndrew Turner {
77404b15329SAndrew Turner uint64_t tmp;
77504b15329SAndrew Turner uint32_t exflag;
77604b15329SAndrew Turner
77704b15329SAndrew Turner __asm __volatile(
77804b15329SAndrew Turner "1: \n"
77904b15329SAndrew Turner " ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n"
78004b15329SAndrew Turner " subs %Q[tmp], %Q[val] \n"
78104b15329SAndrew Turner " sbc %R[tmp], %R[tmp], %R[val] \n"
78204b15329SAndrew Turner " strexd %[exf], %Q[tmp], %R[tmp], [%[ptr]] \n"
78304b15329SAndrew Turner " teq %[exf], #0 \n"
78404b15329SAndrew Turner " it ne \n"
78504b15329SAndrew Turner " bne 1b \n"
78604b15329SAndrew Turner : [exf] "=&r" (exflag),
78704b15329SAndrew Turner [tmp] "=&r" (tmp)
78804b15329SAndrew Turner : [ptr] "r" (p),
78904b15329SAndrew Turner [val] "r" (val)
79004b15329SAndrew Turner : "cc", "memory");
79104b15329SAndrew Turner }
79204b15329SAndrew Turner
79304b15329SAndrew Turner static __inline void
atomic_subtract_long(volatile u_long * p,u_long val)79404b15329SAndrew Turner atomic_subtract_long(volatile u_long *p, u_long val)
79504b15329SAndrew Turner {
79604b15329SAndrew Turner
79704b15329SAndrew Turner atomic_subtract_32((volatile uint32_t *)p, val);
79804b15329SAndrew Turner }
79904b15329SAndrew Turner
80004b15329SAndrew Turner ATOMIC_ACQ_REL(subtract, 32)
80104b15329SAndrew Turner ATOMIC_ACQ_REL(subtract, 64)
ATOMIC_ACQ_REL_LONG(subtract)80204b15329SAndrew Turner ATOMIC_ACQ_REL_LONG(subtract)
80304b15329SAndrew Turner
80404b15329SAndrew Turner static __inline void
80504b15329SAndrew Turner atomic_store_64(volatile uint64_t *p, uint64_t val)
80604b15329SAndrew Turner {
80704b15329SAndrew Turner uint64_t tmp;
80804b15329SAndrew Turner uint32_t exflag;
80904b15329SAndrew Turner
81004b15329SAndrew Turner /*
81104b15329SAndrew Turner * The only way to atomically store 64 bits is with STREXD, which will
81204b15329SAndrew Turner * succeed only if paired up with a preceeding LDREXD using the same
81304b15329SAndrew Turner * address, so we read and discard the existing value before storing.
81404b15329SAndrew Turner */
81504b15329SAndrew Turner __asm __volatile(
81604b15329SAndrew Turner "1: \n"
81704b15329SAndrew Turner " ldrexd %Q[tmp], %R[tmp], [%[ptr]] \n"
81804b15329SAndrew Turner " strexd %[exf], %Q[val], %R[val], [%[ptr]] \n"
81904b15329SAndrew Turner " teq %[exf], #0 \n"
82004b15329SAndrew Turner " it ne \n"
82104b15329SAndrew Turner " bne 1b \n"
82204b15329SAndrew Turner : [tmp] "=&r" (tmp),
82304b15329SAndrew Turner [exf] "=&r" (exflag)
82404b15329SAndrew Turner : [ptr] "r" (p),
82504b15329SAndrew Turner [val] "r" (val)
82604b15329SAndrew Turner : "cc", "memory");
82704b15329SAndrew Turner }
82804b15329SAndrew Turner
82904b15329SAndrew Turner static __inline void
atomic_store_rel_32(volatile uint32_t * p,uint32_t v)83004b15329SAndrew Turner atomic_store_rel_32(volatile uint32_t *p, uint32_t v)
83104b15329SAndrew Turner {
83204b15329SAndrew Turner
83304b15329SAndrew Turner dmb();
83404b15329SAndrew Turner *p = v;
83504b15329SAndrew Turner }
83604b15329SAndrew Turner
83704b15329SAndrew Turner static __inline void
atomic_store_rel_64(volatile uint64_t * p,uint64_t val)83804b15329SAndrew Turner atomic_store_rel_64(volatile uint64_t *p, uint64_t val)
83904b15329SAndrew Turner {
84004b15329SAndrew Turner
84104b15329SAndrew Turner dmb();
84204b15329SAndrew Turner atomic_store_64(p, val);
84304b15329SAndrew Turner }
84404b15329SAndrew Turner
84504b15329SAndrew Turner static __inline void
atomic_store_rel_long(volatile u_long * p,u_long v)84604b15329SAndrew Turner atomic_store_rel_long(volatile u_long *p, u_long v)
84704b15329SAndrew Turner {
84804b15329SAndrew Turner
84904b15329SAndrew Turner dmb();
85004b15329SAndrew Turner *p = v;
85104b15329SAndrew Turner }
85204b15329SAndrew Turner
85304b15329SAndrew Turner static __inline int
atomic_testandclear_32(volatile uint32_t * ptr,u_int bit)85404b15329SAndrew Turner atomic_testandclear_32(volatile uint32_t *ptr, u_int bit)
85504b15329SAndrew Turner {
85604b15329SAndrew Turner int newv, oldv, result;
85704b15329SAndrew Turner
85804b15329SAndrew Turner __asm __volatile(
85904b15329SAndrew Turner " mov ip, #1 \n"
86004b15329SAndrew Turner " lsl ip, ip, %[bit] \n"
86104b15329SAndrew Turner /* Done with %[bit] as input, reuse below as output. */
86204b15329SAndrew Turner "1: \n"
86304b15329SAndrew Turner " ldrex %[oldv], [%[ptr]] \n"
86404b15329SAndrew Turner " bic %[newv], %[oldv], ip \n"
86504b15329SAndrew Turner " strex %[bit], %[newv], [%[ptr]] \n"
86604b15329SAndrew Turner " teq %[bit], #0 \n"
86704b15329SAndrew Turner " it ne \n"
86804b15329SAndrew Turner " bne 1b \n"
86904b15329SAndrew Turner " ands %[bit], %[oldv], ip \n"
87004b15329SAndrew Turner " it ne \n"
87104b15329SAndrew Turner " movne %[bit], #1 \n"
87204b15329SAndrew Turner : [bit] "=&r" (result),
87304b15329SAndrew Turner [oldv] "=&r" (oldv),
87404b15329SAndrew Turner [newv] "=&r" (newv)
87504b15329SAndrew Turner : [ptr] "r" (ptr),
87604b15329SAndrew Turner "[bit]" (bit & 0x1f)
87704b15329SAndrew Turner : "cc", "ip", "memory");
87804b15329SAndrew Turner
87904b15329SAndrew Turner return (result);
88004b15329SAndrew Turner }
88104b15329SAndrew Turner
88204b15329SAndrew Turner static __inline int
atomic_testandclear_int(volatile u_int * p,u_int v)88304b15329SAndrew Turner atomic_testandclear_int(volatile u_int *p, u_int v)
88404b15329SAndrew Turner {
88504b15329SAndrew Turner
88604b15329SAndrew Turner return (atomic_testandclear_32((volatile uint32_t *)p, v));
88704b15329SAndrew Turner }
88804b15329SAndrew Turner
88904b15329SAndrew Turner static __inline int
atomic_testandclear_long(volatile u_long * p,u_int v)89004b15329SAndrew Turner atomic_testandclear_long(volatile u_long *p, u_int v)
89104b15329SAndrew Turner {
89204b15329SAndrew Turner
89304b15329SAndrew Turner return (atomic_testandclear_32((volatile uint32_t *)p, v));
89404b15329SAndrew Turner }
89504b15329SAndrew Turner
89604b15329SAndrew Turner static __inline int
atomic_testandclear_64(volatile uint64_t * p,u_int v)89704b15329SAndrew Turner atomic_testandclear_64(volatile uint64_t *p, u_int v)
89804b15329SAndrew Turner {
89904b15329SAndrew Turner volatile uint32_t *p32;
90004b15329SAndrew Turner
90104b15329SAndrew Turner p32 = (volatile uint32_t *)p;
90204b15329SAndrew Turner /*
90304b15329SAndrew Turner * Assume little-endian,
90404b15329SAndrew Turner * atomic_testandclear_32() uses only last 5 bits of v
90504b15329SAndrew Turner */
90604b15329SAndrew Turner if ((v & 0x20) != 0)
90704b15329SAndrew Turner p32++;
90804b15329SAndrew Turner return (atomic_testandclear_32(p32, v));
90904b15329SAndrew Turner }
91004b15329SAndrew Turner
91104b15329SAndrew Turner static __inline int
atomic_testandset_32(volatile uint32_t * ptr,u_int bit)91204b15329SAndrew Turner atomic_testandset_32(volatile uint32_t *ptr, u_int bit)
91304b15329SAndrew Turner {
91404b15329SAndrew Turner int newv, oldv, result;
91504b15329SAndrew Turner
91604b15329SAndrew Turner __asm __volatile(
91704b15329SAndrew Turner " mov ip, #1 \n"
91804b15329SAndrew Turner " lsl ip, ip, %[bit] \n"
91904b15329SAndrew Turner /* Done with %[bit] as input, reuse below as output. */
92004b15329SAndrew Turner "1: \n"
92104b15329SAndrew Turner " ldrex %[oldv], [%[ptr]] \n"
92204b15329SAndrew Turner " orr %[newv], %[oldv], ip \n"
92304b15329SAndrew Turner " strex %[bit], %[newv], [%[ptr]] \n"
92404b15329SAndrew Turner " teq %[bit], #0 \n"
92504b15329SAndrew Turner " it ne \n"
92604b15329SAndrew Turner " bne 1b \n"
92704b15329SAndrew Turner " ands %[bit], %[oldv], ip \n"
92804b15329SAndrew Turner " it ne \n"
92904b15329SAndrew Turner " movne %[bit], #1 \n"
93004b15329SAndrew Turner : [bit] "=&r" (result),
93104b15329SAndrew Turner [oldv] "=&r" (oldv),
93204b15329SAndrew Turner [newv] "=&r" (newv)
93304b15329SAndrew Turner : [ptr] "r" (ptr),
93404b15329SAndrew Turner "[bit]" (bit & 0x1f)
93504b15329SAndrew Turner : "cc", "ip", "memory");
93604b15329SAndrew Turner
93704b15329SAndrew Turner return (result);
93804b15329SAndrew Turner }
93904b15329SAndrew Turner
94004b15329SAndrew Turner static __inline int
atomic_testandset_int(volatile u_int * p,u_int v)94104b15329SAndrew Turner atomic_testandset_int(volatile u_int *p, u_int v)
94204b15329SAndrew Turner {
94304b15329SAndrew Turner
94404b15329SAndrew Turner return (atomic_testandset_32((volatile uint32_t *)p, v));
94504b15329SAndrew Turner }
94604b15329SAndrew Turner
94704b15329SAndrew Turner static __inline int
atomic_testandset_long(volatile u_long * p,u_int v)94804b15329SAndrew Turner atomic_testandset_long(volatile u_long *p, u_int v)
94904b15329SAndrew Turner {
95004b15329SAndrew Turner
95104b15329SAndrew Turner return (atomic_testandset_32((volatile uint32_t *)p, v));
95204b15329SAndrew Turner }
95304b15329SAndrew Turner
95404b15329SAndrew Turner static __inline int
atomic_testandset_acq_long(volatile u_long * p,u_int v)955987c5a19SJohn Baldwin atomic_testandset_acq_long(volatile u_long *p, u_int v)
956987c5a19SJohn Baldwin {
957987c5a19SJohn Baldwin int ret;
958987c5a19SJohn Baldwin
959987c5a19SJohn Baldwin ret = atomic_testandset_32((volatile uint32_t *)p, v);
960987c5a19SJohn Baldwin dmb();
961987c5a19SJohn Baldwin return (ret);
962987c5a19SJohn Baldwin }
963987c5a19SJohn Baldwin
964987c5a19SJohn Baldwin static __inline int
atomic_testandset_64(volatile uint64_t * p,u_int v)96504b15329SAndrew Turner atomic_testandset_64(volatile uint64_t *p, u_int v)
96604b15329SAndrew Turner {
96704b15329SAndrew Turner volatile uint32_t *p32;
96804b15329SAndrew Turner
96904b15329SAndrew Turner p32 = (volatile uint32_t *)p;
97004b15329SAndrew Turner /*
97104b15329SAndrew Turner * Assume little-endian,
97204b15329SAndrew Turner * atomic_testandset_32() uses only last 5 bits of v
97304b15329SAndrew Turner */
97404b15329SAndrew Turner if ((v & 0x20) != 0)
97504b15329SAndrew Turner p32++;
97604b15329SAndrew Turner return (atomic_testandset_32(p32, v));
97704b15329SAndrew Turner }
97804b15329SAndrew Turner
97904b15329SAndrew Turner static __inline uint32_t
atomic_swap_32(volatile uint32_t * p,uint32_t v)98004b15329SAndrew Turner atomic_swap_32(volatile uint32_t *p, uint32_t v)
98104b15329SAndrew Turner {
98204b15329SAndrew Turner uint32_t ret, exflag;
98304b15329SAndrew Turner
98404b15329SAndrew Turner __asm __volatile(
98504b15329SAndrew Turner "1: ldrex %[ret], [%[ptr]] \n"
98604b15329SAndrew Turner " strex %[exf], %[val], [%[ptr]] \n"
98704b15329SAndrew Turner " teq %[exf], #0 \n"
98804b15329SAndrew Turner " it ne \n"
98904b15329SAndrew Turner " bne 1b \n"
99004b15329SAndrew Turner : [ret] "=&r" (ret),
99104b15329SAndrew Turner [exf] "=&r" (exflag)
99204b15329SAndrew Turner : [val] "r" (v),
99304b15329SAndrew Turner [ptr] "r" (p)
99404b15329SAndrew Turner : "cc", "memory");
99504b15329SAndrew Turner return (ret);
99604b15329SAndrew Turner }
997cf1a573fSOleksandr Tymoshenko
998d7a9bfeeSHans Petter Selasky static __inline u_long
atomic_swap_long(volatile u_long * p,u_long v)999d7a9bfeeSHans Petter Selasky atomic_swap_long(volatile u_long *p, u_long v)
1000d7a9bfeeSHans Petter Selasky {
1001d7a9bfeeSHans Petter Selasky
1002d7a9bfeeSHans Petter Selasky return (atomic_swap_32((volatile uint32_t *)p, v));
1003d7a9bfeeSHans Petter Selasky }
1004d7a9bfeeSHans Petter Selasky
100504b15329SAndrew Turner static __inline uint64_t
atomic_swap_64(volatile uint64_t * p,uint64_t v)100604b15329SAndrew Turner atomic_swap_64(volatile uint64_t *p, uint64_t v)
100704b15329SAndrew Turner {
100804b15329SAndrew Turner uint64_t ret;
100904b15329SAndrew Turner uint32_t exflag;
101004b15329SAndrew Turner
101104b15329SAndrew Turner __asm __volatile(
101204b15329SAndrew Turner "1: ldrexd %Q[ret], %R[ret], [%[ptr]] \n"
101304b15329SAndrew Turner " strexd %[exf], %Q[val], %R[val], [%[ptr]] \n"
101404b15329SAndrew Turner " teq %[exf], #0 \n"
101504b15329SAndrew Turner " it ne \n"
101604b15329SAndrew Turner " bne 1b \n"
101704b15329SAndrew Turner : [ret] "=&r" (ret),
101804b15329SAndrew Turner [exf] "=&r" (exflag)
101904b15329SAndrew Turner : [val] "r" (v),
102004b15329SAndrew Turner [ptr] "r" (p)
102104b15329SAndrew Turner : "cc", "memory");
102204b15329SAndrew Turner return (ret);
102304b15329SAndrew Turner }
102404b15329SAndrew Turner
102504b15329SAndrew Turner #undef ATOMIC_ACQ_REL
102604b15329SAndrew Turner #undef ATOMIC_ACQ_REL_LONG
102704b15329SAndrew Turner
102804b15329SAndrew Turner static __inline void
atomic_thread_fence_acq(void)102904b15329SAndrew Turner atomic_thread_fence_acq(void)
103004b15329SAndrew Turner {
103104b15329SAndrew Turner
103204b15329SAndrew Turner dmb();
103304b15329SAndrew Turner }
103404b15329SAndrew Turner
103504b15329SAndrew Turner static __inline void
atomic_thread_fence_rel(void)103604b15329SAndrew Turner atomic_thread_fence_rel(void)
103704b15329SAndrew Turner {
103804b15329SAndrew Turner
103904b15329SAndrew Turner dmb();
104004b15329SAndrew Turner }
104104b15329SAndrew Turner
104204b15329SAndrew Turner static __inline void
atomic_thread_fence_acq_rel(void)104304b15329SAndrew Turner atomic_thread_fence_acq_rel(void)
104404b15329SAndrew Turner {
104504b15329SAndrew Turner
104604b15329SAndrew Turner dmb();
104704b15329SAndrew Turner }
104804b15329SAndrew Turner
104904b15329SAndrew Turner static __inline void
atomic_thread_fence_seq_cst(void)105004b15329SAndrew Turner atomic_thread_fence_seq_cst(void)
105104b15329SAndrew Turner {
105204b15329SAndrew Turner
105304b15329SAndrew Turner dmb();
105404b15329SAndrew Turner }
105504b15329SAndrew Turner
105698c27681SElliott Mitchell #define atomic_add_ptr atomic_add_32
105798c27681SElliott Mitchell #define atomic_add_acq_ptr atomic_add_acq_32
105898c27681SElliott Mitchell #define atomic_add_rel_ptr atomic_add_rel_32
105998c27681SElliott Mitchell #define atomic_subtract_ptr atomic_subtract_32
106098c27681SElliott Mitchell #define atomic_subtract_acq_ptr atomic_subtract_acq_32
106198c27681SElliott Mitchell #define atomic_subtract_rel_ptr atomic_subtract_rel_32
1062d4047613SIan Lepore #define atomic_clear_ptr atomic_clear_32
106333ce6ec1SMark Johnston #define atomic_clear_acq_ptr atomic_clear_acq_32
106433ce6ec1SMark Johnston #define atomic_clear_rel_ptr atomic_clear_rel_32
1065d4047613SIan Lepore #define atomic_set_ptr atomic_set_32
106633ce6ec1SMark Johnston #define atomic_set_acq_ptr atomic_set_acq_32
106733ce6ec1SMark Johnston #define atomic_set_rel_ptr atomic_set_rel_32
1068dc5f9fcdSOlivier Houchard #define atomic_fcmpset_ptr atomic_fcmpset_32
1069dc5f9fcdSOlivier Houchard #define atomic_fcmpset_acq_ptr atomic_fcmpset_acq_32
107098c27681SElliott Mitchell #define atomic_fcmpset_rel_ptr atomic_fcmpset_rel_32
1071d4047613SIan Lepore #define atomic_cmpset_ptr atomic_cmpset_32
1072d4047613SIan Lepore #define atomic_cmpset_acq_ptr atomic_cmpset_acq_32
107333ce6ec1SMark Johnston #define atomic_cmpset_rel_ptr atomic_cmpset_rel_32
107498c27681SElliott Mitchell #define atomic_fetchadd_ptr atomic_fetchadd_32
107598c27681SElliott Mitchell #define atomic_readandclear_ptr atomic_readandclear_32
107633ce6ec1SMark Johnston #define atomic_load_acq_ptr atomic_load_acq_32
1077d4047613SIan Lepore #define atomic_store_rel_ptr atomic_store_rel_32
107833ce6ec1SMark Johnston #define atomic_swap_ptr atomic_swap_32
1079a80b9ee1SJohn Baldwin #define atomic_testandset_ptr atomic_testandset_32
1080a80b9ee1SJohn Baldwin #define atomic_testandclear_ptr atomic_testandclear_32
108169b40f4dSBernd Walter
108269b40f4dSBernd Walter #define atomic_add_int atomic_add_32
1083cf1a573fSOleksandr Tymoshenko #define atomic_add_acq_int atomic_add_acq_32
1084cf1a573fSOleksandr Tymoshenko #define atomic_add_rel_int atomic_add_rel_32
108569b40f4dSBernd Walter #define atomic_subtract_int atomic_subtract_32
1086cf1a573fSOleksandr Tymoshenko #define atomic_subtract_acq_int atomic_subtract_acq_32
1087cf1a573fSOleksandr Tymoshenko #define atomic_subtract_rel_int atomic_subtract_rel_32
108869b40f4dSBernd Walter #define atomic_clear_int atomic_clear_32
1089cf1a573fSOleksandr Tymoshenko #define atomic_clear_acq_int atomic_clear_acq_32
1090cf1a573fSOleksandr Tymoshenko #define atomic_clear_rel_int atomic_clear_rel_32
109169b40f4dSBernd Walter #define atomic_set_int atomic_set_32
1092cf1a573fSOleksandr Tymoshenko #define atomic_set_acq_int atomic_set_acq_32
1093cf1a573fSOleksandr Tymoshenko #define atomic_set_rel_int atomic_set_rel_32
1094dc5f9fcdSOlivier Houchard #define atomic_fcmpset_int atomic_fcmpset_32
1095dc5f9fcdSOlivier Houchard #define atomic_fcmpset_acq_int atomic_fcmpset_acq_32
1096dc5f9fcdSOlivier Houchard #define atomic_fcmpset_rel_int atomic_fcmpset_rel_32
109769b40f4dSBernd Walter #define atomic_cmpset_int atomic_cmpset_32
1098cf1a573fSOleksandr Tymoshenko #define atomic_cmpset_acq_int atomic_cmpset_acq_32
1099cf1a573fSOleksandr Tymoshenko #define atomic_cmpset_rel_int atomic_cmpset_rel_32
11003c2bc2bfSJohn Baldwin #define atomic_fetchadd_int atomic_fetchadd_32
110169b40f4dSBernd Walter #define atomic_readandclear_int atomic_readandclear_32
1102cf1a573fSOleksandr Tymoshenko #define atomic_load_acq_int atomic_load_acq_32
1103cf1a573fSOleksandr Tymoshenko #define atomic_store_rel_int atomic_store_rel_32
11041eb1d41aSMichal Meloun #define atomic_swap_int atomic_swap_32
11056fc729afSOlivier Houchard
1106ca0ec73cSConrad Meyer #include <sys/_atomic_subword.h>
1107ca0ec73cSConrad Meyer
1108b31abc95SKonstantin Belousov #define atomic_set_short atomic_set_16
1109b31abc95SKonstantin Belousov #define atomic_clear_short atomic_clear_16
1110b31abc95SKonstantin Belousov
11116fc729afSOlivier Houchard #endif /* _MACHINE_ATOMIC_H_ */
1112