1/*
2 * Copyright (c) 2016, Red Hat, Inc. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @bug 8162338
27 * @summary intrinsify fused mac operations
28 * @run main/othervm -XX:-BackgroundCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestFMA
29 *
30 */
31
32import java.lang.annotation.Retention;
33import java.lang.annotation.RetentionPolicy;
34import java.lang.reflect.Method;
35import java.lang.reflect.Modifier;
36
37// Test all fused mac instructions that can be generated
38public class TestFMA {
39
40    @Test(args = {5.0F, 10.0F, 7.0F}, res = 57.0F)
41    static float test1(float a, float b, float c) {
42        return Math.fma(a, b, c);
43    }
44
45    @Test(args = {5.0D, 10.0D, 7.0D}, res = 57.0D)
46    static double test2(double a, double b, double c) {
47        return Math.fma(a, b, c);
48    }
49
50    @Test(args = {5.0F, 10.0F, 7.0F}, res = -43.0F)
51    static float test3(float a, float b, float c) {
52        return Math.fma(-a, b, c);
53    }
54
55    @Test(args = {5.0D, 10.0D, 7.0D}, res = -43.0D)
56    static double test4(double a, double b, double c) {
57        return Math.fma(-a, b, c);
58    }
59
60    @Test(args = {5.0F, 10.0F, 7.0F}, res = -43.0F)
61    static float test5(float a, float b, float c) {
62        return Math.fma(a, -b, c);
63    }
64
65    @Test(args = {5.0D, 10.0D, 7.0D}, res = -43.0D)
66    static double test6(double a, double b, double c) {
67        return Math.fma(a, -b, c);
68    }
69
70    @Test(args = {5.0F, 10.0F, 7.0F}, res = -57.0F)
71    static float test7(float a, float b, float c) {
72        return Math.fma(-a, b, -c);
73    }
74
75    @Test(args = {5.0D, 10.0D, 7.0D}, res = -57.0D)
76    static double test8(double a, double b, double c) {
77        return Math.fma(-a, b, -c);
78    }
79
80    @Test(args = {5.0F, 10.0F, 7.0F}, res = -57.0F)
81    static float test9(float a, float b, float c) {
82        return Math.fma(a, -b, -c);
83    }
84
85    @Test(args = {5.0D, 10.0D, 7.0D}, res = -57.0D)
86    static double test10(double a, double b, double c) {
87        return Math.fma(a, -b, -c);
88    }
89
90    @Test(args = {5.0F, 10.0F, 7.0F}, res = 43.0F)
91    static float test11(float a, float b, float c) {
92        return Math.fma(a, b, -c);
93    }
94
95    @Test(args = {5.0D, 10.0D, 7.0D}, res = 43.0D)
96    static double test12(double a, double b, double c) {
97        return Math.fma(a, b, -c);
98    }
99
100    static public void main(String[] args) throws Exception {
101        TestFMA t = new TestFMA();
102        for (Method m : t.getClass().getDeclaredMethods()) {
103            if (m.getName().matches("test[0-9]+?")) {
104                t.doTest(m);
105            }
106        }
107    }
108
109    @Retention(RetentionPolicy.RUNTIME)
110    @interface Test {
111        double[] args();
112        double res();
113    }
114
115    void doTest(Method m) throws Exception {
116        String name = m.getName();
117        System.out.println("Testing " + name);
118        Class retType = m.getReturnType();
119        Test test = m.getAnnotation(Test.class);
120        double[] args = test.args();
121        double expected = test.res();
122
123        for (int i = 0; i < 20000; i++) {
124            if (retType == double.class) {
125                Object res = m.invoke(null, (double)args[0], (double)args[1], (double)args[2]);
126                if ((double)res != expected) {
127                    throw new RuntimeException(name + " failed : " + (double)res + " != " + expected);
128                }
129            } else {
130                Object res = m.invoke(null, (float)args[0], (float)args[1], (float)args[2]);
131                if ((float)res != (float)expected) {
132                    throw new RuntimeException(name + " failed : " + (float)res + " != " + (float)expected);
133                }
134            }
135        }
136    }
137}
138