11.1Sisaki/*	$NetBSD: t___sync_add.c,v 1.1 2019/02/26 10:01:41 isaki Exp $	*/
21.1Sisaki
31.1Sisaki/*
41.1Sisaki * Copyright (C) 2019 Tetsuya Isaki. All rights reserved.
51.1Sisaki *
61.1Sisaki * Redistribution and use in source and binary forms, with or without
71.1Sisaki * modification, are permitted provided that the following conditions
81.1Sisaki * are met:
91.1Sisaki * 1. Redistributions of source code must retain the above copyright
101.1Sisaki *    notice, this list of conditions and the following disclaimer.
111.1Sisaki * 2. Redistributions in binary form must reproduce the above copyright
121.1Sisaki *    notice, this list of conditions and the following disclaimer in the
131.1Sisaki *    documentation and/or other materials provided with the distribution.
141.1Sisaki *
151.1Sisaki * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
161.1Sisaki * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
171.1Sisaki * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
181.1Sisaki * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
191.1Sisaki * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
201.1Sisaki * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
211.1Sisaki * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
221.1Sisaki * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
231.1Sisaki * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241.1Sisaki * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251.1Sisaki * SUCH DAMAGE.
261.1Sisaki */
271.1Sisaki
281.1Sisaki#include <sys/cdefs.h>
291.1Sisaki__RCSID("$NetBSD: t___sync_add.c,v 1.1 2019/02/26 10:01:41 isaki Exp $");
301.1Sisaki
311.1Sisaki#include <atf-c.h>
321.1Sisaki#include <inttypes.h>
331.1Sisaki#include <machine/types.h>	// for __HAVE_ATOMIC64_OPS
341.1Sisaki
351.1Sisaki/*
361.1Sisaki * These tests don't examine the atomicity.
371.1Sisaki */
381.1Sisaki
391.1Sisaki/* XXX
401.1Sisaki * Depending on a combination of arch and compiler, __sync_* is
411.1Sisaki * implemented as compiler's builtin function.  In that case, even
421.1Sisaki * if libc exports the function symbol, it is not used.  As a result
431.1Sisaki * this tests will examine compiler's builtin functions.
441.1Sisaki * It's better to run only when target is actually in libc.
451.1Sisaki */
461.1Sisaki
471.1Sisaki#define DST    (0x1122334455667788UL)
481.1Sisaki#define SRC    (0xf0e0d0c0b0a09081UL)
491.1Sisaki#define EXPECT (0x0203040506070809UL)
501.1Sisaki
511.1Sisaki#define atf_sync_prefetch(NAME, TYPE, FMT) \
521.1SisakiATF_TC(NAME); \
531.1SisakiATF_TC_HEAD(NAME, tc) \
541.1Sisaki{ \
551.1Sisaki	atf_tc_set_md_var(tc, "descr", #NAME); \
561.1Sisaki} \
571.1SisakiATF_TC_BODY(NAME, tc) \
581.1Sisaki{ \
591.1Sisaki	volatile TYPE val; \
601.1Sisaki	TYPE src; \
611.1Sisaki	TYPE res; \
621.1Sisaki	TYPE expval; \
631.1Sisaki	TYPE expres; \
641.1Sisaki	val = (TYPE)DST; \
651.1Sisaki	src = (TYPE)SRC; \
661.1Sisaki	expval = (TYPE)EXPECT; \
671.1Sisaki	expres = (TYPE)DST; \
681.1Sisaki	res = NAME(&val, src); \
691.1Sisaki	ATF_REQUIRE_MSG(val == expval, \
701.1Sisaki	    "val expects 0x%" FMT " but 0x%" FMT, expval, val); \
711.1Sisaki	ATF_REQUIRE_MSG(res == expres, \
721.1Sisaki	    "res expects 0x%" FMT " but 0x%" FMT, expres, res); \
731.1Sisaki}
741.1Sisaki
751.1Sisakiatf_sync_prefetch(__sync_fetch_and_add_1, uint8_t,  PRIx8);
761.1Sisakiatf_sync_prefetch(__sync_fetch_and_add_2, uint16_t, PRIx16);
771.1Sisakiatf_sync_prefetch(__sync_fetch_and_add_4, uint32_t, PRIx32);
781.1Sisaki#if defined(__HAVE_ATOMIC64_OPS)
791.1Sisakiatf_sync_prefetch(__sync_fetch_and_add_8, uint64_t, PRIx64);
801.1Sisaki#endif
811.1Sisaki
821.1Sisaki#define atf_sync_postfetch(NAME, TYPE, FMT) \
831.1SisakiATF_TC(NAME); \
841.1SisakiATF_TC_HEAD(NAME, tc) \
851.1Sisaki{ \
861.1Sisaki	atf_tc_set_md_var(tc, "descr", #NAME); \
871.1Sisaki} \
881.1SisakiATF_TC_BODY(NAME, tc) \
891.1Sisaki{ \
901.1Sisaki	volatile TYPE val; \
911.1Sisaki	TYPE src; \
921.1Sisaki	TYPE res; \
931.1Sisaki	TYPE exp; \
941.1Sisaki	val = (TYPE)DST; \
951.1Sisaki	src = (TYPE)SRC; \
961.1Sisaki	exp = (TYPE)EXPECT; \
971.1Sisaki	res = NAME(&val, src); \
981.1Sisaki	ATF_REQUIRE_MSG(val == exp, \
991.1Sisaki	    "val expects 0x%" FMT " but 0x%" FMT, exp, val); \
1001.1Sisaki	ATF_REQUIRE_MSG(res == exp, \
1011.1Sisaki	    "res expects 0x%" FMT " but 0x%" FMT, exp, res); \
1021.1Sisaki}
1031.1Sisaki
1041.1Sisakiatf_sync_postfetch(__sync_add_and_fetch_1, uint8_t,  PRIx8);
1051.1Sisakiatf_sync_postfetch(__sync_add_and_fetch_2, uint16_t, PRIx16);
1061.1Sisakiatf_sync_postfetch(__sync_add_and_fetch_4, uint32_t, PRIx32);
1071.1Sisaki#ifdef __HAVE_ATOMIC64_OPS
1081.1Sisakiatf_sync_postfetch(__sync_add_and_fetch_8, uint64_t, PRIx64);
1091.1Sisaki#endif
1101.1Sisaki
1111.1SisakiATF_TP_ADD_TCS(tp)
1121.1Sisaki{
1131.1Sisaki	ATF_TP_ADD_TC(tp, __sync_fetch_and_add_1);
1141.1Sisaki	ATF_TP_ADD_TC(tp, __sync_fetch_and_add_2);
1151.1Sisaki	ATF_TP_ADD_TC(tp, __sync_fetch_and_add_4);
1161.1Sisaki#ifdef __HAVE_ATOMIC64_OPS
1171.1Sisaki	ATF_TP_ADD_TC(tp, __sync_fetch_and_add_8);
1181.1Sisaki#endif
1191.1Sisaki
1201.1Sisaki	ATF_TP_ADD_TC(tp, __sync_add_and_fetch_1);
1211.1Sisaki	ATF_TP_ADD_TC(tp, __sync_add_and_fetch_2);
1221.1Sisaki	ATF_TP_ADD_TC(tp, __sync_add_and_fetch_4);
1231.1Sisaki#ifdef __HAVE_ATOMIC64_OPS
1241.1Sisaki	ATF_TP_ADD_TC(tp, __sync_add_and_fetch_8);
1251.1Sisaki#endif
1261.1Sisaki
1271.1Sisaki	return atf_no_error();
1281.1Sisaki}
129