• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022, 2023, Oracle and/or its affiliates. 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 8289551
27  * @requires (os.arch != "x86" & os.arch != "i386") | vm.opt.UseSSE == "null" | vm.opt.UseSSE > 0
28  * @summary Verify NaN sign and significand bits are preserved across conversions
29  * @run main/othervm -XX:+UnlockDiagnosticVMOptions
30  * -XX:DisableIntrinsic=_float16ToFloat,_floatToFloat16 Binary16ConversionNaN
31  */
32 
33 package test.java.lang.Float;
34 
35 /*
36  * The behavior tested below is an implementation property not
37  * required by the specification. It would be acceptable for this
38  * information to not be preserved (as long as a NaN is returned) if,
39  * say, a intrinsified version using native hardware instructions
40  * behaved differently.
41  *
42  * If that is the case, this test should be modified to disable
43  * intrinsics or to otherwise not run on platforms with an differently
44  * behaving intrinsic.
45  */
46 public class Binary16ConversionNaN {
main(String... argv)47     public static void main(String... argv) {
48         int errors = 0;
49         errors += binary16NaNRoundTrip();
50 
51         if (errors > 0)
52             throw new RuntimeException(errors + " errors");
53     }
54 
55     /*
56      * Put all 16-bit NaN values through a conversion loop and make
57      * sure the significand, sign, and exponent are all preserved.
58      */
binary16NaNRoundTrip()59     private static int binary16NaNRoundTrip() {
60         int errors = 0;
61         final int NAN_EXPONENT = 0x7c00;
62         final int SIGN_BIT     = 0x8000;
63 
64         // A NaN has a nonzero significand
65         for (int i = 1; i <= 0x3ff; i++) {
66             short binary16NaN = (short)(NAN_EXPONENT | i);
67             assert isNaN(binary16NaN);
68             errors += testRoundTrip(                   binary16NaN);
69             errors += testRoundTrip((short)(SIGN_BIT | binary16NaN));
70         }
71         return errors;
72     }
73 
isNaN(short binary16)74     private static boolean isNaN(short binary16) {
75         return ((binary16 & 0x7c00) == 0x7c00) // Max exponent and...
76             && ((binary16 & 0x03ff) != 0 );    // significand nonzero.
77     }
78 
testRoundTrip(int i)79     private static int testRoundTrip(int i) {
80         int errors = 0;
81         short s = (short)i;
82         float f =  Float.float16ToFloat(s);
83         short s2 = Float.floatToFloat16(f);
84 
85         if (s != s2) {
86             errors++;
87             System.out.println("Roundtrip failure on NaN value " +
88                                Integer.toHexString(0xFFFF & (int)s) +
89                                "\t got back " + Integer.toHexString(0xFFFF & (int)s2));
90         }
91         return errors;
92     }
93 }
94