18a7d0e8cSEnji Cooper /*- 28a7d0e8cSEnji Cooper * Copyright (c) 2005 David Schultz <das@FreeBSD.org> 38a7d0e8cSEnji Cooper * All rights reserved. 48a7d0e8cSEnji Cooper * 58a7d0e8cSEnji Cooper * Redistribution and use in source and binary forms, with or without 68a7d0e8cSEnji Cooper * modification, are permitted provided that the following conditions 78a7d0e8cSEnji Cooper * are met: 88a7d0e8cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 98a7d0e8cSEnji Cooper * notice, this list of conditions and the following disclaimer. 108a7d0e8cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 118a7d0e8cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 128a7d0e8cSEnji Cooper * documentation and/or other materials provided with the distribution. 138a7d0e8cSEnji Cooper * 148a7d0e8cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 158a7d0e8cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 168a7d0e8cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 178a7d0e8cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 188a7d0e8cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 198a7d0e8cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 208a7d0e8cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 218a7d0e8cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 228a7d0e8cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 238a7d0e8cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 248a7d0e8cSEnji Cooper * SUCH DAMAGE. 258a7d0e8cSEnji Cooper */ 268a7d0e8cSEnji Cooper 278a7d0e8cSEnji Cooper /* 288a7d0e8cSEnji Cooper * Test for lround(), lroundf(), llround(), and llroundf(). 298a7d0e8cSEnji Cooper */ 308a7d0e8cSEnji Cooper 318a7d0e8cSEnji Cooper #include <sys/cdefs.h> 328a7d0e8cSEnji Cooper __FBSDID("$FreeBSD$"); 338a7d0e8cSEnji Cooper 348a7d0e8cSEnji Cooper #include <fenv.h> 358a7d0e8cSEnji Cooper #include <limits.h> 368a7d0e8cSEnji Cooper #include <math.h> 378a7d0e8cSEnji Cooper #include <stdio.h> 388a7d0e8cSEnji Cooper 39*133bc645SAlex Richardson #include "test-utils.h" 40*133bc645SAlex Richardson 41*133bc645SAlex Richardson #define IGNORE 0x12345 42*133bc645SAlex Richardson 438a7d0e8cSEnji Cooper /* 448a7d0e8cSEnji Cooper * XXX The volatile here is to avoid gcc's bogus constant folding and work 458a7d0e8cSEnji Cooper * around the lack of support for the FENV_ACCESS pragma. 468a7d0e8cSEnji Cooper */ 478a7d0e8cSEnji Cooper #define test(func, x, result, excepts) do { \ 488a7d0e8cSEnji Cooper volatile double _d = x; \ 49*133bc645SAlex Richardson ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ 50*133bc645SAlex Richardson volatile double _r = (func)(_d); \ 51*133bc645SAlex Richardson CHECK_FP_EXCEPTIONS_MSG(excepts, FE_ALL_EXCEPT, "for %s(%s)", \ 52*133bc645SAlex Richardson #func, #x); \ 53*133bc645SAlex Richardson if ((excepts & FE_INVALID) != 0) { \ 54*133bc645SAlex Richardson ATF_REQUIRE_EQ(result, IGNORE); \ 55*133bc645SAlex Richardson ATF_CHECK_EQ_MSG(FE_INVALID, fetestexcept(FE_INVALID), \ 56*133bc645SAlex Richardson "FE_INVALID not set correctly for %s(%s)", #func, #x); \ 57*133bc645SAlex Richardson } else { \ 58*133bc645SAlex Richardson ATF_REQUIRE_MSG(result != IGNORE, "Expected can't be IGNORE!"); \ 59*133bc645SAlex Richardson ATF_REQUIRE_EQ(result, (__STRING(func(_d)), _r)); \ 60*133bc645SAlex Richardson } \ 618a7d0e8cSEnji Cooper } while (0) 628a7d0e8cSEnji Cooper 638a7d0e8cSEnji Cooper #define testall(x, result, excepts) do { \ 648a7d0e8cSEnji Cooper test(lround, x, result, excepts); \ 658a7d0e8cSEnji Cooper test(lroundf, x, result, excepts); \ 668a7d0e8cSEnji Cooper test(llround, x, result, excepts); \ 678a7d0e8cSEnji Cooper test(llroundf, x, result, excepts); \ 688a7d0e8cSEnji Cooper } while (0) 698a7d0e8cSEnji Cooper 708a7d0e8cSEnji Cooper #pragma STDC FENV_ACCESS ON 718a7d0e8cSEnji Cooper 72*133bc645SAlex Richardson ATF_TC_WITHOUT_HEAD(main); 73*133bc645SAlex Richardson ATF_TC_BODY(main, tc) 748a7d0e8cSEnji Cooper { 75*133bc645SAlex Richardson atf_tc_expect_fail("https://bugs.freebsd.org/205451"); 768a7d0e8cSEnji Cooper testall(0.0, 0, 0); 778a7d0e8cSEnji Cooper testall(0.25, 0, FE_INEXACT); 788a7d0e8cSEnji Cooper testall(0.5, 1, FE_INEXACT); 798a7d0e8cSEnji Cooper testall(-0.5, -1, FE_INEXACT); 808a7d0e8cSEnji Cooper testall(1.0, 1, 0); 818a7d0e8cSEnji Cooper testall(0x12345000p0, 0x12345000, 0); 828a7d0e8cSEnji Cooper testall(0x1234.fp0, 0x1235, FE_INEXACT); 838a7d0e8cSEnji Cooper testall(INFINITY, IGNORE, FE_INVALID); 848a7d0e8cSEnji Cooper testall(NAN, IGNORE, FE_INVALID); 858a7d0e8cSEnji Cooper 868a7d0e8cSEnji Cooper #if (LONG_MAX == 0x7fffffffl) 878a7d0e8cSEnji Cooper test(lround, 0x7fffffff.8p0, IGNORE, FE_INVALID); 888a7d0e8cSEnji Cooper test(lround, -0x80000000.8p0, IGNORE, FE_INVALID); 898a7d0e8cSEnji Cooper test(lround, 0x80000000.0p0, IGNORE, FE_INVALID); 908a7d0e8cSEnji Cooper test(lround, 0x7fffffff.4p0, 0x7fffffffl, FE_INEXACT); 918a7d0e8cSEnji Cooper test(lround, -0x80000000.4p0, -0x80000000l, FE_INEXACT); 928a7d0e8cSEnji Cooper test(lroundf, 0x80000000.0p0f, IGNORE, FE_INVALID); 938a7d0e8cSEnji Cooper test(lroundf, 0x7fffff80.0p0f, 0x7fffff80l, 0); 948a7d0e8cSEnji Cooper #elif (LONG_MAX == 0x7fffffffffffffffll) 958a7d0e8cSEnji Cooper test(lround, 0x8000000000000000.0p0, IGNORE, FE_INVALID); 968a7d0e8cSEnji Cooper test(lroundf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID); 978a7d0e8cSEnji Cooper test(lround, 0x7ffffffffffffc00.0p0, 0x7ffffffffffffc00l, 0); 988a7d0e8cSEnji Cooper test(lroundf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000l, 0); 998a7d0e8cSEnji Cooper test(lround, -0x8000000000000800.0p0, IGNORE, FE_INVALID); 1008a7d0e8cSEnji Cooper test(lroundf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID); 101*133bc645SAlex Richardson test(lround, -0x8000000000000000.0p0, (long)-0x8000000000000000l, 0); 102*133bc645SAlex Richardson test(lroundf, -0x8000000000000000.0p0f, (long)-0x8000000000000000l, 0); 1038a7d0e8cSEnji Cooper #else 1048a7d0e8cSEnji Cooper #error "Unsupported long size" 1058a7d0e8cSEnji Cooper #endif 1068a7d0e8cSEnji Cooper 1078a7d0e8cSEnji Cooper #if (LLONG_MAX == 0x7fffffffffffffffLL) 1088a7d0e8cSEnji Cooper test(llround, 0x8000000000000000.0p0, IGNORE, FE_INVALID); 1098a7d0e8cSEnji Cooper test(llroundf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID); 1108a7d0e8cSEnji Cooper test(llround, 0x7ffffffffffffc00.0p0, 0x7ffffffffffffc00ll, 0); 1118a7d0e8cSEnji Cooper test(llroundf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000ll, 0); 1128a7d0e8cSEnji Cooper test(llround, -0x8000000000000800.0p0, IGNORE, FE_INVALID); 1138a7d0e8cSEnji Cooper test(llroundf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID); 114*133bc645SAlex Richardson test(llround, -0x8000000000000000.0p0, (long long)-0x8000000000000000ll, 0); 115*133bc645SAlex Richardson test(llroundf, -0x8000000000000000.0p0f, (long long)-0x8000000000000000ll, 0); 1168a7d0e8cSEnji Cooper #else 1178a7d0e8cSEnji Cooper #error "Unsupported long long size" 1188a7d0e8cSEnji Cooper #endif 119*133bc645SAlex Richardson } 1208a7d0e8cSEnji Cooper 121*133bc645SAlex Richardson ATF_TP_ADD_TCS(tp) 122*133bc645SAlex Richardson { 123*133bc645SAlex Richardson ATF_TP_ADD_TC(tp, main); 1248a7d0e8cSEnji Cooper 125*133bc645SAlex Richardson return (atf_no_error()); 1268a7d0e8cSEnji Cooper } 127