Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /**
     18  * Tests for ABS vectorization.
     19  */
     20 public class Main {
     21 
     22   private static final int SPQUIET = 1 << 22;
     23   private static final long DPQUIET = 1L << 51;
     24 
     25   /// CHECK-START: void Main.doitByte(byte[]) loop_optimization (before)
     26   /// CHECK-DAG: Phi                                       loop:<<Loop:B\d+>> outer_loop:none
     27   /// CHECK-DAG: ArrayGet                                  loop:<<Loop>>      outer_loop:none
     28   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop>>      outer_loop:none
     29   /// CHECK-DAG: ArraySet                                  loop:<<Loop>>      outer_loop:none
     30   //
     31   /// CHECK-START-ARM: void Main.doitByte(byte[]) loop_optimization (after)
     32   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
     33   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
     34   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
     35   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
     36   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
     37   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
     38   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
     39   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
     40   //
     41   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
     42   //
     43   /// CHECK-START-ARM64: void Main.doitByte(byte[]) loop_optimization (after)
     44   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
     45   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
     46   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
     47   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
     48   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
     49   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
     50   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
     51   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
     52   //
     53   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
     54   //
     55   /// CHECK-START-MIPS64: void Main.doitByte(byte[]) loop_optimization (after)
     56   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
     57   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
     58   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
     59   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
     60   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
     61   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
     62   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
     63   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
     64   //
     65   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
     66   private static void doitByte(byte[] x) {
     67     for (int i = 0; i < x.length; i++) {
     68       x[i] = (byte) Math.abs(x[i]);
     69     }
     70   }
     71 
     72   /// CHECK-START: void Main.doitChar(char[]) loop_optimization (before)
     73   /// CHECK-DAG: Phi                                       loop:<<Loop:B\d+>> outer_loop:none
     74   /// CHECK-DAG: ArrayGet                                  loop:<<Loop>>      outer_loop:none
     75   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop>>      outer_loop:none
     76   /// CHECK-DAG: ArraySet                                  loop:<<Loop>>      outer_loop:none
     77   //
     78   /// CHECK-START: void Main.doitChar(char[]) loop_optimization (after)
     79   /// CHECK-NOT: VecAbs
     80   private static void doitChar(char[] x) {
     81     // Basically a nop due to zero extension.
     82     for (int i = 0; i < x.length; i++) {
     83       x[i] = (char) Math.abs(x[i]);
     84     }
     85   }
     86 
     87   /// CHECK-START: void Main.doitShort(short[]) loop_optimization (before)
     88   /// CHECK-DAG: Phi                                       loop:<<Loop:B\d+>> outer_loop:none
     89   /// CHECK-DAG: ArrayGet                                  loop:<<Loop>>      outer_loop:none
     90   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop>>      outer_loop:none
     91   /// CHECK-DAG: ArraySet                                  loop:<<Loop>>      outer_loop:none
     92   //
     93   /// CHECK-START-ARM: void Main.doitShort(short[]) loop_optimization (after)
     94   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
     95   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
     96   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
     97   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
     98   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
     99   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
    100   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
    101   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
    102   //
    103   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    104   //
    105   /// CHECK-START-ARM64: void Main.doitShort(short[]) loop_optimization (after)
    106   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
    107   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
    108   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
    109   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
    110   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
    111   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
    112   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
    113   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
    114   //
    115   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    116   //
    117   /// CHECK-START-MIPS64: void Main.doitShort(short[]) loop_optimization (after)
    118   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
    119   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
    120   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
    121   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
    122   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
    123   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
    124   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
    125   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
    126   //
    127   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    128   private static void doitShort(short[] x) {
    129     for (int i = 0; i < x.length; i++) {
    130       x[i] = (short) Math.abs(x[i]);
    131     }
    132   }
    133 
    134   /// CHECK-START: void Main.doitInt(int[]) loop_optimization (before)
    135   /// CHECK-DAG: Phi                                       loop:<<Loop:B\d+>> outer_loop:none
    136   /// CHECK-DAG: ArrayGet                                  loop:<<Loop>>      outer_loop:none
    137   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop>>      outer_loop:none
    138   /// CHECK-DAG: ArraySet                                  loop:<<Loop>>      outer_loop:none
    139   //
    140   /// CHECK-START-ARM: void Main.doitInt(int[]) loop_optimization (after)
    141   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
    142   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
    143   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
    144   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
    145   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
    146   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
    147   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
    148   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
    149   //
    150   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    151   //
    152   /// CHECK-START-ARM64: void Main.doitInt(int[]) loop_optimization (after)
    153   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
    154   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
    155   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
    156   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
    157   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
    158   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
    159   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
    160   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
    161   //
    162   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    163   //
    164   /// CHECK-START-MIPS64: void Main.doitInt(int[]) loop_optimization (after)
    165   /// CHECK-DAG: Phi                                       loop:<<Loop1:B\d+>> outer_loop:none
    166   /// CHECK-DAG: VecLoad                                   loop:<<Loop1>>      outer_loop:none
    167   /// CHECK-DAG: VecAbs                                    loop:<<Loop1>>      outer_loop:none
    168   /// CHECK-DAG: VecStore                                  loop:<<Loop1>>      outer_loop:none
    169   /// CHECK-DAG: Phi                                       loop:<<Loop2:B\d+>> outer_loop:none
    170   /// CHECK-DAG: ArrayGet                                  loop:<<Loop2>>      outer_loop:none
    171   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsInt loop:<<Loop2>>      outer_loop:none
    172   /// CHECK-DAG: ArraySet                                  loop:<<Loop2>>      outer_loop:none
    173   //
    174   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    175   private static void doitInt(int[] x) {
    176     for (int i = 0; i < x.length; i++) {
    177       x[i] = Math.abs(x[i]);
    178     }
    179   }
    180 
    181   /// CHECK-START: void Main.doitLong(long[]) loop_optimization (before)
    182   /// CHECK-DAG: Phi                                        loop:<<Loop:B\d+>> outer_loop:none
    183   /// CHECK-DAG: ArrayGet                                   loop:<<Loop>>      outer_loop:none
    184   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsLong loop:<<Loop>>      outer_loop:none
    185   /// CHECK-DAG: ArraySet                                   loop:<<Loop>>      outer_loop:none
    186   //
    187   /// CHECK-START-ARM64: void Main.doitLong(long[]) loop_optimization (after)
    188   /// CHECK-DAG: Phi                                        loop:<<Loop1:B\d+>> outer_loop:none
    189   /// CHECK-DAG: VecLoad                                    loop:<<Loop1>>      outer_loop:none
    190   /// CHECK-DAG: VecAbs                                     loop:<<Loop1>>      outer_loop:none
    191   /// CHECK-DAG: VecStore                                   loop:<<Loop1>>      outer_loop:none
    192   /// CHECK-DAG: Phi                                        loop:<<Loop2:B\d+>> outer_loop:none
    193   /// CHECK-DAG: ArrayGet                                   loop:<<Loop2>>      outer_loop:none
    194   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsLong loop:<<Loop2>>      outer_loop:none
    195   /// CHECK-DAG: ArraySet                                   loop:<<Loop2>>      outer_loop:none
    196   //
    197   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    198   //
    199   /// CHECK-START-MIPS64: void Main.doitLong(long[]) loop_optimization (after)
    200   /// CHECK-DAG: Phi                                        loop:<<Loop1:B\d+>> outer_loop:none
    201   /// CHECK-DAG: VecLoad                                    loop:<<Loop1>>      outer_loop:none
    202   /// CHECK-DAG: VecAbs                                     loop:<<Loop1>>      outer_loop:none
    203   /// CHECK-DAG: VecStore                                   loop:<<Loop1>>      outer_loop:none
    204   /// CHECK-DAG: Phi                                        loop:<<Loop2:B\d+>> outer_loop:none
    205   /// CHECK-DAG: ArrayGet                                   loop:<<Loop2>>      outer_loop:none
    206   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsLong loop:<<Loop2>>      outer_loop:none
    207   /// CHECK-DAG: ArraySet                                   loop:<<Loop2>>      outer_loop:none
    208   //
    209   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    210   private static void doitLong(long[] x) {
    211     for (int i = 0; i < x.length; i++) {
    212       x[i] = Math.abs(x[i]);
    213     }
    214   }
    215 
    216   /// CHECK-START: void Main.doitFloat(float[]) loop_optimization (before)
    217   /// CHECK-DAG: Phi                                         loop:<<Loop:B\d+>> outer_loop:none
    218   /// CHECK-DAG: ArrayGet                                    loop:<<Loop>>      outer_loop:none
    219   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop>>      outer_loop:none
    220   /// CHECK-DAG: ArraySet                                     loop:<<Loop>>      outer_loop:none
    221   //
    222   /// CHECK-START-ARM64: void Main.doitFloat(float[]) loop_optimization (after)
    223   /// CHECK-DAG: Phi                                         loop:<<Loop1:B\d+>> outer_loop:none
    224   /// CHECK-DAG: VecLoad                                     loop:<<Loop1>>      outer_loop:none
    225   /// CHECK-DAG: VecAbs                                      loop:<<Loop1>>      outer_loop:none
    226   /// CHECK-DAG: VecStore                                    loop:<<Loop1>>      outer_loop:none
    227   /// CHECK-DAG: Phi                                         loop:<<Loop2:B\d+>> outer_loop:none
    228   /// CHECK-DAG: ArrayGet                                    loop:<<Loop2>>      outer_loop:none
    229   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop2>>      outer_loop:none
    230   /// CHECK-DAG: ArraySet                                    loop:<<Loop2>>      outer_loop:none
    231   //
    232   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    233   //
    234   /// CHECK-START-MIPS64: void Main.doitFloat(float[]) loop_optimization (after)
    235   /// CHECK-DAG: Phi                                         loop:<<Loop1:B\d+>> outer_loop:none
    236   /// CHECK-DAG: VecLoad                                     loop:<<Loop1>>      outer_loop:none
    237   /// CHECK-DAG: VecAbs                                      loop:<<Loop1>>      outer_loop:none
    238   /// CHECK-DAG: VecStore                                    loop:<<Loop1>>      outer_loop:none
    239   /// CHECK-DAG: Phi                                         loop:<<Loop2:B\d+>> outer_loop:none
    240   /// CHECK-DAG: ArrayGet                                    loop:<<Loop2>>      outer_loop:none
    241   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsFloat loop:<<Loop2>>      outer_loop:none
    242   /// CHECK-DAG: ArraySet                                    loop:<<Loop2>>      outer_loop:none
    243   //
    244   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    245   private static void doitFloat(float[] x) {
    246     for (int i = 0; i < x.length; i++) {
    247       x[i] = Math.abs(x[i]);
    248     }
    249   }
    250 
    251   /// CHECK-START: void Main.doitDouble(double[]) loop_optimization (before)
    252   /// CHECK-DAG: Phi                                          loop:<<Loop:B\d+>> outer_loop:none
    253   /// CHECK-DAG: ArrayGet                                     loop:<<Loop>>      outer_loop:none
    254   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsDouble loop:<<Loop>>      outer_loop:none
    255   /// CHECK-DAG: ArraySet                                     loop:<<Loop>>      outer_loop:none
    256   //
    257   /// CHECK-START-ARM64: void Main.doitDouble(double[]) loop_optimization (after)
    258   /// CHECK-DAG: Phi                                          loop:<<Loop1:B\d+>> outer_loop:none
    259   /// CHECK-DAG: VecLoad                                      loop:<<Loop1>>      outer_loop:none
    260   /// CHECK-DAG: VecAbs                                       loop:<<Loop1>>      outer_loop:none
    261   /// CHECK-DAG: VecStore                                     loop:<<Loop1>>      outer_loop:none
    262   /// CHECK-DAG: Phi                                          loop:<<Loop2:B\d+>> outer_loop:none
    263   /// CHECK-DAG: ArrayGet                                     loop:<<Loop2>>      outer_loop:none
    264   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsDouble loop:<<Loop2>>      outer_loop:none
    265   /// CHECK-DAG: ArraySet                                     loop:<<Loop2>>      outer_loop:none
    266   //
    267   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    268   //
    269   /// CHECK-START-MIPS64: void Main.doitDouble(double[]) loop_optimization (after)
    270   /// CHECK-DAG: Phi                                          loop:<<Loop1:B\d+>> outer_loop:none
    271   /// CHECK-DAG: VecLoad                                      loop:<<Loop1>>      outer_loop:none
    272   /// CHECK-DAG: VecAbs                                       loop:<<Loop1>>      outer_loop:none
    273   /// CHECK-DAG: VecStore                                     loop:<<Loop1>>      outer_loop:none
    274   /// CHECK-DAG: Phi                                          loop:<<Loop2:B\d+>> outer_loop:none
    275   /// CHECK-DAG: ArrayGet                                     loop:<<Loop2>>      outer_loop:none
    276   /// CHECK-DAG: InvokeStaticOrDirect intrinsic:MathAbsDouble loop:<<Loop2>>      outer_loop:none
    277   /// CHECK-DAG: ArraySet                                     loop:<<Loop2>>      outer_loop:none
    278   //
    279   /// CHECK-EVAL: "<<Loop1>>" != "<<Loop2>>"
    280   private static void doitDouble(double[] x) {
    281     for (int i = 0; i < x.length; i++) {
    282       x[i] = Math.abs(x[i]);
    283     }
    284   }
    285 
    286   public static void main(String[] args) {
    287     // Bytes, chars, shorts.
    288     byte[] xb = new byte[256];
    289     for (int i = 0; i < 256; i++) {
    290       xb[i] = (byte) i;
    291     }
    292     doitByte(xb);
    293     for (int i = 0; i < 256; i++) {
    294       expectEquals32((byte) Math.abs((byte) i), xb[i]);
    295     }
    296     char[] xc = new char[1024 * 64];
    297     for (int i = 0; i < 1024 * 64; i++) {
    298       xc[i] = (char) i;
    299     }
    300     doitChar(xc);
    301     for (int i = 0; i < 1024 *64; i++) {
    302       expectEquals32((char) Math.abs((char) i), xc[i]);
    303     }
    304     short[] xs = new short[1024 * 64];
    305     for (int i = 0; i < 1024 * 64; i++) {
    306       xs[i] = (short) i;
    307     }
    308     doitShort(xs);
    309     for (int i = 0; i < 1024 * 64; i++) {
    310       expectEquals32((short) Math.abs((short) i), xs[i]);
    311     }
    312     // Set up minint32, maxint32 and some others.
    313     int[] xi = new int[8];
    314     xi[0] = 0x80000000;
    315     xi[1] = 0x7fffffff;
    316     xi[2] = 0x80000001;
    317     xi[3] = -13;
    318     xi[4] = -1;
    319     xi[5] = 0;
    320     xi[6] = 1;
    321     xi[7] = 999;
    322     doitInt(xi);
    323     expectEquals32(0x80000000, xi[0]);
    324     expectEquals32(0x7fffffff, xi[1]);
    325     expectEquals32(0x7fffffff, xi[2]);
    326     expectEquals32(13, xi[3]);
    327     expectEquals32(1, xi[4]);
    328     expectEquals32(0, xi[5]);
    329     expectEquals32(1, xi[6]);
    330     expectEquals32(999, xi[7]);
    331 
    332     // Set up minint64, maxint64 and some others.
    333     long[] xl = new long[8];
    334     xl[0] = 0x8000000000000000L;
    335     xl[1] = 0x7fffffffffffffffL;
    336     xl[2] = 0x8000000000000001L;
    337     xl[3] = -13;
    338     xl[4] = -1;
    339     xl[5] = 0;
    340     xl[6] = 1;
    341     xl[7] = 999;
    342     doitLong(xl);
    343     expectEquals64(0x8000000000000000L, xl[0]);
    344     expectEquals64(0x7fffffffffffffffL, xl[1]);
    345     expectEquals64(0x7fffffffffffffffL, xl[2]);
    346     expectEquals64(13, xl[3]);
    347     expectEquals64(1, xl[4]);
    348     expectEquals64(0, xl[5]);
    349     expectEquals64(1, xl[6]);
    350     expectEquals64(999, xl[7]);
    351 
    352     // Set up float NaN and some others.
    353     float[] xf = new float[16];
    354     xf[0] = Float.intBitsToFloat(0x7f800001);
    355     xf[1] = Float.intBitsToFloat(0x7fa00000);
    356     xf[2] = Float.intBitsToFloat(0x7fc00000);
    357     xf[3] = Float.intBitsToFloat(0x7fffffff);
    358     xf[4] = Float.intBitsToFloat(0xff800001);
    359     xf[5] = Float.intBitsToFloat(0xffa00000);
    360     xf[6] = Float.intBitsToFloat(0xffc00000);
    361     xf[7] = Float.intBitsToFloat(0xffffffff);
    362     xf[8] = Float.NEGATIVE_INFINITY;
    363     xf[9] = -99.2f;
    364     xf[10] = -1.0f;
    365     xf[11] = -0.0f;
    366     xf[12] = +0.0f;
    367     xf[13] = +1.0f;
    368     xf[14] = +99.2f;
    369     xf[15] = Float.POSITIVE_INFINITY;
    370     doitFloat(xf);
    371     expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[0]));
    372     expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[1]));
    373     expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[2]));
    374     expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[3]));
    375     expectEqualsNaN32(0x7f800001, Float.floatToRawIntBits(xf[4]));
    376     expectEqualsNaN32(0x7fa00000, Float.floatToRawIntBits(xf[5]));
    377     expectEqualsNaN32(0x7fc00000, Float.floatToRawIntBits(xf[6]));
    378     expectEqualsNaN32(0x7fffffff, Float.floatToRawIntBits(xf[7]));
    379     expectEquals32(
    380         Float.floatToRawIntBits(Float.POSITIVE_INFINITY),
    381         Float.floatToRawIntBits(xf[8]));
    382     expectEquals32(
    383         Float.floatToRawIntBits(99.2f),
    384         Float.floatToRawIntBits(xf[9]));
    385     expectEquals32(
    386         Float.floatToRawIntBits(1.0f),
    387         Float.floatToRawIntBits(xf[10]));
    388     expectEquals32(0, Float.floatToRawIntBits(xf[11]));
    389     expectEquals32(0, Float.floatToRawIntBits(xf[12]));
    390     expectEquals32(
    391         Float.floatToRawIntBits(1.0f),
    392         Float.floatToRawIntBits(xf[13]));
    393     expectEquals32(
    394         Float.floatToRawIntBits(99.2f),
    395         Float.floatToRawIntBits(xf[14]));
    396     expectEquals32(
    397         Float.floatToRawIntBits(Float.POSITIVE_INFINITY),
    398         Float.floatToRawIntBits(xf[15]));
    399 
    400     // Set up double NaN and some others.
    401     double[] xd = new double[16];
    402     xd[0] = Double.longBitsToDouble(0x7ff0000000000001L);
    403     xd[1] = Double.longBitsToDouble(0x7ff4000000000000L);
    404     xd[2] = Double.longBitsToDouble(0x7ff8000000000000L);
    405     xd[3] = Double.longBitsToDouble(0x7fffffffffffffffL);
    406     xd[4] = Double.longBitsToDouble(0xfff0000000000001L);
    407     xd[5] = Double.longBitsToDouble(0xfff4000000000000L);
    408     xd[6] = Double.longBitsToDouble(0xfff8000000000000L);
    409     xd[7] = Double.longBitsToDouble(0xffffffffffffffffL);
    410     xd[8] = Double.NEGATIVE_INFINITY;
    411     xd[9] = -99.2f;
    412     xd[10] = -1.0f;
    413     xd[11] = -0.0f;
    414     xd[12] = +0.0f;
    415     xd[13] = +1.0f;
    416     xd[14] = +99.2f;
    417     xd[15] = Double.POSITIVE_INFINITY;
    418     doitDouble(xd);
    419     expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[0]));
    420     expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[1]));
    421     expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[2]));
    422     expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[3]));
    423     expectEqualsNaN64(0x7ff0000000000001L, Double.doubleToRawLongBits(xd[4]));
    424     expectEqualsNaN64(0x7ff4000000000000L, Double.doubleToRawLongBits(xd[5]));
    425     expectEqualsNaN64(0x7ff8000000000000L, Double.doubleToRawLongBits(xd[6]));
    426     expectEqualsNaN64(0x7fffffffffffffffL, Double.doubleToRawLongBits(xd[7]));
    427     expectEquals64(
    428         Double.doubleToRawLongBits(Double.POSITIVE_INFINITY),
    429         Double.doubleToRawLongBits(xd[8]));
    430     expectEquals64(
    431         Double.doubleToRawLongBits(99.2f),
    432         Double.doubleToRawLongBits(xd[9]));
    433     expectEquals64(
    434         Double.doubleToRawLongBits(1.0f),
    435         Double.doubleToRawLongBits(xd[10]));
    436     expectEquals64(0, Double.doubleToRawLongBits(xd[11]));
    437     expectEquals64(0, Double.doubleToRawLongBits(xd[12]));
    438     expectEquals64(
    439         Double.doubleToRawLongBits(1.0f),
    440         Double.doubleToRawLongBits(xd[13]));
    441     expectEquals64(
    442         Double.doubleToRawLongBits(99.2f),
    443         Double.doubleToRawLongBits(xd[14]));
    444     expectEquals64(
    445         Double.doubleToRawLongBits(Double.POSITIVE_INFINITY),
    446         Double.doubleToRawLongBits(xd[15]));
    447 
    448     System.out.println("passed");
    449   }
    450 
    451   private static void expectEquals32(int expected, int result) {
    452     if (expected != result) {
    453       throw new Error("Expected: " + expected + ", found: " + result);
    454     }
    455   }
    456 
    457   private static void expectEquals64(long expected, long result) {
    458     if (expected != result) {
    459       throw new Error("Expected: " + expected + ", found: " + result);
    460     }
    461   }
    462 
    463   // We allow that an expected NaN result has become quiet.
    464   private static void expectEqualsNaN32(int expected, int result) {
    465     if (expected != result && (expected | SPQUIET) != result) {
    466       throw new Error("Expected: 0x" + Integer.toHexString(expected)
    467           + ", found: 0x" + Integer.toHexString(result));
    468     }
    469   }
    470 
    471   // We allow that an expected NaN result has become quiet.
    472   private static void expectEqualsNaN64(long expected, long result) {
    473     if (expected != result && (expected | DPQUIET) != result) {
    474       throw new Error("Expected: 0x" + Long.toHexString(expected)
    475           + ", found: 0x" + Long.toHexString(result));
    476     }
    477   }
    478 }
    479