/* Test of fused multiply-add.
Copyright (C) 2011-2023 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
/* Written by Bruno Haible , 2011. */
static void
test_function (DOUBLE (*my_fma) (DOUBLE, DOUBLE, DOUBLE))
{
volatile DOUBLE x;
volatile DOUBLE y;
volatile DOUBLE z;
volatile DOUBLE result;
volatile DOUBLE expected;
/* Combinations with NaN. */
/* "If x or y are NaN, a NaN shall be returned." */
{
x = NAN;
y = NAN;
z = NAN;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = NAN;
y = NAN;
z = L_(1.0);
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = NAN;
y = L_(0.0);
z = NAN;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = NAN;
y = L_(0.0);
z = L_(1.0);
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = L_(0.0);
y = NAN;
z = NAN;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = L_(0.0);
y = NAN;
z = L_(1.0);
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
/* "If x*y is not 0*Inf nor Inf*0 and z is a NaN, a NaN shall be returned." */
{
x = L_(3.0);
y = - L_(2.0);
z = NAN;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
/* "If one of x and y is infinite, the other is zero, and z is a NaN, a NaN
shall be returned and a domain error may occur." */
{
x = INFINITY;
y = L_(0.0);
z = NAN;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = L_(0.0);
y = INFINITY;
z = NAN;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
/* Combinations with Infinity. */
/* "If x multiplied by y is an exact infinity and z is also an infinity but
with the opposite sign, a domain error shall occur, and either a NaN
(if supported), or an implementation-defined value shall be returned." */
{
x = INFINITY;
y = L_(3.0);
z = - INFINITY;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = INFINITY;
y = - L_(3.0);
z = INFINITY;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = L_(3.0);
y = INFINITY;
z = - INFINITY;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = - L_(3.0);
y = INFINITY;
z = INFINITY;
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
/* "If one of x and y is infinite, the other is zero, and z is not a NaN, a
domain error shall occur, and either a NaN (if supported), or an
implementation-defined value shall be returned." */
{
x = INFINITY;
y = L_(0.0);
z = L_(5.0);
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
{
x = L_(0.0);
y = INFINITY;
z = L_(5.0);
result = my_fma (x, y, z);
ASSERT (ISNAN (result));
}
/* Infinite results. */
{
x = - L_(2.0);
y = L_(3.0);
z = INFINITY;
result = my_fma (x, y, z);
expected = INFINITY;
ASSERT (result == expected);
}
{
x = INFINITY;
y = L_(3.0);
z = INFINITY;
result = my_fma (x, y, z);
expected = INFINITY;
ASSERT (result == expected);
}
{
x = INFINITY;
y = - L_(3.0);
z = - INFINITY;
result = my_fma (x, y, z);
expected = - INFINITY;
ASSERT (result == expected);
}
{
x = L_(3.0);
y = INFINITY;
z = INFINITY;
result = my_fma (x, y, z);
expected = INFINITY;
ASSERT (result == expected);
}
{
x = - L_(3.0);
y = INFINITY;
z = - INFINITY;
result = my_fma (x, y, z);
expected = - INFINITY;
ASSERT (result == expected);
}
/* Combinations with zero. */
{
x = L_(0.0);
y = L_(3.0);
z = L_(11.0);
result = my_fma (x, y, z);
expected = L_(11.0);
ASSERT (result == expected);
}
{
x = L_(3.0);
y = L_(0.0);
z = L_(11.0);
result = my_fma (x, y, z);
expected = L_(11.0);
ASSERT (result == expected);
}
{
x = L_(3.0);
y = L_(4.0);
z = L_(0.0);
result = my_fma (x, y, z);
expected = L_(12.0);
ASSERT (result == expected);
}
}