1272343Sngie/* $NetBSD: all_sync_ops_linkable.c,v 1.4 2014/02/21 10:26:25 martin Exp $ */
2272343Sngie
3272343Sngie/*-
4272343Sngie * Copyright (c) 2014 The NetBSD Foundation, Inc.
5272343Sngie * All rights reserved.
6272343Sngie *
7272343Sngie * This code is derived from software contributed to The NetBSD Foundation
8272343Sngie * by Martin Husemann <martin@NetBSD.org>.
9272343Sngie *
10272343Sngie * Redistribution and use in source and binary forms, with or without
11272343Sngie * modification, are permitted provided that the following conditions
12272343Sngie * are met:
13272343Sngie * 1. Redistributions of source code must retain the above copyright
14272343Sngie *    notice, this list of conditions and the following disclaimer.
15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
16272343Sngie *    notice, this list of conditions and the following disclaimer in the
17272343Sngie *    documentation and/or other materials provided with the distribution.
18272343Sngie *
19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22272343Sngie * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29272343Sngie * POSSIBILITY OF SUCH DAMAGE.
30272343Sngie */
31272343Sngie
32272343Sngie/*
33272343Sngie * This is a simple link-time test to verify all builtin atomic sync
34272343Sngie * operations are available. Depending on the exact cpu/arch code generator
35272343Sngie * options, some of these need support functions (which on NetBSD we
36272343Sngie * typically provide in src/common/lib/libc/atomic).
37272343Sngie *
38272343Sngie * The list of operations has been extracted from sync-builtins.def file
39272343Sngie * in the gcc distribution (as of gcc 4.8.2).
40272343Sngie */
41272343Sngie
42272343Sngie#include <machine/types.h>
43272343Sngie#include <sys/inttypes.h>
44272343Sngie
45272343Sngievolatile uint8_t u8 = 0;
46272343Sngievolatile uint16_t u16 = 0;
47272343Sngievolatile uint32_t u32 = 0;
48272343Sngie
49272343Sngie#ifdef __HAVE_ATOMIC64_OPS
50272343Sngievolatile uint64_t u64 = 0;
51272343Sngie#endif
52272343Sngie
53272343Sngieint
54272343Sngiemain(int argc, char **argv)
55272343Sngie{
56272343Sngie	__sync_synchronize();
57272343Sngie	__sync_add_and_fetch(&u8, 1);
58272343Sngie	__sync_add_and_fetch_1(&u8, 1);
59272343Sngie	__sync_add_and_fetch_2(&u16, 1);
60272343Sngie	__sync_add_and_fetch_4(&u32, 1);
61272343Sngie#ifdef __HAVE_ATOMIC64_OPS
62272343Sngie	__sync_add_and_fetch_8(&u64, 1);
63272343Sngie#endif
64272343Sngie	__sync_bool_compare_and_swap(&u8, 1, 2);
65272343Sngie	__sync_bool_compare_and_swap_1(&u8, 1, 2);
66272343Sngie	__sync_bool_compare_and_swap_2(&u16, 1, 2);
67272343Sngie	__sync_bool_compare_and_swap_4(&u32, 1, 2);
68272343Sngie#ifdef __HAVE_ATOMIC64_OPS
69272343Sngie	__sync_bool_compare_and_swap_8(&u64, 1, 2);
70272343Sngie#endif
71272343Sngie	__sync_fetch_and_add(&u8, 1);
72272343Sngie	__sync_fetch_and_add_1(&u8, 1);
73272343Sngie	__sync_fetch_and_add_2(&u16, 1);
74272343Sngie	__sync_fetch_and_add_4(&u32, 1);
75272343Sngie#ifdef __HAVE_ATOMIC64_OPS
76272343Sngie	__sync_fetch_and_add_8(&u64, 1);
77272343Sngie#endif
78272343Sngie	__sync_fetch_and_and(&u8, 0x80);
79272343Sngie	__sync_fetch_and_and_1(&u8, 0x80);
80272343Sngie	__sync_fetch_and_and_2(&u16, 0x80);
81272343Sngie	__sync_fetch_and_and_4(&u32, 0x80);
82272343Sngie#ifdef __HAVE_ATOMIC64_OPS
83272343Sngie	__sync_fetch_and_and_8(&u64, 0x80);
84272343Sngie#endif
85272343Sngie#ifndef __clang__
86272343Sngie	__sync_fetch_and_nand(&u8, 0x80);
87272343Sngie	__sync_fetch_and_nand_1(&u8, 0x80);
88272343Sngie	__sync_fetch_and_nand_2(&u16, 0x80);
89272343Sngie	__sync_fetch_and_nand_4(&u32, 0x80);
90272343Sngie#ifdef __HAVE_ATOMIC64_OPS
91272343Sngie	__sync_fetch_and_nand_8(&u64, 0x80);
92272343Sngie#endif
93272343Sngie#endif
94272343Sngie	__sync_fetch_and_or(&u8, 0x80);
95272343Sngie	__sync_fetch_and_or_1(&u8, 0x80);
96272343Sngie	__sync_fetch_and_or_2(&u16, 0x80);
97272343Sngie	__sync_fetch_and_or_4(&u32, 0x80);
98272343Sngie#ifdef __HAVE_ATOMIC64_OPS
99272343Sngie	__sync_fetch_and_or_8(&u64, 0x80);
100272343Sngie#endif
101272343Sngie	__sync_fetch_and_sub(&u8, 0x80);
102272343Sngie	__sync_fetch_and_sub_1(&u8, 0x80);
103272343Sngie	__sync_fetch_and_sub_2(&u16, 0x80);
104272343Sngie	__sync_fetch_and_sub_4(&u32, 0x80);
105272343Sngie#ifdef __HAVE_ATOMIC64_OPS
106272343Sngie	__sync_fetch_and_sub_8(&u64, 0x80);
107272343Sngie#endif
108272343Sngie	__sync_fetch_and_xor(&u8, 0x80);
109272343Sngie	__sync_fetch_and_xor_1(&u8, 0x80);
110272343Sngie	__sync_fetch_and_xor_2(&u16, 0x80);
111272343Sngie	__sync_fetch_and_xor_4(&u32, 0x80);
112272343Sngie#ifdef __HAVE_ATOMIC64_OPS
113272343Sngie	__sync_fetch_and_xor_8(&u64, 0x80);
114272343Sngie#endif
115272343Sngie	__sync_lock_release(&u8);
116272343Sngie	__sync_lock_release_1(&u8);
117272343Sngie	__sync_lock_release_2(&u16);
118272343Sngie	__sync_lock_release_4(&u32);
119272343Sngie#ifdef __HAVE_ATOMIC64_OPS
120272343Sngie	__sync_lock_release_8(&u64);
121272343Sngie#endif
122272343Sngie	__sync_lock_test_and_set(&u8, 5);
123272343Sngie	__sync_lock_test_and_set_1(&u8, 5);
124272343Sngie	__sync_lock_test_and_set_2(&u16, 5);
125272343Sngie	__sync_lock_test_and_set_4(&u32, 5);
126272343Sngie#ifdef __HAVE_ATOMIC64_OPS
127272343Sngie	__sync_lock_test_and_set_8(&u64, 5);
128272343Sngie#endif
129272343Sngie#ifndef __clang__
130272343Sngie	__sync_nand_and_fetch(&u8, 5);
131272343Sngie	__sync_nand_and_fetch_1(&u8, 5);
132272343Sngie	__sync_nand_and_fetch_2(&u16, 5);
133272343Sngie	__sync_nand_and_fetch_4(&u32, 5);
134272343Sngie#ifdef __HAVE_ATOMIC64_OPS
135272343Sngie	__sync_nand_and_fetch_8(&u64, 5);
136272343Sngie#endif
137272343Sngie#endif
138272343Sngie	__sync_or_and_fetch(&u8, 5);
139272343Sngie	__sync_or_and_fetch_1(&u8, 5);
140272343Sngie	__sync_or_and_fetch_2(&u16, 5);
141272343Sngie	__sync_or_and_fetch_4(&u32, 5);
142272343Sngie#ifdef __HAVE_ATOMIC64_OPS
143272343Sngie	__sync_or_and_fetch_8(&u64, 5);
144272343Sngie#endif
145272343Sngie	__sync_sub_and_fetch(&u8, 5);
146272343Sngie	__sync_sub_and_fetch_1(&u8, 5);
147272343Sngie	__sync_sub_and_fetch_2(&u16, 5);
148272343Sngie	__sync_sub_and_fetch_4(&u32, 5);
149272343Sngie#ifdef __HAVE_ATOMIC64_OPS
150272343Sngie	__sync_sub_and_fetch_8(&u64, 5);
151272343Sngie#endif
152272343Sngie	__sync_val_compare_and_swap(&u8, 5, 9);
153272343Sngie	__sync_val_compare_and_swap_1(&u8, 5, 9);
154272343Sngie	__sync_val_compare_and_swap_2(&u16, 5, 9);
155272343Sngie	__sync_val_compare_and_swap_4(&u32, 5, 9);
156272343Sngie#ifdef __HAVE_ATOMIC64_OPS
157272343Sngie	__sync_val_compare_and_swap_8(&u64, 5, 9);
158272343Sngie#endif
159272343Sngie	__sync_xor_and_fetch(&u8, 5);
160272343Sngie	__sync_xor_and_fetch_1(&u8, 5);
161272343Sngie	__sync_xor_and_fetch_2(&u16, 5);
162272343Sngie	__sync_xor_and_fetch_4(&u32, 5);
163272343Sngie#ifdef __HAVE_ATOMIC64_OPS
164272343Sngie	__sync_xor_and_fetch_8(&u64, 5);
165272343Sngie#endif
166272343Sngie
167272343Sngie	return 0;
168272343Sngie}
169