1 /*
   2  * Copyright (c) 2018, 2024, 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  * @key randomness
  27  *
  28  * @library /test/lib
  29  * @modules jdk.incubator.vector
  30  * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Double64VectorTests
  31  */
  32 
  33 // -- This file was mechanically generated: Do not edit! -- //
  34 
  35 import jdk.incubator.vector.VectorShape;
  36 import jdk.incubator.vector.VectorSpecies;
  37 import jdk.incubator.vector.VectorShuffle;
  38 import jdk.incubator.vector.VectorMask;
  39 import jdk.incubator.vector.VectorOperators;
  40 import jdk.incubator.vector.Vector;
  41 
  42 import jdk.incubator.vector.DoubleVector;
  43 
  44 import org.testng.Assert;
  45 import org.testng.annotations.DataProvider;
  46 import org.testng.annotations.Test;
  47 
  48 import java.lang.Integer;
  49 import java.util.List;
  50 import java.util.Arrays;
  51 import java.util.function.BiFunction;
  52 import java.util.function.IntFunction;
  53 import java.util.Objects;
  54 import java.util.stream.Collectors;
  55 import java.util.stream.Stream;
  56 
  57 @Test
  58 public class Double64VectorTests extends AbstractVectorTest {
  59 
  60     static final VectorSpecies<Double> SPECIES =
  61                 DoubleVector.SPECIES_64;
  62 
  63     static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 100);
  64 
  65 
  66     // for floating point addition reduction ops that may introduce rounding errors
  67     private static final double RELATIVE_ROUNDING_ERROR_FACTOR_ADD = (double)10.0;
  68 
  69     // for floating point multiplication reduction ops that may introduce rounding errors
  70     private static final double RELATIVE_ROUNDING_ERROR_FACTOR_MUL = (double)50.0;
  71 
  72     static final int BUFFER_REPS = Integer.getInteger("jdk.incubator.vector.test.buffer-vectors", 25000 / 64);
  73 
  74     static void assertArraysStrictlyEquals(double[] r, double[] a) {
  75         for (int i = 0; i < a.length; i++) {
  76             long ir = Double.doubleToRawLongBits(r[i]);
  77             long ia = Double.doubleToRawLongBits(a[i]);
  78             if (ir != ia) {
  79                 Assert.fail(String.format("at index #%d, expected = %016X, actual = %016X", i, ia, ir));
  80             }
  81         }
  82     }
  83 
  84     interface FUnOp {
  85         double apply(double a);
  86     }
  87 
  88     static void assertArraysEquals(double[] r, double[] a, FUnOp f) {
  89         int i = 0;
  90         try {
  91             for (; i < a.length; i++) {
  92                 Assert.assertEquals(r[i], f.apply(a[i]));
  93             }
  94         } catch (AssertionError e) {
  95             Assert.assertEquals(r[i], f.apply(a[i]), "at index #" + i + ", input = " + a[i]);
  96         }
  97     }
  98 
  99     interface FUnArrayOp {
 100         double[] apply(double a);
 101     }
 102 
 103     static void assertArraysEquals(double[] r, double[] a, FUnArrayOp f) {
 104         int i = 0;
 105         try {
 106             for (; i < a.length; i += SPECIES.length()) {
 107                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 108                   f.apply(a[i]));
 109             }
 110         } catch (AssertionError e) {
 111             double[] ref = f.apply(a[i]);
 112             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 113             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
 114               + ", res: " + Arrays.toString(res)
 115               + "), at index #" + i);
 116         }
 117     }
 118 
 119     static void assertArraysEquals(double[] r, double[] a, boolean[] mask, FUnOp f) {
 120         int i = 0;
 121         try {
 122             for (; i < a.length; i++) {
 123                 Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i]);
 124             }
 125         } catch (AssertionError e) {
 126             Assert.assertEquals(r[i], mask[i % SPECIES.length()] ? f.apply(a[i]) : a[i], "at index #" + i + ", input = " + a[i] + ", mask = " + mask[i % SPECIES.length()]);
 127         }
 128     }
 129 
 130     interface FReductionOp {
 131         double apply(double[] a, int idx);
 132     }
 133 
 134     interface FReductionAllOp {
 135         double apply(double[] a);
 136     }
 137 
 138     static void assertReductionArraysEquals(double[] r, double rc, double[] a,
 139                                             FReductionOp f, FReductionAllOp fa) {
 140         assertReductionArraysEquals(r, rc, a, f, fa, (double)0.0);
 141     }
 142 
 143     static void assertReductionArraysEquals(double[] r, double rc, double[] a,
 144                                             FReductionOp f, FReductionAllOp fa,
 145                                             double relativeErrorFactor) {
 146         int i = 0;
 147         try {
 148             Assert.assertEquals(rc, fa.apply(a), Math.ulp(rc) * relativeErrorFactor);
 149             for (; i < a.length; i += SPECIES.length()) {
 150                 Assert.assertEquals(r[i], f.apply(a, i), Math.ulp(r[i]) * relativeErrorFactor);
 151             }
 152         } catch (AssertionError e) {
 153             Assert.assertEquals(rc, fa.apply(a), Math.ulp(rc) * relativeErrorFactor, "Final result is incorrect!");
 154             Assert.assertEquals(r[i], f.apply(a, i), Math.ulp(r[i]) * relativeErrorFactor, "at index #" + i);
 155         }
 156     }
 157 
 158     interface FReductionMaskedOp {
 159         double apply(double[] a, int idx, boolean[] mask);
 160     }
 161 
 162     interface FReductionAllMaskedOp {
 163         double apply(double[] a, boolean[] mask);
 164     }
 165 
 166     static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
 167                                             FReductionMaskedOp f, FReductionAllMaskedOp fa) {
 168         assertReductionArraysEqualsMasked(r, rc, a, mask, f, fa, (double)0.0);
 169     }
 170 
 171     static void assertReductionArraysEqualsMasked(double[] r, double rc, double[] a, boolean[] mask,
 172                                             FReductionMaskedOp f, FReductionAllMaskedOp fa,
 173                                             double relativeError) {
 174         int i = 0;
 175         try {
 176             Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError));
 177             for (; i < a.length; i += SPECIES.length()) {
 178                 Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] *
 179 relativeError));
 180             }
 181         } catch (AssertionError e) {
 182             Assert.assertEquals(rc, fa.apply(a, mask), Math.abs(rc * relativeError), "Final result is incorrect!");
 183             Assert.assertEquals(r[i], f.apply(a, i, mask), Math.abs(r[i] * relativeError), "at index #" + i);
 184         }
 185     }
 186 
 187     interface FReductionOpLong {
 188         long apply(double[] a, int idx);
 189     }
 190 
 191     interface FReductionAllOpLong {
 192         long apply(double[] a);
 193     }
 194 
 195     static void assertReductionLongArraysEquals(long[] r, long rc, double[] a,
 196                                             FReductionOpLong f, FReductionAllOpLong fa) {
 197         int i = 0;
 198         try {
 199             Assert.assertEquals(rc, fa.apply(a));
 200             for (; i < a.length; i += SPECIES.length()) {
 201                 Assert.assertEquals(r[i], f.apply(a, i));
 202             }
 203         } catch (AssertionError e) {
 204             Assert.assertEquals(rc, fa.apply(a), "Final result is incorrect!");
 205             Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
 206         }
 207     }
 208 
 209     interface FReductionMaskedOpLong {
 210         long apply(double[] a, int idx, boolean[] mask);
 211     }
 212 
 213     interface FReductionAllMaskedOpLong {
 214         long apply(double[] a, boolean[] mask);
 215     }
 216 
 217     static void assertReductionLongArraysEqualsMasked(long[] r, long rc, double[] a, boolean[] mask,
 218                                             FReductionMaskedOpLong f, FReductionAllMaskedOpLong fa) {
 219         int i = 0;
 220         try {
 221             Assert.assertEquals(rc, fa.apply(a, mask));
 222             for (; i < a.length; i += SPECIES.length()) {
 223                 Assert.assertEquals(r[i], f.apply(a, i, mask));
 224             }
 225         } catch (AssertionError e) {
 226             Assert.assertEquals(rc, fa.apply(a, mask), "Final result is incorrect!");
 227             Assert.assertEquals(r[i], f.apply(a, i, mask), "at index #" + i);
 228         }
 229     }
 230 
 231     interface FBoolReductionOp {
 232         boolean apply(boolean[] a, int idx);
 233     }
 234 
 235     static void assertReductionBoolArraysEquals(boolean[] r, boolean[] a, FBoolReductionOp f) {
 236         int i = 0;
 237         try {
 238             for (; i < a.length; i += SPECIES.length()) {
 239                 Assert.assertEquals(r[i], f.apply(a, i));
 240             }
 241         } catch (AssertionError e) {
 242             Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
 243         }
 244     }
 245 
 246     interface FMaskReductionOp {
 247         int apply(boolean[] a, int idx);
 248     }
 249 
 250     static void assertMaskReductionArraysEquals(int[] r, boolean[] a, FMaskReductionOp f) {
 251         int i = 0;
 252         try {
 253             for (; i < a.length; i += SPECIES.length()) {
 254                 Assert.assertEquals(r[i], f.apply(a, i));
 255             }
 256         } catch (AssertionError e) {
 257             Assert.assertEquals(r[i], f.apply(a, i), "at index #" + i);
 258         }
 259     }
 260 
 261     static void assertRearrangeArraysEquals(double[] r, double[] a, int[] order, int vector_len) {
 262         int i = 0, j = 0;
 263         try {
 264             for (; i < a.length; i += vector_len) {
 265                 for (j = 0; j < vector_len; j++) {
 266                     Assert.assertEquals(r[i+j], a[i+order[i+j]]);
 267                 }
 268             }
 269         } catch (AssertionError e) {
 270             int idx = i + j;
 271             Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]]);
 272         }
 273     }
 274 
 275     static void assertcompressArraysEquals(double[] r, double[] a, boolean[] m, int vector_len) {
 276         int i = 0, j = 0, k = 0;
 277         try {
 278             for (; i < a.length; i += vector_len) {
 279                 k = 0;
 280                 for (j = 0; j < vector_len; j++) {
 281                     if (m[(i + j) % SPECIES.length()]) {
 282                         Assert.assertEquals(r[i + k], a[i + j]);
 283                         k++;
 284                     }
 285                 }
 286                 for (; k < vector_len; k++) {
 287                     Assert.assertEquals(r[i + k], (double)0);
 288                 }
 289             }
 290         } catch (AssertionError e) {
 291             int idx = i + k;
 292             if (m[(i + j) % SPECIES.length()]) {
 293                 Assert.assertEquals(r[idx], a[i + j], "at index #" + idx);
 294             } else {
 295                 Assert.assertEquals(r[idx], (double)0, "at index #" + idx);
 296             }
 297         }
 298     }
 299 
 300     static void assertexpandArraysEquals(double[] r, double[] a, boolean[] m, int vector_len) {
 301         int i = 0, j = 0, k = 0;
 302         try {
 303             for (; i < a.length; i += vector_len) {
 304                 k = 0;
 305                 for (j = 0; j < vector_len; j++) {
 306                     if (m[(i + j) % SPECIES.length()]) {
 307                         Assert.assertEquals(r[i + j], a[i + k]);
 308                         k++;
 309                     } else {
 310                         Assert.assertEquals(r[i + j], (double)0);
 311                     }
 312                 }
 313             }
 314         } catch (AssertionError e) {
 315             int idx = i + j;
 316             if (m[idx % SPECIES.length()]) {
 317                 Assert.assertEquals(r[idx], a[i + k], "at index #" + idx);
 318             } else {
 319                 Assert.assertEquals(r[idx], (double)0, "at index #" + idx);
 320             }
 321         }
 322     }
 323 
 324     static void assertSelectFromTwoVectorEquals(double[] r, double[] order, double[] a, double[] b, int vector_len) {
 325         int i = 0, j = 0;
 326         boolean is_exceptional_idx = false;
 327         int idx = 0, wrapped_index = 0, oidx = 0;
 328         try {
 329             for (; i < a.length; i += vector_len) {
 330                 for (j = 0; j < vector_len; j++) {
 331                     idx = i + j;
 332                     wrapped_index = Math.floorMod((int)order[idx], 2 * vector_len);
 333                     is_exceptional_idx = wrapped_index >= vector_len;
 334                     oidx = is_exceptional_idx ? (wrapped_index - vector_len) : wrapped_index;
 335                     Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]));
 336                 }
 337             }
 338         } catch (AssertionError e) {
 339             Assert.assertEquals(r[idx], (is_exceptional_idx ? b[i + oidx] : a[i + oidx]), "at index #" + idx + ", order = " + order[idx] + ", a = " + a[i + oidx] + ", b = " + b[i + oidx]);
 340         }
 341     }
 342 
 343     static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, int vector_len) {
 344         int i = 0, j = 0;
 345         try {
 346             for (; i < a.length; i += vector_len) {
 347                 for (j = 0; j < vector_len; j++) {
 348                     Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]);
 349                 }
 350             }
 351         } catch (AssertionError e) {
 352             int idx = i + j;
 353             Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]]);
 354         }
 355     }
 356 
 357     static void assertRearrangeArraysEquals(double[] r, double[] a, int[] order, boolean[] mask, int vector_len) {
 358         int i = 0, j = 0;
 359         try {
 360             for (; i < a.length; i += vector_len) {
 361                 for (j = 0; j < vector_len; j++) {
 362                     if (mask[j % SPECIES.length()])
 363                          Assert.assertEquals(r[i+j], a[i+order[i+j]]);
 364                     else
 365                          Assert.assertEquals(r[i+j], (double)0);
 366                 }
 367             }
 368         } catch (AssertionError e) {
 369             int idx = i + j;
 370             if (mask[j % SPECIES.length()])
 371                 Assert.assertEquals(r[i+j], a[i+order[i+j]], "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 372             else
 373                 Assert.assertEquals(r[i+j], (double)0, "at index #" + idx + ", input = " + a[i+order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 374         }
 375     }
 376 
 377     static void assertSelectFromArraysEquals(double[] r, double[] a, double[] order, boolean[] mask, int vector_len) {
 378         int i = 0, j = 0;
 379         try {
 380             for (; i < a.length; i += vector_len) {
 381                 for (j = 0; j < vector_len; j++) {
 382                     if (mask[j % SPECIES.length()])
 383                          Assert.assertEquals(r[i+j], a[i+(int)order[i+j]]);
 384                     else
 385                          Assert.assertEquals(r[i+j], (double)0);
 386                 }
 387             }
 388         } catch (AssertionError e) {
 389             int idx = i + j;
 390             if (mask[j % SPECIES.length()])
 391                 Assert.assertEquals(r[i+j], a[i+(int)order[i+j]], "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 392             else
 393                 Assert.assertEquals(r[i+j], (double)0, "at index #" + idx + ", input = " + a[i+(int)order[i+j]] + ", mask = " + mask[j % SPECIES.length()]);
 394         }
 395     }
 396 
 397     static void assertBroadcastArraysEquals(double[] r, double[] a) {
 398         int i = 0;
 399         for (; i < a.length; i += SPECIES.length()) {
 400             int idx = i;
 401             for (int j = idx; j < (idx + SPECIES.length()); j++)
 402                 a[j]=a[idx];
 403         }
 404 
 405         try {
 406             for (i = 0; i < a.length; i++) {
 407                 Assert.assertEquals(r[i], a[i]);
 408             }
 409         } catch (AssertionError e) {
 410             Assert.assertEquals(r[i], a[i], "at index #" + i + ", input = " + a[i]);
 411         }
 412     }
 413 
 414     interface FBinOp {
 415         double apply(double a, double b);
 416     }
 417 
 418     interface FBinMaskOp {
 419         double apply(double a, double b, boolean m);
 420 
 421         static FBinMaskOp lift(FBinOp f) {
 422             return (a, b, m) -> m ? f.apply(a, b) : a;
 423         }
 424     }
 425 
 426     static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, FBinOp f) {
 427         int i = 0;
 428         try {
 429             for (; i < a.length; i++) {
 430                 //Left associative
 431                 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]));
 432 
 433                 //Right associative
 434                 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])));
 435 
 436                 //Results equal sanity check
 437                 Assert.assertEquals(rl[i], rr[i]);
 438             }
 439         } catch (AssertionError e) {
 440             Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i]), c[i]), "left associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 441             Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i])), "right associative test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 442             Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]);
 443         }
 444     }
 445 
 446    static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinOp f) {
 447        assertArraysEqualsAssociative(rl, rr, a, b, c, mask, FBinMaskOp.lift(f));
 448    }
 449 
 450     static void assertArraysEqualsAssociative(double[] rl, double[] rr, double[] a, double[] b, double[] c, boolean[] mask, FBinMaskOp f) {
 451         int i = 0;
 452         boolean mask_bit = false;
 453         try {
 454             for (; i < a.length; i++) {
 455                 mask_bit = mask[i % SPECIES.length()];
 456                 //Left associative
 457                 Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit));
 458 
 459                 //Right associative
 460                 Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit));
 461 
 462                 //Results equal sanity check
 463                 Assert.assertEquals(rl[i], rr[i]);
 464             }
 465         } catch (AssertionError e) {
 466             Assert.assertEquals(rl[i], f.apply(f.apply(a[i], b[i], mask_bit), c[i], mask_bit), "left associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit);
 467             Assert.assertEquals(rr[i], f.apply(a[i], f.apply(b[i], c[i], mask_bit), mask_bit), "right associative masked test at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i] + ", mask = " + mask_bit);
 468             Assert.assertEquals(rl[i], rr[i], "Result checks not equal at index #" + i + "leftRes = " + rl[i] + ", rightRes = " + rr[i]);
 469         }
 470     }
 471 
 472     static void assertArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 473         int i = 0;
 474         try {
 475             for (; i < a.length; i++) {
 476                 Assert.assertEquals(r[i], f.apply(a[i], b[i]));
 477             }
 478         } catch (AssertionError e) {
 479             Assert.assertEquals(r[i], f.apply(a[i], b[i]), "(" + a[i] + ", " + b[i] + ") at index #" + i);
 480         }
 481     }
 482 
 483     static void assertArraysEquals(double[] r, double[] a, double b, FBinOp f) {
 484         int i = 0;
 485         try {
 486             for (; i < a.length; i++) {
 487                 Assert.assertEquals(r[i], f.apply(a[i], b));
 488             }
 489         } catch (AssertionError e) {
 490             Assert.assertEquals(r[i], f.apply(a[i], b), "(" + a[i] + ", " + b + ") at index #" + i);
 491         }
 492     }
 493 
 494     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 495         int i = 0;
 496         try {
 497             for (; i < a.length; i++) {
 498                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]));
 499             }
 500         } catch (AssertionError e) {
 501             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]),
 502                                 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i);
 503         }
 504     }
 505 
 506     static void assertBroadcastLongArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 507         int i = 0;
 508         try {
 509             for (; i < a.length; i++) {
 510                 Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()])));
 511             }
 512         } catch (AssertionError e) {
 513             Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()])),
 514                                 "(" + a[i] + ", " + b[(i / SPECIES.length()) * SPECIES.length()] + ") at index #" + i);
 515         }
 516     }
 517 
 518     static void assertArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 519         assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 520     }
 521 
 522     static void assertArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 523         int i = 0;
 524         try {
 525             for (; i < a.length; i++) {
 526                 Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]));
 527             }
 528         } catch (AssertionError err) {
 529             Assert.assertEquals(r[i], f.apply(a[i], b[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", mask = " + mask[i % SPECIES.length()]);
 530         }
 531     }
 532 
 533     static void assertArraysEquals(double[] r, double[] a, double b, boolean[] mask, FBinOp f) {
 534         assertArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 535     }
 536 
 537     static void assertArraysEquals(double[] r, double[] a, double b, boolean[] mask, FBinMaskOp f) {
 538         int i = 0;
 539         try {
 540             for (; i < a.length; i++) {
 541                 Assert.assertEquals(r[i], f.apply(a[i], b, mask[i % SPECIES.length()]));
 542             }
 543         } catch (AssertionError err) {
 544             Assert.assertEquals(r[i], f.apply(a[i], b, mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b + ", mask = " + mask[i % SPECIES.length()]);
 545         }
 546     }
 547 
 548     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 549         assertBroadcastArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 550     }
 551 
 552     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 553         int i = 0;
 554         try {
 555             for (; i < a.length; i++) {
 556                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]));
 557             }
 558         } catch (AssertionError err) {
 559             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 560                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
 561                                 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 562                                 mask[i % SPECIES.length()]);
 563         }
 564     }
 565 
 566     static void assertBroadcastLongArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 567         assertBroadcastLongArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 568     }
 569 
 570     static void assertBroadcastLongArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 571         int i = 0;
 572         try {
 573             for (; i < a.length; i++) {
 574                 Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()]), mask[i % SPECIES.length()]));
 575             }
 576         } catch (AssertionError err) {
 577             Assert.assertEquals(r[i], f.apply(a[i], (double)((long)b[(i / SPECIES.length()) * SPECIES.length()]),
 578                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
 579                                 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 580                                 mask[i % SPECIES.length()]);
 581         }
 582     }
 583 
 584     static void assertShiftArraysEquals(double[] r, double[] a, double[] b, FBinOp f) {
 585         int i = 0;
 586         int j = 0;
 587         try {
 588             for (; j < a.length; j += SPECIES.length()) {
 589                 for (i = 0; i < SPECIES.length(); i++) {
 590                     Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]));
 591                 }
 592             }
 593         } catch (AssertionError e) {
 594             Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j]), "at index #" + i + ", " + j);
 595         }
 596     }
 597 
 598     static void assertShiftArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinOp f) {
 599         assertShiftArraysEquals(r, a, b, mask, FBinMaskOp.lift(f));
 600     }
 601 
 602     static void assertShiftArraysEquals(double[] r, double[] a, double[] b, boolean[] mask, FBinMaskOp f) {
 603         int i = 0;
 604         int j = 0;
 605         try {
 606             for (; j < a.length; j += SPECIES.length()) {
 607                 for (i = 0; i < SPECIES.length(); i++) {
 608                     Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]));
 609                 }
 610             }
 611         } catch (AssertionError err) {
 612             Assert.assertEquals(r[i+j], f.apply(a[i+j], b[j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", input2 = " + b[j] + ", mask = " + mask[i]);
 613         }
 614     }
 615 
 616     interface FBinConstOp {
 617         double apply(double a);
 618     }
 619 
 620     interface FBinConstMaskOp {
 621         double apply(double a, boolean m);
 622 
 623         static FBinConstMaskOp lift(FBinConstOp f) {
 624             return (a, m) -> m ? f.apply(a) : a;
 625         }
 626     }
 627 
 628     static void assertShiftConstEquals(double[] r, double[] a, FBinConstOp f) {
 629         int i = 0;
 630         int j = 0;
 631         try {
 632             for (; j < a.length; j += SPECIES.length()) {
 633                 for (i = 0; i < SPECIES.length(); i++) {
 634                     Assert.assertEquals(r[i+j], f.apply(a[i+j]));
 635                 }
 636             }
 637         } catch (AssertionError e) {
 638             Assert.assertEquals(r[i+j], f.apply(a[i+j]), "at index #" + i + ", " + j);
 639         }
 640     }
 641 
 642     static void assertShiftConstEquals(double[] r, double[] a, boolean[] mask, FBinConstOp f) {
 643         assertShiftConstEquals(r, a, mask, FBinConstMaskOp.lift(f));
 644     }
 645 
 646     static void assertShiftConstEquals(double[] r, double[] a, boolean[] mask, FBinConstMaskOp f) {
 647         int i = 0;
 648         int j = 0;
 649         try {
 650             for (; j < a.length; j += SPECIES.length()) {
 651                 for (i = 0; i < SPECIES.length(); i++) {
 652                     Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]));
 653                 }
 654             }
 655         } catch (AssertionError err) {
 656             Assert.assertEquals(r[i+j], f.apply(a[i+j], mask[i]), "at index #" + i + ", input1 = " + a[i+j] + ", mask = " + mask[i]);
 657         }
 658     }
 659 
 660     interface FTernOp {
 661         double apply(double a, double b, double c);
 662     }
 663 
 664     interface FTernMaskOp {
 665         double apply(double a, double b, double c, boolean m);
 666 
 667         static FTernMaskOp lift(FTernOp f) {
 668             return (a, b, c, m) -> m ? f.apply(a, b, c) : a;
 669         }
 670     }
 671 
 672     static void assertArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 673         int i = 0;
 674         try {
 675             for (; i < a.length; i++) {
 676                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]));
 677             }
 678         } catch (AssertionError e) {
 679             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " + c[i]);
 680         }
 681     }
 682 
 683     static void assertArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask, FTernOp f) {
 684         assertArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 685     }
 686 
 687     static void assertArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask, FTernMaskOp f) {
 688         int i = 0;
 689         try {
 690             for (; i < a.length; i++) {
 691                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]));
 692             }
 693         } catch (AssertionError err) {
 694             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[i], mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = "
 695               + b[i] + ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
 696         }
 697     }
 698 
 699     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 700         int i = 0;
 701         try {
 702             for (; i < a.length; i++) {
 703                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]));
 704             }
 705         } catch (AssertionError e) {
 706             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" +
 707                                 i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", input3 = " +
 708                                 c[(i / SPECIES.length()) * SPECIES.length()]);
 709         }
 710     }
 711 
 712     static void assertAltBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 713         int i = 0;
 714         try {
 715             for (; i < a.length; i++) {
 716                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]));
 717             }
 718         } catch (AssertionError e) {
 719             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i]), "at index #" +
 720                                 i + ", input1 = " + a[i] + ", input2 = " +
 721                                 b[(i / SPECIES.length()) * SPECIES.length()] + ",  input3 = " + c[i]);
 722         }
 723     }
 724 
 725     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 726                                             FTernOp f) {
 727         assertBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 728     }
 729 
 730     static void assertBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 731                                             FTernMaskOp f) {
 732         int i = 0;
 733         try {
 734             for (; i < a.length; i++) {
 735                 Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()],
 736                                     mask[i % SPECIES.length()]));
 737             }
 738         } catch (AssertionError err) {
 739             Assert.assertEquals(r[i], f.apply(a[i], b[i], c[(i / SPECIES.length()) * SPECIES.length()],
 740                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
 741                                 b[i] + ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 742                                 mask[i % SPECIES.length()]);
 743         }
 744     }
 745 
 746     static void assertAltBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 747                                             FTernOp f) {
 748         assertAltBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 749     }
 750 
 751     static void assertAltBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 752                                             FTernMaskOp f) {
 753         int i = 0;
 754         try {
 755             for (; i < a.length; i++) {
 756                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i],
 757                                     mask[i % SPECIES.length()]));
 758             }
 759         } catch (AssertionError err) {
 760             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()], c[i],
 761                                 mask[i % SPECIES.length()]), "at index #" + i + ", input1 = " + a[i] +
 762                                 ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] +
 763                                 ", input3 = " + c[i] + ", mask = " + mask[i % SPECIES.length()]);
 764         }
 765     }
 766 
 767     static void assertDoubleBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, FTernOp f) {
 768         int i = 0;
 769         try {
 770             for (; i < a.length; i++) {
 771                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 772                                     c[(i / SPECIES.length()) * SPECIES.length()]));
 773             }
 774         } catch (AssertionError e) {
 775             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 776                                 c[(i / SPECIES.length()) * SPECIES.length()]), "at index #" + i + ", input1 = " + a[i]
 777                                 + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] + ", input3 = " +
 778                                 c[(i / SPECIES.length()) * SPECIES.length()]);
 779         }
 780     }
 781 
 782     static void assertDoubleBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 783                                                   FTernOp f) {
 784         assertDoubleBroadcastArraysEquals(r, a, b, c, mask, FTernMaskOp.lift(f));
 785     }
 786 
 787     static void assertDoubleBroadcastArraysEquals(double[] r, double[] a, double[] b, double[] c, boolean[] mask,
 788                                                   FTernMaskOp f) {
 789         int i = 0;
 790         try {
 791             for (; i < a.length; i++) {
 792                 Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 793                                     c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]));
 794             }
 795         } catch (AssertionError err) {
 796             Assert.assertEquals(r[i], f.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()],
 797                                 c[(i / SPECIES.length()) * SPECIES.length()], mask[i % SPECIES.length()]), "at index #"
 798                                 + i + ", input1 = " + a[i] + ", input2 = " + b[(i / SPECIES.length()) * SPECIES.length()] +
 799                                 ", input3 = " + c[(i / SPECIES.length()) * SPECIES.length()] + ", mask = " +
 800                                 mask[i % SPECIES.length()]);
 801         }
 802     }
 803 
 804 
 805     static boolean isWithin1Ulp(double actual, double expected) {
 806         if (Double.isNaN(expected) && !Double.isNaN(actual)) {
 807             return false;
 808         } else if (!Double.isNaN(expected) && Double.isNaN(actual)) {
 809             return false;
 810         }
 811 
 812         double low = Math.nextDown(expected);
 813         double high = Math.nextUp(expected);
 814 
 815         if (Double.compare(low, expected) > 0) {
 816             return false;
 817         }
 818 
 819         if (Double.compare(high, expected) < 0) {
 820             return false;
 821         }
 822 
 823         return true;
 824     }
 825 
 826     static void assertArraysEqualsWithinOneUlp(double[] r, double[] a, FUnOp mathf, FUnOp strictmathf) {
 827         int i = 0;
 828         try {
 829             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 830             for (; i < a.length; i++) {
 831                 Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i])) == 0 ||
 832                                     isWithin1Ulp(r[i], strictmathf.apply(a[i])));
 833             }
 834         } catch (AssertionError e) {
 835             Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i])) == 0, "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i]));
 836             Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i])), "at index #" + i + ", input = " + a[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i]));
 837         }
 838     }
 839 
 840     static void assertArraysEqualsWithinOneUlp(double[] r, double[] a, double[] b, FBinOp mathf, FBinOp strictmathf) {
 841         int i = 0;
 842         try {
 843             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 844             for (; i < a.length; i++) {
 845                 Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i], b[i])) == 0 ||
 846                                     isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])));
 847             }
 848         } catch (AssertionError e) {
 849             Assert.assertTrue(Double.compare(r[i], mathf.apply(a[i], b[i])) == 0, "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected = " + mathf.apply(a[i], b[i]));
 850             Assert.assertTrue(isWithin1Ulp(r[i], strictmathf.apply(a[i], b[i])), "at index #" + i + ", input1 = " + a[i] + ", input2 = " + b[i] + ", actual = " + r[i] + ", expected (within 1 ulp) = " + strictmathf.apply(a[i], b[i]));
 851         }
 852     }
 853 
 854     static void assertBroadcastArraysEqualsWithinOneUlp(double[] r, double[] a, double[] b,
 855                                                         FBinOp mathf, FBinOp strictmathf) {
 856         int i = 0;
 857         try {
 858             // Check that result is within 1 ulp of strict math or equivalent to math implementation.
 859             for (; i < a.length; i++) {
 860                 Assert.assertTrue(Double.compare(r[i],
 861                                   mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0 ||
 862                                   isWithin1Ulp(r[i],
 863                                   strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])));
 864             }
 865         } catch (AssertionError e) {
 866             Assert.assertTrue(Double.compare(r[i],
 867                               mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])) == 0,
 868                               "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
 869                               b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] +
 870                               ", expected = " + mathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()]));
 871             Assert.assertTrue(isWithin1Ulp(r[i],
 872                               strictmathf.apply(a[i], b[(i / SPECIES.length()) * SPECIES.length()])),
 873                              "at index #" + i + ", input1 = " + a[i] + ", input2 = " +
 874                              b[(i / SPECIES.length()) * SPECIES.length()] + ", actual = " + r[i] +
 875                              ", expected (within 1 ulp) = " + strictmathf.apply(a[i],
 876                              b[(i / SPECIES.length()) * SPECIES.length()]));
 877         }
 878     }
 879 
 880     interface FGatherScatterOp {
 881         double[] apply(double[] a, int ix, int[] b, int iy);
 882     }
 883 
 884     static void assertArraysEquals(double[] r, double[] a, int[] b, FGatherScatterOp f) {
 885         int i = 0;
 886         try {
 887             for (; i < a.length; i += SPECIES.length()) {
 888                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 889                   f.apply(a, i, b, i));
 890             }
 891         } catch (AssertionError e) {
 892             double[] ref = f.apply(a, i, b, i);
 893             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 894             Assert.assertEquals(res, ref,
 895               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 896               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 897               + ", b: "
 898               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 899               + " at index #" + i);
 900         }
 901     }
 902 
 903     interface FGatherMaskedOp {
 904         double[] apply(double[] a, int ix, boolean[] mask, int[] b, int iy);
 905     }
 906 
 907     interface FScatterMaskedOp {
 908         double[] apply(double[] r, double[] a, int ix, boolean[] mask, int[] b, int iy);
 909     }
 910 
 911     static void assertArraysEquals(double[] r, double[] a, int[] b, boolean[] mask, FGatherMaskedOp f) {
 912         int i = 0;
 913         try {
 914             for (; i < a.length; i += SPECIES.length()) {
 915                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 916                   f.apply(a, i, mask, b, i));
 917             }
 918         } catch (AssertionError e) {
 919             double[] ref = f.apply(a, i, mask, b, i);
 920             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 921             Assert.assertEquals(res, ref,
 922               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 923               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 924               + ", b: "
 925               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 926               + ", mask: "
 927               + Arrays.toString(mask)
 928               + " at index #" + i);
 929         }
 930     }
 931 
 932     static void assertArraysEquals(double[] r, double[] a, int[] b, boolean[] mask, FScatterMaskedOp f) {
 933         int i = 0;
 934         try {
 935             for (; i < a.length; i += SPECIES.length()) {
 936                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 937                   f.apply(r, a, i, mask, b, i));
 938             }
 939         } catch (AssertionError e) {
 940             double[] ref = f.apply(r, a, i, mask, b, i);
 941             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 942             Assert.assertEquals(res, ref,
 943               "(ref: " + Arrays.toString(ref) + ", res: " + Arrays.toString(res) + ", a: "
 944               + Arrays.toString(Arrays.copyOfRange(a, i, i+SPECIES.length()))
 945               + ", b: "
 946               + Arrays.toString(Arrays.copyOfRange(b, i, i+SPECIES.length()))
 947               + ", r: "
 948               + Arrays.toString(Arrays.copyOfRange(r, i, i+SPECIES.length()))
 949               + ", mask: "
 950               + Arrays.toString(mask)
 951               + " at index #" + i);
 952         }
 953     }
 954 
 955     interface FLaneOp {
 956         double[] apply(double[] a, int origin, int idx);
 957     }
 958 
 959     static void assertArraysEquals(double[] r, double[] a, int origin, FLaneOp f) {
 960         int i = 0;
 961         try {
 962             for (; i < a.length; i += SPECIES.length()) {
 963                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 964                   f.apply(a, origin, i));
 965             }
 966         } catch (AssertionError e) {
 967             double[] ref = f.apply(a, origin, i);
 968             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 969             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
 970               + ", res: " + Arrays.toString(res)
 971               + "), at index #" + i);
 972         }
 973     }
 974 
 975     interface FLaneBop {
 976         double[] apply(double[] a, double[] b, int origin, int idx);
 977     }
 978 
 979     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, FLaneBop f) {
 980         int i = 0;
 981         try {
 982             for (; i < a.length; i += SPECIES.length()) {
 983                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
 984                   f.apply(a, b, origin, i));
 985             }
 986         } catch (AssertionError e) {
 987             double[] ref = f.apply(a, b, origin, i);
 988             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
 989             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
 990               + ", res: " + Arrays.toString(res)
 991               + "), at index #" + i
 992               + ", at origin #" + origin);
 993         }
 994     }
 995 
 996     interface FLaneMaskedBop {
 997         double[] apply(double[] a, double[] b, int origin, boolean[] mask, int idx);
 998     }
 999 
