blob: 587f15cfbb87c394df4d57605f8999efe82a8bfe [file] [log] [blame]
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
*
* @summary converted from VM Testbase jit/FloatingPoint/FPCompare/TestFPBinop.
* VM Testbase keywords: [jit, quick]
*
* @library /vmTestbase
* /test/lib
* @run driver jdk.test.lib.FileInstaller . .
* @run main/othervm jit.FloatingPoint.FPCompare.TestFPBinop.TestFPBinop
*/
package jit.FloatingPoint.FPCompare.TestFPBinop;
import nsk.share.TestFailure;
import nsk.share.GoldChecker;
/** Test of Floating Point Binary Ops.
** This is intended to be run on a known-correct system and the
** answer compared with the golden answer with diff or equivalent.
*/
public class TestFPBinop {
public static final GoldChecker goldChecker = new GoldChecker( "TestFPBinop" );
static float floatValues [] = {
Float.MIN_VALUE, Float.MAX_VALUE,
-Float.MIN_VALUE, -Float.MAX_VALUE,
-1.0f, 1.0f, -0.0f, 0.0f,
Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY,
Float.NaN
};
static double doubleValues [] = {
Double.MIN_VALUE, Double.MAX_VALUE,
-Double.MIN_VALUE, -Double.MAX_VALUE,
-1.0, 1.0, -0.0, 0.0,
Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY,
Double.NaN
};
static int nValues = floatValues.length;
static float fOne, fZero;
static double dOne, dZero;
/* This is intended to thrwart an optimizing compiler
* from simplifying some of the expressions by using algebraic
* identities. */
static {
fOne = new Integer(1).floatValue();
fZero = new Integer(0).floatValue();
dOne = new Integer(1).doubleValue();
dZero = new Integer(0).doubleValue();
}
static final boolean DEBUG = false;
static String operandType = "";
// static values
static float xs, ys;
static double xS, yS;
/** Test of Floating Point Binary operators.
** The following orthogonal variables need to be tested.
** <ul>
** <li> Data type: float or double
** <li> Operator: +, -, *, /
** <li> Data values: +-normal, +-zero, NaN, +-infinity, +- min, +-max
** <li> Operand: variable, parameter, static, field, array element,
** function reference, expression, explicit constant.
** </ul>
*/
public static void main (String [] args) {
testFloats();
testDoubles();
TestFPBinop.goldChecker.check();
}
static void testFloats() {
for (int i = 0; i < floatValues.length; i++) {
float iVal = floatValues[i];
for (int j = 0; j < floatValues.length; j++) {
float jVal = floatValues[j];
testFloat(iVal, jVal);
}
}
}
static void testDoubles() {
for (int i = 0; i < doubleValues.length; i++) {
double iVal = doubleValues[i];
for (int j = 0; j < doubleValues.length; j++) {
double jVal = doubleValues[j];
testDouble(iVal, jVal);
}
}
}
static void testFloat (float x, float y) {
testFloatP(x, y);
testFloatL(x, y);
testFloatS(x, y);
testFloatF(x, y);
testFloatA(x, y);
testFloatM(x, y);
testFloat1(x, y);
testFloat2(x, y);
testFloat3(x, y);
}
static void testFloatP(float x, float y) {
check(x, y, x + y, "param", "+");
check(x, y, x - y, "param", "-");
check(x, y, x * y, "param", "*");
check(x, y, x / y, "param", "/");
}
static void testFloatL(float x, float y) {
float xl = x;
float yl = y;
check(xl, yl, xl + yl, "local", "+");
check(xl, yl, xl - yl, "local", "-");
check(xl, yl, xl * yl, "local", "*");
check(xl, yl, xl / yl, "local", "/");
}
static void testFloatS(float x, float y) {
xs = x;
ys = y;
check(xs, ys, xs + ys, "static", "+");
check(xs, ys, xs - ys, "static", "-");
check(xs, ys, xs * ys, "static", "*");
check(xs, ys, xs / ys, "static", "/");
}
static void testFloatF(float x, float y) {
FloatObject xo = new FloatObject(x);
FloatObject yo = new FloatObject(y);
check(xo.f, yo.f, xo.f + yo.f, "field", "+");
check(xo.f, yo.f, xo.f - yo.f, "field", "-");
check(xo.f, yo.f, xo.f * yo.f, "field", "*");
check(xo.f, yo.f, xo.f / yo.f, "field", "/");
}
static void testFloatA(float x, float y) {
int i = index(x);
int j = index(y);
float a [] = floatValues;
check(a[i], a[j], a[i] + a[j], "a[i]", "+");
check(a[i], a[j], a[i] - a[j], "a[i]", "-");
check(a[i], a[j], a[i] * a[j], "a[i]", "*");
check(a[i], a[j], a[i] / a[j], "a[i]", "/");
}
static void testFloatM(float x, float y) {
check(i(x), i(y), i(x) + i(y), "f(x)", "+");
check(i(x), i(y), i(x) - i(y), "f(x)", "-");
check(i(x), i(y), i(x) * i(y), "f(x)", "*");
check(i(x), i(y), i(x) / i(y), "f(x)", "/");
}
static void testFloat1(float x, float y) {
float zero = fZero;
float one = fOne;
check(((x + zero) * one), y, ((x + zero) * one) + y, "lExpr", "+");
check(((x + zero) * one), y, ((x + zero) * one) - y, "lExpr", "-");
check(((x + zero) * one), y, ((x + zero) * one) * y, "lExpr", "*");
check(((x + zero) * one), y, ((x + zero) * one) / y, "lExpr", "/");
}
static void testFloat3(float x, float y) {
float zero = fZero;
float one = fOne;
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) + (zero + one * y), "exprs", "+");
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) - (zero + one * y), "exprs", "-");
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) * (zero + one * y), "exprs", "*");
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) / (zero + one * y), "exprs", "/");
}
static void testFloat2(float x, float y) {
float zero = fZero;
float one = fOne;
operandType = "rExpr";
check(x, (zero + one * y), x + (zero + one * y), "rExpr", "+");
check(x, (zero + one * y), x - (zero + one * y), "rExpr", "-");
check(x, (zero + one * y), x * (zero + one * y), "rExpr", "*");
check(x, (zero + one * y), x / (zero + one * y), "rExpr", "/");
}
static void testDouble (double x, double y) {
testDoubleP(x, y);
testDoubleL(x, y);
testDoubleS(x, y);
testDoubleF(x, y);
testDoubleA(x, y);
testDoubleM(x, y);
testDouble1(x, y);
testDouble2(x, y);
testDouble3(x, y);
}
static void testDoubleP (double x, double y) {
check(x, y, x + y, "param", "+");
check(x, y, x - y, "param", "-");
check(x, y, x * y, "param", "*");
check(x, y, x / y, "param", "/");
}
static void testDoubleL (double x, double y) {
double xl = x;
double yl = y;
check(xl, yl, xl + yl, "local", "+");
check(xl, yl, xl - yl, "local", "-");
check(xl, yl, xl * yl, "local", "*");
check(xl, yl, xl / yl, "local", "/");
}
static void testDoubleS (double x, double y) {
xS = x;
yS = y;
check(xS, yS, xS + yS, "static", "+");
check(xS, yS, xS - yS, "static", "-");
check(xS, yS, xS * yS, "static", "*");
check(xS, yS, xS / yS, "static", "/");
}
static void testDoubleF (double x, double y) {
DoubleObject xo = new DoubleObject(x);
DoubleObject yo = new DoubleObject(y);
check(xo.f, yo.f, xo.f + yo.f, "field", "+");
check(xo.f, yo.f, xo.f - yo.f, "field", "-");
check(xo.f, yo.f, xo.f * yo.f, "field", "*");
check(xo.f, yo.f, xo.f / yo.f, "field", "/");
}
static void testDoubleA (double x, double y) {
int i = index(x);
int j = index(y);
double a [] = doubleValues;
check(a[i], a[j], a[i] + a[j], "a[i]", "+");
check(a[i], a[j], a[i] - a[j], "a[i]", "-");
check(a[i], a[j], a[i] * a[j], "a[i]", "*");
check(a[i], a[j], a[i] / a[j], "a[i]", "/");
}
static void testDoubleM (double x, double y) {
check(i(x), i(y), i(x) + i(y), "f(x)", "+");
check(i(x), i(y), i(x) - i(y), "f(x)", "-");
check(i(x), i(y), i(x) * i(y), "f(x)", "*");
check(i(x), i(y), i(x) / i(y), "f(x)", "/");
}
static void testDouble1 (double x, double y) {
double zero = dZero;
double one = dOne;
check(((x + zero) * one), y, ((x + zero) * one) + y, "lExpr", "+");
check(((x + zero) * one), y, ((x + zero) * one) - y, "lExpr", "-");
check(((x + zero) * one), y, ((x + zero) * one) * y, "lExpr", "*");
check(((x + zero) * one), y, ((x + zero) * one) / y, "lExpr", "/");
}
static void testDouble3 (double x, double y) {
double zero = dZero;
double one = dOne;
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) + (zero + one * y), "exprs", "+");
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) - (zero + one * y), "exprs", "-");
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) * (zero + one * y), "exprs", "*");
check(((x + zero) * one), (zero + one * y), ((x + zero) * one) / (zero + one * y), "exprs", "/");
}
static void testDouble2 (double x, double y) {
double zero = dZero;
double one = dOne;
check(x, (zero + one * y), x + (zero + one * y), "rExpr", "+");
check(x, (zero + one * y), x - (zero + one * y), "rExpr", "-");
check(x, (zero + one * y), x * (zero + one * y), "rExpr", "*");
check(x, (zero + one * y), x / (zero + one * y), "rExpr", "/");
}
/* The convoluted coding is intended to prevent inlining */
static float i(float x) {
while (Float.isNaN(x) && Float.floatToIntBits(x) == 0) {
x = 0.0f;
}
return x;
}
static double i(double x) {
while (Double.isNaN(x) && Double.doubleToLongBits(x) == 0L) {
x = 0.0;
}
return x;
}
static int index(float x) {
for (int i = 0; i < floatValues.length; i++) {
if (new Float(x).equals(new Float(floatValues[i])))
return i;
}
throw new TestFailure("ERROR: can't find " + x + " in floatValues.");
}
static int index(double x) {
for (int i = 0; i < doubleValues.length; i++) {
if (new Double(x).equals(new Double(doubleValues[i])))
return i;
}
throw new TestFailure("ERROR: can't find " + x + " in doubleValues.");
}
static void check (float x, float y, float result,
String operands, String operator) {
TestFPBinop.goldChecker.println(x + " " + operator + " " + y +
" = " + result + ", with float " +
operands + " operands");
}
static void check (double x, double y, double result,
String operands, String operator) {
TestFPBinop.goldChecker.println(x + " " + operator + " " + y +
" = " + result + ", with double " +
operands + " operands");
}
}
class FloatObject {
public float f;
public FloatObject(float x) {
f = x;
}
}
class DoubleObject {
public double f;
public DoubleObject(double x) {
f = x;
}
}