1*8a7d0e8cSEnji Cooper /*- 2*8a7d0e8cSEnji Cooper * Copyright (c) 2008 David Schultz <das@FreeBSD.org> 3*8a7d0e8cSEnji Cooper * All rights reserved. 4*8a7d0e8cSEnji Cooper * 5*8a7d0e8cSEnji Cooper * Redistribution and use in source and binary forms, with or without 6*8a7d0e8cSEnji Cooper * modification, are permitted provided that the following conditions 7*8a7d0e8cSEnji Cooper * are met: 8*8a7d0e8cSEnji Cooper * 1. Redistributions of source code must retain the above copyright 9*8a7d0e8cSEnji Cooper * notice, this list of conditions and the following disclaimer. 10*8a7d0e8cSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 11*8a7d0e8cSEnji Cooper * notice, this list of conditions and the following disclaimer in the 12*8a7d0e8cSEnji Cooper * documentation and/or other materials provided with the distribution. 13*8a7d0e8cSEnji Cooper * 14*8a7d0e8cSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*8a7d0e8cSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*8a7d0e8cSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*8a7d0e8cSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*8a7d0e8cSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*8a7d0e8cSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*8a7d0e8cSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*8a7d0e8cSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*8a7d0e8cSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*8a7d0e8cSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*8a7d0e8cSEnji Cooper * SUCH DAMAGE. 25*8a7d0e8cSEnji Cooper */ 26*8a7d0e8cSEnji Cooper 27*8a7d0e8cSEnji Cooper /* 28*8a7d0e8cSEnji Cooper * Tests for fma{,f,l}(). 29*8a7d0e8cSEnji Cooper */ 30*8a7d0e8cSEnji Cooper 31*8a7d0e8cSEnji Cooper #include <sys/cdefs.h> 32*8a7d0e8cSEnji Cooper __FBSDID("$FreeBSD$"); 33*8a7d0e8cSEnji Cooper 34*8a7d0e8cSEnji Cooper #include <sys/param.h> 35*8a7d0e8cSEnji Cooper #include <assert.h> 36*8a7d0e8cSEnji Cooper #include <fenv.h> 37*8a7d0e8cSEnji Cooper #include <float.h> 38*8a7d0e8cSEnji Cooper #include <math.h> 39*8a7d0e8cSEnji Cooper #include <stdio.h> 40*8a7d0e8cSEnji Cooper #include <stdlib.h> 41*8a7d0e8cSEnji Cooper 42*8a7d0e8cSEnji Cooper #include "test-utils.h" 43*8a7d0e8cSEnji Cooper 44*8a7d0e8cSEnji Cooper #pragma STDC FENV_ACCESS ON 45*8a7d0e8cSEnji Cooper 46*8a7d0e8cSEnji Cooper /* 47*8a7d0e8cSEnji Cooper * Test that a function returns the correct value and sets the 48*8a7d0e8cSEnji Cooper * exception flags correctly. The exceptmask specifies which 49*8a7d0e8cSEnji Cooper * exceptions we should check. We need to be lenient for several 50*8a7d0e8cSEnji Cooper * reasons, but mainly because on some architectures it's impossible 51*8a7d0e8cSEnji Cooper * to raise FE_OVERFLOW without raising FE_INEXACT. 52*8a7d0e8cSEnji Cooper * 53*8a7d0e8cSEnji Cooper * These are macros instead of functions so that assert provides more 54*8a7d0e8cSEnji Cooper * meaningful error messages. 55*8a7d0e8cSEnji Cooper */ 56*8a7d0e8cSEnji Cooper #define test(func, x, y, z, result, exceptmask, excepts) do { \ 57*8a7d0e8cSEnji Cooper volatile long double _vx = (x), _vy = (y), _vz = (z); \ 58*8a7d0e8cSEnji Cooper assert(feclearexcept(FE_ALL_EXCEPT) == 0); \ 59*8a7d0e8cSEnji Cooper assert(fpequal((func)(_vx, _vy, _vz), (result))); \ 60*8a7d0e8cSEnji Cooper assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \ 61*8a7d0e8cSEnji Cooper } while (0) 62*8a7d0e8cSEnji Cooper 63*8a7d0e8cSEnji Cooper #define testall(x, y, z, result, exceptmask, excepts) do { \ 64*8a7d0e8cSEnji Cooper test(fma, (double)(x), (double)(y), (double)(z), \ 65*8a7d0e8cSEnji Cooper (double)(result), (exceptmask), (excepts)); \ 66*8a7d0e8cSEnji Cooper test(fmaf, (float)(x), (float)(y), (float)(z), \ 67*8a7d0e8cSEnji Cooper (float)(result), (exceptmask), (excepts)); \ 68*8a7d0e8cSEnji Cooper test(fmal, (x), (y), (z), (result), (exceptmask), (excepts)); \ 69*8a7d0e8cSEnji Cooper } while (0) 70*8a7d0e8cSEnji Cooper 71*8a7d0e8cSEnji Cooper /* Test in all rounding modes. */ 72*8a7d0e8cSEnji Cooper #define testrnd(func, x, y, z, rn, ru, rd, rz, exceptmask, excepts) do { \ 73*8a7d0e8cSEnji Cooper fesetround(FE_TONEAREST); \ 74*8a7d0e8cSEnji Cooper test((func), (x), (y), (z), (rn), (exceptmask), (excepts)); \ 75*8a7d0e8cSEnji Cooper fesetround(FE_UPWARD); \ 76*8a7d0e8cSEnji Cooper test((func), (x), (y), (z), (ru), (exceptmask), (excepts)); \ 77*8a7d0e8cSEnji Cooper fesetround(FE_DOWNWARD); \ 78*8a7d0e8cSEnji Cooper test((func), (x), (y), (z), (rd), (exceptmask), (excepts)); \ 79*8a7d0e8cSEnji Cooper fesetround(FE_TOWARDZERO); \ 80*8a7d0e8cSEnji Cooper test((func), (x), (y), (z), (rz), (exceptmask), (excepts)); \ 81*8a7d0e8cSEnji Cooper } while (0) 82*8a7d0e8cSEnji Cooper 83*8a7d0e8cSEnji Cooper /* 84*8a7d0e8cSEnji Cooper * This is needed because clang constant-folds fma in ways that are incorrect 85*8a7d0e8cSEnji Cooper * in rounding modes other than FE_TONEAREST. 86*8a7d0e8cSEnji Cooper */ 87*8a7d0e8cSEnji Cooper volatile double one = 1.0; 88*8a7d0e8cSEnji Cooper 89*8a7d0e8cSEnji Cooper static void 90*8a7d0e8cSEnji Cooper test_zeroes(void) 91*8a7d0e8cSEnji Cooper { 92*8a7d0e8cSEnji Cooper const int rd = (fegetround() == FE_DOWNWARD); 93*8a7d0e8cSEnji Cooper 94*8a7d0e8cSEnji Cooper testall(0.0, 0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); 95*8a7d0e8cSEnji Cooper testall(1.0, 0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); 96*8a7d0e8cSEnji Cooper testall(0.0, 1.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); 97*8a7d0e8cSEnji Cooper testall(0.0, 0.0, 1.0, 1.0, ALL_STD_EXCEPT, 0); 98*8a7d0e8cSEnji Cooper 99*8a7d0e8cSEnji Cooper testall(-0.0, 0.0, 0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 100*8a7d0e8cSEnji Cooper testall(0.0, -0.0, 0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 101*8a7d0e8cSEnji Cooper testall(-0.0, -0.0, 0.0, 0.0, ALL_STD_EXCEPT, 0); 102*8a7d0e8cSEnji Cooper testall(0.0, 0.0, -0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 103*8a7d0e8cSEnji Cooper testall(-0.0, -0.0, -0.0, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 104*8a7d0e8cSEnji Cooper 105*8a7d0e8cSEnji Cooper testall(-0.0, 0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0); 106*8a7d0e8cSEnji Cooper testall(0.0, -0.0, -0.0, -0.0, ALL_STD_EXCEPT, 0); 107*8a7d0e8cSEnji Cooper 108*8a7d0e8cSEnji Cooper testall(-one, one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 109*8a7d0e8cSEnji Cooper testall(one, -one, one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 110*8a7d0e8cSEnji Cooper testall(-one, -one, -one, rd ? -0.0 : 0.0, ALL_STD_EXCEPT, 0); 111*8a7d0e8cSEnji Cooper 112*8a7d0e8cSEnji Cooper switch (fegetround()) { 113*8a7d0e8cSEnji Cooper case FE_TONEAREST: 114*8a7d0e8cSEnji Cooper case FE_TOWARDZERO: 115*8a7d0e8cSEnji Cooper test(fmaf, -FLT_MIN, FLT_MIN, 0.0, -0.0, 116*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW); 117*8a7d0e8cSEnji Cooper test(fma, -DBL_MIN, DBL_MIN, 0.0, -0.0, 118*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW); 119*8a7d0e8cSEnji Cooper test(fmal, -LDBL_MIN, LDBL_MIN, 0.0, -0.0, 120*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT | FE_UNDERFLOW); 121*8a7d0e8cSEnji Cooper } 122*8a7d0e8cSEnji Cooper } 123*8a7d0e8cSEnji Cooper 124*8a7d0e8cSEnji Cooper static void 125*8a7d0e8cSEnji Cooper test_infinities(void) 126*8a7d0e8cSEnji Cooper { 127*8a7d0e8cSEnji Cooper 128*8a7d0e8cSEnji Cooper testall(INFINITY, 1.0, -1.0, INFINITY, ALL_STD_EXCEPT, 0); 129*8a7d0e8cSEnji Cooper testall(-1.0, INFINITY, 0.0, -INFINITY, ALL_STD_EXCEPT, 0); 130*8a7d0e8cSEnji Cooper testall(0.0, 0.0, INFINITY, INFINITY, ALL_STD_EXCEPT, 0); 131*8a7d0e8cSEnji Cooper testall(1.0, 1.0, INFINITY, INFINITY, ALL_STD_EXCEPT, 0); 132*8a7d0e8cSEnji Cooper testall(1.0, 1.0, -INFINITY, -INFINITY, ALL_STD_EXCEPT, 0); 133*8a7d0e8cSEnji Cooper 134*8a7d0e8cSEnji Cooper testall(INFINITY, -INFINITY, 1.0, -INFINITY, ALL_STD_EXCEPT, 0); 135*8a7d0e8cSEnji Cooper testall(INFINITY, INFINITY, 1.0, INFINITY, ALL_STD_EXCEPT, 0); 136*8a7d0e8cSEnji Cooper testall(-INFINITY, -INFINITY, INFINITY, INFINITY, ALL_STD_EXCEPT, 0); 137*8a7d0e8cSEnji Cooper 138*8a7d0e8cSEnji Cooper testall(0.0, INFINITY, 1.0, NAN, ALL_STD_EXCEPT, FE_INVALID); 139*8a7d0e8cSEnji Cooper testall(INFINITY, 0.0, -0.0, NAN, ALL_STD_EXCEPT, FE_INVALID); 140*8a7d0e8cSEnji Cooper 141*8a7d0e8cSEnji Cooper /* The invalid exception is optional in this case. */ 142*8a7d0e8cSEnji Cooper testall(INFINITY, 0.0, NAN, NAN, ALL_STD_EXCEPT & ~FE_INVALID, 0); 143*8a7d0e8cSEnji Cooper 144*8a7d0e8cSEnji Cooper testall(INFINITY, INFINITY, -INFINITY, NAN, 145*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INVALID); 146*8a7d0e8cSEnji Cooper testall(-INFINITY, INFINITY, INFINITY, NAN, 147*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INVALID); 148*8a7d0e8cSEnji Cooper testall(INFINITY, -1.0, INFINITY, NAN, 149*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INVALID); 150*8a7d0e8cSEnji Cooper 151*8a7d0e8cSEnji Cooper test(fmaf, FLT_MAX, FLT_MAX, -INFINITY, -INFINITY, ALL_STD_EXCEPT, 0); 152*8a7d0e8cSEnji Cooper test(fma, DBL_MAX, DBL_MAX, -INFINITY, -INFINITY, ALL_STD_EXCEPT, 0); 153*8a7d0e8cSEnji Cooper test(fmal, LDBL_MAX, LDBL_MAX, -INFINITY, -INFINITY, 154*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, 0); 155*8a7d0e8cSEnji Cooper test(fmaf, FLT_MAX, -FLT_MAX, INFINITY, INFINITY, ALL_STD_EXCEPT, 0); 156*8a7d0e8cSEnji Cooper test(fma, DBL_MAX, -DBL_MAX, INFINITY, INFINITY, ALL_STD_EXCEPT, 0); 157*8a7d0e8cSEnji Cooper test(fmal, LDBL_MAX, -LDBL_MAX, INFINITY, INFINITY, 158*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, 0); 159*8a7d0e8cSEnji Cooper } 160*8a7d0e8cSEnji Cooper 161*8a7d0e8cSEnji Cooper static void 162*8a7d0e8cSEnji Cooper test_nans(void) 163*8a7d0e8cSEnji Cooper { 164*8a7d0e8cSEnji Cooper 165*8a7d0e8cSEnji Cooper testall(NAN, 0.0, 0.0, NAN, ALL_STD_EXCEPT, 0); 166*8a7d0e8cSEnji Cooper testall(1.0, NAN, 1.0, NAN, ALL_STD_EXCEPT, 0); 167*8a7d0e8cSEnji Cooper testall(1.0, -1.0, NAN, NAN, ALL_STD_EXCEPT, 0); 168*8a7d0e8cSEnji Cooper testall(0.0, 0.0, NAN, NAN, ALL_STD_EXCEPT, 0); 169*8a7d0e8cSEnji Cooper testall(NAN, NAN, NAN, NAN, ALL_STD_EXCEPT, 0); 170*8a7d0e8cSEnji Cooper 171*8a7d0e8cSEnji Cooper /* x*y should not raise an inexact/overflow/underflow if z is NaN. */ 172*8a7d0e8cSEnji Cooper testall(M_PI, M_PI, NAN, NAN, ALL_STD_EXCEPT, 0); 173*8a7d0e8cSEnji Cooper test(fmaf, FLT_MIN, FLT_MIN, NAN, NAN, ALL_STD_EXCEPT, 0); 174*8a7d0e8cSEnji Cooper test(fma, DBL_MIN, DBL_MIN, NAN, NAN, ALL_STD_EXCEPT, 0); 175*8a7d0e8cSEnji Cooper test(fmal, LDBL_MIN, LDBL_MIN, NAN, NAN, ALL_STD_EXCEPT, 0); 176*8a7d0e8cSEnji Cooper test(fmaf, FLT_MAX, FLT_MAX, NAN, NAN, ALL_STD_EXCEPT, 0); 177*8a7d0e8cSEnji Cooper test(fma, DBL_MAX, DBL_MAX, NAN, NAN, ALL_STD_EXCEPT, 0); 178*8a7d0e8cSEnji Cooper test(fmal, LDBL_MAX, LDBL_MAX, NAN, NAN, ALL_STD_EXCEPT, 0); 179*8a7d0e8cSEnji Cooper } 180*8a7d0e8cSEnji Cooper 181*8a7d0e8cSEnji Cooper /* 182*8a7d0e8cSEnji Cooper * Tests for cases where z is very small compared to x*y. 183*8a7d0e8cSEnji Cooper */ 184*8a7d0e8cSEnji Cooper static void 185*8a7d0e8cSEnji Cooper test_small_z(void) 186*8a7d0e8cSEnji Cooper { 187*8a7d0e8cSEnji Cooper 188*8a7d0e8cSEnji Cooper /* x*y positive, z positive */ 189*8a7d0e8cSEnji Cooper if (fegetround() == FE_UPWARD) { 190*8a7d0e8cSEnji Cooper test(fmaf, one, one, 0x1.0p-100, 1.0 + FLT_EPSILON, 191*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 192*8a7d0e8cSEnji Cooper test(fma, one, one, 0x1.0p-200, 1.0 + DBL_EPSILON, 193*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 194*8a7d0e8cSEnji Cooper test(fmal, one, one, 0x1.0p-200, 1.0 + LDBL_EPSILON, 195*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 196*8a7d0e8cSEnji Cooper } else { 197*8a7d0e8cSEnji Cooper testall(0x1.0p100, one, 0x1.0p-100, 0x1.0p100, 198*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 199*8a7d0e8cSEnji Cooper } 200*8a7d0e8cSEnji Cooper 201*8a7d0e8cSEnji Cooper /* x*y negative, z negative */ 202*8a7d0e8cSEnji Cooper if (fegetround() == FE_DOWNWARD) { 203*8a7d0e8cSEnji Cooper test(fmaf, -one, one, -0x1.0p-100, -(1.0 + FLT_EPSILON), 204*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 205*8a7d0e8cSEnji Cooper test(fma, -one, one, -0x1.0p-200, -(1.0 + DBL_EPSILON), 206*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 207*8a7d0e8cSEnji Cooper test(fmal, -one, one, -0x1.0p-200, -(1.0 + LDBL_EPSILON), 208*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 209*8a7d0e8cSEnji Cooper } else { 210*8a7d0e8cSEnji Cooper testall(0x1.0p100, -one, -0x1.0p-100, -0x1.0p100, 211*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 212*8a7d0e8cSEnji Cooper } 213*8a7d0e8cSEnji Cooper 214*8a7d0e8cSEnji Cooper /* x*y positive, z negative */ 215*8a7d0e8cSEnji Cooper if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) { 216*8a7d0e8cSEnji Cooper test(fmaf, one, one, -0x1.0p-100, 1.0 - FLT_EPSILON / 2, 217*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 218*8a7d0e8cSEnji Cooper test(fma, one, one, -0x1.0p-200, 1.0 - DBL_EPSILON / 2, 219*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 220*8a7d0e8cSEnji Cooper test(fmal, one, one, -0x1.0p-200, 1.0 - LDBL_EPSILON / 2, 221*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 222*8a7d0e8cSEnji Cooper } else { 223*8a7d0e8cSEnji Cooper testall(0x1.0p100, one, -0x1.0p-100, 0x1.0p100, 224*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 225*8a7d0e8cSEnji Cooper } 226*8a7d0e8cSEnji Cooper 227*8a7d0e8cSEnji Cooper /* x*y negative, z positive */ 228*8a7d0e8cSEnji Cooper if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) { 229*8a7d0e8cSEnji Cooper test(fmaf, -one, one, 0x1.0p-100, -1.0 + FLT_EPSILON / 2, 230*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 231*8a7d0e8cSEnji Cooper test(fma, -one, one, 0x1.0p-200, -1.0 + DBL_EPSILON / 2, 232*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 233*8a7d0e8cSEnji Cooper test(fmal, -one, one, 0x1.0p-200, -1.0 + LDBL_EPSILON / 2, 234*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 235*8a7d0e8cSEnji Cooper } else { 236*8a7d0e8cSEnji Cooper testall(-0x1.0p100, one, 0x1.0p-100, -0x1.0p100, 237*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 238*8a7d0e8cSEnji Cooper } 239*8a7d0e8cSEnji Cooper } 240*8a7d0e8cSEnji Cooper 241*8a7d0e8cSEnji Cooper /* 242*8a7d0e8cSEnji Cooper * Tests for cases where z is very large compared to x*y. 243*8a7d0e8cSEnji Cooper */ 244*8a7d0e8cSEnji Cooper static void 245*8a7d0e8cSEnji Cooper test_big_z(void) 246*8a7d0e8cSEnji Cooper { 247*8a7d0e8cSEnji Cooper 248*8a7d0e8cSEnji Cooper /* z positive, x*y positive */ 249*8a7d0e8cSEnji Cooper if (fegetround() == FE_UPWARD) { 250*8a7d0e8cSEnji Cooper test(fmaf, 0x1.0p-50, 0x1.0p-50, 1.0, 1.0 + FLT_EPSILON, 251*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 252*8a7d0e8cSEnji Cooper test(fma, 0x1.0p-100, 0x1.0p-100, 1.0, 1.0 + DBL_EPSILON, 253*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 254*8a7d0e8cSEnji Cooper test(fmal, 0x1.0p-100, 0x1.0p-100, 1.0, 1.0 + LDBL_EPSILON, 255*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 256*8a7d0e8cSEnji Cooper } else { 257*8a7d0e8cSEnji Cooper testall(-0x1.0p-50, -0x1.0p-50, 0x1.0p100, 0x1.0p100, 258*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 259*8a7d0e8cSEnji Cooper } 260*8a7d0e8cSEnji Cooper 261*8a7d0e8cSEnji Cooper /* z negative, x*y negative */ 262*8a7d0e8cSEnji Cooper if (fegetround() == FE_DOWNWARD) { 263*8a7d0e8cSEnji Cooper test(fmaf, -0x1.0p-50, 0x1.0p-50, -1.0, -(1.0 + FLT_EPSILON), 264*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 265*8a7d0e8cSEnji Cooper test(fma, -0x1.0p-100, 0x1.0p-100, -1.0, -(1.0 + DBL_EPSILON), 266*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 267*8a7d0e8cSEnji Cooper test(fmal, -0x1.0p-100, 0x1.0p-100, -1.0, -(1.0 + LDBL_EPSILON), 268*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 269*8a7d0e8cSEnji Cooper } else { 270*8a7d0e8cSEnji Cooper testall(0x1.0p-50, -0x1.0p-50, -0x1.0p100, -0x1.0p100, 271*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 272*8a7d0e8cSEnji Cooper } 273*8a7d0e8cSEnji Cooper 274*8a7d0e8cSEnji Cooper /* z negative, x*y positive */ 275*8a7d0e8cSEnji Cooper if (fegetround() == FE_UPWARD || fegetround() == FE_TOWARDZERO) { 276*8a7d0e8cSEnji Cooper test(fmaf, -0x1.0p-50, -0x1.0p-50, -1.0, 277*8a7d0e8cSEnji Cooper -1.0 + FLT_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); 278*8a7d0e8cSEnji Cooper test(fma, -0x1.0p-100, -0x1.0p-100, -1.0, 279*8a7d0e8cSEnji Cooper -1.0 + DBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); 280*8a7d0e8cSEnji Cooper test(fmal, -0x1.0p-100, -0x1.0p-100, -1.0, 281*8a7d0e8cSEnji Cooper -1.0 + LDBL_EPSILON / 2, ALL_STD_EXCEPT, FE_INEXACT); 282*8a7d0e8cSEnji Cooper } else { 283*8a7d0e8cSEnji Cooper testall(0x1.0p-50, 0x1.0p-50, -0x1.0p100, -0x1.0p100, 284*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 285*8a7d0e8cSEnji Cooper } 286*8a7d0e8cSEnji Cooper 287*8a7d0e8cSEnji Cooper /* z positive, x*y negative */ 288*8a7d0e8cSEnji Cooper if (fegetround() == FE_DOWNWARD || fegetround() == FE_TOWARDZERO) { 289*8a7d0e8cSEnji Cooper test(fmaf, 0x1.0p-50, -0x1.0p-50, 1.0, 1.0 - FLT_EPSILON / 2, 290*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 291*8a7d0e8cSEnji Cooper test(fma, 0x1.0p-100, -0x1.0p-100, 1.0, 1.0 - DBL_EPSILON / 2, 292*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 293*8a7d0e8cSEnji Cooper test(fmal, 0x1.0p-100, -0x1.0p-100, 1.0, 1.0 - LDBL_EPSILON / 2, 294*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 295*8a7d0e8cSEnji Cooper } else { 296*8a7d0e8cSEnji Cooper testall(-0x1.0p-50, 0x1.0p-50, 0x1.0p100, 0x1.0p100, 297*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 298*8a7d0e8cSEnji Cooper } 299*8a7d0e8cSEnji Cooper } 300*8a7d0e8cSEnji Cooper 301*8a7d0e8cSEnji Cooper static void 302*8a7d0e8cSEnji Cooper test_accuracy(void) 303*8a7d0e8cSEnji Cooper { 304*8a7d0e8cSEnji Cooper 305*8a7d0e8cSEnji Cooper /* ilogb(x*y) - ilogb(z) = 20 */ 306*8a7d0e8cSEnji Cooper testrnd(fmaf, -0x1.c139d8p-51, -0x1.600e7ap32, 0x1.26558cp-38, 307*8a7d0e8cSEnji Cooper 0x1.34e48ap-18, 0x1.34e48cp-18, 0x1.34e48ap-18, 0x1.34e48ap-18, 308*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 309*8a7d0e8cSEnji Cooper testrnd(fma, -0x1.c139d7b84f1a3p-51, -0x1.600e7a2a16484p32, 310*8a7d0e8cSEnji Cooper 0x1.26558cac31580p-38, 0x1.34e48a78aae97p-18, 311*8a7d0e8cSEnji Cooper 0x1.34e48a78aae97p-18, 0x1.34e48a78aae96p-18, 312*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96p-18, ALL_STD_EXCEPT, FE_INEXACT); 313*8a7d0e8cSEnji Cooper #if LDBL_MANT_DIG == 113 314*8a7d0e8cSEnji Cooper testrnd(fmal, -0x1.c139d7b84f1a3079263afcc5bae3p-51L, 315*8a7d0e8cSEnji Cooper -0x1.600e7a2a164840edbe2e7d301a72p32L, 316*8a7d0e8cSEnji Cooper 0x1.26558cac315807eb07e448042101p-38L, 317*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96c76ed36077dd387p-18L, 318*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96c76ed36077dd388p-18L, 319*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96c76ed36077dd387p-18L, 320*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96c76ed36077dd387p-18L, 321*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 322*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 64 323*8a7d0e8cSEnji Cooper testrnd(fmal, -0x1.c139d7b84f1a307ap-51L, -0x1.600e7a2a164840eep32L, 324*8a7d0e8cSEnji Cooper 0x1.26558cac315807ecp-38L, 0x1.34e48a78aae96c78p-18L, 325*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96c78p-18L, 0x1.34e48a78aae96c76p-18L, 326*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96c76p-18L, ALL_STD_EXCEPT, FE_INEXACT); 327*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 53 328*8a7d0e8cSEnji Cooper testrnd(fmal, -0x1.c139d7b84f1a3p-51L, -0x1.600e7a2a16484p32L, 329*8a7d0e8cSEnji Cooper 0x1.26558cac31580p-38L, 0x1.34e48a78aae97p-18L, 330*8a7d0e8cSEnji Cooper 0x1.34e48a78aae97p-18L, 0x1.34e48a78aae96p-18L, 331*8a7d0e8cSEnji Cooper 0x1.34e48a78aae96p-18L, ALL_STD_EXCEPT, FE_INEXACT); 332*8a7d0e8cSEnji Cooper #endif 333*8a7d0e8cSEnji Cooper 334*8a7d0e8cSEnji Cooper /* ilogb(x*y) - ilogb(z) = -40 */ 335*8a7d0e8cSEnji Cooper testrnd(fmaf, 0x1.98210ap53, 0x1.9556acp-24, 0x1.d87da4p70, 336*8a7d0e8cSEnji Cooper 0x1.d87da4p70, 0x1.d87da6p70, 0x1.d87da4p70, 0x1.d87da4p70, 337*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 338*8a7d0e8cSEnji Cooper testrnd(fma, 0x1.98210ac83fe2bp53, 0x1.9556ac1475f0fp-24, 339*8a7d0e8cSEnji Cooper 0x1.d87da3aafc60ep70, 0x1.d87da3aafda40p70, 340*8a7d0e8cSEnji Cooper 0x1.d87da3aafda40p70, 0x1.d87da3aafda3fp70, 341*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3fp70, ALL_STD_EXCEPT, FE_INEXACT); 342*8a7d0e8cSEnji Cooper #if LDBL_MANT_DIG == 113 343*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.98210ac83fe2a8f65b6278b74cebp53L, 344*8a7d0e8cSEnji Cooper 0x1.9556ac1475f0f28968b61d0de65ap-24L, 345*8a7d0e8cSEnji Cooper 0x1.d87da3aafc60d830aa4c6d73b749p70L, 346*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3f36a69eb86488224p70L, 347*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3f36a69eb86488225p70L, 348*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3f36a69eb86488224p70L, 349*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3f36a69eb86488224p70L, 350*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 351*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 64 352*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.98210ac83fe2a8f6p53L, 0x1.9556ac1475f0f28ap-24L, 353*8a7d0e8cSEnji Cooper 0x1.d87da3aafc60d83p70L, 0x1.d87da3aafda3f36ap70L, 354*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3f36ap70L, 0x1.d87da3aafda3f368p70L, 355*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3f368p70L, ALL_STD_EXCEPT, FE_INEXACT); 356*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 53 357*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.98210ac83fe2bp53L, 0x1.9556ac1475f0fp-24L, 358*8a7d0e8cSEnji Cooper 0x1.d87da3aafc60ep70L, 0x1.d87da3aafda40p70L, 359*8a7d0e8cSEnji Cooper 0x1.d87da3aafda40p70L, 0x1.d87da3aafda3fp70L, 360*8a7d0e8cSEnji Cooper 0x1.d87da3aafda3fp70L, ALL_STD_EXCEPT, FE_INEXACT); 361*8a7d0e8cSEnji Cooper #endif 362*8a7d0e8cSEnji Cooper 363*8a7d0e8cSEnji Cooper /* ilogb(x*y) - ilogb(z) = 0 */ 364*8a7d0e8cSEnji Cooper testrnd(fmaf, 0x1.31ad02p+100, 0x1.2fbf7ap-42, -0x1.c3e106p+58, 365*8a7d0e8cSEnji Cooper -0x1.64c27cp+56, -0x1.64c27ap+56, -0x1.64c27cp+56, 366*8a7d0e8cSEnji Cooper -0x1.64c27ap+56, ALL_STD_EXCEPT, FE_INEXACT); 367*8a7d0e8cSEnji Cooper testrnd(fma, 0x1.31ad012ede8aap+100, 0x1.2fbf79c839067p-42, 368*8a7d0e8cSEnji Cooper -0x1.c3e106929056ep+58, -0x1.64c282b970a5fp+56, 369*8a7d0e8cSEnji Cooper -0x1.64c282b970a5ep+56, -0x1.64c282b970a5fp+56, 370*8a7d0e8cSEnji Cooper -0x1.64c282b970a5ep+56, ALL_STD_EXCEPT, FE_INEXACT); 371*8a7d0e8cSEnji Cooper #if LDBL_MANT_DIG == 113 372*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.31ad012ede8aa282fa1c19376d16p+100L, 373*8a7d0e8cSEnji Cooper 0x1.2fbf79c839066f0f5c68f6d2e814p-42L, 374*8a7d0e8cSEnji Cooper -0x1.c3e106929056ec19de72bfe64215p+58L, 375*8a7d0e8cSEnji Cooper -0x1.64c282b970a612598fc025ca8cddp+56L, 376*8a7d0e8cSEnji Cooper -0x1.64c282b970a612598fc025ca8cddp+56L, 377*8a7d0e8cSEnji Cooper -0x1.64c282b970a612598fc025ca8cdep+56L, 378*8a7d0e8cSEnji Cooper -0x1.64c282b970a612598fc025ca8cddp+56L, 379*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 380*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 64 381*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.31ad012ede8aa4eap+100L, 0x1.2fbf79c839066aeap-42L, 382*8a7d0e8cSEnji Cooper -0x1.c3e106929056e61p+58L, -0x1.64c282b970a60298p+56L, 383*8a7d0e8cSEnji Cooper -0x1.64c282b970a60298p+56L, -0x1.64c282b970a6029ap+56L, 384*8a7d0e8cSEnji Cooper -0x1.64c282b970a60298p+56L, ALL_STD_EXCEPT, FE_INEXACT); 385*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 53 386*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.31ad012ede8aap+100L, 0x1.2fbf79c839067p-42L, 387*8a7d0e8cSEnji Cooper -0x1.c3e106929056ep+58L, -0x1.64c282b970a5fp+56L, 388*8a7d0e8cSEnji Cooper -0x1.64c282b970a5ep+56L, -0x1.64c282b970a5fp+56L, 389*8a7d0e8cSEnji Cooper -0x1.64c282b970a5ep+56L, ALL_STD_EXCEPT, FE_INEXACT); 390*8a7d0e8cSEnji Cooper #endif 391*8a7d0e8cSEnji Cooper 392*8a7d0e8cSEnji Cooper /* x*y (rounded) ~= -z */ 393*8a7d0e8cSEnji Cooper /* XXX spurious inexact exceptions */ 394*8a7d0e8cSEnji Cooper testrnd(fmaf, 0x1.bbffeep-30, -0x1.1d164cp-74, 0x1.ee7296p-104, 395*8a7d0e8cSEnji Cooper -0x1.c46ea8p-128, -0x1.c46ea8p-128, -0x1.c46ea8p-128, 396*8a7d0e8cSEnji Cooper -0x1.c46ea8p-128, ALL_STD_EXCEPT & ~FE_INEXACT, 0); 397*8a7d0e8cSEnji Cooper testrnd(fma, 0x1.bbffeea6fc7d6p-30, 0x1.1d164c6cbf078p-74, 398*8a7d0e8cSEnji Cooper -0x1.ee72993aff948p-104, -0x1.71f72ac7d9d8p-159, 399*8a7d0e8cSEnji Cooper -0x1.71f72ac7d9d8p-159, -0x1.71f72ac7d9d8p-159, 400*8a7d0e8cSEnji Cooper -0x1.71f72ac7d9d8p-159, ALL_STD_EXCEPT & ~FE_INEXACT, 0); 401*8a7d0e8cSEnji Cooper #if LDBL_MANT_DIG == 113 402*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.bbffeea6fc7d65927d147f437675p-30L, 403*8a7d0e8cSEnji Cooper 0x1.1d164c6cbf078b7a22607d1cd6a2p-74L, 404*8a7d0e8cSEnji Cooper -0x1.ee72993aff94973876031bec0944p-104L, 405*8a7d0e8cSEnji Cooper 0x1.64e086175b3a2adc36e607058814p-217L, 406*8a7d0e8cSEnji Cooper 0x1.64e086175b3a2adc36e607058814p-217L, 407*8a7d0e8cSEnji Cooper 0x1.64e086175b3a2adc36e607058814p-217L, 408*8a7d0e8cSEnji Cooper 0x1.64e086175b3a2adc36e607058814p-217L, 409*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT & ~FE_INEXACT, 0); 410*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 64 411*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.bbffeea6fc7d6592p-30L, 0x1.1d164c6cbf078b7ap-74L, 412*8a7d0e8cSEnji Cooper -0x1.ee72993aff949736p-104L, 0x1.af190e7a1ee6ad94p-168L, 413*8a7d0e8cSEnji Cooper 0x1.af190e7a1ee6ad94p-168L, 0x1.af190e7a1ee6ad94p-168L, 414*8a7d0e8cSEnji Cooper 0x1.af190e7a1ee6ad94p-168L, ALL_STD_EXCEPT & ~FE_INEXACT, 0); 415*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 53 416*8a7d0e8cSEnji Cooper testrnd(fmal, 0x1.bbffeea6fc7d6p-30L, 0x1.1d164c6cbf078p-74L, 417*8a7d0e8cSEnji Cooper -0x1.ee72993aff948p-104L, -0x1.71f72ac7d9d8p-159L, 418*8a7d0e8cSEnji Cooper -0x1.71f72ac7d9d8p-159L, -0x1.71f72ac7d9d8p-159L, 419*8a7d0e8cSEnji Cooper -0x1.71f72ac7d9d8p-159L, ALL_STD_EXCEPT & ~FE_INEXACT, 0); 420*8a7d0e8cSEnji Cooper #endif 421*8a7d0e8cSEnji Cooper } 422*8a7d0e8cSEnji Cooper 423*8a7d0e8cSEnji Cooper static void 424*8a7d0e8cSEnji Cooper test_double_rounding(void) 425*8a7d0e8cSEnji Cooper { 426*8a7d0e8cSEnji Cooper 427*8a7d0e8cSEnji Cooper /* 428*8a7d0e8cSEnji Cooper * a = 0x1.8000000000001p0 429*8a7d0e8cSEnji Cooper * b = 0x1.8000000000001p0 430*8a7d0e8cSEnji Cooper * c = -0x0.0000000000000000000000000080...1p+1 431*8a7d0e8cSEnji Cooper * a * b = 0x1.2000000000001800000000000080p+1 432*8a7d0e8cSEnji Cooper * 433*8a7d0e8cSEnji Cooper * The correct behavior is to round DOWN to 0x1.2000000000001p+1 in 434*8a7d0e8cSEnji Cooper * round-to-nearest mode. An implementation that computes a*b+c in 435*8a7d0e8cSEnji Cooper * double+double precision, however, will get 0x1.20000000000018p+1, 436*8a7d0e8cSEnji Cooper * and then round UP. 437*8a7d0e8cSEnji Cooper */ 438*8a7d0e8cSEnji Cooper fesetround(FE_TONEAREST); 439*8a7d0e8cSEnji Cooper test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0, 440*8a7d0e8cSEnji Cooper -0x1.0000000000001p-104, 0x1.2000000000001p+1, 441*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 442*8a7d0e8cSEnji Cooper fesetround(FE_DOWNWARD); 443*8a7d0e8cSEnji Cooper test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0, 444*8a7d0e8cSEnji Cooper -0x1.0000000000001p-104, 0x1.2000000000001p+1, 445*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 446*8a7d0e8cSEnji Cooper fesetround(FE_UPWARD); 447*8a7d0e8cSEnji Cooper test(fma, 0x1.8000000000001p0, 0x1.8000000000001p0, 448*8a7d0e8cSEnji Cooper -0x1.0000000000001p-104, 0x1.2000000000002p+1, 449*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 450*8a7d0e8cSEnji Cooper 451*8a7d0e8cSEnji Cooper fesetround(FE_TONEAREST); 452*8a7d0e8cSEnji Cooper test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200002p+1, 453*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 454*8a7d0e8cSEnji Cooper fesetround(FE_DOWNWARD); 455*8a7d0e8cSEnji Cooper test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200002p+1, 456*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 457*8a7d0e8cSEnji Cooper fesetround(FE_UPWARD); 458*8a7d0e8cSEnji Cooper test(fmaf, 0x1.800002p+0, 0x1.800002p+0, -0x1.000002p-46, 0x1.200004p+1, 459*8a7d0e8cSEnji Cooper ALL_STD_EXCEPT, FE_INEXACT); 460*8a7d0e8cSEnji Cooper 461*8a7d0e8cSEnji Cooper fesetround(FE_TONEAREST); 462*8a7d0e8cSEnji Cooper #if LDBL_MANT_DIG == 64 463*8a7d0e8cSEnji Cooper test(fmal, 0x1.4p+0L, 0x1.0000000000000004p+0L, 0x1p-128L, 464*8a7d0e8cSEnji Cooper 0x1.4000000000000006p+0L, ALL_STD_EXCEPT, FE_INEXACT); 465*8a7d0e8cSEnji Cooper #elif LDBL_MANT_DIG == 113 466*8a7d0e8cSEnji Cooper test(fmal, 0x1.8000000000000000000000000001p+0L, 467*8a7d0e8cSEnji Cooper 0x1.8000000000000000000000000001p+0L, 468*8a7d0e8cSEnji Cooper -0x1.0000000000000000000000000001p-224L, 469*8a7d0e8cSEnji Cooper 0x1.2000000000000000000000000001p+1L, ALL_STD_EXCEPT, FE_INEXACT); 470*8a7d0e8cSEnji Cooper #endif 471*8a7d0e8cSEnji Cooper 472*8a7d0e8cSEnji Cooper } 473*8a7d0e8cSEnji Cooper 474*8a7d0e8cSEnji Cooper int 475*8a7d0e8cSEnji Cooper main(int argc, char *argv[]) 476*8a7d0e8cSEnji Cooper { 477*8a7d0e8cSEnji Cooper int rmodes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO }; 478*8a7d0e8cSEnji Cooper int i, j; 479*8a7d0e8cSEnji Cooper 480*8a7d0e8cSEnji Cooper #if defined(__i386__) 481*8a7d0e8cSEnji Cooper printf("1..0 # SKIP all testcases fail on i386\n"); 482*8a7d0e8cSEnji Cooper exit(0); 483*8a7d0e8cSEnji Cooper #endif 484*8a7d0e8cSEnji Cooper 485*8a7d0e8cSEnji Cooper j = 1; 486*8a7d0e8cSEnji Cooper 487*8a7d0e8cSEnji Cooper printf("1..19\n"); 488*8a7d0e8cSEnji Cooper 489*8a7d0e8cSEnji Cooper for (i = 0; i < nitems(rmodes); i++, j++) { 490*8a7d0e8cSEnji Cooper printf("rmode = %d\n", rmodes[i]); 491*8a7d0e8cSEnji Cooper fesetround(rmodes[i]); 492*8a7d0e8cSEnji Cooper test_zeroes(); 493*8a7d0e8cSEnji Cooper printf("ok %d - fma zeroes\n", j); 494*8a7d0e8cSEnji Cooper } 495*8a7d0e8cSEnji Cooper 496*8a7d0e8cSEnji Cooper for (i = 0; i < nitems(rmodes); i++, j++) { 497*8a7d0e8cSEnji Cooper #if defined(__amd64__) 498*8a7d0e8cSEnji Cooper printf("ok %d # SKIP testcase fails assertion on " 499*8a7d0e8cSEnji Cooper "amd64\n", j); 500*8a7d0e8cSEnji Cooper continue; 501*8a7d0e8cSEnji Cooper #endif 502*8a7d0e8cSEnji Cooper printf("rmode = %d\n", rmodes[i]); 503*8a7d0e8cSEnji Cooper fesetround(rmodes[i]); 504*8a7d0e8cSEnji Cooper test_infinities(); 505*8a7d0e8cSEnji Cooper printf("ok %d - fma infinities\n", j); 506*8a7d0e8cSEnji Cooper } 507*8a7d0e8cSEnji Cooper 508*8a7d0e8cSEnji Cooper fesetround(FE_TONEAREST); 509*8a7d0e8cSEnji Cooper test_nans(); 510*8a7d0e8cSEnji Cooper printf("ok 9 - fma NaNs\n"); 511*8a7d0e8cSEnji Cooper 512*8a7d0e8cSEnji Cooper for (i = 0; i < nitems(rmodes); i++, j++) { 513*8a7d0e8cSEnji Cooper printf("rmode = %d\n", rmodes[i]); 514*8a7d0e8cSEnji Cooper fesetround(rmodes[i]); 515*8a7d0e8cSEnji Cooper test_small_z(); 516*8a7d0e8cSEnji Cooper printf("ok %d - fma small z\n", j); 517*8a7d0e8cSEnji Cooper } 518*8a7d0e8cSEnji Cooper 519*8a7d0e8cSEnji Cooper for (i = 0; i < nitems(rmodes); i++, j++) { 520*8a7d0e8cSEnji Cooper printf("rmode = %d\n", rmodes[i]); 521*8a7d0e8cSEnji Cooper fesetround(rmodes[i]); 522*8a7d0e8cSEnji Cooper test_big_z(); 523*8a7d0e8cSEnji Cooper printf("ok %d - fma big z\n", j); 524*8a7d0e8cSEnji Cooper } 525*8a7d0e8cSEnji Cooper 526*8a7d0e8cSEnji Cooper fesetround(FE_TONEAREST); 527*8a7d0e8cSEnji Cooper test_accuracy(); 528*8a7d0e8cSEnji Cooper printf("ok %d - fma accuracy\n", j); 529*8a7d0e8cSEnji Cooper j++; 530*8a7d0e8cSEnji Cooper 531*8a7d0e8cSEnji Cooper test_double_rounding(); 532*8a7d0e8cSEnji Cooper printf("ok %d - fma double rounding\n", j); 533*8a7d0e8cSEnji Cooper j++; 534*8a7d0e8cSEnji Cooper 535*8a7d0e8cSEnji Cooper /* 536*8a7d0e8cSEnji Cooper * TODO: 537*8a7d0e8cSEnji Cooper * - Tests for subnormals 538*8a7d0e8cSEnji Cooper * - Cancellation tests (e.g., z = (double)x*y, but x*y is inexact) 539*8a7d0e8cSEnji Cooper */ 540*8a7d0e8cSEnji Cooper 541*8a7d0e8cSEnji Cooper return (0); 542*8a7d0e8cSEnji Cooper } 543