1000     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, boolean[] mask, FLaneMaskedBop f) {
1001         int i = 0;
1002         try {
1003             for (; i < a.length; i += SPECIES.length()) {
1004                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1005                   f.apply(a, b, origin, mask, i));
1006             }
1007         } catch (AssertionError e) {
1008             double[] ref = f.apply(a, b, origin, mask, i);
1009             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1010             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1011               + ", res: " + Arrays.toString(res)
1012               + "), at index #" + i
1013               + ", at origin #" + origin);
1014         }
1015     }
1016 
1017     interface FLanePartBop {
1018         double[] apply(double[] a, double[] b, int origin, int part, int idx);
1019     }
1020 
1021     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, int part, FLanePartBop f) {
1022         int i = 0;
1023         try {
1024             for (; i < a.length; i += SPECIES.length()) {
1025                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1026                   f.apply(a, b, origin, part, i));
1027             }
1028         } catch (AssertionError e) {
1029             double[] ref = f.apply(a, b, origin, part, i);
1030             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1031             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1032               + ", res: " + Arrays.toString(res)
1033               + "), at index #" + i
1034               + ", at origin #" + origin
1035               + ", with part #" + part);
1036         }
1037     }
1038 
1039     interface FLanePartMaskedBop {
1040         double[] apply(double[] a, double[] b, int origin, int part, boolean[] mask, int idx);
1041     }
1042 
1043     static void assertArraysEquals(double[] r, double[] a, double[] b, int origin, int part, boolean[] mask, FLanePartMaskedBop f) {
1044         int i = 0;
1045         try {
1046             for (; i < a.length; i += SPECIES.length()) {
1047                 Assert.assertEquals(Arrays.copyOfRange(r, i, i+SPECIES.length()),
1048                   f.apply(a, b, origin, part, mask, i));
1049             }
1050         } catch (AssertionError e) {
1051             double[] ref = f.apply(a, b, origin, part, mask, i);
1052             double[] res = Arrays.copyOfRange(r, i, i+SPECIES.length());
1053             Assert.assertEquals(res, ref, "(ref: " + Arrays.toString(ref)
1054               + ", res: " + Arrays.toString(res)
1055               + "), at index #" + i
1056               + ", at origin #" + origin
1057               + ", with part #" + part);
1058         }
1059     }
1060 
1061     static int intCornerCaseValue(int i) {
1062         switch(i % 5) {
1063             case 0:
1064                 return Integer.MAX_VALUE;
1065             case 1:
1066                 return Integer.MIN_VALUE;
1067             case 2:
1068                 return Integer.MIN_VALUE;
1069             case 3:
1070                 return Integer.MAX_VALUE;
1071             default:
1072                 return (int)0;
1073         }
1074     }
1075 
1076     static final List<IntFunction<double[]>> INT_DOUBLE_GENERATORS = List.of(
1077             withToString("double[-i * 5]", (int s) -> {
1078                 return fill(s * BUFFER_REPS,
1079                             i -> (double)(-i * 5));
1080             }),
1081             withToString("double[i * 5]", (int s) -> {
1082                 return fill(s * BUFFER_REPS,
1083                             i -> (double)(i * 5));
1084             }),
1085             withToString("double[i + 1]", (int s) -> {
1086                 return fill(s * BUFFER_REPS,
1087                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
1088             }),
1089             withToString("double[intCornerCaseValue(i)]", (int s) -> {
1090                 return fill(s * BUFFER_REPS,
1091                             i -> (double)intCornerCaseValue(i));
1092             })
1093     );
1094 
1095     static void assertArraysEquals(int[] r, double[] a, int offs) {
1096         int i = 0;
1097         try {
1098             for (; i < r.length; i++) {
1099                 Assert.assertEquals(r[i], (int)(a[i+offs]));
1100             }
1101         } catch (AssertionError e) {
1102             Assert.assertEquals(r[i], (int)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1103         }
1104     }
1105 
1106     static long longCornerCaseValue(int i) {
1107         switch(i % 5) {
1108             case 0:
1109                 return Long.MAX_VALUE;
1110             case 1:
1111                 return Long.MIN_VALUE;
1112             case 2:
1113                 return Long.MIN_VALUE;
1114             case 3:
1115                 return Long.MAX_VALUE;
1116             default:
1117                 return (long)0;
1118         }
1119     }
1120 
1121     static final List<IntFunction<double[]>> LONG_DOUBLE_GENERATORS = List.of(
1122             withToString("double[-i * 5]", (int s) -> {
1123                 return fill(s * BUFFER_REPS,
1124                             i -> (double)(-i * 5));
1125             }),
1126             withToString("double[i * 5]", (int s) -> {
1127                 return fill(s * BUFFER_REPS,
1128                             i -> (double)(i * 5));
1129             }),
1130             withToString("double[i + 1]", (int s) -> {
1131                 return fill(s * BUFFER_REPS,
1132                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
1133             }),
1134             withToString("double[cornerCaseValue(i)]", (int s) -> {
1135                 return fill(s * BUFFER_REPS,
1136                             i -> (double)longCornerCaseValue(i));
1137             })
1138     );
1139 
1140 
1141     static void assertArraysEquals(long[] r, double[] a, int offs) {
1142         int i = 0;
1143         try {
1144             for (; i < r.length; i++) {
1145                 Assert.assertEquals(r[i], (long)(a[i+offs]));
1146             }
1147         } catch (AssertionError e) {
1148             Assert.assertEquals(r[i], (long)(a[i+offs]), "at index #" + i + ", input = " + a[i+offs]);
1149         }
1150     }
1151 
1152     static long bits(double e) {
1153         return  Double.doubleToLongBits(e);
1154     }
1155 
1156     static final List<IntFunction<double[]>> DOUBLE_GENERATORS = List.of(
1157             withToString("double[-i * 5]", (int s) -> {
1158                 return fill(s * BUFFER_REPS,
1159                             i -> (double)(-i * 5));
1160             }),
1161             withToString("double[i * 5]", (int s) -> {
1162                 return fill(s * BUFFER_REPS,
1163                             i -> (double)(i * 5));
1164             }),
1165             withToString("double[i + 1]", (int s) -> {
1166                 return fill(s * BUFFER_REPS,
1167                             i -> (((double)(i + 1) == 0) ? 1 : (double)(i + 1)));
1168             }),
1169             withToString("double[0.01 + (i / (i + 1))]", (int s) -> {
1170                 return fill(s * BUFFER_REPS,
1171                             i -> (double)0.01 + ((double)i / (i + 1)));
1172             }),
1173             withToString("double[i -> i % 17 == 0 ? cornerCaseValue(i) : 0.01 + (i / (i + 1))]", (int s) -> {
1174                 return fill(s * BUFFER_REPS,
1175                             i -> i % 17 == 0 ? cornerCaseValue(i) : (double)0.01 + ((double)i / (i + 1)));
1176             }),
1177             withToString("double[cornerCaseValue(i)]", (int s) -> {
1178                 return fill(s * BUFFER_REPS,
1179                             i -> cornerCaseValue(i));
1180             })
1181     );
1182 
1183     // Create combinations of pairs
1184     // @@@ Might be sensitive to order e.g. div by 0
1185     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_PAIRS =
1186         Stream.of(DOUBLE_GENERATORS.get(0)).
1187                 flatMap(fa -> DOUBLE_GENERATORS.stream().skip(1).map(fb -> List.of(fa, fb))).
1188                 collect(Collectors.toList());
1189 
1190     @DataProvider
1191     public Object[][] boolUnaryOpProvider() {
1192         return BOOL_ARRAY_GENERATORS.stream().
1193                 map(f -> new Object[]{f}).
1194                 toArray(Object[][]::new);
1195     }
1196 
1197     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_TRIPLES =
1198         DOUBLE_GENERATOR_PAIRS.stream().
1199                 flatMap(pair -> DOUBLE_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
1200                 collect(Collectors.toList());
1201 
1202     static final List<IntFunction<double[]>> SELECT_FROM_INDEX_GENERATORS = List.of(
1203             withToString("double[0..VECLEN*2)", (int s) -> {
1204                 return fill(s * BUFFER_REPS,
1205                             i -> (double)(RAND.nextInt()));
1206             })
1207     );
1208 
1209     static final List<List<IntFunction<double[]>>> DOUBLE_GENERATOR_SELECT_FROM_TRIPLES =
1210         DOUBLE_GENERATOR_PAIRS.stream().
1211                 flatMap(pair -> SELECT_FROM_INDEX_GENERATORS.stream().map(f -> List.of(pair.get(0), pair.get(1), f))).
1212                 collect(Collectors.toList());
1213 
1214     @DataProvider
1215     public Object[][] doubleBinaryOpProvider() {
1216         return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
1217                 toArray(Object[][]::new);
1218     }
1219 
1220     @DataProvider
1221     public Object[][] doubleIndexedOpProvider() {
1222         return DOUBLE_GENERATOR_PAIRS.stream().map(List::toArray).
1223                 toArray(Object[][]::new);
1224     }
1225 
1226     @DataProvider
1227     public Object[][] doubleBinaryOpMaskProvider() {
1228         return BOOLEAN_MASK_GENERATORS.stream().
1229                 flatMap(fm -> DOUBLE_GENERATOR_PAIRS.stream().map(lfa -> {
1230                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1231                 })).
1232                 toArray(Object[][]::new);
1233     }
1234 
1235     @DataProvider
1236     public Object[][] doubleTernaryOpProvider() {
1237         return DOUBLE_GENERATOR_TRIPLES.stream().map(List::toArray).
1238                 toArray(Object[][]::new);
1239     }
1240 
1241     @DataProvider
1242     public Object[][] doubleSelectFromTwoVectorOpProvider() {
1243         return DOUBLE_GENERATOR_SELECT_FROM_TRIPLES.stream().map(List::toArray).
1244                 toArray(Object[][]::new);
1245     }
1246 
1247     @DataProvider
1248     public Object[][] doubleTernaryOpMaskProvider() {
1249         return BOOLEAN_MASK_GENERATORS.stream().
1250                 flatMap(fm -> DOUBLE_GENERATOR_TRIPLES.stream().map(lfa -> {
1251                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1252                 })).
1253                 toArray(Object[][]::new);
1254     }
1255 
1256     @DataProvider
1257     public Object[][] doubleUnaryOpProvider() {
1258         return DOUBLE_GENERATORS.stream().
1259                 map(f -> new Object[]{f}).
1260                 toArray(Object[][]::new);
1261     }
1262 
1263     @DataProvider
1264     public Object[][] doubleUnaryOpMaskProvider() {
1265         return BOOLEAN_MASK_GENERATORS.stream().
1266                 flatMap(fm -> DOUBLE_GENERATORS.stream().map(fa -> {
1267                     return new Object[] {fa, fm};
1268                 })).
1269                 toArray(Object[][]::new);
1270     }
1271 
1272     @DataProvider
1273     public Object[][] doubletoIntUnaryOpProvider() {
1274         return INT_DOUBLE_GENERATORS.stream().
1275                 map(f -> new Object[]{f}).
1276                 toArray(Object[][]::new);
1277     }
1278 
1279     @DataProvider
1280     public Object[][] doubletoLongUnaryOpProvider() {
1281         return LONG_DOUBLE_GENERATORS.stream().
1282                 map(f -> new Object[]{f}).
1283                 toArray(Object[][]::new);
1284     }
1285 
1286     @DataProvider
1287     public Object[][] maskProvider() {
1288         return BOOLEAN_MASK_GENERATORS.stream().
1289                 map(f -> new Object[]{f}).
1290                 toArray(Object[][]::new);
1291     }
1292 
1293     @DataProvider
1294     public Object[][] maskCompareOpProvider() {
1295         return BOOLEAN_MASK_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1296                 toArray(Object[][]::new);
1297     }
1298 
1299     @DataProvider
1300     public Object[][] shuffleProvider() {
1301         return INT_SHUFFLE_GENERATORS.stream().
1302                 map(f -> new Object[]{f}).
1303                 toArray(Object[][]::new);
1304     }
1305 
1306     @DataProvider
1307     public Object[][] shuffleCompareOpProvider() {
1308         return INT_SHUFFLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1309                 toArray(Object[][]::new);
1310     }
1311 
1312     @DataProvider
1313     public Object[][] doubleUnaryOpShuffleProvider() {
1314         return INT_SHUFFLE_GENERATORS.stream().
1315                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1316                     return new Object[] {fa, fs};
1317                 })).
1318                 toArray(Object[][]::new);
1319     }
1320 
1321     @DataProvider
1322     public Object[][] doubleUnaryOpShuffleMaskProvider() {
1323         return BOOLEAN_MASK_GENERATORS.stream().
1324                 flatMap(fm -> INT_SHUFFLE_GENERATORS.stream().
1325                     flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1326                         return new Object[] {fa, fs, fm};
1327                 }))).
1328                 toArray(Object[][]::new);
1329     }
1330 
1331     static final List<BiFunction<Integer,Integer,double[]>> DOUBLE_SHUFFLE_GENERATORS = List.of(
1332             withToStringBi("shuffle[random]", (Integer l, Integer m) -> {
1333                 double[] a = new double[l];
1334                 int upper = m;
1335                 for (int i = 0; i < 1; i++) {
1336                     a[i] = (double)RAND.nextInt(upper);
1337                 }
1338                 return a;
1339             })
1340     );
1341 
1342     @DataProvider
1343     public Object[][] doubleUnaryOpSelectFromProvider() {
1344         return DOUBLE_SHUFFLE_GENERATORS.stream().
1345                 flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1346                     return new Object[] {fa, fs};
1347                 })).
1348                 toArray(Object[][]::new);
1349     }
1350 
1351     @DataProvider
1352     public Object[][] doubleUnaryOpSelectFromMaskProvider() {
1353         return BOOLEAN_MASK_GENERATORS.stream().
1354                 flatMap(fm -> DOUBLE_SHUFFLE_GENERATORS.stream().
1355                     flatMap(fs -> DOUBLE_GENERATORS.stream().map(fa -> {
1356                         return new Object[] {fa, fs, fm};
1357                 }))).
1358                 toArray(Object[][]::new);
1359     }
1360 
1361     static final List<IntFunction<double[]>> DOUBLE_COMPARE_GENERATORS = List.of(
1362             withToString("double[i]", (int s) -> {
1363                 return fill(s * BUFFER_REPS,
1364                             i -> (double)i);
1365             }),
1366             withToString("double[i - length / 2]", (int s) -> {
1367                 return fill(s * BUFFER_REPS,
1368                             i -> (double)(i - (s * BUFFER_REPS / 2)));
1369             }),
1370             withToString("double[i + 1]", (int s) -> {
1371                 return fill(s * BUFFER_REPS,
1372                             i -> (double)(i + 1));
1373             }),
1374             withToString("double[i - 2]", (int s) -> {
1375                 return fill(s * BUFFER_REPS,
1376                             i -> (double)(i - 2));
1377             }),
1378             withToString("double[zigZag(i)]", (int s) -> {
1379                 return fill(s * BUFFER_REPS,
1380                             i -> i%3 == 0 ? (double)i : (i%3 == 1 ? (double)(i + 1) : (double)(i - 2)));
1381             }),
1382             withToString("double[cornerCaseValue(i)]", (int s) -> {
1383                 return fill(s * BUFFER_REPS,
1384                             i -> cornerCaseValue(i));
1385             })
1386     );
1387 
1388     static final List<List<IntFunction<double[]>>> DOUBLE_TEST_GENERATOR_ARGS =
1389         DOUBLE_COMPARE_GENERATORS.stream().
1390                 map(fa -> List.of(fa)).
1391                 collect(Collectors.toList());
1392 
1393     @DataProvider
1394     public Object[][] doubleTestOpProvider() {
1395         return DOUBLE_TEST_GENERATOR_ARGS.stream().map(List::toArray).
1396                 toArray(Object[][]::new);
1397     }
1398 
1399     @DataProvider
1400     public Object[][] doubleTestOpMaskProvider() {
1401         return BOOLEAN_MASK_GENERATORS.stream().
1402                 flatMap(fm -> DOUBLE_TEST_GENERATOR_ARGS.stream().map(lfa -> {
1403                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1404                 })).
1405                 toArray(Object[][]::new);
1406     }
1407 
1408     static final List<List<IntFunction<double[]>>> DOUBLE_COMPARE_GENERATOR_PAIRS =
1409         DOUBLE_COMPARE_GENERATORS.stream().
1410                 flatMap(fa -> DOUBLE_COMPARE_GENERATORS.stream().map(fb -> List.of(fa, fb))).
1411                 collect(Collectors.toList());
1412 
1413     @DataProvider
1414     public Object[][] doubleCompareOpProvider() {
1415         return DOUBLE_COMPARE_GENERATOR_PAIRS.stream().map(List::toArray).
1416                 toArray(Object[][]::new);
1417     }
1418 
1419     @DataProvider
1420     public Object[][] doubleCompareOpMaskProvider() {
1421         return BOOLEAN_MASK_GENERATORS.stream().
1422                 flatMap(fm -> DOUBLE_COMPARE_GENERATOR_PAIRS.stream().map(lfa -> {
1423                     return Stream.concat(lfa.stream(), Stream.of(fm)).toArray();
1424                 })).
1425                 toArray(Object[][]::new);
1426     }
1427 
1428     interface ToDoubleF {
1429         double apply(int i);
1430     }
1431 
1432     static double[] fill(int s , ToDoubleF f) {
1433         return fill(new double[s], f);
1434     }
1435 
1436     static double[] fill(double[] a, ToDoubleF f) {
1437         for (int i = 0; i < a.length; i++) {
1438             a[i] = f.apply(i);
1439         }
1440         return a;
1441     }
1442 
1443     static double cornerCaseValue(int i) {
1444         return switch(i % 8) {
1445             case 0  -> Double.MAX_VALUE;
1446             case 1  -> Double.MIN_VALUE;
1447             case 2  -> Double.NEGATIVE_INFINITY;
1448             case 3  -> Double.POSITIVE_INFINITY;
1449             case 4  -> Double.NaN;
1450             case 5  -> Double.longBitsToDouble(0x7FF123456789ABCDL);
1451             case 6  -> (double)0.0;
1452             default -> (double)-0.0;
1453         };
1454     }
1455 
1456     static final IntFunction<double[]> fr = (vl) -> {
1457         int length = BUFFER_REPS * vl;
1458         return new double[length];
1459     };
1460 
1461     static final IntFunction<boolean[]> fmr = (vl) -> {
1462         int length = BUFFER_REPS * vl;
1463         return new boolean[length];
1464     };
1465 
1466     static final IntFunction<long[]> lfr = (vl) -> {
1467         int length = BUFFER_REPS * vl;
1468         return new long[length];
1469     };
1470 
1471     static boolean eq(double a, double b) {
1472         return a == b;
1473     }
1474 
1475     static boolean neq(double a, double b) {
1476         return a != b;
1477     }
1478 
1479     static boolean lt(double a, double b) {
1480         return a < b;
1481     }
1482 
1483     static boolean le(double a, double b) {
1484         return a <= b;
1485     }
1486 
1487     static boolean gt(double a, double b) {
1488         return a > b;
1489     }
1490 
1491     static boolean ge(double a, double b) {
1492         return a >= b;
1493     }
1494 
1495     static double firstNonZero(double a, double b) {
1496         return Double.compare(a, (double) 0) != 0 ? a : b;
1497     }
1498 
1499     @Test
1500     static void smokeTest1() {
1501         DoubleVector three = DoubleVector.broadcast(SPECIES, (byte)-3);
1502         DoubleVector three2 = (DoubleVector) SPECIES.broadcast(-3);
1503         assert(three.eq(three2).allTrue());
1504         DoubleVector three3 = three2.broadcast(1).broadcast(-3);
1505         assert(three.eq(three3).allTrue());
1506         int scale = 2;
1507         Class<?> ETYPE = double.class;
1508         if (ETYPE == double.class || ETYPE == long.class)
1509             scale = 1000000;
1510         else if (ETYPE == byte.class && SPECIES.length() >= 64)
1511             scale = 1;
1512         DoubleVector higher = three.addIndex(scale);
1513         VectorMask<Double> m = three.compare(VectorOperators.LE, higher);
1514         assert(m.allTrue());
1515         m = higher.min((double)-1).test(VectorOperators.IS_NEGATIVE);
1516         assert(m.allTrue());
1517         m = higher.test(VectorOperators.IS_FINITE);
1518         assert(m.allTrue());
1519         double max = higher.reduceLanes(VectorOperators.MAX);
1520         assert(max == -3 + scale * (SPECIES.length()-1));
1521     }
1522 
1523     private static double[]
1524     bothToArray(DoubleVector a, DoubleVector b) {
1525         double[] r = new double[a.length() + b.length()];
1526         a.intoArray(r, 0);
1527         b.intoArray(r, a.length());
1528         return r;
1529     }
1530 
1531     @Test
1532     static void smokeTest2() {
1533         // Do some zipping and shuffling.
1534         DoubleVector io = (DoubleVector) SPECIES.broadcast(0).addIndex(1);
1535         DoubleVector io2 = (DoubleVector) VectorShuffle.iota(SPECIES,0,1,false).toVector();
1536         Assert.assertEquals(io, io2);
1537         DoubleVector a = io.add((double)1); //[1,2]
1538         DoubleVector b = a.neg();  //[-1,-2]
1539         double[] abValues = bothToArray(a,b); //[1,2,-1,-2]
1540         VectorShuffle<Double> zip0 = VectorShuffle.makeZip(SPECIES, 0);
1541         VectorShuffle<Double> zip1 = VectorShuffle.makeZip(SPECIES, 1);
1542         DoubleVector zab0 = a.rearrange(zip0,b); //[1,-1]
1543         DoubleVector zab1 = a.rearrange(zip1,b); //[2,-2]
1544         double[] zabValues = bothToArray(zab0, zab1); //[1,-1,2,-2]
1545         // manually zip
1546         double[] manual = new double[zabValues.length];
1547         for (int i = 0; i < manual.length; i += 2) {
1548             manual[i+0] = abValues[i/2];
1549             manual[i+1] = abValues[a.length() + i/2];
1550         }
1551         Assert.assertEquals(Arrays.toString(zabValues), Arrays.toString(manual));
1552         VectorShuffle<Double> unz0 = VectorShuffle.makeUnzip(SPECIES, 0);
1553         VectorShuffle<Double> unz1 = VectorShuffle.makeUnzip(SPECIES, 1);
1554         DoubleVector uab0 = zab0.rearrange(unz0,zab1);
1555         DoubleVector uab1 = zab0.rearrange(unz1,zab1);
1556         double[] abValues1 = bothToArray(uab0, uab1);
1557         Assert.assertEquals(Arrays.toString(abValues), Arrays.toString(abValues1));
1558     }
1559 
1560     static void iotaShuffle() {
1561         DoubleVector io = (DoubleVector) SPECIES.broadcast(0).addIndex(1);
1562         DoubleVector io2 = (DoubleVector) VectorShuffle.iota(SPECIES, 0 , 1, false).toVector();
1563         Assert.assertEquals(io, io2);
1564     }
1565 
1566     @Test
1567     // Test all shuffle related operations.
1568     static void shuffleTest() {
1569         // To test backend instructions, make sure that C2 is used.
1570         for (int loop = 0; loop < INVOC_COUNT * INVOC_COUNT; loop++) {
1571             iotaShuffle();
1572         }
1573     }
1574 
1575     @Test
1576     void viewAsIntegeralLanesTest() {
1577         Vector<?> asIntegral = SPECIES.zero().viewAsIntegralLanes();
1578         VectorSpecies<?> asIntegralSpecies = asIntegral.species();
1579         Assert.assertNotEquals(asIntegralSpecies.elementType(), SPECIES.elementType());
1580         Assert.assertEquals(asIntegralSpecies.vectorShape(), SPECIES.vectorShape());
1581         Assert.assertEquals(asIntegralSpecies.length(), SPECIES.length());
1582         Assert.assertEquals(asIntegral.viewAsFloatingLanes().species(), SPECIES);
1583     }
1584 
1585     @Test
1586     void viewAsFloatingLanesTest() {
1587         Vector<?> asFloating = SPECIES.zero().viewAsFloatingLanes();
1588         Assert.assertEquals(asFloating.species(), SPECIES);
1589     }
1590 
1591     static double ADD(double a, double b) {
1592         return (double)(a + b);
1593     }
1594 
1595     @Test(dataProvider = "doubleBinaryOpProvider")
1596     static void ADDDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1597         double[] a = fa.apply(SPECIES.length());
1598         double[] b = fb.apply(SPECIES.length());
1599         double[] r = fr.apply(SPECIES.length());
1600 
1601         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1602             for (int i = 0; i < a.length; i += SPECIES.length()) {
1603                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1604                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1605                 av.lanewise(VectorOperators.ADD, bv).intoArray(r, i);
1606             }
1607         }
1608 
1609         assertArraysEquals(r, a, b, Double64VectorTests::ADD);
1610     }
1611 
1612     static double add(double a, double b) {
1613         return (double)(a + b);
1614     }
1615 
1616     @Test(dataProvider = "doubleBinaryOpProvider")
1617     static void addDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1618         double[] a = fa.apply(SPECIES.length());
1619         double[] b = fb.apply(SPECIES.length());
1620         double[] r = fr.apply(SPECIES.length());
1621 
1622         for (int i = 0; i < a.length; i += SPECIES.length()) {
1623             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1624             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1625             av.add(bv).intoArray(r, i);
1626         }
1627 
1628         assertArraysEquals(r, a, b, Double64VectorTests::add);
1629     }
1630 
1631     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1632     static void ADDDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1633                                           IntFunction<boolean[]> fm) {
1634         double[] a = fa.apply(SPECIES.length());
1635         double[] b = fb.apply(SPECIES.length());
1636         double[] r = fr.apply(SPECIES.length());
1637         boolean[] mask = fm.apply(SPECIES.length());
1638         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1639 
1640         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1641             for (int i = 0; i < a.length; i += SPECIES.length()) {
1642                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1643                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1644                 av.lanewise(VectorOperators.ADD, bv, vmask).intoArray(r, i);
1645             }
1646         }
1647 
1648         assertArraysEquals(r, a, b, mask, Double64VectorTests::ADD);
1649     }
1650 
1651     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1652     static void addDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1653                                           IntFunction<boolean[]> fm) {
1654         double[] a = fa.apply(SPECIES.length());
1655         double[] b = fb.apply(SPECIES.length());
1656         double[] r = fr.apply(SPECIES.length());
1657         boolean[] mask = fm.apply(SPECIES.length());
1658         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1659 
1660         for (int i = 0; i < a.length; i += SPECIES.length()) {
1661             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1662             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1663             av.add(bv, vmask).intoArray(r, i);
1664         }
1665 
1666         assertArraysEquals(r, a, b, mask, Double64VectorTests::add);
1667     }
1668 
1669     static double SUB(double a, double b) {
1670         return (double)(a - b);
1671     }
1672 
1673     @Test(dataProvider = "doubleBinaryOpProvider")
1674     static void SUBDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1675         double[] a = fa.apply(SPECIES.length());
1676         double[] b = fb.apply(SPECIES.length());
1677         double[] r = fr.apply(SPECIES.length());
1678 
1679         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1680             for (int i = 0; i < a.length; i += SPECIES.length()) {
1681                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1682                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1683                 av.lanewise(VectorOperators.SUB, bv).intoArray(r, i);
1684             }
1685         }
1686 
1687         assertArraysEquals(r, a, b, Double64VectorTests::SUB);
1688     }
1689 
1690     static double sub(double a, double b) {
1691         return (double)(a - b);
1692     }
1693 
1694     @Test(dataProvider = "doubleBinaryOpProvider")
1695     static void subDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1696         double[] a = fa.apply(SPECIES.length());
1697         double[] b = fb.apply(SPECIES.length());
1698         double[] r = fr.apply(SPECIES.length());
1699 
1700         for (int i = 0; i < a.length; i += SPECIES.length()) {
1701             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1702             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1703             av.sub(bv).intoArray(r, i);
1704         }
1705 
1706         assertArraysEquals(r, a, b, Double64VectorTests::sub);
1707     }
1708 
1709     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1710     static void SUBDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1711                                           IntFunction<boolean[]> fm) {
1712         double[] a = fa.apply(SPECIES.length());
1713         double[] b = fb.apply(SPECIES.length());
1714         double[] r = fr.apply(SPECIES.length());
1715         boolean[] mask = fm.apply(SPECIES.length());
1716         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1717 
1718         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1719             for (int i = 0; i < a.length; i += SPECIES.length()) {
1720                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1721                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1722                 av.lanewise(VectorOperators.SUB, bv, vmask).intoArray(r, i);
1723             }
1724         }
1725 
1726         assertArraysEquals(r, a, b, mask, Double64VectorTests::SUB);
1727     }
1728 
1729     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1730     static void subDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1731                                           IntFunction<boolean[]> fm) {
1732         double[] a = fa.apply(SPECIES.length());
1733         double[] b = fb.apply(SPECIES.length());
1734         double[] r = fr.apply(SPECIES.length());
1735         boolean[] mask = fm.apply(SPECIES.length());
1736         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1737 
1738         for (int i = 0; i < a.length; i += SPECIES.length()) {
1739             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1740             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1741             av.sub(bv, vmask).intoArray(r, i);
1742         }
1743 
1744         assertArraysEquals(r, a, b, mask, Double64VectorTests::sub);
1745     }
1746 
1747     static double MUL(double a, double b) {
1748         return (double)(a * b);
1749     }
1750 
1751     @Test(dataProvider = "doubleBinaryOpProvider")
1752     static void MULDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1753         double[] a = fa.apply(SPECIES.length());
1754         double[] b = fb.apply(SPECIES.length());
1755         double[] r = fr.apply(SPECIES.length());
1756 
1757         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1758             for (int i = 0; i < a.length; i += SPECIES.length()) {
1759                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1760                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1761                 av.lanewise(VectorOperators.MUL, bv).intoArray(r, i);
1762             }
1763         }
1764 
1765         assertArraysEquals(r, a, b, Double64VectorTests::MUL);
1766     }
1767 
1768     static double mul(double a, double b) {
1769         return (double)(a * b);
1770     }
1771 
1772     @Test(dataProvider = "doubleBinaryOpProvider")
1773     static void mulDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1774         double[] a = fa.apply(SPECIES.length());
1775         double[] b = fb.apply(SPECIES.length());
1776         double[] r = fr.apply(SPECIES.length());
1777 
1778         for (int i = 0; i < a.length; i += SPECIES.length()) {
1779             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1780             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1781             av.mul(bv).intoArray(r, i);
1782         }
1783 
1784         assertArraysEquals(r, a, b, Double64VectorTests::mul);
1785     }
1786 
1787     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1788     static void MULDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1789                                           IntFunction<boolean[]> fm) {
1790         double[] a = fa.apply(SPECIES.length());
1791         double[] b = fb.apply(SPECIES.length());
1792         double[] r = fr.apply(SPECIES.length());
1793         boolean[] mask = fm.apply(SPECIES.length());
1794         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1795 
1796         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1797             for (int i = 0; i < a.length; i += SPECIES.length()) {
1798                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1799                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1800                 av.lanewise(VectorOperators.MUL, bv, vmask).intoArray(r, i);
1801             }
1802         }
1803 
1804         assertArraysEquals(r, a, b, mask, Double64VectorTests::MUL);
1805     }
1806 
1807     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1808     static void mulDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1809                                           IntFunction<boolean[]> fm) {
1810         double[] a = fa.apply(SPECIES.length());
1811         double[] b = fb.apply(SPECIES.length());
1812         double[] r = fr.apply(SPECIES.length());
1813         boolean[] mask = fm.apply(SPECIES.length());
1814         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1815 
1816         for (int i = 0; i < a.length; i += SPECIES.length()) {
1817             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1818             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1819             av.mul(bv, vmask).intoArray(r, i);
1820         }
1821 
1822         assertArraysEquals(r, a, b, mask, Double64VectorTests::mul);
1823     }
1824 
1825     static double DIV(double a, double b) {
1826         return (double)(a / b);
1827     }
1828 
1829     @Test(dataProvider = "doubleBinaryOpProvider")
1830     static void DIVDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1831         double[] a = fa.apply(SPECIES.length());
1832         double[] b = fb.apply(SPECIES.length());
1833         double[] r = fr.apply(SPECIES.length());
1834 
1835         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1836             for (int i = 0; i < a.length; i += SPECIES.length()) {
1837                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1838                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1839                 av.lanewise(VectorOperators.DIV, bv).intoArray(r, i);
1840             }
1841         }
1842 
1843         assertArraysEquals(r, a, b, Double64VectorTests::DIV);
1844     }
1845 
1846     static double div(double a, double b) {
1847         return (double)(a / b);
1848     }
1849 
1850     @Test(dataProvider = "doubleBinaryOpProvider")
1851     static void divDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1852         double[] a = fa.apply(SPECIES.length());
1853         double[] b = fb.apply(SPECIES.length());
1854         double[] r = fr.apply(SPECIES.length());
1855 
1856         for (int i = 0; i < a.length; i += SPECIES.length()) {
1857             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1858             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1859             av.div(bv).intoArray(r, i);
1860         }
1861 
1862         assertArraysEquals(r, a, b, Double64VectorTests::div);
1863     }
1864 
1865     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1866     static void DIVDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1867                                           IntFunction<boolean[]> fm) {
1868         double[] a = fa.apply(SPECIES.length());
1869         double[] b = fb.apply(SPECIES.length());
1870         double[] r = fr.apply(SPECIES.length());
1871         boolean[] mask = fm.apply(SPECIES.length());
1872         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1873 
1874         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1875             for (int i = 0; i < a.length; i += SPECIES.length()) {
1876                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1877                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1878                 av.lanewise(VectorOperators.DIV, bv, vmask).intoArray(r, i);
1879             }
1880         }
1881 
1882         assertArraysEquals(r, a, b, mask, Double64VectorTests::DIV);
1883     }
1884 
1885     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1886     static void divDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1887                                           IntFunction<boolean[]> fm) {
1888         double[] a = fa.apply(SPECIES.length());
1889         double[] b = fb.apply(SPECIES.length());
1890         double[] r = fr.apply(SPECIES.length());
1891         boolean[] mask = fm.apply(SPECIES.length());
1892         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1893 
1894         for (int i = 0; i < a.length; i += SPECIES.length()) {
1895             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1896             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1897             av.div(bv, vmask).intoArray(r, i);
1898         }
1899 
1900         assertArraysEquals(r, a, b, mask, Double64VectorTests::div);
1901     }
1902 
1903     static double FIRST_NONZERO(double a, double b) {
1904         return (double)(Double.doubleToLongBits(a)!=0?a:b);
1905     }
1906 
1907     @Test(dataProvider = "doubleBinaryOpProvider")
1908     static void FIRST_NONZERODouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1909         double[] a = fa.apply(SPECIES.length());
1910         double[] b = fb.apply(SPECIES.length());
1911         double[] r = fr.apply(SPECIES.length());
1912 
1913         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1914             for (int i = 0; i < a.length; i += SPECIES.length()) {
1915                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1916                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1917                 av.lanewise(VectorOperators.FIRST_NONZERO, bv).intoArray(r, i);
1918             }
1919         }
1920 
1921         assertArraysEquals(r, a, b, Double64VectorTests::FIRST_NONZERO);
1922     }
1923 
1924     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1925     static void FIRST_NONZERODouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
1926                                           IntFunction<boolean[]> fm) {
1927         double[] a = fa.apply(SPECIES.length());
1928         double[] b = fb.apply(SPECIES.length());
1929         double[] r = fr.apply(SPECIES.length());
1930         boolean[] mask = fm.apply(SPECIES.length());
1931         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1932 
1933         for (int ic = 0; ic < INVOC_COUNT; ic++) {
1934             for (int i = 0; i < a.length; i += SPECIES.length()) {
1935                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1936                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
1937                 av.lanewise(VectorOperators.FIRST_NONZERO, bv, vmask).intoArray(r, i);
1938             }
1939         }
1940 
1941         assertArraysEquals(r, a, b, mask, Double64VectorTests::FIRST_NONZERO);
1942     }
1943 
1944     @Test(dataProvider = "doubleBinaryOpProvider")
1945     static void addDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1946         double[] a = fa.apply(SPECIES.length());
1947         double[] b = fb.apply(SPECIES.length());
1948         double[] r = fr.apply(SPECIES.length());
1949 
1950         for (int i = 0; i < a.length; i += SPECIES.length()) {
1951             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1952             av.add(b[i]).intoArray(r, i);
1953         }
1954 
1955         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::add);
1956     }
1957 
1958     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1959     static void addDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
1960                                           IntFunction<boolean[]> fm) {
1961         double[] a = fa.apply(SPECIES.length());
1962         double[] b = fb.apply(SPECIES.length());
1963         double[] r = fr.apply(SPECIES.length());
1964         boolean[] mask = fm.apply(SPECIES.length());
1965         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1966 
1967         for (int i = 0; i < a.length; i += SPECIES.length()) {
1968             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1969             av.add(b[i], vmask).intoArray(r, i);
1970         }
1971 
1972         assertBroadcastArraysEquals(r, a, b, mask, Double64VectorTests::add);
1973     }
1974 
1975     @Test(dataProvider = "doubleBinaryOpProvider")
1976     static void subDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
1977         double[] a = fa.apply(SPECIES.length());
1978         double[] b = fb.apply(SPECIES.length());
1979         double[] r = fr.apply(SPECIES.length());
1980 
1981         for (int i = 0; i < a.length; i += SPECIES.length()) {
1982             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
1983             av.sub(b[i]).intoArray(r, i);
1984         }
1985 
1986         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::sub);
1987     }
1988 
1989     @Test(dataProvider = "doubleBinaryOpMaskProvider")
1990     static void subDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
1991                                           IntFunction<boolean[]> fm) {
1992         double[] a = fa.apply(SPECIES.length());
1993         double[] b = fb.apply(SPECIES.length());
1994         double[] r = fr.apply(SPECIES.length());
1995         boolean[] mask = fm.apply(SPECIES.length());
1996         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
1997 
1998         for (int i = 0; i < a.length; i += SPECIES.length()) {
1999             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2000             av.sub(b[i], vmask).intoArray(r, i);
2001         }
2002 
2003         assertBroadcastArraysEquals(r, a, b, mask, Double64VectorTests::sub);
2004     }
2005 
2006     @Test(dataProvider = "doubleBinaryOpProvider")
2007     static void mulDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2008         double[] a = fa.apply(SPECIES.length());
2009         double[] b = fb.apply(SPECIES.length());
2010         double[] r = fr.apply(SPECIES.length());
2011 
2012         for (int i = 0; i < a.length; i += SPECIES.length()) {
2013             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2014             av.mul(b[i]).intoArray(r, i);
2015         }
2016 
2017         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::mul);
2018     }
2019 
2020     @Test(dataProvider = "doubleBinaryOpMaskProvider")
2021     static void mulDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
2022                                           IntFunction<boolean[]> fm) {
2023         double[] a = fa.apply(SPECIES.length());
2024         double[] b = fb.apply(SPECIES.length());
2025         double[] r = fr.apply(SPECIES.length());
2026         boolean[] mask = fm.apply(SPECIES.length());
2027         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2028 
2029         for (int i = 0; i < a.length; i += SPECIES.length()) {
2030             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2031             av.mul(b[i], vmask).intoArray(r, i);
2032         }
2033 
2034         assertBroadcastArraysEquals(r, a, b, mask, Double64VectorTests::mul);
2035     }
2036 
2037     @Test(dataProvider = "doubleBinaryOpProvider")
2038     static void divDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2039         double[] a = fa.apply(SPECIES.length());
2040         double[] b = fb.apply(SPECIES.length());
2041         double[] r = fr.apply(SPECIES.length());
2042 
2043         for (int i = 0; i < a.length; i += SPECIES.length()) {
2044             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2045             av.div(b[i]).intoArray(r, i);
2046         }
2047 
2048         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::div);
2049     }
2050 
2051     @Test(dataProvider = "doubleBinaryOpMaskProvider")
2052     static void divDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
2053                                           IntFunction<boolean[]> fm) {
2054         double[] a = fa.apply(SPECIES.length());
2055         double[] b = fb.apply(SPECIES.length());
2056         double[] r = fr.apply(SPECIES.length());
2057         boolean[] mask = fm.apply(SPECIES.length());
2058         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2059 
2060         for (int i = 0; i < a.length; i += SPECIES.length()) {
2061             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2062             av.div(b[i], vmask).intoArray(r, i);
2063         }
2064 
2065         assertBroadcastArraysEquals(r, a, b, mask, Double64VectorTests::div);
2066     }
2067 
2068     @Test(dataProvider = "doubleBinaryOpProvider")
2069     static void ADDDouble64VectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2070         double[] a = fa.apply(SPECIES.length());
2071         double[] b = fb.apply(SPECIES.length());
2072         double[] r = fr.apply(SPECIES.length());
2073 
2074         for (int i = 0; i < a.length; i += SPECIES.length()) {
2075             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2076             av.lanewise(VectorOperators.ADD, (long)b[i]).intoArray(r, i);
2077         }
2078 
2079         assertBroadcastLongArraysEquals(r, a, b, Double64VectorTests::ADD);
2080     }
2081 
2082     @Test(dataProvider = "doubleBinaryOpMaskProvider")
2083     static void ADDDouble64VectorTestsBroadcastMaskedLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
2084                                           IntFunction<boolean[]> fm) {
2085         double[] a = fa.apply(SPECIES.length());
2086         double[] b = fb.apply(SPECIES.length());
2087         double[] r = fr.apply(SPECIES.length());
2088         boolean[] mask = fm.apply(SPECIES.length());
2089         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2090 
2091         for (int i = 0; i < a.length; i += SPECIES.length()) {
2092             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2093             av.lanewise(VectorOperators.ADD, (long)b[i], vmask).intoArray(r, i);
2094         }
2095 
2096         assertBroadcastLongArraysEquals(r, a, b, mask, Double64VectorTests::ADD);
2097     }
2098 
2099     static DoubleVector bv_MIN = DoubleVector.broadcast(SPECIES, (double)10);
2100 
2101     @Test(dataProvider = "doubleUnaryOpProvider")
2102     static void MINDouble64VectorTestsWithMemOp(IntFunction<double[]> fa) {
2103         double[] a = fa.apply(SPECIES.length());
2104         double[] r = fr.apply(SPECIES.length());
2105 
2106         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2107             for (int i = 0; i < a.length; i += SPECIES.length()) {
2108                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2109                 av.lanewise(VectorOperators.MIN, bv_MIN).intoArray(r, i);
2110             }
2111         }
2112 
2113         assertArraysEquals(r, a, (double)10, Double64VectorTests::MIN);
2114     }
2115 
2116     static DoubleVector bv_min = DoubleVector.broadcast(SPECIES, (double)10);
2117 
2118     @Test(dataProvider = "doubleUnaryOpProvider")
2119     static void minDouble64VectorTestsWithMemOp(IntFunction<double[]> fa) {
2120         double[] a = fa.apply(SPECIES.length());
2121         double[] r = fr.apply(SPECIES.length());
2122 
2123         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2124             for (int i = 0; i < a.length; i += SPECIES.length()) {
2125                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2126                 av.min(bv_min).intoArray(r, i);
2127             }
2128         }
2129 
2130         assertArraysEquals(r, a, (double)10, Double64VectorTests::min);
2131     }
2132 
2133     static DoubleVector bv_MIN_M = DoubleVector.broadcast(SPECIES, (double)10);
2134 
2135     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2136     static void MINDouble64VectorTestsMaskedWithMemOp(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2137         double[] a = fa.apply(SPECIES.length());
2138         double[] r = fr.apply(SPECIES.length());
2139         boolean[] mask = fm.apply(SPECIES.length());
2140         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2141 
2142         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2143             for (int i = 0; i < a.length; i += SPECIES.length()) {
2144                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2145                 av.lanewise(VectorOperators.MIN, bv_MIN_M, vmask).intoArray(r, i);
2146             }
2147         }
2148 
2149         assertArraysEquals(r, a, (double)10, mask, Double64VectorTests::MIN);
2150     }
2151 
2152     static DoubleVector bv_MAX = DoubleVector.broadcast(SPECIES, (double)10);
2153 
2154     @Test(dataProvider = "doubleUnaryOpProvider")
2155     static void MAXDouble64VectorTestsWithMemOp(IntFunction<double[]> fa) {
2156         double[] a = fa.apply(SPECIES.length());
2157         double[] r = fr.apply(SPECIES.length());
2158 
2159         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2160             for (int i = 0; i < a.length; i += SPECIES.length()) {
2161                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2162                 av.lanewise(VectorOperators.MAX, bv_MAX).intoArray(r, i);
2163             }
2164         }
2165 
2166         assertArraysEquals(r, a, (double)10, Double64VectorTests::MAX);
2167     }
2168 
2169     static DoubleVector bv_max = DoubleVector.broadcast(SPECIES, (double)10);
2170 
2171     @Test(dataProvider = "doubleUnaryOpProvider")
2172     static void maxDouble64VectorTestsWithMemOp(IntFunction<double[]> fa) {
2173         double[] a = fa.apply(SPECIES.length());
2174         double[] r = fr.apply(SPECIES.length());
2175 
2176         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2177             for (int i = 0; i < a.length; i += SPECIES.length()) {
2178                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2179                 av.max(bv_max).intoArray(r, i);
2180             }
2181         }
2182 
2183         assertArraysEquals(r, a, (double)10, Double64VectorTests::max);
2184     }
2185 
2186     static DoubleVector bv_MAX_M = DoubleVector.broadcast(SPECIES, (double)10);
2187 
2188     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2189     static void MAXDouble64VectorTestsMaskedWithMemOp(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2190         double[] a = fa.apply(SPECIES.length());
2191         double[] r = fr.apply(SPECIES.length());
2192         boolean[] mask = fm.apply(SPECIES.length());
2193         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2194 
2195         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2196             for (int i = 0; i < a.length; i += SPECIES.length()) {
2197                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2198                 av.lanewise(VectorOperators.MAX, bv_MAX_M, vmask).intoArray(r, i);
2199             }
2200         }
2201 
2202         assertArraysEquals(r, a, (double)10, mask, Double64VectorTests::MAX);
2203     }
2204 
2205     static double MIN(double a, double b) {
2206         return (double)(Math.min(a, b));
2207     }
2208 
2209     @Test(dataProvider = "doubleBinaryOpProvider")
2210     static void MINDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2211         double[] a = fa.apply(SPECIES.length());
2212         double[] b = fb.apply(SPECIES.length());
2213         double[] r = fr.apply(SPECIES.length());
2214 
2215         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2216             for (int i = 0; i < a.length; i += SPECIES.length()) {
2217                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2218                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2219                 av.lanewise(VectorOperators.MIN, bv).intoArray(r, i);
2220             }
2221         }
2222 
2223         assertArraysEquals(r, a, b, Double64VectorTests::MIN);
2224     }
2225 
2226     static double min(double a, double b) {
2227         return (double)(Math.min(a, b));
2228     }
2229 
2230     @Test(dataProvider = "doubleBinaryOpProvider")
2231     static void minDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2232         double[] a = fa.apply(SPECIES.length());
2233         double[] b = fb.apply(SPECIES.length());
2234         double[] r = fr.apply(SPECIES.length());
2235 
2236         for (int i = 0; i < a.length; i += SPECIES.length()) {
2237             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2238             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2239             av.min(bv).intoArray(r, i);
2240         }
2241 
2242         assertArraysEquals(r, a, b, Double64VectorTests::min);
2243     }
2244 
2245     static double MAX(double a, double b) {
2246         return (double)(Math.max(a, b));
2247     }
2248 
2249     @Test(dataProvider = "doubleBinaryOpProvider")
2250     static void MAXDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2251         double[] a = fa.apply(SPECIES.length());
2252         double[] b = fb.apply(SPECIES.length());
2253         double[] r = fr.apply(SPECIES.length());
2254 
2255         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2256             for (int i = 0; i < a.length; i += SPECIES.length()) {
2257                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2258                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2259                 av.lanewise(VectorOperators.MAX, bv).intoArray(r, i);
2260             }
2261         }
2262 
2263         assertArraysEquals(r, a, b, Double64VectorTests::MAX);
2264     }
2265 
2266     static double max(double a, double b) {
2267         return (double)(Math.max(a, b));
2268     }
2269 
2270     @Test(dataProvider = "doubleBinaryOpProvider")
2271     static void maxDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2272         double[] a = fa.apply(SPECIES.length());
2273         double[] b = fb.apply(SPECIES.length());
2274         double[] r = fr.apply(SPECIES.length());
2275 
2276         for (int i = 0; i < a.length; i += SPECIES.length()) {
2277             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2278             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
2279             av.max(bv).intoArray(r, i);
2280         }
2281 
2282         assertArraysEquals(r, a, b, Double64VectorTests::max);
2283     }
2284 
2285     @Test(dataProvider = "doubleBinaryOpProvider")
2286     static void MINDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2287         double[] a = fa.apply(SPECIES.length());
2288         double[] b = fb.apply(SPECIES.length());
2289         double[] r = fr.apply(SPECIES.length());
2290 
2291         for (int i = 0; i < a.length; i += SPECIES.length()) {
2292             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2293             av.lanewise(VectorOperators.MIN, b[i]).intoArray(r, i);
2294         }
2295 
2296         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::MIN);
2297     }
2298 
2299     @Test(dataProvider = "doubleBinaryOpProvider")
2300     static void minDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2301         double[] a = fa.apply(SPECIES.length());
2302         double[] b = fb.apply(SPECIES.length());
2303         double[] r = fr.apply(SPECIES.length());
2304 
2305         for (int i = 0; i < a.length; i += SPECIES.length()) {
2306             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2307             av.min(b[i]).intoArray(r, i);
2308         }
2309 
2310         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::min);
2311     }
2312 
2313     @Test(dataProvider = "doubleBinaryOpProvider")
2314     static void MAXDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2315         double[] a = fa.apply(SPECIES.length());
2316         double[] b = fb.apply(SPECIES.length());
2317         double[] r = fr.apply(SPECIES.length());
2318 
2319         for (int i = 0; i < a.length; i += SPECIES.length()) {
2320             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2321             av.lanewise(VectorOperators.MAX, b[i]).intoArray(r, i);
2322         }
2323 
2324         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::MAX);
2325     }
2326 
2327     @Test(dataProvider = "doubleBinaryOpProvider")
2328     static void maxDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
2329         double[] a = fa.apply(SPECIES.length());
2330         double[] b = fb.apply(SPECIES.length());
2331         double[] r = fr.apply(SPECIES.length());
2332 
2333         for (int i = 0; i < a.length; i += SPECIES.length()) {
2334             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2335             av.max(b[i]).intoArray(r, i);
2336         }
2337 
2338         assertBroadcastArraysEquals(r, a, b, Double64VectorTests::max);
2339     }
2340 
2341     static double ADDReduce(double[] a, int idx) {
2342         double res = 0;
2343         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2344             res += a[i];
2345         }
2346 
2347         return res;
2348     }
2349 
2350     static double ADDReduceAll(double[] a) {
2351         double res = 0;
2352         for (int i = 0; i < a.length; i += SPECIES.length()) {
2353             res += ADDReduce(a, i);
2354         }
2355 
2356         return res;
2357     }
2358 
2359     @Test(dataProvider = "doubleUnaryOpProvider")
2360     static void ADDReduceDouble64VectorTests(IntFunction<double[]> fa) {
2361         double[] a = fa.apply(SPECIES.length());
2362         double[] r = fr.apply(SPECIES.length());
2363         double ra = 0;
2364 
2365         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2366             for (int i = 0; i < a.length; i += SPECIES.length()) {
2367                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2368                 r[i] = av.reduceLanes(VectorOperators.ADD);
2369             }
2370         }
2371 
2372         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2373             ra = 0;
2374             for (int i = 0; i < a.length; i += SPECIES.length()) {
2375                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2376                 ra += av.reduceLanes(VectorOperators.ADD);
2377             }
2378         }
2379 
2380         assertReductionArraysEquals(r, ra, a,
2381                 Double64VectorTests::ADDReduce, Double64VectorTests::ADDReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
2382     }
2383 
2384     static double ADDReduceMasked(double[] a, int idx, boolean[] mask) {
2385         double res = 0;
2386         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2387             if (mask[i % SPECIES.length()])
2388                 res += a[i];
2389         }
2390 
2391         return res;
2392     }
2393 
2394     static double ADDReduceAllMasked(double[] a, boolean[] mask) {
2395         double res = 0;
2396         for (int i = 0; i < a.length; i += SPECIES.length()) {
2397             res += ADDReduceMasked(a, i, mask);
2398         }
2399 
2400         return res;
2401     }
2402 
2403     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2404     static void ADDReduceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2405         double[] a = fa.apply(SPECIES.length());
2406         double[] r = fr.apply(SPECIES.length());
2407         boolean[] mask = fm.apply(SPECIES.length());
2408         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2409         double ra = 0;
2410 
2411         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2412             for (int i = 0; i < a.length; i += SPECIES.length()) {
2413                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2414                 r[i] = av.reduceLanes(VectorOperators.ADD, vmask);
2415             }
2416         }
2417 
2418         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2419             ra = 0;
2420             for (int i = 0; i < a.length; i += SPECIES.length()) {
2421                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2422                 ra += av.reduceLanes(VectorOperators.ADD, vmask);
2423             }
2424         }
2425 
2426         assertReductionArraysEqualsMasked(r, ra, a, mask,
2427                 Double64VectorTests::ADDReduceMasked, Double64VectorTests::ADDReduceAllMasked, RELATIVE_ROUNDING_ERROR_FACTOR_ADD);
2428     }
2429 
2430     static double MULReduce(double[] a, int idx) {
2431         double res = 1;
2432         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2433             res *= a[i];
2434         }
2435 
2436         return res;
2437     }
2438 
2439     static double MULReduceAll(double[] a) {
2440         double res = 1;
2441         for (int i = 0; i < a.length; i += SPECIES.length()) {
2442             res *= MULReduce(a, i);
2443         }
2444 
2445         return res;
2446     }
2447 
2448     @Test(dataProvider = "doubleUnaryOpProvider")
2449     static void MULReduceDouble64VectorTests(IntFunction<double[]> fa) {
2450         double[] a = fa.apply(SPECIES.length());
2451         double[] r = fr.apply(SPECIES.length());
2452         double ra = 1;
2453 
2454         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2455             for (int i = 0; i < a.length; i += SPECIES.length()) {
2456                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2457                 r[i] = av.reduceLanes(VectorOperators.MUL);
2458             }
2459         }
2460 
2461         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2462             ra = 1;
2463             for (int i = 0; i < a.length; i += SPECIES.length()) {
2464                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2465                 ra *= av.reduceLanes(VectorOperators.MUL);
2466             }
2467         }
2468 
2469         assertReductionArraysEquals(r, ra, a,
2470                 Double64VectorTests::MULReduce, Double64VectorTests::MULReduceAll, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
2471     }
2472 
2473     static double MULReduceMasked(double[] a, int idx, boolean[] mask) {
2474         double res = 1;
2475         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2476             if (mask[i % SPECIES.length()])
2477                 res *= a[i];
2478         }
2479 
2480         return res;
2481     }
2482 
2483     static double MULReduceAllMasked(double[] a, boolean[] mask) {
2484         double res = 1;
2485         for (int i = 0; i < a.length; i += SPECIES.length()) {
2486             res *= MULReduceMasked(a, i, mask);
2487         }
2488 
2489         return res;
2490     }
2491 
2492     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2493     static void MULReduceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2494         double[] a = fa.apply(SPECIES.length());
2495         double[] r = fr.apply(SPECIES.length());
2496         boolean[] mask = fm.apply(SPECIES.length());
2497         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2498         double ra = 1;
2499 
2500         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2501             for (int i = 0; i < a.length; i += SPECIES.length()) {
2502                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2503                 r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
2504             }
2505         }
2506 
2507         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2508             ra = 1;
2509             for (int i = 0; i < a.length; i += SPECIES.length()) {
2510                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2511                 ra *= av.reduceLanes(VectorOperators.MUL, vmask);
2512             }
2513         }
2514 
2515         assertReductionArraysEqualsMasked(r, ra, a, mask,
2516                 Double64VectorTests::MULReduceMasked, Double64VectorTests::MULReduceAllMasked, RELATIVE_ROUNDING_ERROR_FACTOR_MUL);
2517     }
2518 
2519     static double MINReduce(double[] a, int idx) {
2520         double res = Double.POSITIVE_INFINITY;
2521         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2522             res = (double) Math.min(res, a[i]);
2523         }
2524 
2525         return res;
2526     }
2527 
2528     static double MINReduceAll(double[] a) {
2529         double res = Double.POSITIVE_INFINITY;
2530         for (int i = 0; i < a.length; i += SPECIES.length()) {
2531             res = (double) Math.min(res, MINReduce(a, i));
2532         }
2533 
2534         return res;
2535     }
2536 
2537     @Test(dataProvider = "doubleUnaryOpProvider")
2538     static void MINReduceDouble64VectorTests(IntFunction<double[]> fa) {
2539         double[] a = fa.apply(SPECIES.length());
2540         double[] r = fr.apply(SPECIES.length());
2541         double ra = Double.POSITIVE_INFINITY;
2542 
2543         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2544             for (int i = 0; i < a.length; i += SPECIES.length()) {
2545                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2546                 r[i] = av.reduceLanes(VectorOperators.MIN);
2547             }
2548         }
2549 
2550         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2551             ra = Double.POSITIVE_INFINITY;
2552             for (int i = 0; i < a.length; i += SPECIES.length()) {
2553                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2554                 ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN));
2555             }
2556         }
2557 
2558         assertReductionArraysEquals(r, ra, a,
2559                 Double64VectorTests::MINReduce, Double64VectorTests::MINReduceAll);
2560     }
2561 
2562     static double MINReduceMasked(double[] a, int idx, boolean[] mask) {
2563         double res = Double.POSITIVE_INFINITY;
2564         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2565             if (mask[i % SPECIES.length()])
2566                 res = (double) Math.min(res, a[i]);
2567         }
2568 
2569         return res;
2570     }
2571 
2572     static double MINReduceAllMasked(double[] a, boolean[] mask) {
2573         double res = Double.POSITIVE_INFINITY;
2574         for (int i = 0; i < a.length; i += SPECIES.length()) {
2575             res = (double) Math.min(res, MINReduceMasked(a, i, mask));
2576         }
2577 
2578         return res;
2579     }
2580 
2581     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2582     static void MINReduceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2583         double[] a = fa.apply(SPECIES.length());
2584         double[] r = fr.apply(SPECIES.length());
2585         boolean[] mask = fm.apply(SPECIES.length());
2586         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2587         double ra = Double.POSITIVE_INFINITY;
2588 
2589         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2590             for (int i = 0; i < a.length; i += SPECIES.length()) {
2591                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2592                 r[i] = av.reduceLanes(VectorOperators.MIN, vmask);
2593             }
2594         }
2595 
2596         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2597             ra = Double.POSITIVE_INFINITY;
2598             for (int i = 0; i < a.length; i += SPECIES.length()) {
2599                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2600                 ra = (double) Math.min(ra, av.reduceLanes(VectorOperators.MIN, vmask));
2601             }
2602         }
2603 
2604         assertReductionArraysEqualsMasked(r, ra, a, mask,
2605                 Double64VectorTests::MINReduceMasked, Double64VectorTests::MINReduceAllMasked);
2606     }
2607 
2608     static double MAXReduce(double[] a, int idx) {
2609         double res = Double.NEGATIVE_INFINITY;
2610         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2611             res = (double) Math.max(res, a[i]);
2612         }
2613 
2614         return res;
2615     }
2616 
2617     static double MAXReduceAll(double[] a) {
2618         double res = Double.NEGATIVE_INFINITY;
2619         for (int i = 0; i < a.length; i += SPECIES.length()) {
2620             res = (double) Math.max(res, MAXReduce(a, i));
2621         }
2622 
2623         return res;
2624     }
2625 
2626     @Test(dataProvider = "doubleUnaryOpProvider")
2627     static void MAXReduceDouble64VectorTests(IntFunction<double[]> fa) {
2628         double[] a = fa.apply(SPECIES.length());
2629         double[] r = fr.apply(SPECIES.length());
2630         double ra = Double.NEGATIVE_INFINITY;
2631 
2632         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2633             for (int i = 0; i < a.length; i += SPECIES.length()) {
2634                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2635                 r[i] = av.reduceLanes(VectorOperators.MAX);
2636             }
2637         }
2638 
2639         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2640             ra = Double.NEGATIVE_INFINITY;
2641             for (int i = 0; i < a.length; i += SPECIES.length()) {
2642                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2643                 ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX));
2644             }
2645         }
2646 
2647         assertReductionArraysEquals(r, ra, a,
2648                 Double64VectorTests::MAXReduce, Double64VectorTests::MAXReduceAll);
2649     }
2650 
2651     static double MAXReduceMasked(double[] a, int idx, boolean[] mask) {
2652         double res = Double.NEGATIVE_INFINITY;
2653         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2654             if (mask[i % SPECIES.length()])
2655                 res = (double) Math.max(res, a[i]);
2656         }
2657 
2658         return res;
2659     }
2660 
2661     static double MAXReduceAllMasked(double[] a, boolean[] mask) {
2662         double res = Double.NEGATIVE_INFINITY;
2663         for (int i = 0; i < a.length; i += SPECIES.length()) {
2664             res = (double) Math.max(res, MAXReduceMasked(a, i, mask));
2665         }
2666 
2667         return res;
2668     }
2669 
2670     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2671     static void MAXReduceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2672         double[] a = fa.apply(SPECIES.length());
2673         double[] r = fr.apply(SPECIES.length());
2674         boolean[] mask = fm.apply(SPECIES.length());
2675         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2676         double ra = Double.NEGATIVE_INFINITY;
2677 
2678         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2679             for (int i = 0; i < a.length; i += SPECIES.length()) {
2680                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2681                 r[i] = av.reduceLanes(VectorOperators.MAX, vmask);
2682             }
2683         }
2684 
2685         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2686             ra = Double.NEGATIVE_INFINITY;
2687             for (int i = 0; i < a.length; i += SPECIES.length()) {
2688                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2689                 ra = (double) Math.max(ra, av.reduceLanes(VectorOperators.MAX, vmask));
2690             }
2691         }
2692 
2693         assertReductionArraysEqualsMasked(r, ra, a, mask,
2694                 Double64VectorTests::MAXReduceMasked, Double64VectorTests::MAXReduceAllMasked);
2695     }
2696 
2697     static double FIRST_NONZEROReduce(double[] a, int idx) {
2698         double res = (double) 0;
2699         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2700             res = firstNonZero(res, a[i]);
2701         }
2702 
2703         return res;
2704     }
2705 
2706     static double FIRST_NONZEROReduceAll(double[] a) {
2707         double res = (double) 0;
2708         for (int i = 0; i < a.length; i += SPECIES.length()) {
2709             res = firstNonZero(res, FIRST_NONZEROReduce(a, i));
2710         }
2711 
2712         return res;
2713     }
2714 
2715     @Test(dataProvider = "doubleUnaryOpProvider")
2716     static void FIRST_NONZEROReduceDouble64VectorTests(IntFunction<double[]> fa) {
2717         double[] a = fa.apply(SPECIES.length());
2718         double[] r = fr.apply(SPECIES.length());
2719         double ra = (double) 0;
2720 
2721         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2722             for (int i = 0; i < a.length; i += SPECIES.length()) {
2723                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2724                 r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO);
2725             }
2726         }
2727 
2728         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2729             ra = (double) 0;
2730             for (int i = 0; i < a.length; i += SPECIES.length()) {
2731                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2732                 ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO));
2733             }
2734         }
2735 
2736         assertReductionArraysEquals(r, ra, a,
2737                 Double64VectorTests::FIRST_NONZEROReduce, Double64VectorTests::FIRST_NONZEROReduceAll);
2738     }
2739 
2740     static double FIRST_NONZEROReduceMasked(double[] a, int idx, boolean[] mask) {
2741         double res = (double) 0;
2742         for (int i = idx; i < (idx + SPECIES.length()); i++) {
2743             if (mask[i % SPECIES.length()])
2744                 res = firstNonZero(res, a[i]);
2745         }
2746 
2747         return res;
2748     }
2749 
2750     static double FIRST_NONZEROReduceAllMasked(double[] a, boolean[] mask) {
2751         double res = (double) 0;
2752         for (int i = 0; i < a.length; i += SPECIES.length()) {
2753             res = firstNonZero(res, FIRST_NONZEROReduceMasked(a, i, mask));
2754         }
2755 
2756         return res;
2757     }
2758 
2759     @Test(dataProvider = "doubleUnaryOpMaskProvider")
2760     static void FIRST_NONZEROReduceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
2761         double[] a = fa.apply(SPECIES.length());
2762         double[] r = fr.apply(SPECIES.length());
2763         boolean[] mask = fm.apply(SPECIES.length());
2764         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2765         double ra = (double) 0;
2766 
2767         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2768             for (int i = 0; i < a.length; i += SPECIES.length()) {
2769                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2770                 r[i] = av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask);
2771             }
2772         }
2773 
2774         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2775             ra = (double) 0;
2776             for (int i = 0; i < a.length; i += SPECIES.length()) {
2777                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2778                 ra = firstNonZero(ra, av.reduceLanes(VectorOperators.FIRST_NONZERO, vmask));
2779             }
2780         }
2781 
2782         assertReductionArraysEqualsMasked(r, ra, a, mask,
2783                 Double64VectorTests::FIRST_NONZEROReduceMasked, Double64VectorTests::FIRST_NONZEROReduceAllMasked);
2784     }
2785 
2786     @Test(dataProvider = "doubleBinaryOpProvider")
2787     static void withDouble64VectorTests(IntFunction<double []> fa, IntFunction<double []> fb) {
2788         double[] a = fa.apply(SPECIES.length());
2789         double[] b = fb.apply(SPECIES.length());
2790         double[] r = fr.apply(SPECIES.length());
2791 
2792         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2793             for (int i = 0, j = 0; i < a.length; i += SPECIES.length()) {
2794                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2795                 av.withLane(j, b[i + j]).intoArray(r, i);
2796                 a[i + j] = b[i + j];
2797                 j = (j + 1) & (SPECIES.length() - 1);
2798             }
2799         }
2800 
2801 
2802         assertArraysStrictlyEquals(r, a);
2803     }
2804 
2805     static boolean testIS_DEFAULT(double a) {
2806         return bits(a)==0;
2807     }
2808 
2809     @Test(dataProvider = "doubleTestOpProvider")
2810     static void IS_DEFAULTDouble64VectorTests(IntFunction<double[]> fa) {
2811         double[] a = fa.apply(SPECIES.length());
2812 
2813         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2814             for (int i = 0; i < a.length; i += SPECIES.length()) {
2815                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2816                 VectorMask<Double> mv = av.test(VectorOperators.IS_DEFAULT);
2817 
2818                 // Check results as part of computation.
2819                 for (int j = 0; j < SPECIES.length(); j++) {
2820                     Assert.assertEquals(mv.laneIsSet(j), testIS_DEFAULT(a[i + j]));
2821                 }
2822             }
2823         }
2824     }
2825 
2826     @Test(dataProvider = "doubleTestOpMaskProvider")
2827     static void IS_DEFAULTMaskedDouble64VectorTests(IntFunction<double[]> fa,
2828                                           IntFunction<boolean[]> fm) {
2829         double[] a = fa.apply(SPECIES.length());
2830         boolean[] mask = fm.apply(SPECIES.length());
2831         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2832 
2833         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2834             for (int i = 0; i < a.length; i += SPECIES.length()) {
2835                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2836                 VectorMask<Double> mv = av.test(VectorOperators.IS_DEFAULT, vmask);
2837 
2838                 // Check results as part of computation.
2839                 for (int j = 0; j < SPECIES.length(); j++) {
2840                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_DEFAULT(a[i + j]));
2841                 }
2842             }
2843         }
2844     }
2845 
2846     static boolean testIS_NEGATIVE(double a) {
2847         return bits(a)<0;
2848     }
2849 
2850     @Test(dataProvider = "doubleTestOpProvider")
2851     static void IS_NEGATIVEDouble64VectorTests(IntFunction<double[]> fa) {
2852         double[] a = fa.apply(SPECIES.length());
2853 
2854         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2855             for (int i = 0; i < a.length; i += SPECIES.length()) {
2856                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2857                 VectorMask<Double> mv = av.test(VectorOperators.IS_NEGATIVE);
2858 
2859                 // Check results as part of computation.
2860                 for (int j = 0; j < SPECIES.length(); j++) {
2861                     Assert.assertEquals(mv.laneIsSet(j), testIS_NEGATIVE(a[i + j]));
2862                 }
2863             }
2864         }
2865     }
2866 
2867     @Test(dataProvider = "doubleTestOpMaskProvider")
2868     static void IS_NEGATIVEMaskedDouble64VectorTests(IntFunction<double[]> fa,
2869                                           IntFunction<boolean[]> fm) {
2870         double[] a = fa.apply(SPECIES.length());
2871         boolean[] mask = fm.apply(SPECIES.length());
2872         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2873 
2874         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2875             for (int i = 0; i < a.length; i += SPECIES.length()) {
2876                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2877                 VectorMask<Double> mv = av.test(VectorOperators.IS_NEGATIVE, vmask);
2878 
2879                 // Check results as part of computation.
2880                 for (int j = 0; j < SPECIES.length(); j++) {
2881                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_NEGATIVE(a[i + j]));
2882                 }
2883             }
2884         }
2885     }
2886 
2887     static boolean testIS_FINITE(double a) {
2888         return Double.isFinite(a);
2889     }
2890 
2891     @Test(dataProvider = "doubleTestOpProvider")
2892     static void IS_FINITEDouble64VectorTests(IntFunction<double[]> fa) {
2893         double[] a = fa.apply(SPECIES.length());
2894 
2895         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2896             for (int i = 0; i < a.length; i += SPECIES.length()) {
2897                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2898                 VectorMask<Double> mv = av.test(VectorOperators.IS_FINITE);
2899 
2900                 // Check results as part of computation.
2901                 for (int j = 0; j < SPECIES.length(); j++) {
2902                     Assert.assertEquals(mv.laneIsSet(j), testIS_FINITE(a[i + j]));
2903                 }
2904             }
2905         }
2906     }
2907 
2908     @Test(dataProvider = "doubleTestOpMaskProvider")
2909     static void IS_FINITEMaskedDouble64VectorTests(IntFunction<double[]> fa,
2910                                           IntFunction<boolean[]> fm) {
2911         double[] a = fa.apply(SPECIES.length());
2912         boolean[] mask = fm.apply(SPECIES.length());
2913         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2914 
2915         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2916             for (int i = 0; i < a.length; i += SPECIES.length()) {
2917                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2918                 VectorMask<Double> mv = av.test(VectorOperators.IS_FINITE, vmask);
2919 
2920                 // Check results as part of computation.
2921                 for (int j = 0; j < SPECIES.length(); j++) {
2922                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_FINITE(a[i + j]));
2923                 }
2924             }
2925         }
2926     }
2927 
2928     static boolean testIS_NAN(double a) {
2929         return Double.isNaN(a);
2930     }
2931 
2932     @Test(dataProvider = "doubleTestOpProvider")
2933     static void IS_NANDouble64VectorTests(IntFunction<double[]> fa) {
2934         double[] a = fa.apply(SPECIES.length());
2935 
2936         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2937             for (int i = 0; i < a.length; i += SPECIES.length()) {
2938                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2939                 VectorMask<Double> mv = av.test(VectorOperators.IS_NAN);
2940 
2941                 // Check results as part of computation.
2942                 for (int j = 0; j < SPECIES.length(); j++) {
2943                     Assert.assertEquals(mv.laneIsSet(j), testIS_NAN(a[i + j]));
2944                 }
2945             }
2946         }
2947     }
2948 
2949     @Test(dataProvider = "doubleTestOpMaskProvider")
2950     static void IS_NANMaskedDouble64VectorTests(IntFunction<double[]> fa,
2951                                           IntFunction<boolean[]> fm) {
2952         double[] a = fa.apply(SPECIES.length());
2953         boolean[] mask = fm.apply(SPECIES.length());
2954         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2955 
2956         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2957             for (int i = 0; i < a.length; i += SPECIES.length()) {
2958                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2959                 VectorMask<Double> mv = av.test(VectorOperators.IS_NAN, vmask);
2960 
2961                 // Check results as part of computation.
2962                 for (int j = 0; j < SPECIES.length(); j++) {
2963                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_NAN(a[i + j]));
2964                 }
2965             }
2966         }
2967     }
2968 
2969     static boolean testIS_INFINITE(double a) {
2970         return Double.isInfinite(a);
2971     }
2972 
2973     @Test(dataProvider = "doubleTestOpProvider")
2974     static void IS_INFINITEDouble64VectorTests(IntFunction<double[]> fa) {
2975         double[] a = fa.apply(SPECIES.length());
2976 
2977         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2978             for (int i = 0; i < a.length; i += SPECIES.length()) {
2979                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
2980                 VectorMask<Double> mv = av.test(VectorOperators.IS_INFINITE);
2981 
2982                 // Check results as part of computation.
2983                 for (int j = 0; j < SPECIES.length(); j++) {
2984                     Assert.assertEquals(mv.laneIsSet(j), testIS_INFINITE(a[i + j]));
2985                 }
2986             }
2987         }
2988     }
2989 
2990     @Test(dataProvider = "doubleTestOpMaskProvider")
2991     static void IS_INFINITEMaskedDouble64VectorTests(IntFunction<double[]> fa,
2992                                           IntFunction<boolean[]> fm) {
2993         double[] a = fa.apply(SPECIES.length());
2994         boolean[] mask = fm.apply(SPECIES.length());
2995         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
2996 
2997         for (int ic = 0; ic < INVOC_COUNT; ic++) {
2998             for (int i = 0; i < a.length; i += SPECIES.length()) {
2999                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3000                 VectorMask<Double> mv = av.test(VectorOperators.IS_INFINITE, vmask);
3001 
3002                 // Check results as part of computation.
3003                 for (int j = 0; j < SPECIES.length(); j++) {
3004                     Assert.assertEquals(mv.laneIsSet(j),  vmask.laneIsSet(j) && testIS_INFINITE(a[i + j]));
3005                 }
3006             }
3007         }
3008     }
3009 
3010     @Test(dataProvider = "doubleCompareOpProvider")
3011     static void LTDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3012         double[] a = fa.apply(SPECIES.length());
3013         double[] b = fb.apply(SPECIES.length());
3014 
3015         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3016             for (int i = 0; i < a.length; i += SPECIES.length()) {
3017                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3018                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3019                 VectorMask<Double> mv = av.compare(VectorOperators.LT, bv);
3020 
3021                 // Check results as part of computation.
3022                 for (int j = 0; j < SPECIES.length(); j++) {
3023                     Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j]));
3024                 }
3025             }
3026         }
3027     }
3028 
3029     @Test(dataProvider = "doubleCompareOpProvider")
3030     static void ltDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3031         double[] a = fa.apply(SPECIES.length());
3032         double[] b = fb.apply(SPECIES.length());
3033 
3034         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3035             for (int i = 0; i < a.length; i += SPECIES.length()) {
3036                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3037                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3038                 VectorMask<Double> mv = av.lt(bv);
3039 
3040                 // Check results as part of computation.
3041                 for (int j = 0; j < SPECIES.length(); j++) {
3042                     Assert.assertEquals(mv.laneIsSet(j), lt(a[i + j], b[i + j]));
3043                 }
3044             }
3045         }
3046     }
3047 
3048     @Test(dataProvider = "doubleCompareOpMaskProvider")
3049     static void LTDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3050                                                 IntFunction<boolean[]> fm) {
3051         double[] a = fa.apply(SPECIES.length());
3052         double[] b = fb.apply(SPECIES.length());
3053         boolean[] mask = fm.apply(SPECIES.length());
3054 
3055         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3056 
3057         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3058             for (int i = 0; i < a.length; i += SPECIES.length()) {
3059                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3060                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3061                 VectorMask<Double> mv = av.compare(VectorOperators.LT, bv, vmask);
3062 
3063                 // Check results as part of computation.
3064                 for (int j = 0; j < SPECIES.length(); j++) {
3065                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && lt(a[i + j], b[i + j]));
3066                 }
3067             }
3068         }
3069     }
3070 
3071     @Test(dataProvider = "doubleCompareOpProvider")
3072     static void GTDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3073         double[] a = fa.apply(SPECIES.length());
3074         double[] b = fb.apply(SPECIES.length());
3075 
3076         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3077             for (int i = 0; i < a.length; i += SPECIES.length()) {
3078                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3079                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3080                 VectorMask<Double> mv = av.compare(VectorOperators.GT, bv);
3081 
3082                 // Check results as part of computation.
3083                 for (int j = 0; j < SPECIES.length(); j++) {
3084                     Assert.assertEquals(mv.laneIsSet(j), gt(a[i + j], b[i + j]));
3085                 }
3086             }
3087         }
3088     }
3089 
3090     @Test(dataProvider = "doubleCompareOpMaskProvider")
3091     static void GTDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3092                                                 IntFunction<boolean[]> fm) {
3093         double[] a = fa.apply(SPECIES.length());
3094         double[] b = fb.apply(SPECIES.length());
3095         boolean[] mask = fm.apply(SPECIES.length());
3096 
3097         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3098 
3099         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3100             for (int i = 0; i < a.length; i += SPECIES.length()) {
3101                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3102                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3103                 VectorMask<Double> mv = av.compare(VectorOperators.GT, bv, vmask);
3104 
3105                 // Check results as part of computation.
3106                 for (int j = 0; j < SPECIES.length(); j++) {
3107                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && gt(a[i + j], b[i + j]));
3108                 }
3109             }
3110         }
3111     }
3112 
3113     @Test(dataProvider = "doubleCompareOpProvider")
3114     static void EQDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3115         double[] a = fa.apply(SPECIES.length());
3116         double[] b = fb.apply(SPECIES.length());
3117 
3118         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3119             for (int i = 0; i < a.length; i += SPECIES.length()) {
3120                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3121                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3122                 VectorMask<Double> mv = av.compare(VectorOperators.EQ, bv);
3123 
3124                 // Check results as part of computation.
3125                 for (int j = 0; j < SPECIES.length(); j++) {
3126                     Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j]));
3127                 }
3128             }
3129         }
3130     }
3131 
3132     @Test(dataProvider = "doubleCompareOpProvider")
3133     static void eqDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3134         double[] a = fa.apply(SPECIES.length());
3135         double[] b = fb.apply(SPECIES.length());
3136 
3137         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3138             for (int i = 0; i < a.length; i += SPECIES.length()) {
3139                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3140                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3141                 VectorMask<Double> mv = av.eq(bv);
3142 
3143                 // Check results as part of computation.
3144                 for (int j = 0; j < SPECIES.length(); j++) {
3145                     Assert.assertEquals(mv.laneIsSet(j), eq(a[i + j], b[i + j]));
3146                 }
3147             }
3148         }
3149     }
3150 
3151     @Test(dataProvider = "doubleCompareOpMaskProvider")
3152     static void EQDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3153                                                 IntFunction<boolean[]> fm) {
3154         double[] a = fa.apply(SPECIES.length());
3155         double[] b = fb.apply(SPECIES.length());
3156         boolean[] mask = fm.apply(SPECIES.length());
3157 
3158         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3159 
3160         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3161             for (int i = 0; i < a.length; i += SPECIES.length()) {
3162                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3163                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3164                 VectorMask<Double> mv = av.compare(VectorOperators.EQ, bv, vmask);
3165 
3166                 // Check results as part of computation.
3167                 for (int j = 0; j < SPECIES.length(); j++) {
3168                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && eq(a[i + j], b[i + j]));
3169                 }
3170             }
3171         }
3172     }
3173 
3174     @Test(dataProvider = "doubleCompareOpProvider")
3175     static void NEDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3176         double[] a = fa.apply(SPECIES.length());
3177         double[] b = fb.apply(SPECIES.length());
3178 
3179         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3180             for (int i = 0; i < a.length; i += SPECIES.length()) {
3181                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3182                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3183                 VectorMask<Double> mv = av.compare(VectorOperators.NE, bv);
3184 
3185                 // Check results as part of computation.
3186                 for (int j = 0; j < SPECIES.length(); j++) {
3187                     Assert.assertEquals(mv.laneIsSet(j), neq(a[i + j], b[i + j]));
3188                 }
3189             }
3190         }
3191     }
3192 
3193     @Test(dataProvider = "doubleCompareOpMaskProvider")
3194     static void NEDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3195                                                 IntFunction<boolean[]> fm) {
3196         double[] a = fa.apply(SPECIES.length());
3197         double[] b = fb.apply(SPECIES.length());
3198         boolean[] mask = fm.apply(SPECIES.length());
3199 
3200         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3201 
3202         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3203             for (int i = 0; i < a.length; i += SPECIES.length()) {
3204                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3205                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3206                 VectorMask<Double> mv = av.compare(VectorOperators.NE, bv, vmask);
3207 
3208                 // Check results as part of computation.
3209                 for (int j = 0; j < SPECIES.length(); j++) {
3210                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && neq(a[i + j], b[i + j]));
3211                 }
3212             }
3213         }
3214     }
3215 
3216     @Test(dataProvider = "doubleCompareOpProvider")
3217     static void LEDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3218         double[] a = fa.apply(SPECIES.length());
3219         double[] b = fb.apply(SPECIES.length());
3220 
3221         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3222             for (int i = 0; i < a.length; i += SPECIES.length()) {
3223                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3224                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3225                 VectorMask<Double> mv = av.compare(VectorOperators.LE, bv);
3226 
3227                 // Check results as part of computation.
3228                 for (int j = 0; j < SPECIES.length(); j++) {
3229                     Assert.assertEquals(mv.laneIsSet(j), le(a[i + j], b[i + j]));
3230                 }
3231             }
3232         }
3233     }
3234 
3235     @Test(dataProvider = "doubleCompareOpMaskProvider")
3236     static void LEDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3237                                                 IntFunction<boolean[]> fm) {
3238         double[] a = fa.apply(SPECIES.length());
3239         double[] b = fb.apply(SPECIES.length());
3240         boolean[] mask = fm.apply(SPECIES.length());
3241 
3242         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3243 
3244         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3245             for (int i = 0; i < a.length; i += SPECIES.length()) {
3246                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3247                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3248                 VectorMask<Double> mv = av.compare(VectorOperators.LE, bv, vmask);
3249 
3250                 // Check results as part of computation.
3251                 for (int j = 0; j < SPECIES.length(); j++) {
3252                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && le(a[i + j], b[i + j]));
3253                 }
3254             }
3255         }
3256     }
3257 
3258     @Test(dataProvider = "doubleCompareOpProvider")
3259     static void GEDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3260         double[] a = fa.apply(SPECIES.length());
3261         double[] b = fb.apply(SPECIES.length());
3262 
3263         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3264             for (int i = 0; i < a.length; i += SPECIES.length()) {
3265                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3266                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3267                 VectorMask<Double> mv = av.compare(VectorOperators.GE, bv);
3268 
3269                 // Check results as part of computation.
3270                 for (int j = 0; j < SPECIES.length(); j++) {
3271                     Assert.assertEquals(mv.laneIsSet(j), ge(a[i + j], b[i + j]));
3272                 }
3273             }
3274         }
3275     }
3276 
3277     @Test(dataProvider = "doubleCompareOpMaskProvider")
3278     static void GEDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3279                                                 IntFunction<boolean[]> fm) {
3280         double[] a = fa.apply(SPECIES.length());
3281         double[] b = fb.apply(SPECIES.length());
3282         boolean[] mask = fm.apply(SPECIES.length());
3283 
3284         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3285 
3286         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3287             for (int i = 0; i < a.length; i += SPECIES.length()) {
3288                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3289                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3290                 VectorMask<Double> mv = av.compare(VectorOperators.GE, bv, vmask);
3291 
3292                 // Check results as part of computation.
3293                 for (int j = 0; j < SPECIES.length(); j++) {
3294                     Assert.assertEquals(mv.laneIsSet(j), mask[j] && ge(a[i + j], b[i + j]));
3295                 }
3296             }
3297         }
3298     }
3299 
3300     @Test(dataProvider = "doubleCompareOpProvider")
3301     static void LTDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3302         double[] a = fa.apply(SPECIES.length());
3303         double[] b = fb.apply(SPECIES.length());
3304 
3305         for (int i = 0; i < a.length; i += SPECIES.length()) {
3306             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3307             VectorMask<Double> mv = av.compare(VectorOperators.LT, b[i]);
3308 
3309             // Check results as part of computation.
3310             for (int j = 0; j < SPECIES.length(); j++) {
3311                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i]);
3312             }
3313         }
3314     }
3315 
3316     @Test(dataProvider = "doubleCompareOpMaskProvider")
3317     static void LTDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa,
3318                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3319         double[] a = fa.apply(SPECIES.length());
3320         double[] b = fb.apply(SPECIES.length());
3321         boolean[] mask = fm.apply(SPECIES.length());
3322 
3323         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3324 
3325         for (int i = 0; i < a.length; i += SPECIES.length()) {
3326             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3327             VectorMask<Double> mv = av.compare(VectorOperators.LT, b[i], vmask);
3328 
3329             // Check results as part of computation.
3330             for (int j = 0; j < SPECIES.length(); j++) {
3331                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < b[i]));
3332             }
3333         }
3334     }
3335 
3336     @Test(dataProvider = "doubleCompareOpProvider")
3337     static void LTDouble64VectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3338         double[] a = fa.apply(SPECIES.length());
3339         double[] b = fb.apply(SPECIES.length());
3340 
3341         for (int i = 0; i < a.length; i += SPECIES.length()) {
3342             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3343             VectorMask<Double> mv = av.compare(VectorOperators.LT, (long)b[i]);
3344 
3345             // Check results as part of computation.
3346             for (int j = 0; j < SPECIES.length(); j++) {
3347                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] < (double)((long)b[i]));
3348             }
3349         }
3350     }
3351 
3352     @Test(dataProvider = "doubleCompareOpMaskProvider")
3353     static void LTDouble64VectorTestsBroadcastLongMaskedSmokeTest(IntFunction<double[]> fa,
3354                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3355         double[] a = fa.apply(SPECIES.length());
3356         double[] b = fb.apply(SPECIES.length());
3357         boolean[] mask = fm.apply(SPECIES.length());
3358 
3359         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3360 
3361         for (int i = 0; i < a.length; i += SPECIES.length()) {
3362             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3363             VectorMask<Double> mv = av.compare(VectorOperators.LT, (long)b[i], vmask);
3364 
3365             // Check results as part of computation.
3366             for (int j = 0; j < SPECIES.length(); j++) {
3367                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] < (double)((long)b[i])));
3368             }
3369         }
3370     }
3371 
3372     @Test(dataProvider = "doubleCompareOpProvider")
3373     static void EQDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3374         double[] a = fa.apply(SPECIES.length());
3375         double[] b = fb.apply(SPECIES.length());
3376 
3377         for (int i = 0; i < a.length; i += SPECIES.length()) {
3378             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3379             VectorMask<Double> mv = av.compare(VectorOperators.EQ, b[i]);
3380 
3381             // Check results as part of computation.
3382             for (int j = 0; j < SPECIES.length(); j++) {
3383                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i]);
3384             }
3385         }
3386     }
3387 
3388     @Test(dataProvider = "doubleCompareOpMaskProvider")
3389     static void EQDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa,
3390                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3391         double[] a = fa.apply(SPECIES.length());
3392         double[] b = fb.apply(SPECIES.length());
3393         boolean[] mask = fm.apply(SPECIES.length());
3394 
3395         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3396 
3397         for (int i = 0; i < a.length; i += SPECIES.length()) {
3398             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3399             VectorMask<Double> mv = av.compare(VectorOperators.EQ, b[i], vmask);
3400 
3401             // Check results as part of computation.
3402             for (int j = 0; j < SPECIES.length(); j++) {
3403                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == b[i]));
3404             }
3405         }
3406     }
3407 
3408     @Test(dataProvider = "doubleCompareOpProvider")
3409     static void EQDouble64VectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3410         double[] a = fa.apply(SPECIES.length());
3411         double[] b = fb.apply(SPECIES.length());
3412 
3413         for (int i = 0; i < a.length; i += SPECIES.length()) {
3414             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3415             VectorMask<Double> mv = av.compare(VectorOperators.EQ, (long)b[i]);
3416 
3417             // Check results as part of computation.
3418             for (int j = 0; j < SPECIES.length(); j++) {
3419                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] == (double)((long)b[i]));
3420             }
3421         }
3422     }
3423 
3424     @Test(dataProvider = "doubleCompareOpMaskProvider")
3425     static void EQDouble64VectorTestsBroadcastLongMaskedSmokeTest(IntFunction<double[]> fa,
3426                                 IntFunction<double[]> fb, IntFunction<boolean[]> fm) {
3427         double[] a = fa.apply(SPECIES.length());
3428         double[] b = fb.apply(SPECIES.length());
3429         boolean[] mask = fm.apply(SPECIES.length());
3430 
3431         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3432 
3433         for (int i = 0; i < a.length; i += SPECIES.length()) {
3434             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3435             VectorMask<Double> mv = av.compare(VectorOperators.EQ, (long)b[i], vmask);
3436 
3437             // Check results as part of computation.
3438             for (int j = 0; j < SPECIES.length(); j++) {
3439                 Assert.assertEquals(mv.laneIsSet(j), mask[j] && (a[i + j] == (double)((long)b[i])));
3440             }
3441         }
3442     }
3443 
3444     static double blend(double a, double b, boolean mask) {
3445         return mask ? b : a;
3446     }
3447 
3448     @Test(dataProvider = "doubleBinaryOpMaskProvider")
3449     static void blendDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb,
3450                                           IntFunction<boolean[]> fm) {
3451         double[] a = fa.apply(SPECIES.length());
3452         double[] b = fb.apply(SPECIES.length());
3453         double[] r = fr.apply(SPECIES.length());
3454         boolean[] mask = fm.apply(SPECIES.length());
3455         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3456 
3457         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3458             for (int i = 0; i < a.length; i += SPECIES.length()) {
3459                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3460                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3461                 av.blend(bv, vmask).intoArray(r, i);
3462             }
3463         }
3464 
3465         assertArraysEquals(r, a, b, mask, Double64VectorTests::blend);
3466     }
3467 
3468     @Test(dataProvider = "doubleUnaryOpShuffleProvider")
3469     static void RearrangeDouble64VectorTests(IntFunction<double[]> fa,
3470                                            BiFunction<Integer,Integer,int[]> fs) {
3471         double[] a = fa.apply(SPECIES.length());
3472         int[] order = fs.apply(a.length, SPECIES.length());
3473         double[] r = fr.apply(SPECIES.length());
3474 
3475         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3476             for (int i = 0; i < a.length; i += SPECIES.length()) {
3477                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3478                 av.rearrange(VectorShuffle.fromArray(SPECIES, order, i)).intoArray(r, i);
3479             }
3480         }
3481 
3482         assertRearrangeArraysEquals(r, a, order, SPECIES.length());
3483     }
3484 
3485     @Test(dataProvider = "doubleUnaryOpShuffleMaskProvider")
3486     static void RearrangeDouble64VectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
3487                                                           BiFunction<Integer,Integer,int[]> fs,
3488                                                           IntFunction<boolean[]> fm) {
3489         double[] a = fa.apply(SPECIES.length());
3490         int[] order = fs.apply(a.length, SPECIES.length());
3491         double[] r = fr.apply(SPECIES.length());
3492         boolean[] mask = fm.apply(SPECIES.length());
3493         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3494 
3495         for (int i = 0; i < a.length; i += SPECIES.length()) {
3496             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3497             av.rearrange(VectorShuffle.fromArray(SPECIES, order, i), vmask).intoArray(r, i);
3498         }
3499 
3500         assertRearrangeArraysEquals(r, a, order, mask, SPECIES.length());
3501     }
3502 
3503     @Test(dataProvider = "doubleUnaryOpMaskProvider")
3504     static void compressDouble64VectorTests(IntFunction<double[]> fa,
3505                                                 IntFunction<boolean[]> fm) {
3506         double[] a = fa.apply(SPECIES.length());
3507         double[] r = fr.apply(SPECIES.length());
3508         boolean[] mask = fm.apply(SPECIES.length());
3509         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3510 
3511         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3512             for (int i = 0; i < a.length; i += SPECIES.length()) {
3513                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3514                 av.compress(vmask).intoArray(r, i);
3515             }
3516         }
3517 
3518         assertcompressArraysEquals(r, a, mask, SPECIES.length());
3519     }
3520 
3521     @Test(dataProvider = "doubleUnaryOpMaskProvider")
3522     static void expandDouble64VectorTests(IntFunction<double[]> fa,
3523                                                 IntFunction<boolean[]> fm) {
3524         double[] a = fa.apply(SPECIES.length());
3525         double[] r = fr.apply(SPECIES.length());
3526         boolean[] mask = fm.apply(SPECIES.length());
3527         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3528 
3529         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3530             for (int i = 0; i < a.length; i += SPECIES.length()) {
3531                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3532                 av.expand(vmask).intoArray(r, i);
3533             }
3534         }
3535 
3536         assertexpandArraysEquals(r, a, mask, SPECIES.length());
3537     }
3538 
3539     @Test(dataProvider = "doubleUnaryOpProvider")
3540     static void getDouble64VectorTests(IntFunction<double[]> fa) {
3541         double[] a = fa.apply(SPECIES.length());
3542         double[] r = fr.apply(SPECIES.length());
3543 
3544         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3545             for (int i = 0; i < a.length; i += SPECIES.length()) {
3546                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3547                 int num_lanes = SPECIES.length();
3548                 // Manually unroll because full unroll happens after intrinsification.
3549                 // Unroll is needed because get intrinsic requires for index to be a known constant.
3550                 if (num_lanes == 1) {
3551                     r[i]=av.lane(0);
3552                 } else if (num_lanes == 2) {
3553                     r[i]=av.lane(0);
3554                     r[i+1]=av.lane(1);
3555                 } else if (num_lanes == 4) {
3556                     r[i]=av.lane(0);
3557                     r[i+1]=av.lane(1);
3558                     r[i+2]=av.lane(2);
3559                     r[i+3]=av.lane(3);
3560                 } else if (num_lanes == 8) {
3561                     r[i]=av.lane(0);
3562                     r[i+1]=av.lane(1);
3563                     r[i+2]=av.lane(2);
3564                     r[i+3]=av.lane(3);
3565                     r[i+4]=av.lane(4);
3566                     r[i+5]=av.lane(5);
3567                     r[i+6]=av.lane(6);
3568                     r[i+7]=av.lane(7);
3569                 } else if (num_lanes == 16) {
3570                     r[i]=av.lane(0);
3571                     r[i+1]=av.lane(1);
3572                     r[i+2]=av.lane(2);
3573                     r[i+3]=av.lane(3);
3574                     r[i+4]=av.lane(4);
3575                     r[i+5]=av.lane(5);
3576                     r[i+6]=av.lane(6);
3577                     r[i+7]=av.lane(7);
3578                     r[i+8]=av.lane(8);
3579                     r[i+9]=av.lane(9);
3580                     r[i+10]=av.lane(10);
3581                     r[i+11]=av.lane(11);
3582                     r[i+12]=av.lane(12);
3583                     r[i+13]=av.lane(13);
3584                     r[i+14]=av.lane(14);
3585                     r[i+15]=av.lane(15);
3586                 } else if (num_lanes == 32) {
3587                     r[i]=av.lane(0);
3588                     r[i+1]=av.lane(1);
3589                     r[i+2]=av.lane(2);
3590                     r[i+3]=av.lane(3);
3591                     r[i+4]=av.lane(4);
3592                     r[i+5]=av.lane(5);
3593                     r[i+6]=av.lane(6);
3594                     r[i+7]=av.lane(7);
3595                     r[i+8]=av.lane(8);
3596                     r[i+9]=av.lane(9);
3597                     r[i+10]=av.lane(10);
3598                     r[i+11]=av.lane(11);
3599                     r[i+12]=av.lane(12);
3600                     r[i+13]=av.lane(13);
3601                     r[i+14]=av.lane(14);
3602                     r[i+15]=av.lane(15);
3603                     r[i+16]=av.lane(16);
3604                     r[i+17]=av.lane(17);
3605                     r[i+18]=av.lane(18);
3606                     r[i+19]=av.lane(19);
3607                     r[i+20]=av.lane(20);
3608                     r[i+21]=av.lane(21);
3609                     r[i+22]=av.lane(22);
3610                     r[i+23]=av.lane(23);
3611                     r[i+24]=av.lane(24);
3612                     r[i+25]=av.lane(25);
3613                     r[i+26]=av.lane(26);
3614                     r[i+27]=av.lane(27);
3615                     r[i+28]=av.lane(28);
3616                     r[i+29]=av.lane(29);
3617                     r[i+30]=av.lane(30);
3618                     r[i+31]=av.lane(31);
3619                 } else if (num_lanes == 64) {
3620                     r[i]=av.lane(0);
3621                     r[i+1]=av.lane(1);
3622                     r[i+2]=av.lane(2);
3623                     r[i+3]=av.lane(3);
3624                     r[i+4]=av.lane(4);
3625                     r[i+5]=av.lane(5);
3626                     r[i+6]=av.lane(6);
3627                     r[i+7]=av.lane(7);
3628                     r[i+8]=av.lane(8);
3629                     r[i+9]=av.lane(9);
3630                     r[i+10]=av.lane(10);
3631                     r[i+11]=av.lane(11);
3632                     r[i+12]=av.lane(12);
3633                     r[i+13]=av.lane(13);
3634                     r[i+14]=av.lane(14);
3635                     r[i+15]=av.lane(15);
3636                     r[i+16]=av.lane(16);
3637                     r[i+17]=av.lane(17);
3638                     r[i+18]=av.lane(18);
3639                     r[i+19]=av.lane(19);
3640                     r[i+20]=av.lane(20);
3641                     r[i+21]=av.lane(21);
3642                     r[i+22]=av.lane(22);
3643                     r[i+23]=av.lane(23);
3644                     r[i+24]=av.lane(24);
3645                     r[i+25]=av.lane(25);
3646                     r[i+26]=av.lane(26);
3647                     r[i+27]=av.lane(27);
3648                     r[i+28]=av.lane(28);
3649                     r[i+29]=av.lane(29);
3650                     r[i+30]=av.lane(30);
3651                     r[i+31]=av.lane(31);
3652                     r[i+32]=av.lane(32);
3653                     r[i+33]=av.lane(33);
3654                     r[i+34]=av.lane(34);
3655                     r[i+35]=av.lane(35);
3656                     r[i+36]=av.lane(36);
3657                     r[i+37]=av.lane(37);
3658                     r[i+38]=av.lane(38);
3659                     r[i+39]=av.lane(39);
3660                     r[i+40]=av.lane(40);
3661                     r[i+41]=av.lane(41);
3662                     r[i+42]=av.lane(42);
3663                     r[i+43]=av.lane(43);
3664                     r[i+44]=av.lane(44);
3665                     r[i+45]=av.lane(45);
3666                     r[i+46]=av.lane(46);
3667                     r[i+47]=av.lane(47);
3668                     r[i+48]=av.lane(48);
3669                     r[i+49]=av.lane(49);
3670                     r[i+50]=av.lane(50);
3671                     r[i+51]=av.lane(51);
3672                     r[i+52]=av.lane(52);
3673                     r[i+53]=av.lane(53);
3674                     r[i+54]=av.lane(54);
3675                     r[i+55]=av.lane(55);
3676                     r[i+56]=av.lane(56);
3677                     r[i+57]=av.lane(57);
3678                     r[i+58]=av.lane(58);
3679                     r[i+59]=av.lane(59);
3680                     r[i+60]=av.lane(60);
3681                     r[i+61]=av.lane(61);
3682                     r[i+62]=av.lane(62);
3683                     r[i+63]=av.lane(63);
3684                 } else {
3685                     for (int j = 0; j < SPECIES.length(); j++) {
3686                         r[i+j]=av.lane(j);
3687                     }
3688                 }
3689             }
3690         }
3691 
3692         assertArraysStrictlyEquals(r, a);
3693     }
3694 
3695     @Test(dataProvider = "doubleUnaryOpProvider")
3696     static void BroadcastDouble64VectorTests(IntFunction<double[]> fa) {
3697         double[] a = fa.apply(SPECIES.length());
3698         double[] r = new double[a.length];
3699 
3700         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3701             for (int i = 0; i < a.length; i += SPECIES.length()) {
3702                 DoubleVector.broadcast(SPECIES, a[i]).intoArray(r, i);
3703             }
3704         }
3705 
3706         assertBroadcastArraysEquals(r, a);
3707     }
3708 
3709     @Test(dataProvider = "doubleUnaryOpProvider")
3710     static void ZeroDouble64VectorTests(IntFunction<double[]> fa) {
3711         double[] a = fa.apply(SPECIES.length());
3712         double[] r = new double[a.length];
3713 
3714         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3715             for (int i = 0; i < a.length; i += SPECIES.length()) {
3716                 DoubleVector.zero(SPECIES).intoArray(a, i);
3717             }
3718         }
3719 
3720         Assert.assertEquals(a, r);
3721     }
3722 
3723     static double[] sliceUnary(double[] a, int origin, int idx) {
3724         double[] res = new double[SPECIES.length()];
3725         for (int i = 0; i < SPECIES.length(); i++){
3726             if(i+origin < SPECIES.length())
3727                 res[i] = a[idx+i+origin];
3728             else
3729                 res[i] = (double)0;
3730         }
3731         return res;
3732     }
3733 
3734     @Test(dataProvider = "doubleUnaryOpProvider")
3735     static void sliceUnaryDouble64VectorTests(IntFunction<double[]> fa) {
3736         double[] a = fa.apply(SPECIES.length());
3737         double[] r = new double[a.length];
3738         int origin = RAND.nextInt(SPECIES.length());
3739         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3740             for (int i = 0; i < a.length; i += SPECIES.length()) {
3741                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3742                 av.slice(origin).intoArray(r, i);
3743             }
3744         }
3745 
3746         assertArraysEquals(r, a, origin, Double64VectorTests::sliceUnary);
3747     }
3748 
3749     static double[] sliceBinary(double[] a, double[] b, int origin, int idx) {
3750         double[] res = new double[SPECIES.length()];
3751         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3752             if(i+origin < SPECIES.length())
3753                 res[i] = a[idx+i+origin];
3754             else {
3755                 res[i] = b[idx+j];
3756                 j++;
3757             }
3758         }
3759         return res;
3760     }
3761 
3762     @Test(dataProvider = "doubleBinaryOpProvider")
3763     static void sliceBinaryDouble64VectorTestsBinary(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3764         double[] a = fa.apply(SPECIES.length());
3765         double[] b = fb.apply(SPECIES.length());
3766         double[] r = new double[a.length];
3767         int origin = RAND.nextInt(SPECIES.length());
3768         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3769             for (int i = 0; i < a.length; i += SPECIES.length()) {
3770                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3771                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3772                 av.slice(origin, bv).intoArray(r, i);
3773             }
3774         }
3775 
3776         assertArraysEquals(r, a, b, origin, Double64VectorTests::sliceBinary);
3777     }
3778 
3779     static double[] slice(double[] a, double[] b, int origin, boolean[] mask, int idx) {
3780         double[] res = new double[SPECIES.length()];
3781         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3782             if(i+origin < SPECIES.length())
3783                 res[i] = mask[i] ? a[idx+i+origin] : (double)0;
3784             else {
3785                 res[i] = mask[i] ? b[idx+j] : (double)0;
3786                 j++;
3787             }
3788         }
3789         return res;
3790     }
3791 
3792     @Test(dataProvider = "doubleBinaryOpMaskProvider")
3793     static void sliceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3794     IntFunction<boolean[]> fm) {
3795         double[] a = fa.apply(SPECIES.length());
3796         double[] b = fb.apply(SPECIES.length());
3797         boolean[] mask = fm.apply(SPECIES.length());
3798         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3799 
3800         double[] r = new double[a.length];
3801         int origin = RAND.nextInt(SPECIES.length());
3802         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3803             for (int i = 0; i < a.length; i += SPECIES.length()) {
3804                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3805                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3806                 av.slice(origin, bv, vmask).intoArray(r, i);
3807             }
3808         }
3809 
3810         assertArraysEquals(r, a, b, origin, mask, Double64VectorTests::slice);
3811     }
3812 
3813     static double[] unsliceUnary(double[] a, int origin, int idx) {
3814         double[] res = new double[SPECIES.length()];
3815         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3816             if(i < origin)
3817                 res[i] = (double)0;
3818             else {
3819                 res[i] = a[idx+j];
3820                 j++;
3821             }
3822         }
3823         return res;
3824     }
3825 
3826     @Test(dataProvider = "doubleUnaryOpProvider")
3827     static void unsliceUnaryDouble64VectorTests(IntFunction<double[]> fa) {
3828         double[] a = fa.apply(SPECIES.length());
3829         double[] r = new double[a.length];
3830         int origin = RAND.nextInt(SPECIES.length());
3831         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3832             for (int i = 0; i < a.length; i += SPECIES.length()) {
3833                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3834                 av.unslice(origin).intoArray(r, i);
3835             }
3836         }
3837 
3838         assertArraysEquals(r, a, origin, Double64VectorTests::unsliceUnary);
3839     }
3840 
3841     static double[] unsliceBinary(double[] a, double[] b, int origin, int part, int idx) {
3842         double[] res = new double[SPECIES.length()];
3843         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3844             if (part == 0) {
3845                 if (i < origin)
3846                     res[i] = b[idx+i];
3847                 else {
3848                     res[i] = a[idx+j];
3849                     j++;
3850                 }
3851             } else if (part == 1) {
3852                 if (i < origin)
3853                     res[i] = a[idx+SPECIES.length()-origin+i];
3854                 else {
3855                     res[i] = b[idx+origin+j];
3856                     j++;
3857                 }
3858             }
3859         }
3860         return res;
3861     }
3862 
3863     @Test(dataProvider = "doubleBinaryOpProvider")
3864     static void unsliceBinaryDouble64VectorTestsBinary(IntFunction<double[]> fa, IntFunction<double[]> fb) {
3865         double[] a = fa.apply(SPECIES.length());
3866         double[] b = fb.apply(SPECIES.length());
3867         double[] r = new double[a.length];
3868         int origin = RAND.nextInt(SPECIES.length());
3869         int part = RAND.nextInt(2);
3870         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3871             for (int i = 0; i < a.length; i += SPECIES.length()) {
3872                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3873                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3874                 av.unslice(origin, bv, part).intoArray(r, i);
3875             }
3876         }
3877 
3878         assertArraysEquals(r, a, b, origin, part, Double64VectorTests::unsliceBinary);
3879     }
3880 
3881     static double[] unslice(double[] a, double[] b, int origin, int part, boolean[] mask, int idx) {
3882         double[] res = new double[SPECIES.length()];
3883         for (int i = 0, j = 0; i < SPECIES.length(); i++){
3884             if(i+origin < SPECIES.length())
3885                 res[i] = b[idx+i+origin];
3886             else {
3887                 res[i] = b[idx+j];
3888                 j++;
3889             }
3890         }
3891         for (int i = 0; i < SPECIES.length(); i++){
3892             res[i] = mask[i] ? a[idx+i] : res[i];
3893         }
3894         double[] res1 = new double[SPECIES.length()];
3895         if (part == 0) {
3896             for (int i = 0, j = 0; i < SPECIES.length(); i++){
3897                 if (i < origin)
3898                     res1[i] = b[idx+i];
3899                 else {
3900                    res1[i] = res[j];
3901                    j++;
3902                 }
3903             }
3904         } else if (part == 1) {
3905             for (int i = 0, j = 0; i < SPECIES.length(); i++){
3906                 if (i < origin)
3907                     res1[i] = res[SPECIES.length()-origin+i];
3908                 else {
3909                     res1[i] = b[idx+origin+j];
3910                     j++;
3911                 }
3912             }
3913         }
3914         return res1;
3915     }
3916 
3917     @Test(dataProvider = "doubleBinaryOpMaskProvider")
3918     static void unsliceDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
3919     IntFunction<boolean[]> fm) {
3920         double[] a = fa.apply(SPECIES.length());
3921         double[] b = fb.apply(SPECIES.length());
3922         boolean[] mask = fm.apply(SPECIES.length());
3923         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
3924         double[] r = new double[a.length];
3925         int origin = RAND.nextInt(SPECIES.length());
3926         int part = RAND.nextInt(2);
3927         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3928             for (int i = 0; i < a.length; i += SPECIES.length()) {
3929                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3930                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
3931                 av.unslice(origin, bv, part, vmask).intoArray(r, i);
3932             }
3933         }
3934 
3935         assertArraysEquals(r, a, b, origin, part, mask, Double64VectorTests::unslice);
3936     }
3937 
3938     static double SIN(double a) {
3939         return (double)(Math.sin((double)a));
3940     }
3941 
3942     static double strictSIN(double a) {
3943         return (double)(StrictMath.sin((double)a));
3944     }
3945 
3946     @Test(dataProvider = "doubleUnaryOpProvider")
3947     static void SINDouble64VectorTests(IntFunction<double[]> fa) {
3948         double[] a = fa.apply(SPECIES.length());
3949         double[] r = fr.apply(SPECIES.length());
3950 
3951         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3952             for (int i = 0; i < a.length; i += SPECIES.length()) {
3953                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3954                 av.lanewise(VectorOperators.SIN).intoArray(r, i);
3955             }
3956         }
3957 
3958         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::SIN, Double64VectorTests::strictSIN);
3959     }
3960 
3961     static double EXP(double a) {
3962         return (double)(Math.exp((double)a));
3963     }
3964 
3965     static double strictEXP(double a) {
3966         return (double)(StrictMath.exp((double)a));
3967     }
3968 
3969     @Test(dataProvider = "doubleUnaryOpProvider")
3970     static void EXPDouble64VectorTests(IntFunction<double[]> fa) {
3971         double[] a = fa.apply(SPECIES.length());
3972         double[] r = fr.apply(SPECIES.length());
3973 
3974         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3975             for (int i = 0; i < a.length; i += SPECIES.length()) {
3976                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
3977                 av.lanewise(VectorOperators.EXP).intoArray(r, i);
3978             }
3979         }
3980 
3981         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::EXP, Double64VectorTests::strictEXP);
3982     }
3983 
3984     static double LOG1P(double a) {
3985         return (double)(Math.log1p((double)a));
3986     }
3987 
3988     static double strictLOG1P(double a) {
3989         return (double)(StrictMath.log1p((double)a));
3990     }
3991 
3992     @Test(dataProvider = "doubleUnaryOpProvider")
3993     static void LOG1PDouble64VectorTests(IntFunction<double[]> fa) {
3994         double[] a = fa.apply(SPECIES.length());
3995         double[] r = fr.apply(SPECIES.length());
3996 
3997         for (int ic = 0; ic < INVOC_COUNT; ic++) {
3998             for (int i = 0; i < a.length; i += SPECIES.length()) {
3999                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4000                 av.lanewise(VectorOperators.LOG1P).intoArray(r, i);
4001             }
4002         }
4003 
4004         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::LOG1P, Double64VectorTests::strictLOG1P);
4005     }
4006 
4007     static double LOG(double a) {
4008         return (double)(Math.log((double)a));
4009     }
4010 
4011     static double strictLOG(double a) {
4012         return (double)(StrictMath.log((double)a));
4013     }
4014 
4015     @Test(dataProvider = "doubleUnaryOpProvider")
4016     static void LOGDouble64VectorTests(IntFunction<double[]> fa) {
4017         double[] a = fa.apply(SPECIES.length());
4018         double[] r = fr.apply(SPECIES.length());
4019 
4020         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4021             for (int i = 0; i < a.length; i += SPECIES.length()) {
4022                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4023                 av.lanewise(VectorOperators.LOG).intoArray(r, i);
4024             }
4025         }
4026 
4027         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::LOG, Double64VectorTests::strictLOG);
4028     }
4029 
4030     static double LOG10(double a) {
4031         return (double)(Math.log10((double)a));
4032     }
4033 
4034     static double strictLOG10(double a) {
4035         return (double)(StrictMath.log10((double)a));
4036     }
4037 
4038     @Test(dataProvider = "doubleUnaryOpProvider")
4039     static void LOG10Double64VectorTests(IntFunction<double[]> fa) {
4040         double[] a = fa.apply(SPECIES.length());
4041         double[] r = fr.apply(SPECIES.length());
4042 
4043         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4044             for (int i = 0; i < a.length; i += SPECIES.length()) {
4045                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4046                 av.lanewise(VectorOperators.LOG10).intoArray(r, i);
4047             }
4048         }
4049 
4050         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::LOG10, Double64VectorTests::strictLOG10);
4051     }
4052 
4053     static double EXPM1(double a) {
4054         return (double)(Math.expm1((double)a));
4055     }
4056 
4057     static double strictEXPM1(double a) {
4058         return (double)(StrictMath.expm1((double)a));
4059     }
4060 
4061     @Test(dataProvider = "doubleUnaryOpProvider")
4062     static void EXPM1Double64VectorTests(IntFunction<double[]> fa) {
4063         double[] a = fa.apply(SPECIES.length());
4064         double[] r = fr.apply(SPECIES.length());
4065 
4066         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4067             for (int i = 0; i < a.length; i += SPECIES.length()) {
4068                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4069                 av.lanewise(VectorOperators.EXPM1).intoArray(r, i);
4070             }
4071         }
4072 
4073         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::EXPM1, Double64VectorTests::strictEXPM1);
4074     }
4075 
4076     static double COS(double a) {
4077         return (double)(Math.cos((double)a));
4078     }
4079 
4080     static double strictCOS(double a) {
4081         return (double)(StrictMath.cos((double)a));
4082     }
4083 
4084     @Test(dataProvider = "doubleUnaryOpProvider")
4085     static void COSDouble64VectorTests(IntFunction<double[]> fa) {
4086         double[] a = fa.apply(SPECIES.length());
4087         double[] r = fr.apply(SPECIES.length());
4088 
4089         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4090             for (int i = 0; i < a.length; i += SPECIES.length()) {
4091                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4092                 av.lanewise(VectorOperators.COS).intoArray(r, i);
4093             }
4094         }
4095 
4096         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::COS, Double64VectorTests::strictCOS);
4097     }
4098 
4099     static double TAN(double a) {
4100         return (double)(Math.tan((double)a));
4101     }
4102 
4103     static double strictTAN(double a) {
4104         return (double)(StrictMath.tan((double)a));
4105     }
4106 
4107     @Test(dataProvider = "doubleUnaryOpProvider")
4108     static void TANDouble64VectorTests(IntFunction<double[]> fa) {
4109         double[] a = fa.apply(SPECIES.length());
4110         double[] r = fr.apply(SPECIES.length());
4111 
4112         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4113             for (int i = 0; i < a.length; i += SPECIES.length()) {
4114                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4115                 av.lanewise(VectorOperators.TAN).intoArray(r, i);
4116             }
4117         }
4118 
4119         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::TAN, Double64VectorTests::strictTAN);
4120     }
4121 
4122     static double SINH(double a) {
4123         return (double)(Math.sinh((double)a));
4124     }
4125 
4126     static double strictSINH(double a) {
4127         return (double)(StrictMath.sinh((double)a));
4128     }
4129 
4130     @Test(dataProvider = "doubleUnaryOpProvider")
4131     static void SINHDouble64VectorTests(IntFunction<double[]> fa) {
4132         double[] a = fa.apply(SPECIES.length());
4133         double[] r = fr.apply(SPECIES.length());
4134 
4135         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4136             for (int i = 0; i < a.length; i += SPECIES.length()) {
4137                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4138                 av.lanewise(VectorOperators.SINH).intoArray(r, i);
4139             }
4140         }
4141 
4142         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::SINH, Double64VectorTests::strictSINH);
4143     }
4144 
4145     static double COSH(double a) {
4146         return (double)(Math.cosh((double)a));
4147     }
4148 
4149     static double strictCOSH(double a) {
4150         return (double)(StrictMath.cosh((double)a));
4151     }
4152 
4153     @Test(dataProvider = "doubleUnaryOpProvider")
4154     static void COSHDouble64VectorTests(IntFunction<double[]> fa) {
4155         double[] a = fa.apply(SPECIES.length());
4156         double[] r = fr.apply(SPECIES.length());
4157 
4158         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4159             for (int i = 0; i < a.length; i += SPECIES.length()) {
4160                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4161                 av.lanewise(VectorOperators.COSH).intoArray(r, i);
4162             }
4163         }
4164 
4165         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::COSH, Double64VectorTests::strictCOSH);
4166     }
4167 
4168     static double TANH(double a) {
4169         return (double)(Math.tanh((double)a));
4170     }
4171 
4172     static double strictTANH(double a) {
4173         return (double)(StrictMath.tanh((double)a));
4174     }
4175 
4176     @Test(dataProvider = "doubleUnaryOpProvider")
4177     static void TANHDouble64VectorTests(IntFunction<double[]> fa) {
4178         double[] a = fa.apply(SPECIES.length());
4179         double[] r = fr.apply(SPECIES.length());
4180 
4181         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4182             for (int i = 0; i < a.length; i += SPECIES.length()) {
4183                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4184                 av.lanewise(VectorOperators.TANH).intoArray(r, i);
4185             }
4186         }
4187 
4188         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::TANH, Double64VectorTests::strictTANH);
4189     }
4190 
4191     static double ASIN(double a) {
4192         return (double)(Math.asin((double)a));
4193     }
4194 
4195     static double strictASIN(double a) {
4196         return (double)(StrictMath.asin((double)a));
4197     }
4198 
4199     @Test(dataProvider = "doubleUnaryOpProvider")
4200     static void ASINDouble64VectorTests(IntFunction<double[]> fa) {
4201         double[] a = fa.apply(SPECIES.length());
4202         double[] r = fr.apply(SPECIES.length());
4203 
4204         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4205             for (int i = 0; i < a.length; i += SPECIES.length()) {
4206                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4207                 av.lanewise(VectorOperators.ASIN).intoArray(r, i);
4208             }
4209         }
4210 
4211         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::ASIN, Double64VectorTests::strictASIN);
4212     }
4213 
4214     static double ACOS(double a) {
4215         return (double)(Math.acos((double)a));
4216     }
4217 
4218     static double strictACOS(double a) {
4219         return (double)(StrictMath.acos((double)a));
4220     }
4221 
4222     @Test(dataProvider = "doubleUnaryOpProvider")
4223     static void ACOSDouble64VectorTests(IntFunction<double[]> fa) {
4224         double[] a = fa.apply(SPECIES.length());
4225         double[] r = fr.apply(SPECIES.length());
4226 
4227         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4228             for (int i = 0; i < a.length; i += SPECIES.length()) {
4229                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4230                 av.lanewise(VectorOperators.ACOS).intoArray(r, i);
4231             }
4232         }
4233 
4234         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::ACOS, Double64VectorTests::strictACOS);
4235     }
4236 
4237     static double ATAN(double a) {
4238         return (double)(Math.atan((double)a));
4239     }
4240 
4241     static double strictATAN(double a) {
4242         return (double)(StrictMath.atan((double)a));
4243     }
4244 
4245     @Test(dataProvider = "doubleUnaryOpProvider")
4246     static void ATANDouble64VectorTests(IntFunction<double[]> fa) {
4247         double[] a = fa.apply(SPECIES.length());
4248         double[] r = fr.apply(SPECIES.length());
4249 
4250         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4251             for (int i = 0; i < a.length; i += SPECIES.length()) {
4252                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4253                 av.lanewise(VectorOperators.ATAN).intoArray(r, i);
4254             }
4255         }
4256 
4257         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::ATAN, Double64VectorTests::strictATAN);
4258     }
4259 
4260     static double CBRT(double a) {
4261         return (double)(Math.cbrt((double)a));
4262     }
4263 
4264     static double strictCBRT(double a) {
4265         return (double)(StrictMath.cbrt((double)a));
4266     }
4267 
4268     @Test(dataProvider = "doubleUnaryOpProvider")
4269     static void CBRTDouble64VectorTests(IntFunction<double[]> fa) {
4270         double[] a = fa.apply(SPECIES.length());
4271         double[] r = fr.apply(SPECIES.length());
4272 
4273         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4274             for (int i = 0; i < a.length; i += SPECIES.length()) {
4275                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4276                 av.lanewise(VectorOperators.CBRT).intoArray(r, i);
4277             }
4278         }
4279 
4280         assertArraysEqualsWithinOneUlp(r, a, Double64VectorTests::CBRT, Double64VectorTests::strictCBRT);
4281     }
4282 
4283     static double HYPOT(double a, double b) {
4284         return (double)(Math.hypot((double)a, (double)b));
4285     }
4286 
4287     static double strictHYPOT(double a, double b) {
4288         return (double)(StrictMath.hypot((double)a, (double)b));
4289     }
4290 
4291     @Test(dataProvider = "doubleBinaryOpProvider")
4292     static void HYPOTDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4293         double[] a = fa.apply(SPECIES.length());
4294         double[] b = fb.apply(SPECIES.length());
4295         double[] r = fr.apply(SPECIES.length());
4296 
4297         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4298             for (int i = 0; i < a.length; i += SPECIES.length()) {
4299                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4300                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4301                 av.lanewise(VectorOperators.HYPOT, bv).intoArray(r, i);
4302             }
4303         }
4304 
4305         assertArraysEqualsWithinOneUlp(r, a, b, Double64VectorTests::HYPOT, Double64VectorTests::strictHYPOT);
4306     }
4307 
4308 
4309     static double POW(double a, double b) {
4310         return (double)(Math.pow((double)a, (double)b));
4311     }
4312 
4313     static double strictPOW(double a, double b) {
4314         return (double)(StrictMath.pow((double)a, (double)b));
4315     }
4316 
4317     @Test(dataProvider = "doubleBinaryOpProvider")
4318     static void POWDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4319         double[] a = fa.apply(SPECIES.length());
4320         double[] b = fb.apply(SPECIES.length());
4321         double[] r = fr.apply(SPECIES.length());
4322 
4323         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4324             for (int i = 0; i < a.length; i += SPECIES.length()) {
4325                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4326                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4327                 av.lanewise(VectorOperators.POW, bv).intoArray(r, i);
4328             }
4329         }
4330 
4331         assertArraysEqualsWithinOneUlp(r, a, b, Double64VectorTests::POW, Double64VectorTests::strictPOW);
4332     }
4333 
4334 
4335     static double pow(double a, double b) {
4336         return (double)(Math.pow((double)a, (double)b));
4337     }
4338 
4339     static double strictpow(double a, double b) {
4340         return (double)(StrictMath.pow((double)a, (double)b));
4341     }
4342 
4343     @Test(dataProvider = "doubleBinaryOpProvider")
4344     static void powDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4345         double[] a = fa.apply(SPECIES.length());
4346         double[] b = fb.apply(SPECIES.length());
4347         double[] r = fr.apply(SPECIES.length());
4348 
4349         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4350             for (int i = 0; i < a.length; i += SPECIES.length()) {
4351                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4352                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4353                 av.pow(bv).intoArray(r, i);
4354             }
4355         }
4356 
4357         assertArraysEqualsWithinOneUlp(r, a, b, Double64VectorTests::pow, Double64VectorTests::strictpow);
4358     }
4359 
4360 
4361     static double ATAN2(double a, double b) {
4362         return (double)(Math.atan2((double)a, (double)b));
4363     }
4364 
4365     static double strictATAN2(double a, double b) {
4366         return (double)(StrictMath.atan2((double)a, (double)b));
4367     }
4368 
4369     @Test(dataProvider = "doubleBinaryOpProvider")
4370     static void ATAN2Double64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4371         double[] a = fa.apply(SPECIES.length());
4372         double[] b = fb.apply(SPECIES.length());
4373         double[] r = fr.apply(SPECIES.length());
4374 
4375         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4376             for (int i = 0; i < a.length; i += SPECIES.length()) {
4377                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4378                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4379                 av.lanewise(VectorOperators.ATAN2, bv).intoArray(r, i);
4380             }
4381         }
4382 
4383         assertArraysEqualsWithinOneUlp(r, a, b, Double64VectorTests::ATAN2, Double64VectorTests::strictATAN2);
4384     }
4385 
4386 
4387     @Test(dataProvider = "doubleBinaryOpProvider")
4388     static void POWDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4389         double[] a = fa.apply(SPECIES.length());
4390         double[] b = fb.apply(SPECIES.length());
4391         double[] r = fr.apply(SPECIES.length());
4392 
4393         for (int i = 0; i < a.length; i += SPECIES.length()) {
4394             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4395             av.lanewise(VectorOperators.POW, b[i]).intoArray(r, i);
4396         }
4397 
4398         assertBroadcastArraysEqualsWithinOneUlp(r, a, b, Double64VectorTests::POW, Double64VectorTests::strictPOW);
4399     }
4400 
4401 
4402     @Test(dataProvider = "doubleBinaryOpProvider")
4403     static void powDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4404         double[] a = fa.apply(SPECIES.length());
4405         double[] b = fb.apply(SPECIES.length());
4406         double[] r = fr.apply(SPECIES.length());
4407 
4408         for (int i = 0; i < a.length; i += SPECIES.length()) {
4409             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4410             av.pow(b[i]).intoArray(r, i);
4411         }
4412 
4413         assertBroadcastArraysEqualsWithinOneUlp(r, a, b, Double64VectorTests::pow, Double64VectorTests::strictpow);
4414     }
4415 
4416 
4417     static double FMA(double a, double b, double c) {
4418         return (double)(Math.fma(a, b, c));
4419     }
4420 
4421     static double fma(double a, double b, double c) {
4422         return (double)(Math.fma(a, b, c));
4423     }
4424 
4425     @Test(dataProvider = "doubleTernaryOpProvider")
4426     static void FMADouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4427         int count = INVOC_COUNT;
4428         switch ("FMA") {
4429         case "fma": case "lanewise_FMA":
4430            // Math.fma uses BigDecimal
4431            count = Math.max(5, count/20); break;
4432         }
4433         final int INVOC_COUNT = count;
4434         double[] a = fa.apply(SPECIES.length());
4435         double[] b = fb.apply(SPECIES.length());
4436         double[] c = fc.apply(SPECIES.length());
4437         double[] r = fr.apply(SPECIES.length());
4438 
4439         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4440             for (int i = 0; i < a.length; i += SPECIES.length()) {
4441                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4442                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4443                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4444                 av.lanewise(VectorOperators.FMA, bv, cv).intoArray(r, i);
4445             }
4446         }
4447 
4448         assertArraysEquals(r, a, b, c, Double64VectorTests::FMA);
4449     }
4450 
4451     @Test(dataProvider = "doubleTernaryOpProvider")
4452     static void fmaDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4453         int count = INVOC_COUNT;
4454         switch ("fma") {
4455         case "fma": case "lanewise_FMA":
4456            // Math.fma uses BigDecimal
4457            count = Math.max(5, count/20); break;
4458         }
4459         final int INVOC_COUNT = count;
4460         double[] a = fa.apply(SPECIES.length());
4461         double[] b = fb.apply(SPECIES.length());
4462         double[] c = fc.apply(SPECIES.length());
4463         double[] r = fr.apply(SPECIES.length());
4464 
4465         for (int i = 0; i < a.length; i += SPECIES.length()) {
4466             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4467             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4468             DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4469             av.fma(bv, cv).intoArray(r, i);
4470         }
4471 
4472         assertArraysEquals(r, a, b, c, Double64VectorTests::fma);
4473     }
4474 
4475     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4476     static void FMADouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<double[]> fb,
4477                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4478         int count = INVOC_COUNT;
4479         switch ("FMA") {
4480         case "fma": case "lanewise_FMA":
4481            // Math.fma uses BigDecimal
4482            count = Math.max(5, count/20); break;
4483         }
4484         final int INVOC_COUNT = count;
4485         double[] a = fa.apply(SPECIES.length());
4486         double[] b = fb.apply(SPECIES.length());
4487         double[] c = fc.apply(SPECIES.length());
4488         double[] r = fr.apply(SPECIES.length());
4489         boolean[] mask = fm.apply(SPECIES.length());
4490         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4491 
4492         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4493             for (int i = 0; i < a.length; i += SPECIES.length()) {
4494                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4495                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4496                 DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4497                 av.lanewise(VectorOperators.FMA, bv, cv, vmask).intoArray(r, i);
4498             }
4499         }
4500 
4501         assertArraysEquals(r, a, b, c, mask, Double64VectorTests::FMA);
4502     }
4503 
4504     @Test(dataProvider = "doubleTernaryOpProvider")
4505     static void FMADouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4506         double[] a = fa.apply(SPECIES.length());
4507         double[] b = fb.apply(SPECIES.length());
4508         double[] c = fc.apply(SPECIES.length());
4509         double[] r = fr.apply(SPECIES.length());
4510 
4511         for (int i = 0; i < a.length; i += SPECIES.length()) {
4512             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4513             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4514             av.lanewise(VectorOperators.FMA, bv, c[i]).intoArray(r, i);
4515         }
4516         assertBroadcastArraysEquals(r, a, b, c, Double64VectorTests::FMA);
4517     }
4518 
4519     @Test(dataProvider = "doubleTernaryOpProvider")
4520     static void FMADouble64VectorTestsAltBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4521         double[] a = fa.apply(SPECIES.length());
4522         double[] b = fb.apply(SPECIES.length());
4523         double[] c = fc.apply(SPECIES.length());
4524         double[] r = fr.apply(SPECIES.length());
4525 
4526         for (int i = 0; i < a.length; i += SPECIES.length()) {
4527             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4528             DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4529             av.lanewise(VectorOperators.FMA, b[i], cv).intoArray(r, i);
4530         }
4531         assertAltBroadcastArraysEquals(r, a, b, c, Double64VectorTests::FMA);
4532     }
4533 
4534     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4535     static void FMADouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4536                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4537         double[] a = fa.apply(SPECIES.length());
4538         double[] b = fb.apply(SPECIES.length());
4539         double[] c = fc.apply(SPECIES.length());
4540         double[] r = fr.apply(SPECIES.length());
4541         boolean[] mask = fm.apply(SPECIES.length());
4542         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4543 
4544         for (int i = 0; i < a.length; i += SPECIES.length()) {
4545             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4546             DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
4547             av.lanewise(VectorOperators.FMA, bv, c[i], vmask).intoArray(r, i);
4548         }
4549 
4550         assertBroadcastArraysEquals(r, a, b, c, mask, Double64VectorTests::FMA);
4551     }
4552 
4553     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4554     static void FMADouble64VectorTestsAltBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4555                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4556         double[] a = fa.apply(SPECIES.length());
4557         double[] b = fb.apply(SPECIES.length());
4558         double[] c = fc.apply(SPECIES.length());
4559         double[] r = fr.apply(SPECIES.length());
4560         boolean[] mask = fm.apply(SPECIES.length());
4561         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4562 
4563         for (int i = 0; i < a.length; i += SPECIES.length()) {
4564             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4565             DoubleVector cv = DoubleVector.fromArray(SPECIES, c, i);
4566             av.lanewise(VectorOperators.FMA, b[i], cv, vmask).intoArray(r, i);
4567         }
4568 
4569         assertAltBroadcastArraysEquals(r, a, b, c, mask, Double64VectorTests::FMA);
4570     }
4571 
4572     @Test(dataProvider = "doubleTernaryOpProvider")
4573     static void FMADouble64VectorTestsDoubleBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4574         int count = INVOC_COUNT;
4575         switch ("FMA") {
4576         case "fma": case "lanewise_FMA":
4577            // Math.fma uses BigDecimal
4578            count = Math.max(5, count/20); break;
4579         }
4580         final int INVOC_COUNT = count;
4581         double[] a = fa.apply(SPECIES.length());
4582         double[] b = fb.apply(SPECIES.length());
4583         double[] c = fc.apply(SPECIES.length());
4584         double[] r = fr.apply(SPECIES.length());
4585 
4586         for (int i = 0; i < a.length; i += SPECIES.length()) {
4587             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4588             av.lanewise(VectorOperators.FMA, b[i], c[i]).intoArray(r, i);
4589         }
4590 
4591         assertDoubleBroadcastArraysEquals(r, a, b, c, Double64VectorTests::FMA);
4592     }
4593 
4594     @Test(dataProvider = "doubleTernaryOpProvider")
4595     static void fmaDouble64VectorTestsDoubleBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
4596         int count = INVOC_COUNT;
4597         switch ("fma") {
4598         case "fma": case "lanewise_FMA":
4599            // Math.fma uses BigDecimal
4600            count = Math.max(5, count/20); break;
4601         }
4602         final int INVOC_COUNT = count;
4603         double[] a = fa.apply(SPECIES.length());
4604         double[] b = fb.apply(SPECIES.length());
4605         double[] c = fc.apply(SPECIES.length());
4606         double[] r = fr.apply(SPECIES.length());
4607 
4608         for (int i = 0; i < a.length; i += SPECIES.length()) {
4609             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4610             av.fma(b[i], c[i]).intoArray(r, i);
4611         }
4612 
4613         assertDoubleBroadcastArraysEquals(r, a, b, c, Double64VectorTests::fma);
4614     }
4615 
4616     @Test(dataProvider = "doubleTernaryOpMaskProvider")
4617     static void FMADouble64VectorTestsDoubleBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4618                                           IntFunction<double[]> fc, IntFunction<boolean[]> fm) {
4619         int count = INVOC_COUNT;
4620         switch ("FMA") {
4621         case "fma": case "lanewise_FMA":
4622            // Math.fma uses BigDecimal
4623            count = Math.max(5, count/20); break;
4624         }
4625         final int INVOC_COUNT = count;
4626         double[] a = fa.apply(SPECIES.length());
4627         double[] b = fb.apply(SPECIES.length());
4628         double[] c = fc.apply(SPECIES.length());
4629         double[] r = fr.apply(SPECIES.length());
4630         boolean[] mask = fm.apply(SPECIES.length());
4631         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4632 
4633         for (int i = 0; i < a.length; i += SPECIES.length()) {
4634             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4635             av.lanewise(VectorOperators.FMA, b[i], c[i], vmask).intoArray(r, i);
4636         }
4637 
4638         assertDoubleBroadcastArraysEquals(r, a, b, c, mask, Double64VectorTests::FMA);
4639     }
4640 
4641     static double NEG(double a) {
4642         return (double)(-((double)a));
4643     }
4644 
4645     static double neg(double a) {
4646         return (double)(-((double)a));
4647     }
4648 
4649     @Test(dataProvider = "doubleUnaryOpProvider")
4650     static void NEGDouble64VectorTests(IntFunction<double[]> fa) {
4651         double[] a = fa.apply(SPECIES.length());
4652         double[] r = fr.apply(SPECIES.length());
4653 
4654         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4655             for (int i = 0; i < a.length; i += SPECIES.length()) {
4656                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4657                 av.lanewise(VectorOperators.NEG).intoArray(r, i);
4658             }
4659         }
4660 
4661         assertArraysEquals(r, a, Double64VectorTests::NEG);
4662     }
4663 
4664     @Test(dataProvider = "doubleUnaryOpProvider")
4665     static void negDouble64VectorTests(IntFunction<double[]> fa) {
4666         double[] a = fa.apply(SPECIES.length());
4667         double[] r = fr.apply(SPECIES.length());
4668 
4669         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4670             for (int i = 0; i < a.length; i += SPECIES.length()) {
4671                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4672                 av.neg().intoArray(r, i);
4673             }
4674         }
4675 
4676         assertArraysEquals(r, a, Double64VectorTests::neg);
4677     }
4678 
4679     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4680     static void NEGMaskedDouble64VectorTests(IntFunction<double[]> fa,
4681                                                 IntFunction<boolean[]> fm) {
4682         double[] a = fa.apply(SPECIES.length());
4683         double[] r = fr.apply(SPECIES.length());
4684         boolean[] mask = fm.apply(SPECIES.length());
4685         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4686 
4687         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4688             for (int i = 0; i < a.length; i += SPECIES.length()) {
4689                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4690                 av.lanewise(VectorOperators.NEG, vmask).intoArray(r, i);
4691             }
4692         }
4693 
4694         assertArraysEquals(r, a, mask, Double64VectorTests::NEG);
4695     }
4696 
4697     static double ABS(double a) {
4698         return (double)(Math.abs((double)a));
4699     }
4700 
4701     static double abs(double a) {
4702         return (double)(Math.abs((double)a));
4703     }
4704 
4705     @Test(dataProvider = "doubleUnaryOpProvider")
4706     static void ABSDouble64VectorTests(IntFunction<double[]> fa) {
4707         double[] a = fa.apply(SPECIES.length());
4708         double[] r = fr.apply(SPECIES.length());
4709 
4710         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4711             for (int i = 0; i < a.length; i += SPECIES.length()) {
4712                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4713                 av.lanewise(VectorOperators.ABS).intoArray(r, i);
4714             }
4715         }
4716 
4717         assertArraysEquals(r, a, Double64VectorTests::ABS);
4718     }
4719 
4720     @Test(dataProvider = "doubleUnaryOpProvider")
4721     static void absDouble64VectorTests(IntFunction<double[]> fa) {
4722         double[] a = fa.apply(SPECIES.length());
4723         double[] r = fr.apply(SPECIES.length());
4724 
4725         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4726             for (int i = 0; i < a.length; i += SPECIES.length()) {
4727                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4728                 av.abs().intoArray(r, i);
4729             }
4730         }
4731 
4732         assertArraysEquals(r, a, Double64VectorTests::abs);
4733     }
4734 
4735     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4736     static void ABSMaskedDouble64VectorTests(IntFunction<double[]> fa,
4737                                                 IntFunction<boolean[]> fm) {
4738         double[] a = fa.apply(SPECIES.length());
4739         double[] r = fr.apply(SPECIES.length());
4740         boolean[] mask = fm.apply(SPECIES.length());
4741         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4742 
4743         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4744             for (int i = 0; i < a.length; i += SPECIES.length()) {
4745                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4746                 av.lanewise(VectorOperators.ABS, vmask).intoArray(r, i);
4747             }
4748         }
4749 
4750         assertArraysEquals(r, a, mask, Double64VectorTests::ABS);
4751     }
4752 
4753     static double SQRT(double a) {
4754         return (double)(Math.sqrt((double)a));
4755     }
4756 
4757     static double sqrt(double a) {
4758         return (double)(Math.sqrt((double)a));
4759     }
4760 
4761     @Test(dataProvider = "doubleUnaryOpProvider")
4762     static void SQRTDouble64VectorTests(IntFunction<double[]> fa) {
4763         double[] a = fa.apply(SPECIES.length());
4764         double[] r = fr.apply(SPECIES.length());
4765 
4766         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4767             for (int i = 0; i < a.length; i += SPECIES.length()) {
4768                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4769                 av.lanewise(VectorOperators.SQRT).intoArray(r, i);
4770             }
4771         }
4772 
4773         assertArraysEquals(r, a, Double64VectorTests::SQRT);
4774     }
4775 
4776     @Test(dataProvider = "doubleUnaryOpProvider")
4777     static void sqrtDouble64VectorTests(IntFunction<double[]> fa) {
4778         double[] a = fa.apply(SPECIES.length());
4779         double[] r = fr.apply(SPECIES.length());
4780 
4781         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4782             for (int i = 0; i < a.length; i += SPECIES.length()) {
4783                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4784                 av.sqrt().intoArray(r, i);
4785             }
4786         }
4787 
4788         assertArraysEquals(r, a, Double64VectorTests::sqrt);
4789     }
4790 
4791     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4792     static void SQRTMaskedDouble64VectorTests(IntFunction<double[]> fa,
4793                                                 IntFunction<boolean[]> fm) {
4794         double[] a = fa.apply(SPECIES.length());
4795         double[] r = fr.apply(SPECIES.length());
4796         boolean[] mask = fm.apply(SPECIES.length());
4797         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4798 
4799         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4800             for (int i = 0; i < a.length; i += SPECIES.length()) {
4801                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4802                 av.lanewise(VectorOperators.SQRT, vmask).intoArray(r, i);
4803             }
4804         }
4805 
4806         assertArraysEquals(r, a, mask, Double64VectorTests::SQRT);
4807     }
4808 
4809     @Test(dataProvider = "doubleCompareOpProvider")
4810     static void ltDouble64VectorTestsBroadcastSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4811         double[] a = fa.apply(SPECIES.length());
4812         double[] b = fb.apply(SPECIES.length());
4813 
4814         for (int i = 0; i < a.length; i += SPECIES.length()) {
4815             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4816             VectorMask<Double> mv = av.lt(b[i]);
4817 
4818             // Check results as part of computation.
4819             for (int j = 0; j < SPECIES.length(); j++) {
4820                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] < b[i]);
4821             }
4822         }
4823     }
4824 
4825     @Test(dataProvider = "doubleCompareOpProvider")
4826     static void eqDouble64VectorTestsBroadcastMaskedSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb) {
4827         double[] a = fa.apply(SPECIES.length());
4828         double[] b = fb.apply(SPECIES.length());
4829 
4830         for (int i = 0; i < a.length; i += SPECIES.length()) {
4831             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4832             VectorMask<Double> mv = av.eq(b[i]);
4833 
4834             // Check results as part of computation.
4835             for (int j = 0; j < SPECIES.length(); j++) {
4836                 Assert.assertEquals(mv.laneIsSet(j), a[i + j] == b[i]);
4837             }
4838         }
4839     }
4840 
4841     @Test(dataProvider = "doubletoIntUnaryOpProvider")
4842     static void toIntArrayDouble64VectorTestsSmokeTest(IntFunction<double[]> fa) {
4843         double[] a = fa.apply(SPECIES.length());
4844 
4845         for (int i = 0; i < a.length; i += SPECIES.length()) {
4846             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4847             int[] r = av.toIntArray();
4848             assertArraysEquals(r, a, i);
4849         }
4850     }
4851 
4852     @Test(dataProvider = "doubletoLongUnaryOpProvider")
4853     static void toLongArrayDouble64VectorTestsSmokeTest(IntFunction<double[]> fa) {
4854         double[] a = fa.apply(SPECIES.length());
4855 
4856         for (int i = 0; i < a.length; i += SPECIES.length()) {
4857             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4858             long[] r = av.toLongArray();
4859             assertArraysEquals(r, a, i);
4860         }
4861     }
4862 
4863 
4864     @Test(dataProvider = "doubleUnaryOpProvider")
4865     static void toStringDouble64VectorTestsSmokeTest(IntFunction<double[]> fa) {
4866         double[] a = fa.apply(SPECIES.length());
4867 
4868         for (int i = 0; i < a.length; i += SPECIES.length()) {
4869             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4870             String str = av.toString();
4871 
4872             double subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
4873             Assert.assertTrue(str.equals(Arrays.toString(subarr)), "at index " + i + ", string should be = " + Arrays.toString(subarr) + ", but is = " + str);
4874         }
4875     }
4876 
4877     @Test(dataProvider = "doubleUnaryOpProvider")
4878     static void hashCodeDouble64VectorTestsSmokeTest(IntFunction<double[]> fa) {
4879         double[] a = fa.apply(SPECIES.length());
4880 
4881         for (int i = 0; i < a.length; i += SPECIES.length()) {
4882             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4883             int hash = av.hashCode();
4884 
4885             double subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
4886             int expectedHash = Objects.hash(SPECIES, Arrays.hashCode(subarr));
4887             Assert.assertTrue(hash == expectedHash, "at index " + i + ", hash should be = " + expectedHash + ", but is = " + hash);
4888         }
4889     }
4890 
4891 
4892     static long ADDReduceLong(double[] a, int idx) {
4893         double res = 0;
4894         for (int i = idx; i < (idx + SPECIES.length()); i++) {
4895             res += a[i];
4896         }
4897 
4898         return (long)res;
4899     }
4900 
4901     static long ADDReduceAllLong(double[] a) {
4902         long res = 0;
4903         for (int i = 0; i < a.length; i += SPECIES.length()) {
4904             res += ADDReduceLong(a, i);
4905         }
4906 
4907         return res;
4908     }
4909 
4910     @Test(dataProvider = "doubleUnaryOpProvider")
4911     static void ADDReduceLongDouble64VectorTests(IntFunction<double[]> fa) {
4912         double[] a = fa.apply(SPECIES.length());
4913         long[] r = lfr.apply(SPECIES.length());
4914         long ra = 0;
4915 
4916         for (int i = 0; i < a.length; i += SPECIES.length()) {
4917             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4918             r[i] = av.reduceLanesToLong(VectorOperators.ADD);
4919         }
4920 
4921         ra = 0;
4922         for (int i = 0; i < a.length; i ++) {
4923             ra += r[i];
4924         }
4925 
4926         assertReductionLongArraysEquals(r, ra, a,
4927                 Double64VectorTests::ADDReduceLong, Double64VectorTests::ADDReduceAllLong);
4928     }
4929 
4930     static long ADDReduceLongMasked(double[] a, int idx, boolean[] mask) {
4931         double res = 0;
4932         for (int i = idx; i < (idx + SPECIES.length()); i++) {
4933             if(mask[i % SPECIES.length()])
4934                 res += a[i];
4935         }
4936 
4937         return (long)res;
4938     }
4939 
4940     static long ADDReduceAllLongMasked(double[] a, boolean[] mask) {
4941         long res = 0;
4942         for (int i = 0; i < a.length; i += SPECIES.length()) {
4943             res += ADDReduceLongMasked(a, i, mask);
4944         }
4945 
4946         return res;
4947     }
4948 
4949     @Test(dataProvider = "doubleUnaryOpMaskProvider")
4950     static void ADDReduceLongDouble64VectorTestsMasked(IntFunction<double[]> fa, IntFunction<boolean[]> fm) {
4951         double[] a = fa.apply(SPECIES.length());
4952         long[] r = lfr.apply(SPECIES.length());
4953         boolean[] mask = fm.apply(SPECIES.length());
4954         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4955         long ra = 0;
4956 
4957         for (int i = 0; i < a.length; i += SPECIES.length()) {
4958             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4959             r[i] = av.reduceLanesToLong(VectorOperators.ADD, vmask);
4960         }
4961 
4962         ra = 0;
4963         for (int i = 0; i < a.length; i ++) {
4964             ra += r[i];
4965         }
4966 
4967         assertReductionLongArraysEqualsMasked(r, ra, a, mask,
4968                 Double64VectorTests::ADDReduceLongMasked, Double64VectorTests::ADDReduceAllLongMasked);
4969     }
4970 
4971     @Test(dataProvider = "doubletoLongUnaryOpProvider")
4972     static void BroadcastLongDouble64VectorTestsSmokeTest(IntFunction<double[]> fa) {
4973         double[] a = fa.apply(SPECIES.length());
4974         double[] r = new double[a.length];
4975 
4976         for (int i = 0; i < a.length; i += SPECIES.length()) {
4977             DoubleVector.broadcast(SPECIES, (long)a[i]).intoArray(r, i);
4978         }
4979         assertBroadcastArraysEquals(r, a);
4980     }
4981 
4982     @Test(dataProvider = "doubleBinaryOpMaskProvider")
4983     static void blendDouble64VectorTestsBroadcastLongSmokeTest(IntFunction<double[]> fa, IntFunction<double[]> fb,
4984                                           IntFunction<boolean[]> fm) {
4985         double[] a = fa.apply(SPECIES.length());
4986         double[] b = fb.apply(SPECIES.length());
4987         double[] r = fr.apply(SPECIES.length());
4988         boolean[] mask = fm.apply(SPECIES.length());
4989         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
4990 
4991         for (int ic = 0; ic < INVOC_COUNT; ic++) {
4992             for (int i = 0; i < a.length; i += SPECIES.length()) {
4993                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
4994                 av.blend((long)b[i], vmask).intoArray(r, i);
4995             }
4996         }
4997         assertBroadcastLongArraysEquals(r, a, b, mask, Double64VectorTests::blend);
4998     }
4999 
5000 
5001     @Test(dataProvider = "doubleUnaryOpSelectFromProvider")
5002     static void SelectFromDouble64VectorTests(IntFunction<double[]> fa,
5003                                            BiFunction<Integer,Integer,double[]> fs) {
5004         double[] a = fa.apply(SPECIES.length());
5005         double[] order = fs.apply(a.length, SPECIES.length());
5006         double[] r = fr.apply(SPECIES.length());
5007 
5008         for (int i = 0; i < a.length; i += SPECIES.length()) {
5009             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
5010             DoubleVector bv = DoubleVector.fromArray(SPECIES, order, i);
5011             bv.selectFrom(av).intoArray(r, i);
5012         }
5013 
5014         assertSelectFromArraysEquals(r, a, order, SPECIES.length());
5015     }
5016 
5017     @Test(dataProvider = "doubleSelectFromTwoVectorOpProvider")
5018     static void SelectFromTwoVectorDouble64VectorTests(IntFunction<double[]> fa, IntFunction<double[]> fb, IntFunction<double[]> fc) {
5019         double[] a = fa.apply(SPECIES.length());
5020         double[] b = fb.apply(SPECIES.length());
5021         double[] idx = fc.apply(SPECIES.length());
5022         double[] r = fr.apply(SPECIES.length());
5023 
5024         for (int ic = 0; ic < INVOC_COUNT; ic++) {
5025             for (int i = 0; i < idx.length; i += SPECIES.length()) {
5026                 DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
5027                 DoubleVector bv = DoubleVector.fromArray(SPECIES, b, i);
5028                 DoubleVector idxv = DoubleVector.fromArray(SPECIES, idx, i);
5029                 idxv.selectFrom(av, bv).intoArray(r, i);
5030             }
5031         }
5032         assertSelectFromTwoVectorEquals(r, idx, a, b, SPECIES.length());
5033     }
5034 
5035     @Test(dataProvider = "doubleUnaryOpSelectFromMaskProvider")
5036     static void SelectFromDouble64VectorTestsMaskedSmokeTest(IntFunction<double[]> fa,
5037                                                            BiFunction<Integer,Integer,double[]> fs,
5038                                                            IntFunction<boolean[]> fm) {
5039         double[] a = fa.apply(SPECIES.length());
5040         double[] order = fs.apply(a.length, SPECIES.length());
5041         double[] r = fr.apply(SPECIES.length());
5042         boolean[] mask = fm.apply(SPECIES.length());
5043         VectorMask<Double> vmask = VectorMask.fromArray(SPECIES, mask, 0);
5044 
5045         for (int i = 0; i < a.length; i += SPECIES.length()) {
5046             DoubleVector av = DoubleVector.fromArray(SPECIES, a, i);
5047             DoubleVector bv = DoubleVector.fromArray(SPECIES, order, i);
5048             bv.selectFrom(av, vmask).intoArray(r, i);
5049         }
5050 
5051         assertSelectFromArraysEquals(r, a, order, mask, SPECIES.length());
5052     }
5053 
5054     @Test(dataProvider = "shuffleProvider")
5055     static void shuffleMiscellaneousDouble64VectorTestsSmokeTest(BiFunction<Integer,Integer,int[]> fs) {
5056         int[] a = fs.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5057 
5058         for (int i = 0; i < a.length; i += SPECIES.length()) {
5059             var shuffle = VectorShuffle.fromArray(SPECIES, a, i);
5060             int hash = shuffle.hashCode();
5061             int length = shuffle.length();
5062 
5063             int subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
5064             int expectedHash = Objects.hash(SPECIES, Arrays.hashCode(subarr));
5065             Assert.assertTrue(hash == expectedHash, "at index " + i + ", hash should be = " + expectedHash + ", but is = " + hash);
5066             Assert.assertEquals(length, SPECIES.length());
5067         }
5068     }
5069 
5070     @Test(dataProvider = "shuffleProvider")
5071     static void shuffleToStringDouble64VectorTestsSmokeTest(BiFunction<Integer,Integer,int[]> fs) {
5072         int[] a = fs.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5073 
5074         for (int i = 0; i < a.length; i += SPECIES.length()) {
5075             var shuffle = VectorShuffle.fromArray(SPECIES, a, i);
5076             String str = shuffle.toString();
5077 
5078             int subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
5079             Assert.assertTrue(str.equals("Shuffle" + Arrays.toString(subarr)), "at index " +
5080                 i + ", string should be = " + Arrays.toString(subarr) + ", but is = " + str);
5081         }
5082     }
5083 
5084     @Test(dataProvider = "shuffleCompareOpProvider")
5085     static void shuffleEqualsDouble64VectorTestsSmokeTest(BiFunction<Integer,Integer,int[]> fa, BiFunction<Integer,Integer,int[]> fb) {
5086         int[] a = fa.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5087         int[] b = fb.apply(SPECIES.length() * BUFFER_REPS, SPECIES.length());
5088 
5089         for (int i = 0; i < a.length; i += SPECIES.length()) {
5090             var av = VectorShuffle.fromArray(SPECIES, a, i);
5091             var bv = VectorShuffle.fromArray(SPECIES, b, i);
5092             boolean eq = av.equals(bv);
5093             int to = i + SPECIES.length();
5094             Assert.assertEquals(eq, Arrays.equals(a, i, to, b, i, to));
5095         }
5096     }
5097 
5098     @Test(dataProvider = "maskCompareOpProvider")
5099     static void maskEqualsDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5100         boolean[] a = fa.apply(SPECIES.length());
5101         boolean[] b = fb.apply(SPECIES.length());
5102 
5103         for (int i = 0; i < a.length; i += SPECIES.length()) {
5104             var av = SPECIES.loadMask(a, i);
5105             var bv = SPECIES.loadMask(b, i);
5106             boolean equals = av.equals(bv);
5107             int to = i + SPECIES.length();
5108             Assert.assertEquals(equals, Arrays.equals(a, i, to, b, i, to));
5109         }
5110     }
5111 
5112     static boolean band(boolean a, boolean b) {
5113         return a & b;
5114     }
5115 
5116     @Test(dataProvider = "maskCompareOpProvider")
5117     static void maskAndDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5118         boolean[] a = fa.apply(SPECIES.length());
5119         boolean[] b = fb.apply(SPECIES.length());
5120         boolean[] r = new boolean[a.length];
5121 
5122         for (int i = 0; i < a.length; i += SPECIES.length()) {
5123             var av = SPECIES.loadMask(a, i);
5124             var bv = SPECIES.loadMask(b, i);
5125             var cv = av.and(bv);
5126             cv.intoArray(r, i);
5127         }
5128         assertArraysEquals(r, a, b, Double64VectorTests::band);
5129     }
5130 
5131     static boolean bor(boolean a, boolean b) {
5132         return a | b;
5133     }
5134 
5135     @Test(dataProvider = "maskCompareOpProvider")
5136     static void maskOrDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5137         boolean[] a = fa.apply(SPECIES.length());
5138         boolean[] b = fb.apply(SPECIES.length());
5139         boolean[] r = new boolean[a.length];
5140 
5141         for (int i = 0; i < a.length; i += SPECIES.length()) {
5142             var av = SPECIES.loadMask(a, i);
5143             var bv = SPECIES.loadMask(b, i);
5144             var cv = av.or(bv);
5145             cv.intoArray(r, i);
5146         }
5147         assertArraysEquals(r, a, b, Double64VectorTests::bor);
5148     }
5149 
5150     static boolean bxor(boolean a, boolean b) {
5151         return a != b;
5152     }
5153 
5154     @Test(dataProvider = "maskCompareOpProvider")
5155     static void maskXorDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5156         boolean[] a = fa.apply(SPECIES.length());
5157         boolean[] b = fb.apply(SPECIES.length());
5158         boolean[] r = new boolean[a.length];
5159 
5160         for (int i = 0; i < a.length; i += SPECIES.length()) {
5161             var av = SPECIES.loadMask(a, i);
5162             var bv = SPECIES.loadMask(b, i);
5163             var cv = av.xor(bv);
5164             cv.intoArray(r, i);
5165         }
5166         assertArraysEquals(r, a, b, Double64VectorTests::bxor);
5167     }
5168 
5169     static boolean bandNot(boolean a, boolean b) {
5170         return a & !b;
5171     }
5172 
5173     @Test(dataProvider = "maskCompareOpProvider")
5174     static void maskAndNotDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5175         boolean[] a = fa.apply(SPECIES.length());
5176         boolean[] b = fb.apply(SPECIES.length());
5177         boolean[] r = new boolean[a.length];
5178 
5179         for (int i = 0; i < a.length; i += SPECIES.length()) {
5180             var av = SPECIES.loadMask(a, i);
5181             var bv = SPECIES.loadMask(b, i);
5182             var cv = av.andNot(bv);
5183             cv.intoArray(r, i);
5184         }
5185         assertArraysEquals(r, a, b, Double64VectorTests::bandNot);
5186     }
5187 
5188     static boolean beq(boolean a, boolean b) {
5189         return (a == b);
5190     }
5191 
5192     @Test(dataProvider = "maskCompareOpProvider")
5193     static void maskEqDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa, IntFunction<boolean[]> fb) {
5194         boolean[] a = fa.apply(SPECIES.length());
5195         boolean[] b = fb.apply(SPECIES.length());
5196         boolean[] r = new boolean[a.length];
5197 
5198         for (int i = 0; i < a.length; i += SPECIES.length()) {
5199             var av = SPECIES.loadMask(a, i);
5200             var bv = SPECIES.loadMask(b, i);
5201             var cv = av.eq(bv);
5202             cv.intoArray(r, i);
5203         }
5204         assertArraysEquals(r, a, b, Double64VectorTests::beq);
5205     }
5206 
5207     @Test(dataProvider = "maskProvider")
5208     static void maskHashCodeDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5209         boolean[] a = fa.apply(SPECIES.length());
5210 
5211         for (int i = 0; i < a.length; i += SPECIES.length()) {
5212             var vmask = SPECIES.loadMask(a, i);
5213             int hash = vmask.hashCode();
5214 
5215             boolean subarr[] = Arrays.copyOfRange(a, i, i + SPECIES.length());
5216             int expectedHash = Objects.hash(SPECIES, Arrays.hashCode(subarr));
5217             Assert.assertTrue(hash == expectedHash, "at index " + i + ", hash should be = " + expectedHash + ", but is = " + hash);
5218         }
5219     }
5220 
5221     static int maskTrueCount(boolean[] a, int idx) {
5222         int trueCount = 0;
5223         for (int i = idx; i < idx + SPECIES.length(); i++) {
5224             trueCount += a[i] ? 1 : 0;
5225         }
5226         return trueCount;
5227     }
5228 
5229     @Test(dataProvider = "maskProvider")
5230     static void maskTrueCountDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5231         boolean[] a = fa.apply(SPECIES.length());
5232         int[] r = new int[a.length];
5233 
5234         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5235             for (int i = 0; i < a.length; i += SPECIES.length()) {
5236                 var vmask = SPECIES.loadMask(a, i);
5237                 r[i] = vmask.trueCount();
5238             }
5239         }
5240 
5241         assertMaskReductionArraysEquals(r, a, Double64VectorTests::maskTrueCount);
5242     }
5243 
5244     static int maskLastTrue(boolean[] a, int idx) {
5245         int i = idx + SPECIES.length() - 1;
5246         for (; i >= idx; i--) {
5247             if (a[i]) {
5248                 break;
5249             }
5250         }
5251         return i - idx;
5252     }
5253 
5254     @Test(dataProvider = "maskProvider")
5255     static void maskLastTrueDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5256         boolean[] a = fa.apply(SPECIES.length());
5257         int[] r = new int[a.length];
5258 
5259         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5260             for (int i = 0; i < a.length; i += SPECIES.length()) {
5261                 var vmask = SPECIES.loadMask(a, i);
5262                 r[i] = vmask.lastTrue();
5263             }
5264         }
5265 
5266         assertMaskReductionArraysEquals(r, a, Double64VectorTests::maskLastTrue);
5267     }
5268 
5269     static int maskFirstTrue(boolean[] a, int idx) {
5270         int i = idx;
5271         for (; i < idx + SPECIES.length(); i++) {
5272             if (a[i]) {
5273                 break;
5274             }
5275         }
5276         return i - idx;
5277     }
5278 
5279     @Test(dataProvider = "maskProvider")
5280     static void maskFirstTrueDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5281         boolean[] a = fa.apply(SPECIES.length());
5282         int[] r = new int[a.length];
5283 
5284         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5285             for (int i = 0; i < a.length; i += SPECIES.length()) {
5286                 var vmask = SPECIES.loadMask(a, i);
5287                 r[i] = vmask.firstTrue();
5288             }
5289         }
5290 
5291         assertMaskReductionArraysEquals(r, a, Double64VectorTests::maskFirstTrue);
5292     }
5293 
5294     @Test(dataProvider = "maskProvider")
5295     static void maskCompressDouble64VectorTestsSmokeTest(IntFunction<boolean[]> fa) {
5296         int trueCount = 0;
5297         boolean[] a = fa.apply(SPECIES.length());
5298 
5299         for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
5300             for (int i = 0; i < a.length; i += SPECIES.length()) {
5301                 var vmask = SPECIES.loadMask(a, i);
5302                 trueCount = vmask.trueCount();
5303                 var rmask = vmask.compress();
5304                 for (int j = 0; j < SPECIES.length(); j++)  {
5305                     Assert.assertEquals(rmask.laneIsSet(j), j < trueCount);
5306                 }
5307             }
5308         }
5309     }
5310 
5311     @DataProvider
5312     public static Object[][] longMaskProvider() {
5313         return new Object[][]{
5314                 {0xFFFFFFFFFFFFFFFFL},
5315                 {0x0000000000000000L},
5316                 {0x5555555555555555L},
5317                 {0x0123456789abcdefL},
5318         };
5319     }
5320 
5321     @Test(dataProvider = "longMaskProvider")
5322     static void maskFromToLongDouble64VectorTestsSmokeTest(long inputLong) {
5323         var vmask = VectorMask.fromLong(SPECIES, inputLong);
5324         long outputLong = vmask.toLong();
5325         Assert.assertEquals(outputLong, (inputLong & (((0xFFFFFFFFFFFFFFFFL >>> (64 - SPECIES.length()))))));
5326     }
5327 
5328     @DataProvider
5329     public static Object[][] offsetProvider() {
5330         return new Object[][]{
5331                 {0},
5332                 {-1},
5333                 {+1},
5334                 {+2},
5335                 {-2},
5336         };
5337     }
5338 
5339     @Test(dataProvider = "offsetProvider")
5340     static void indexInRangeDouble64VectorTestsSmokeTest(int offset) {
5341         int limit = SPECIES.length() * BUFFER_REPS;
5342         for (int i = 0; i < limit; i += SPECIES.length()) {
5343             var actualMask = SPECIES.indexInRange(i + offset, limit);
5344             var expectedMask = SPECIES.maskAll(true).indexInRange(i + offset, limit);
5345             assert(actualMask.equals(expectedMask));
5346             for (int j = 0; j < SPECIES.length(); j++)  {
5347                 int index = i + j + offset;
5348                 Assert.assertEquals(actualMask.laneIsSet(j), index >= 0 && index < limit);
5349             }
5350         }
5351     }
5352 
5353     @Test(dataProvider = "offsetProvider")
5354     static void indexInRangeLongDouble64VectorTestsSmokeTest(int offset) {
5355         long limit = SPECIES.length() * BUFFER_REPS;
5356         for (long i = 0; i < limit; i += SPECIES.length()) {
5357             var actualMask = SPECIES.indexInRange(i + offset, limit);
5358             var expectedMask = SPECIES.maskAll(true).indexInRange(i + offset, limit);
5359             assert(actualMask.equals(expectedMask));
5360             for (int j = 0; j < SPECIES.length(); j++)  {
5361                 long index = i + j + offset;
5362                 Assert.assertEquals(actualMask.laneIsSet(j), index >= 0 && index < limit);
5363             }
5364         }
5365     }
5366 
5367     @DataProvider
5368     public static Object[][] lengthProvider() {
5369         return new Object[][]{
5370                 {0},
5371                 {1},
5372                 {32},
5373                 {37},
5374                 {1024},
5375                 {1024+1},
5376                 {1024+5},
5377         };
5378     }
5379 
5380     @Test(dataProvider = "lengthProvider")
5381     static void loopBoundDouble64VectorTestsSmokeTest(int length) {
5382         int actualLoopBound = SPECIES.loopBound(length);
5383         int expectedLoopBound = length - Math.floorMod(length, SPECIES.length());
5384         Assert.assertEquals(actualLoopBound, expectedLoopBound);
5385     }
5386 
5387     @Test(dataProvider = "lengthProvider")
5388     static void loopBoundLongDouble64VectorTestsSmokeTest(int _length) {
5389         long length = _length;
5390         long actualLoopBound = SPECIES.loopBound(length);
5391         long expectedLoopBound = length - Math.floorMod(length, SPECIES.length());
5392         Assert.assertEquals(actualLoopBound, expectedLoopBound);
5393     }
5394 
5395     @Test
5396     static void ElementSizeDouble64VectorTestsSmokeTest() {
5397         DoubleVector av = DoubleVector.zero(SPECIES);
5398         int elsize = av.elementSize();
5399         Assert.assertEquals(elsize, Double.SIZE);
5400     }
5401 
5402     @Test
5403     static void VectorShapeDouble64VectorTestsSmokeTest() {
5404         DoubleVector av = DoubleVector.zero(SPECIES);
5405         VectorShape vsh = av.shape();
5406         assert(vsh.equals(VectorShape.S_64_BIT));
5407     }
5408 
5409     @Test
5410     static void ShapeWithLanesDouble64VectorTestsSmokeTest() {
5411         DoubleVector av = DoubleVector.zero(SPECIES);
5412         VectorShape vsh = av.shape();
5413         VectorSpecies species = vsh.withLanes(double.class);
5414         assert(species.equals(SPECIES));
5415     }
5416 
5417     @Test
5418     static void ElementTypeDouble64VectorTestsSmokeTest() {
5419         DoubleVector av = DoubleVector.zero(SPECIES);
5420         assert(av.species().elementType() == double.class);
5421     }
5422 
5423     @Test
5424     static void SpeciesElementSizeDouble64VectorTestsSmokeTest() {
5425         DoubleVector av = DoubleVector.zero(SPECIES);
5426         assert(av.species().elementSize() == Double.SIZE);
5427     }
5428 
5429     @Test
5430     static void VectorTypeDouble64VectorTestsSmokeTest() {
5431         DoubleVector av = DoubleVector.zero(SPECIES);
5432         assert(av.species().vectorType() == av.getClass());
5433     }
5434 
5435     @Test
5436     static void WithLanesDouble64VectorTestsSmokeTest() {
5437         DoubleVector av = DoubleVector.zero(SPECIES);
5438         VectorSpecies species = av.species().withLanes(double.class);
5439         assert(species.equals(SPECIES));
5440     }
5441 
5442     @Test
5443     static void WithShapeDouble64VectorTestsSmokeTest() {
5444         DoubleVector av = DoubleVector.zero(SPECIES);
5445         VectorShape vsh = av.shape();
5446         VectorSpecies species = av.species().withShape(vsh);
5447         assert(species.equals(SPECIES));
5448     }
5449 
5450     @Test
5451     static void MaskAllTrueDouble64VectorTestsSmokeTest() {
5452         for (int ic = 0; ic < INVOC_COUNT; ic++) {
5453           Assert.assertEquals(SPECIES.maskAll(true).toLong(), -1L >>> (64 - SPECIES.length()));
5454         }
5455     }
5456 }