1 /*
   2  * Copyright (c) 2017, 2019, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.DoubleBuffer;
  29 import java.nio.ByteOrder;
  30 import java.util.Arrays;
  31 import java.util.Objects;
  32 import java.util.function.BinaryOperator;
  33 import java.util.function.IntUnaryOperator;
  34 import java.util.function.Function;
  35 import java.util.function.UnaryOperator;
  36 import java.util.concurrent.ThreadLocalRandom;
  37 
  38 import jdk.internal.misc.Unsafe;
  39 import jdk.internal.vm.annotation.ForceInline;
  40 
  41 import static jdk.incubator.vector.VectorIntrinsics.*;
  42 import static jdk.incubator.vector.VectorOperators.*;
  43 
  44 // -- This file was mechanically generated: Do not edit! -- //
  45 
  46 /**
  47  * A specialized {@link Vector} representing an ordered immutable sequence of
  48  * {@code double} values.
  49  */
  50 @SuppressWarnings("cast")  // warning: redundant cast
  51 public abstract class DoubleVector extends AbstractVector<Double> {
  52 
  53     DoubleVector() {}
  54 
  55     static final int FORBID_OPCODE_KIND = VO_NOFP;
  56 
  57     @ForceInline
  58     static int opCode(Operator op) {
  59         return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND);
  60     }
  61     @ForceInline
  62     static int opCode(Operator op, int requireKind) {
  63         requireKind |= VO_OPCODE_VALID;
  64         return VectorOperators.opCode(op, requireKind, FORBID_OPCODE_KIND);
  65     }
  66     @ForceInline
  67     static boolean opKind(Operator op, int bit) {
  68         return VectorOperators.opKind(op, bit);
  69     }
  70 
  71     // Virtualized factories and operators,
  72     // coded with portable definitions.
  73     // These are all @ForceInline in case
  74     // they need to be used performantly.
  75     // The various shape-specific subclasses
  76     // also specialize them by wrapping
  77     // them in a call like this:
  78     //    return (Byte128Vector)
  79     //       super.bOp((Byte128Vector) o);
  80     // The purpose of that is to forcibly inline
  81     // the generic definition from this file
  82     // into a sharply type- and size-specific
  83     // wrapper in the subclass file, so that
  84     // the JIT can specialize the code.
  85     // The code is only inlined and expanded
  86     // if it gets hot.  Think of it as a cheap
  87     // and lazy version of C++ templates.
  88 
  89     // Virtualized getter
  90 
  91     /*package-private*/
  92     abstract double[] getElements();
  93 
  94     // Virtualized constructors
  95 
  96     /**
  97      * Build a vector directly using my own constructor.
  98      * It is an error if the array is aliased elsewhere.
  99      */
 100     /*package-private*/
 101     abstract DoubleVector vectorFactory(double[] vec);
 102 
 103     /**
 104      * Build a mask directly using my species.
 105      * It is an error if the array is aliased elsewhere.
 106      */
 107     /*package-private*/
 108     @ForceInline
 109     final
 110     AbstractMask<Double> maskFactory(boolean[] bits) {
 111         return vspecies().maskFactory(bits);
 112     }
 113 
 114     // Constant loader (takes dummy as vector arg)
 115     interface FVOp {
 116         double apply(int i);
 117     }
 118 
 119     /*package-private*/
 120     @ForceInline
 121     final
 122     DoubleVector vOp(FVOp f) {
 123         double[] res = new double[length()];
 124         for (int i = 0; i < res.length; i++) {
 125             res[i] = f.apply(i);
 126         }
 127         return vectorFactory(res);
 128     }
 129 
 130     @ForceInline
 131     final
 132     DoubleVector vOp(VectorMask<Double> m, FVOp f) {
 133         double[] res = new double[length()];
 134         boolean[] mbits = ((AbstractMask<Double>)m).getBits();
 135         for (int i = 0; i < res.length; i++) {
 136             if (mbits[i]) {
 137                 res[i] = f.apply(i);
 138             }
 139         }
 140         return vectorFactory(res);
 141     }
 142 
 143     // Unary operator
 144 
 145     /*package-private*/
 146     interface FUnOp {
 147         double apply(int i, double a);
 148     }
 149 
 150     /*package-private*/
 151     abstract
 152     DoubleVector uOp(FUnOp f);
 153     @ForceInline
 154     final
 155     DoubleVector uOpTemplate(FUnOp f) {
 156         double[] vec = getElements();
 157         double[] res = new double[length()];
 158         for (int i = 0; i < res.length; i++) {
 159             res[i] = f.apply(i, vec[i]);
 160         }
 161         return vectorFactory(res);
 162     }
 163 
 164     /*package-private*/
 165     abstract
 166     DoubleVector uOp(VectorMask<Double> m,
 167                              FUnOp f);
 168     @ForceInline
 169     final
 170     DoubleVector uOpTemplate(VectorMask<Double> m,
 171                                      FUnOp f) {
 172         double[] vec = getElements();
 173         double[] res = new double[length()];
 174         boolean[] mbits = ((AbstractMask<Double>)m).getBits();
 175         for (int i = 0; i < res.length; i++) {
 176             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
 177         }
 178         return vectorFactory(res);
 179     }
 180 
 181     // Binary operator
 182 
 183     /*package-private*/
 184     interface FBinOp {
 185         double apply(int i, double a, double b);
 186     }
 187 
 188     /*package-private*/
 189     abstract
 190     DoubleVector bOp(Vector<Double> o,
 191                              FBinOp f);
 192     @ForceInline
 193     final
 194     DoubleVector bOpTemplate(Vector<Double> o,
 195                                      FBinOp f) {
 196         double[] res = new double[length()];
 197         double[] vec1 = this.getElements();
 198         double[] vec2 = ((DoubleVector)o).getElements();
 199         for (int i = 0; i < res.length; i++) {
 200             res[i] = f.apply(i, vec1[i], vec2[i]);
 201         }
 202         return vectorFactory(res);
 203     }
 204 
 205     /*package-private*/
 206     abstract
 207     DoubleVector bOp(Vector<Double> o,
 208                              VectorMask<Double> m,
 209                              FBinOp f);
 210     @ForceInline
 211     final
 212     DoubleVector bOpTemplate(Vector<Double> o,
 213                                      VectorMask<Double> m,
 214                                      FBinOp f) {
 215         double[] res = new double[length()];
 216         double[] vec1 = this.getElements();
 217         double[] vec2 = ((DoubleVector)o).getElements();
 218         boolean[] mbits = ((AbstractMask<Double>)m).getBits();
 219         for (int i = 0; i < res.length; i++) {
 220             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 221         }
 222         return vectorFactory(res);
 223     }
 224 
 225     // Ternary operator
 226 
 227     /*package-private*/
 228     interface FTriOp {
 229         double apply(int i, double a, double b, double c);
 230     }
 231 
 232     /*package-private*/
 233     abstract
 234     DoubleVector tOp(Vector<Double> o1,
 235                              Vector<Double> o2,
 236                              FTriOp f);
 237     @ForceInline
 238     final
 239     DoubleVector tOpTemplate(Vector<Double> o1,
 240                                      Vector<Double> o2,
 241                                      FTriOp f) {
 242         double[] res = new double[length()];
 243         double[] vec1 = this.getElements();
 244         double[] vec2 = ((DoubleVector)o1).getElements();
 245         double[] vec3 = ((DoubleVector)o2).getElements();
 246         for (int i = 0; i < res.length; i++) {
 247             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 248         }
 249         return vectorFactory(res);
 250     }
 251 
 252     /*package-private*/
 253     abstract
 254     DoubleVector tOp(Vector<Double> o1,
 255                              Vector<Double> o2,
 256                              VectorMask<Double> m,
 257                              FTriOp f);
 258     @ForceInline
 259     final
 260     DoubleVector tOpTemplate(Vector<Double> o1,
 261                                      Vector<Double> o2,
 262                                      VectorMask<Double> m,
 263                                      FTriOp f) {
 264         double[] res = new double[length()];
 265         double[] vec1 = this.getElements();
 266         double[] vec2 = ((DoubleVector)o1).getElements();
 267         double[] vec3 = ((DoubleVector)o2).getElements();
 268         boolean[] mbits = ((AbstractMask<Double>)m).getBits();
 269         for (int i = 0; i < res.length; i++) {
 270             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 271         }
 272         return vectorFactory(res);
 273     }
 274 
 275     // Reduction operator
 276 
 277     /*package-private*/
 278     abstract
 279     double rOp(double v, FBinOp f);
 280     @ForceInline
 281     final
 282     double rOpTemplate(double v, FBinOp f) {
 283         double[] vec = getElements();
 284         for (int i = 0; i < vec.length; i++) {
 285             v = f.apply(i, v, vec[i]);
 286         }
 287         return v;
 288     }
 289 
 290     // Memory reference
 291 
 292     /*package-private*/
 293     interface FLdOp<M> {
 294         double apply(M memory, int offset, int i);
 295     }
 296 
 297     /*package-private*/
 298     @ForceInline
 299     final
 300     <M> DoubleVector ldOp(M memory, int offset,
 301                                   FLdOp<M> f) {
 302         //dummy; no vec = getElements();
 303         double[] res = new double[length()];
 304         for (int i = 0; i < res.length; i++) {
 305             res[i] = f.apply(memory, offset, i);
 306         }
 307         return vectorFactory(res);
 308     }
 309 
 310     /*package-private*/
 311     @ForceInline
 312     final
 313     <M> DoubleVector ldOp(M memory, int offset,
 314                                   VectorMask<Double> m,
 315                                   FLdOp<M> f) {
 316         //double[] vec = getElements();
 317         double[] res = new double[length()];
 318         boolean[] mbits = ((AbstractMask<Double>)m).getBits();
 319         for (int i = 0; i < res.length; i++) {
 320             if (mbits[i]) {
 321                 res[i] = f.apply(memory, offset, i);
 322             }
 323         }
 324         return vectorFactory(res);
 325     }
 326 
 327     interface FStOp<M> {
 328         void apply(M memory, int offset, int i, double a);
 329     }
 330 
 331     /*package-private*/
 332     @ForceInline
 333     final
 334     <M> void stOp(M memory, int offset,
 335                   FStOp<M> f) {
 336         double[] vec = getElements();
 337         for (int i = 0; i < vec.length; i++) {
 338             f.apply(memory, offset, i, vec[i]);
 339         }
 340     }
 341 
 342     /*package-private*/
 343     @ForceInline
 344     final
 345     <M> void stOp(M memory, int offset,
 346                   VectorMask<Double> m,
 347                   FStOp<M> f) {
 348         double[] vec = getElements();
 349         boolean[] mbits = ((AbstractMask<Double>)m).getBits();
 350         for (int i = 0; i < vec.length; i++) {
 351             if (mbits[i]) {
 352                 f.apply(memory, offset, i, vec[i]);
 353             }
 354         }
 355     }
 356 
 357     // Binary test
 358 
 359     /*package-private*/
 360     interface FBinTest {
 361         boolean apply(int cond, int i, double a, double b);
 362     }
 363 
 364     /*package-private*/
 365     @ForceInline
 366     final
 367     AbstractMask<Double> bTest(int cond,
 368                                   Vector<Double> o,
 369                                   FBinTest f) {
 370         double[] vec1 = getElements();
 371         double[] vec2 = ((DoubleVector)o).getElements();
 372         boolean[] bits = new boolean[length()];
 373         for (int i = 0; i < length(); i++){
 374             bits[i] = f.apply(cond, i, vec1[i], vec2[i]);
 375         }
 376         return maskFactory(bits);
 377     }
 378 
 379     /*package-private*/
 380     @ForceInline
 381     static boolean doBinTest(int cond, double a, double b) {
 382         switch (cond) {
 383         case BT_eq:  return a == b;
 384         case BT_ne:  return a != b;
 385         case BT_lt:  return a < b;
 386         case BT_le:  return a <= b;
 387         case BT_gt:  return a > b;
 388         case BT_ge:  return a >= b;
 389         }
 390         throw new AssertionError(Integer.toHexString(cond));
 391     }
 392 
 393     /*package-private*/
 394     @Override
 395     abstract DoubleSpecies vspecies();
 396 
 397     /*package-private*/
 398     @ForceInline
 399     static long toBits(double e) {
 400         return  Double.doubleToLongBits(e);
 401     }
 402 
 403     /*package-private*/
 404     @ForceInline
 405     static double fromBits(long bits) {
 406         return Double.longBitsToDouble((long)bits);
 407     }
 408 
 409     // Static factories (other than memory operations)
 410 
 411     // Note: A surprising behavior in javadoc
 412     // sometimes makes a lone /** {@inheritDoc} */
 413     // comment drop the method altogether,
 414     // apparently if the method mentions an
 415     // parameter or return type of Vector<Double>
 416     // instead of Vector<E> as originally specified.
 417     // Adding an empty HTML fragment appears to
 418     // nudge javadoc into providing the desired
 419     // inherited documentation.  We use the HTML
 420     // comment <!--workaround--> for this.
 421 
 422     /**
 423      * {@inheritDoc} <!--workaround-->
 424      */
 425     @ForceInline
 426     public static DoubleVector zero(VectorSpecies<Double> species) {
 427         DoubleSpecies vsp = (DoubleSpecies) species;
 428         return VectorIntrinsics.broadcastCoerced(vsp.vectorType(), double.class, species.length(),
 429                         toBits(0.0f), vsp,
 430                         ((bits_, s_) -> s_.rvOp(i -> bits_)));
 431     }
 432 
 433     /**
 434      * Returns a vector of the same species as this one
 435      * where all lane elements are set to
 436      * the primitive value {@code e}.
 437      *
 438      * The contents of the current vector are discarded;
 439      * only the species is relevant to this operation.
 440      *
 441      * <p> This method returns the value of this expression:
 442      * {@code DoubleVector.broadcast(this.species(), e)}.
 443      *
 444      * @apiNote
 445      * Unlike the similar method named {@code broadcast()}
 446      * in the supertype {@code Vector}, this method does not
 447      * need to validate its argument, and cannot throw
 448      * {@code IllegalArgumentException}.  This method is
 449      * therefore preferable to the supertype method.
 450      *
 451      * @param e the value to broadcast
 452      * @return a vector where all lane elements are set to
 453      *         the primitive value {@code e}
 454      * @see #broadcast(VectorSpecies,long)
 455      * @see Vector#broadcast(long)
 456      * @see VectorSpecies#broadcast(long)
 457      */
 458     public abstract DoubleVector broadcast(double e);
 459 
 460     /**
 461      * Returns a vector of the given species
 462      * where all lane elements are set to
 463      * the primitive value {@code e}.
 464      *
 465      * @param species species of the desired vector
 466      * @param e the value to broadcast
 467      * @return a vector where all lane elements are set to
 468      *         the primitive value {@code e}
 469      * @see #broadcast(long)
 470      * @see Vector#broadcast(long)
 471      * @see VectorSpecies#broadcast(long)
 472      */
 473     public static DoubleVector broadcast(VectorSpecies<Double> species, double e) {
 474         DoubleSpecies vsp = (DoubleSpecies) species;
 475         return vsp.broadcast(e);
 476     }
 477 
 478     /*package-private*/
 479     @ForceInline
 480     final DoubleVector broadcastTemplate(double e) {
 481         DoubleSpecies vsp = vspecies();
 482         return vsp.broadcast(e);
 483     }
 484 
 485     /**
 486      * {@inheritDoc} <!--workaround-->
 487      * @apiNote
 488      * When working with vector subtypes like {@code DoubleVector},
 489      * {@linkplain #broadcast(double) the more strongly typed method}
 490      * is typically selected.  It can be explicitly selected
 491      * using a cast: {@code v.broadcast((double)e)}.
 492      * The two expressions will produce numerically identical results.
 493      */
 494     @Override
 495     public abstract DoubleVector broadcast(long e);
 496 
 497     /**
 498      * Returns a vector of the given species
 499      * where all lane elements are set to
 500      * the primitive value {@code e}.
 501      *
 502      * The {@code long} value must be accurately representable
 503      * by the {@code ETYPE} of the vector species, so that
 504      * {@code e==(long)(ETYPE)e}.
 505      *
 506      * @param species species of the desired vector
 507      * @param e the value to broadcast
 508      * @return a vector where all lane elements are set to
 509      *         the primitive value {@code e}
 510      * @throws IllegalArgumentException
 511      *         if the given {@code long} value cannot
 512      *         be represented by the vector's {@code ETYPE}
 513      * @see #broadcast(VectorSpecies,double)
 514      * @see VectorSpecies#checkValue(long)
 515      */
 516     public static DoubleVector broadcast(VectorSpecies<Double> species, long e) {
 517         DoubleSpecies vsp = (DoubleSpecies) species;
 518         return vsp.broadcast(e);
 519     }
 520 
 521     /*package-private*/
 522     @ForceInline
 523     final DoubleVector broadcastTemplate(long e) {
 524         return vspecies().broadcast(e);
 525     }
 526 
 527     /**
 528      * Returns a vector where each lane element is set to given
 529      * primitive values.
 530      * <p>
 531      * For each vector lane, where {@code N} is the vector lane index, the
 532      * the primitive value at index {@code N} is placed into the resulting
 533      * vector at lane index {@code N}.
 534      *
 535      * @param species species of the desired vector
 536      * @param es the given primitive values
 537      * @return a vector where each lane element is set to given primitive
 538      * values
 539      * @throws IllegalArgumentException
 540      *         if {@code es.length != species.length()}
 541      */
 542     @ForceInline
 543     @SuppressWarnings("unchecked")
 544     public static DoubleVector fromValues(VectorSpecies<Double> species, double... es) {
 545         DoubleSpecies vsp = (DoubleSpecies) species;
 546         int vlength = vsp.laneCount();
 547         VectorIntrinsics.requireLength(es.length, vlength);
 548         // Get an unaliased copy and use it directly:
 549         return vsp.vectorFactory(Arrays.copyOf(es, vlength));
 550     }
 551 
 552     /**
 553      * Returns a vector where the first lane element is set to the primtive
 554      * value {@code e}, all other lane elements are set to the default
 555      * value(positive zero).
 556      *
 557      * @param species species of the desired vector
 558      * @param e the value
 559      * @return a vector where the first lane element is set to the primitive
 560      * value {@code e}
 561      */
 562     // FIXME: Does this carry its weight?
 563     @ForceInline
 564     public static DoubleVector single(VectorSpecies<Double> species, double e) {
 565         return zero(species).withLane(0, e);
 566     }
 567 
 568     /**
 569      * Returns a vector where each lane element is set to a randomly
 570      * generated primitive value.
 571      *
 572      * The semantics are equivalent to calling
 573      * {@link ThreadLocalRandom#nextDouble()}
 574      * for each lane, from first to last.
 575      *
 576      * @param species species of the desired vector
 577      * @return a vector where each lane elements is set to a randomly
 578      * generated primitive value
 579      */
 580     public static DoubleVector random(VectorSpecies<Double> species) {
 581         DoubleSpecies vsp = (DoubleSpecies) species;
 582         ThreadLocalRandom r = ThreadLocalRandom.current();
 583         return vsp.vOp(i -> nextRandom(r));
 584     }
 585     private static double nextRandom(ThreadLocalRandom r) {
 586         return r.nextDouble();
 587     }
 588 
 589     // Unary lanewise support
 590 
 591     /**
 592      * {@inheritDoc} <!--workaround-->
 593      */
 594     public abstract
 595     DoubleVector lanewise(VectorOperators.Unary op);
 596 
 597     @ForceInline
 598     final
 599     DoubleVector lanewiseTemplate(VectorOperators.Unary op) {
 600         if (opKind(op, VO_SPECIAL)) {
 601             if (op == ZOMO) {
 602                 return blend(broadcast(-1), compare(NE, 0));
 603             }
 604         }
 605         int opc = opCode(op);
 606         return VectorIntrinsics.unaryOp(
 607             opc, getClass(), double.class, length(),
 608             this,
 609             UN_IMPL.find(op, opc, (opc_) -> {
 610               switch (opc_) {
 611                 case VECTOR_OP_NEG: return v0 ->
 612                         v0.uOp((i, a) -> (double) -a);
 613                 case VECTOR_OP_ABS: return v0 ->
 614                         v0.uOp((i, a) -> (double) Math.abs(a));
 615                 case VECTOR_OP_SIN: return v0 ->
 616                         v0.uOp((i, a) -> (double) Math.sin(a));
 617                 case VECTOR_OP_COS: return v0 ->
 618                         v0.uOp((i, a) -> (double) Math.cos(a));
 619                 case VECTOR_OP_TAN: return v0 ->
 620                         v0.uOp((i, a) -> (double) Math.tan(a));
 621                 case VECTOR_OP_ASIN: return v0 ->
 622                         v0.uOp((i, a) -> (double) Math.asin(a));
 623                 case VECTOR_OP_ACOS: return v0 ->
 624                         v0.uOp((i, a) -> (double) Math.acos(a));
 625                 case VECTOR_OP_ATAN: return v0 ->
 626                         v0.uOp((i, a) -> (double) Math.atan(a));
 627                 case VECTOR_OP_EXP: return v0 ->
 628                         v0.uOp((i, a) -> (double) Math.exp(a));
 629                 case VECTOR_OP_LOG: return v0 ->
 630                         v0.uOp((i, a) -> (double) Math.log(a));
 631                 case VECTOR_OP_LOG10: return v0 ->
 632                         v0.uOp((i, a) -> (double) Math.log10(a));
 633                 case VECTOR_OP_SQRT: return v0 ->
 634                         v0.uOp((i, a) -> (double) Math.sqrt(a));
 635                 case VECTOR_OP_CBRT: return v0 ->
 636                         v0.uOp((i, a) -> (double) Math.cbrt(a));
 637                 case VECTOR_OP_SINH: return v0 ->
 638                         v0.uOp((i, a) -> (double) Math.sinh(a));
 639                 case VECTOR_OP_COSH: return v0 ->
 640                         v0.uOp((i, a) -> (double) Math.cosh(a));
 641                 case VECTOR_OP_TANH: return v0 ->
 642                         v0.uOp((i, a) -> (double) Math.tanh(a));
 643                 case VECTOR_OP_EXPM1: return v0 ->
 644                         v0.uOp((i, a) -> (double) Math.expm1(a));
 645                 case VECTOR_OP_LOG1P: return v0 ->
 646                         v0.uOp((i, a) -> (double) Math.log1p(a));
 647                 default: return null;
 648               }}));
 649     }
 650     private static final
 651     ImplCache<Unary,UnaryOperator<DoubleVector>> UN_IMPL
 652         = new ImplCache<>(Unary.class, DoubleVector.class);
 653 
 654     /**
 655      * {@inheritDoc} <!--workaround-->
 656      */
 657     @ForceInline
 658     public final
 659     DoubleVector lanewise(VectorOperators.Unary op,
 660                                   VectorMask<Double> m) {
 661         return blend(lanewise(op), m);
 662     }
 663 
 664     // Binary lanewise support
 665 
 666     /**
 667      * {@inheritDoc} <!--workaround-->
 668      * @see #lanewise(VectorOperators.Binary,double)
 669      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
 670      */
 671     @Override
 672     public abstract
 673     DoubleVector lanewise(VectorOperators.Binary op,
 674                                   Vector<Double> v);
 675     @ForceInline
 676     final
 677     DoubleVector lanewiseTemplate(VectorOperators.Binary op,
 678                                           Vector<Double> v) {
 679         DoubleVector that = (DoubleVector) v;
 680         that.check(this);
 681         if (opKind(op, VO_SPECIAL )) {
 682             if (op == FIRST_NONZERO) {
 683                 // FIXME: Support this in the JIT.
 684                 VectorMask<Long> thisNZ
 685                     = this.viewAsIntegralLanes().compare(NE, (long) 0);
 686                 that = that.blend((double) 0, thisNZ.cast(vspecies()));
 687                 op = OR_UNCHECKED;
 688                 // FIXME: Support OR_UNCHECKED on float/double also!
 689                 return this.viewAsIntegralLanes()
 690                     .lanewise(op, that.viewAsIntegralLanes())
 691                     .viewAsFloatingLanes();
 692             }
 693         }
 694         int opc = opCode(op);
 695         return VectorIntrinsics.binaryOp(
 696             opc, getClass(), double.class, length(),
 697             this, that,
 698             BIN_IMPL.find(op, opc, (opc_) -> {
 699               switch (opc_) {
 700                 case VECTOR_OP_ADD: return (v0, v1) ->
 701                         v0.bOp(v1, (i, a, b) -> (double)(a + b));
 702                 case VECTOR_OP_SUB: return (v0, v1) ->
 703                         v0.bOp(v1, (i, a, b) -> (double)(a - b));
 704                 case VECTOR_OP_MUL: return (v0, v1) ->
 705                         v0.bOp(v1, (i, a, b) -> (double)(a * b));
 706                 case VECTOR_OP_DIV: return (v0, v1) ->
 707                         v0.bOp(v1, (i, a, b) -> (double)(a / b));
 708                 case VECTOR_OP_MAX: return (v0, v1) ->
 709                         v0.bOp(v1, (i, a, b) -> (double)Math.max(a, b));
 710                 case VECTOR_OP_MIN: return (v0, v1) ->
 711                         v0.bOp(v1, (i, a, b) -> (double)Math.min(a, b));
 712                 case VECTOR_OP_FIRST_NONZERO: return (v0, v1) ->
 713                         v0.bOp(v1, (i, a, b) -> toBits(a) != 0 ? a : b);
 714                 case VECTOR_OP_OR: return (v0, v1) ->
 715                         v0.bOp(v1, (i, a, b) -> fromBits(toBits(a) | toBits(b)));
 716                 case VECTOR_OP_ATAN2: return (v0, v1) ->
 717                         v0.bOp(v1, (i, a, b) -> (double) Math.atan2(a, b));
 718                 case VECTOR_OP_POW: return (v0, v1) ->
 719                         v0.bOp(v1, (i, a, b) -> (double) Math.pow(a, b));
 720                 case VECTOR_OP_HYPOT: return (v0, v1) ->
 721                         v0.bOp(v1, (i, a, b) -> (double) Math.hypot(a, b));
 722                 default: return null;
 723                 }}));
 724     }
 725     private static final
 726     ImplCache<Binary,BinaryOperator<DoubleVector>> BIN_IMPL
 727         = new ImplCache<>(Binary.class, DoubleVector.class);
 728 
 729     /**
 730      * {@inheritDoc} <!--workaround-->
 731      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
 732      */
 733     @ForceInline
 734     public final
 735     DoubleVector lanewise(VectorOperators.Binary op,
 736                                   Vector<Double> v,
 737                                   VectorMask<Double> m) {
 738         return blend(lanewise(op, v), m);
 739     }
 740     // FIXME: Maybe all of the public final methods in this file (the
 741     // simple ones that just call lanewise) should be pushed down to
 742     // the X-VectorBits template.  They can't optimize properly at
 743     // this level, and must rely on inlining.  Does it work?
 744     // (If it works, of course keep the code here.)
 745 
 746     /**
 747      * Combines the lane values of this vector
 748      * with the value of a broadcast scalar.
 749      *
 750      * This is a lane-wise binary operation which applies
 751      * the selected operation to each lane.
 752      * The return value will be equal to this expression:
 753      * {@code this.lanewise(op, this.broadcast(e))}.
 754      *
 755      * @param op the operation used to process lane values
 756      * @param e the input scalar
 757      * @return the result of applying the operation lane-wise
 758      *         to the two input vectors
 759      * @throws UnsupportedOperationException if this vector does
 760      *         not support the requested operation
 761      * @see #lanewise(VectorOperators.Binary,Vector)
 762      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
 763      */
 764     @ForceInline
 765     public final
 766     DoubleVector lanewise(VectorOperators.Binary op,
 767                                   double e) {
 768         int opc = opCode(op);
 769         return lanewise(op, broadcast(e));
 770     }
 771 
 772     /**
 773      * Combines the lane values of this vector
 774      * with the value of a broadcast scalar,
 775      * with selection of lane elements controlled by a mask.
 776      *
 777      * This is a masked lane-wise binary operation which applies
 778      * the selected operation to each lane.
 779      * The return value will be equal to this expression:
 780      * {@code this.lanewise(op, this.broadcast(e), m)}.
 781      *
 782      * @param op the operation used to process lane values
 783      * @param e the input scalar
 784      * @param m the mask controlling lane selection
 785      * @return the result of applying the operation lane-wise
 786      *         to the input vector and the scalar
 787      * @throws UnsupportedOperationException if this vector does
 788      *         not support the requested operation
 789      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
 790      * @see #lanewise(VectorOperators.Binary,double)
 791      */
 792     @ForceInline
 793     public final
 794     DoubleVector lanewise(VectorOperators.Binary op,
 795                                   double e,
 796                                   VectorMask<Double> m) {
 797         return blend(lanewise(op, e), m);
 798     }
 799 
 800     /**
 801      * {@inheritDoc} <!--workaround-->
 802      * @apiNote
 803      * When working with vector subtypes like {@code DoubleVector},
 804      * {@linkplain #lanewise(VectorOperators.Binary,double)
 805      * the more strongly typed method}
 806      * is typically selected.  It can be explicitly selected
 807      * using a cast: {@code v.lanewise(op,(double)e)}.
 808      * The two expressions will produce numerically identical results.
 809      */
 810     @ForceInline
 811     public final
 812     DoubleVector lanewise(VectorOperators.Binary op,
 813                                   long e) {
 814         double e1 = (double) e;
 815         if ((long)e1 != e
 816             ) {
 817             vspecies().checkValue(e);  // for exception
 818         }
 819         return lanewise(op, e1);
 820     }
 821 
 822     /**
 823      * {@inheritDoc} <!--workaround-->
 824      * @apiNote
 825      * When working with vector subtypes like {@code DoubleVector},
 826      * {@linkplain #lanewise(VectorOperators.Binary,double,VectorMask)
 827      * the more strongly typed method}
 828      * is typically selected.  It can be explicitly selected
 829      * using a cast: {@code v.lanewise(op,(double)e,m)}.
 830      * The two expressions will produce numerically identical results.
 831      */
 832     @ForceInline
 833     public final
 834     DoubleVector lanewise(VectorOperators.Binary op,
 835                                   long e, VectorMask<Double> m) {
 836         return blend(lanewise(op, e), m);
 837     }
 838 
 839 
 840     // Ternary lanewise support
 841 
 842     // Ternary operators come in eight variations:
 843     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2])
 844     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask)
 845 
 846     // It is annoying to support all of these variations of masking
 847     // and broadcast, but it would be more surprising not to continue
 848     // the obvious pattern started by unary and binary.
 849 
 850    /**
 851      * {@inheritDoc} <!--workaround-->
 852      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
 853      * @see #lanewise(VectorOperators.Ternary,Vector,double,VectorMask)
 854      * @see #lanewise(VectorOperators.Ternary,double,Vector,VectorMask)
 855      * @see #lanewise(VectorOperators.Ternary,double,double)
 856      * @see #lanewise(VectorOperators.Ternary,Vector,double)
 857      * @see #lanewise(VectorOperators.Ternary,double,Vector)
 858      */
 859     @Override
 860     public abstract
 861     DoubleVector lanewise(VectorOperators.Ternary op,
 862                                                   Vector<Double> v1,
 863                                                   Vector<Double> v2);
 864     @ForceInline
 865     final
 866     DoubleVector lanewiseTemplate(VectorOperators.Ternary op,
 867                                           Vector<Double> v1,
 868                                           Vector<Double> v2) {
 869         DoubleVector that = (DoubleVector) v1;
 870         DoubleVector tother = (DoubleVector) v2;
 871         // It's a word: https://www.dictionary.com/browse/tother
 872         // See also Chapter 11 of Dickens, Our Mutual Friend:
 873         // "Totherest Governor," replied Mr Riderhood...
 874         that.check(this);
 875         tother.check(this);
 876         int opc = opCode(op);
 877         return VectorIntrinsics.ternaryOp(
 878             opc, getClass(), double.class, length(),
 879             this, that, tother,
 880             TERN_IMPL.find(op, opc, (opc_) -> {
 881               switch (opc_) {
 882                 case VECTOR_OP_FMA: return (v0, v1_, v2_) ->
 883                         v0.tOp(v1_, v2_, (i, a, b, c) -> Math.fma(a, b, c));
 884                 default: return null;
 885                 }}));
 886     }
 887     private static final
 888     ImplCache<Ternary,TernaryOperation<DoubleVector>> TERN_IMPL
 889         = new ImplCache<>(Ternary.class, DoubleVector.class);
 890 
 891     /**
 892      * {@inheritDoc} <!--workaround-->
 893      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
 894      * @see #lanewise(VectorOperators.Ternary,Vector,double,VectorMask)
 895      * @see #lanewise(VectorOperators.Ternary,double,Vector,VectorMask)
 896      */
 897     @ForceInline
 898     public final
 899     DoubleVector lanewise(VectorOperators.Ternary op,
 900                                   Vector<Double> v1,
 901                                   Vector<Double> v2,
 902                                   VectorMask<Double> m) {
 903         return blend(lanewise(op, v1, v2), m);
 904     }
 905 
 906     /**
 907      * Combines the lane values of this vector
 908      * with the values of two broadcast scalars.
 909      *
 910      * This is a lane-wise ternary operation which applies
 911      * the selected operation to each lane.
 912      * The return value will be equal to this expression:
 913      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}.
 914      *
 915      * @param op the operation used to combine lane values
 916      * @param e1 the first input scalar
 917      * @param e2 the second input scalar
 918      * @return the result of applying the operation lane-wise
 919      *         to the input vector and the scalars
 920      * @throws UnsupportedOperationException if this vector does
 921      *         not support the requested operation
 922      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 923      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
 924      */
 925     @ForceInline
 926     public final
 927     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,e2)
 928                                   double e1,
 929                                   double e2) {
 930         return lanewise(op, broadcast(e1), broadcast(e2));
 931     }
 932 
 933     /**
 934      * Combines the lane values of this vector
 935      * with the values of two broadcast scalars,
 936      * with selection of lane elements controlled by a mask.
 937      *
 938      * This is a masked lane-wise ternary operation which applies
 939      * the selected operation to each lane.
 940      * The return value will be equal to this expression:
 941      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}.
 942      *
 943      * @param op the operation used to combine lane values
 944      * @param e1 the first input scalar
 945      * @param e2 the second input scalar
 946      * @param m the mask controlling lane selection
 947      * @return the result of applying the operation lane-wise
 948      *         to the input vector and the scalars
 949      * @throws UnsupportedOperationException if this vector does
 950      *         not support the requested operation
 951      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
 952      * @see #lanewise(VectorOperators.Ternary,double,double)
 953      */
 954     @ForceInline
 955     public final
 956     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m)
 957                                   double e1,
 958                                   double e2,
 959                                   VectorMask<Double> m) {
 960         return blend(lanewise(op, e1, e2), m);
 961     }
 962 
 963     /**
 964      * Combines the lane values of this vector
 965      * with the values of another vector and a broadcast scalar.
 966      *
 967      * This is a lane-wise ternary operation which applies
 968      * the selected operation to each lane.
 969      * The return value will be equal to this expression:
 970      * {@code this.lanewise(op, v1, this.broadcast(e2))}.
 971      *
 972      * @param op the operation used to combine lane values
 973      * @param v1 the other input vector
 974      * @param e2 the input scalar
 975      * @return the result of applying the operation lane-wise
 976      *         to the input vectors and the scalar
 977      * @throws UnsupportedOperationException if this vector does
 978      *         not support the requested operation
 979      * @see #lanewise(VectorOperators.Ternary,double,double)
 980      * @see #lanewise(VectorOperators.Ternary,Vector,double,VectorMask)
 981      */
 982     @ForceInline
 983     public final
 984     DoubleVector lanewise(VectorOperators.Ternary op, //(op,v1,e2)
 985                                   Vector<Double> v1,
 986                                   double e2) {
 987         return lanewise(op, v1, broadcast(e2));
 988     }
 989 
 990     /**
 991      * Combines the lane values of this vector
 992      * with the values of another vector and a broadcast scalar,
 993      * with selection of lane elements controlled by a mask.
 994      *
 995      * This is a masked lane-wise ternary operation which applies
 996      * the selected operation to each lane.
 997      * The return value will be equal to this expression:
 998      * {@code this.lanewise(op, v1, this.broadcast(e2), m)}.
 999      *
1000      * @param op the operation used to combine lane values
1001      * @param v1 the other input vector
1002      * @param e2 the input scalar
1003      * @param m the mask controlling lane selection
1004      * @return the result of applying the operation lane-wise
1005      *         to the input vectors and the scalar
1006      * @throws UnsupportedOperationException if this vector does
1007      *         not support the requested operation
1008      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1009      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
1010      * @see #lanewise(VectorOperators.Ternary,Vector,double)
1011      */
1012     @ForceInline
1013     public final
1014     DoubleVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m)
1015                                   Vector<Double> v1,
1016                                   double e2,
1017                                   VectorMask<Double> m) {
1018         return blend(lanewise(op, v1, e2), m);
1019     }
1020 
1021     /**
1022      * Combines the lane values of this vector
1023      * with the values of another vector and a broadcast scalar.
1024      *
1025      * This is a lane-wise ternary operation which applies
1026      * the selected operation to each lane.
1027      * The return value will be equal to this expression:
1028      * {@code this.lanewise(op, this.broadcast(e1), v2)}.
1029      *
1030      * @param op the operation used to combine lane values
1031      * @param e1 the input scalar
1032      * @param v2 the other input vector
1033      * @return the result of applying the operation lane-wise
1034      *         to the input vectors and the scalar
1035      * @throws UnsupportedOperationException if this vector does
1036      *         not support the requested operation
1037      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1038      * @see #lanewise(VectorOperators.Ternary,double,Vector,VectorMask)
1039      */
1040     @ForceInline
1041     public final
1042     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,v2)
1043                                   double e1,
1044                                   Vector<Double> v2) {
1045         return lanewise(op, broadcast(e1), v2);
1046     }
1047 
1048     /**
1049      * Combines the lane values of this vector
1050      * with the values of another vector and a broadcast scalar,
1051      * with selection of lane elements controlled by a mask.
1052      *
1053      * This is a masked lane-wise ternary operation which applies
1054      * the selected operation to each lane.
1055      * The return value will be equal to this expression:
1056      * {@code this.lanewise(op, this.broadcast(e1), v2, m)}.
1057      *
1058      * @param op the operation used to combine lane values
1059      * @param e1 the input scalar
1060      * @param v2 the other input vector
1061      * @param m the mask controlling lane selection
1062      * @return the result of applying the operation lane-wise
1063      *         to the input vectors and the scalar
1064      * @throws UnsupportedOperationException if this vector does
1065      *         not support the requested operation
1066      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
1067      * @see #lanewise(VectorOperators.Ternary,double,Vector)
1068      */
1069     @ForceInline
1070     public final
1071     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m)
1072                                   double e1,
1073                                   Vector<Double> v2,
1074                                   VectorMask<Double> m) {
1075         return blend(lanewise(op, e1, v2), m);
1076     }
1077 
1078     // (Thus endeth the Great and Mighty Ternary Ogdoad.)
1079     // https://en.wikipedia.org/wiki/Ogdoad
1080 
1081     /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV
1082     //
1083     // These include masked and non-masked versions.
1084     // This subclass adds broadcast (masked or not).
1085 
1086     /**
1087      * {@inheritDoc} <!--workaround-->
1088      * @see #add(double)
1089      */
1090     @Override
1091     @ForceInline
1092     public final DoubleVector add(Vector<Double> v) {
1093         return lanewise(ADD, v);
1094     }
1095 
1096     /**
1097      * Adds this vector to the broadcast of an input scalar.
1098      *
1099      * This is a lane-wise binary operation which applies
1100      * the primitive addition operation ({@code +}) to each lane.
1101      *
1102      * This method is also equivalent to the expression
1103      * {@link #lanewise(VectorOperators.Binary,double)
1104      *    lanewise}{@code (}{@link VectorOperators#ADD
1105      *    ADD}{@code , e)}.
1106      *
1107      * @param e the input scalar
1108      * @return the result of adding each lane of this vector to the scalar
1109      * @see #add(Vector)
1110      * @see #broadcast(double)
1111      * @see #add(double,VectorMask)
1112      * @see VectorOperators#ADD
1113      * @see #lanewise(VectorOperators.Binary,Vector)
1114      * @see #lanewise(VectorOperators.Binary,double)
1115      */
1116     @ForceInline
1117     public final
1118     DoubleVector add(double e) {
1119         return lanewise(ADD, e);
1120     }
1121 
1122     /**
1123      * {@inheritDoc} <!--workaround-->
1124      * @see #add(double,VectorMask)
1125      */
1126     @Override
1127     @ForceInline
1128     public final DoubleVector add(Vector<Double> v,
1129                                           VectorMask<Double> m) {
1130         return lanewise(ADD, v, m);
1131     }
1132 
1133     /**
1134      * Adds this vector to the broadcast of an input scalar,
1135      * selecting lane elements controlled by a mask.
1136      *
1137      * This is a masked lane-wise binary operation which applies
1138      * the primitive addition operation ({@code +}) to each lane.
1139      *
1140      * This method is also equivalent to the expression
1141      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1142      *    lanewise}{@code (}{@link VectorOperators#ADD
1143      *    ADD}{@code , s, m)}.
1144      *
1145      * @param e the input scalar
1146      * @param m the mask controlling lane selection
1147      * @return the result of adding each lane of this vector to the scalar
1148      * @see #add(Vector,VectorMask)
1149      * @see #broadcast(double)
1150      * @see #add(double)
1151      * @see VectorOperators#ADD
1152      * @see #lanewise(VectorOperators.Binary,Vector)
1153      * @see #lanewise(VectorOperators.Binary,double)
1154      */
1155     @ForceInline
1156     public final DoubleVector add(double e,
1157                                           VectorMask<Double> m) {
1158         return lanewise(ADD, e, m);
1159     }
1160 
1161     /**
1162      * {@inheritDoc} <!--workaround-->
1163      * @see #sub(double)
1164      */
1165     @Override
1166     @ForceInline
1167     public final DoubleVector sub(Vector<Double> v) {
1168         return lanewise(SUB, v);
1169     }
1170 
1171     /**
1172      * Subtracts an input scalar from this vector.
1173      *
1174      * This is a masked lane-wise binary operation which applies
1175      * the primitive subtraction operation ({@code -}) to each lane.
1176      *
1177      * This method is also equivalent to the expression
1178      * {@link #lanewise(VectorOperators.Binary,double)
1179      *    lanewise}{@code (}{@link VectorOperators#SUB
1180      *    SUB}{@code , e)}.
1181      *
1182      * @param e the input scalar
1183      * @return the result of subtracting the scalar from each lane of this vector
1184      * @see #sub(Vector)
1185      * @see #broadcast(double)
1186      * @see #sub(double,VectorMask)
1187      * @see VectorOperators#SUB
1188      * @see #lanewise(VectorOperators.Binary,Vector)
1189      * @see #lanewise(VectorOperators.Binary,double)
1190      */
1191     @ForceInline
1192     public final DoubleVector sub(double e) {
1193         return lanewise(SUB, e);
1194     }
1195 
1196     /**
1197      * {@inheritDoc} <!--workaround-->
1198      * @see #sub(double,VectorMask)
1199      */
1200     @Override
1201     @ForceInline
1202     public final DoubleVector sub(Vector<Double> v,
1203                                           VectorMask<Double> m) {
1204         return lanewise(SUB, v, m);
1205     }
1206 
1207     /**
1208      * Subtracts an input scalar from this vector
1209      * under the control of a mask.
1210      *
1211      * This is a masked lane-wise binary operation which applies
1212      * the primitive subtraction operation ({@code -}) to each lane.
1213      *
1214      * This method is also equivalent to the expression
1215      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1216      *    lanewise}{@code (}{@link VectorOperators#SUB
1217      *    SUB}{@code , s, m)}.
1218      *
1219      * @param e the input scalar
1220      * @param m the mask controlling lane selection
1221      * @return the result of subtracting the scalar from each lane of this vector
1222      * @see #sub(Vector,VectorMask)
1223      * @see #broadcast(double)
1224      * @see #sub(double)
1225      * @see VectorOperators#SUB
1226      * @see #lanewise(VectorOperators.Binary,Vector)
1227      * @see #lanewise(VectorOperators.Binary,double)
1228      */
1229     @ForceInline
1230     public final DoubleVector sub(double e,
1231                                           VectorMask<Double> m) {
1232         return lanewise(SUB, e, m);
1233     }
1234 
1235     /**
1236      * {@inheritDoc} <!--workaround-->
1237      * @see #mul(double)
1238      */
1239     @Override
1240     @ForceInline
1241     public final DoubleVector mul(Vector<Double> v) {
1242         return lanewise(MUL, v);
1243     }
1244 
1245     /**
1246      * Multiplies this vector by the broadcast of an input scalar.
1247      *
1248      * This is a lane-wise binary operation which applies
1249      * the primitive multiplication operation ({@code *}) to each lane.
1250      *
1251      * This method is also equivalent to the expression
1252      * {@link #lanewise(VectorOperators.Binary,double)
1253      *    lanewise}{@code (}{@link VectorOperators#MUL
1254      *    MUL}{@code , e)}.
1255      *
1256      * @param e the input scalar
1257      * @return the result of multiplying this vector by the given scalar
1258      * @see #mul(Vector)
1259      * @see #broadcast(double)
1260      * @see #mul(double,VectorMask)
1261      * @see VectorOperators#MUL
1262      * @see #lanewise(VectorOperators.Binary,Vector)
1263      * @see #lanewise(VectorOperators.Binary,double)
1264      */
1265     @ForceInline
1266     public final DoubleVector mul(double e) {
1267         return lanewise(MUL, e);
1268     }
1269 
1270     /**
1271      * {@inheritDoc} <!--workaround-->
1272      * @see #mul(double,VectorMask)
1273      */
1274     @Override
1275     @ForceInline
1276     public final DoubleVector mul(Vector<Double> v,
1277                                           VectorMask<Double> m) {
1278         return lanewise(MUL, v, m);
1279     }
1280 
1281     /**
1282      * Multiplies this vector by the broadcast of an input scalar,
1283      * selecting lane elements controlled by a mask.
1284      *
1285      * This is a masked lane-wise binary operation which applies
1286      * the primitive multiplication operation ({@code *}) to each lane.
1287      *
1288      * This method is also equivalent to the expression
1289      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1290      *    lanewise}{@code (}{@link VectorOperators#MUL
1291      *    MUL}{@code , s, m)}.
1292      *
1293      * @param e the input scalar
1294      * @param m the mask controlling lane selection
1295      * @return the result of muling each lane of this vector to the scalar
1296      * @see #mul(Vector,VectorMask)
1297      * @see #broadcast(double)
1298      * @see #mul(double)
1299      * @see VectorOperators#MUL
1300      * @see #lanewise(VectorOperators.Binary,Vector)
1301      * @see #lanewise(VectorOperators.Binary,double)
1302      */
1303     @ForceInline
1304     public final DoubleVector mul(double e,
1305                                           VectorMask<Double> m) {
1306         return lanewise(MUL, e, m);
1307     }
1308 
1309     /**
1310      * {@inheritDoc} <!--workaround-->
1311      * @apiNote Because the underlying scalar operator is an IEEE
1312      * floating point number, division by zero in fact will
1313      * not throw an exception, but will yield a signed
1314      * infinity or NaN.
1315      */
1316     @Override
1317     @ForceInline
1318     public final DoubleVector div(Vector<Double> v) {
1319         return lanewise(DIV, v);
1320     }
1321 
1322     /**
1323      * Divides this vector by the broadcast of an input scalar.
1324      *
1325      * This is a lane-wise binary operation which applies
1326      * the primitive division operation ({@code /}) to each lane.
1327      *
1328      * This method is also equivalent to the expression
1329      * {@link #lanewise(VectorOperators.Binary,double)
1330      *    lanewise}{@code (}{@link VectorOperators#DIV
1331      *    DIV}{@code , e)}.
1332      *
1333      * @apiNote Because the underlying scalar operator is an IEEE
1334      * floating point number, division by zero in fact will
1335      * not throw an exception, but will yield a signed
1336      * infinity or NaN.
1337      * @see #div(double)
1338 
1339      *
1340      * @param e the input scalar
1341      * @return the result of dividing each lane of this vector by the scalar
1342      * @see #div(Vector)
1343      * @see #broadcast(double)
1344      * @see #div(double,VectorMask)
1345      * @see VectorOperators#DIV
1346      * @see #lanewise(VectorOperators.Binary,Vector)
1347      * @see #lanewise(VectorOperators.Binary,double)
1348      */
1349     @ForceInline
1350     public final DoubleVector div(double e) {
1351         return lanewise(DIV, e);
1352     }
1353 
1354     /**
1355      * {@inheritDoc} <!--workaround-->
1356      * @see #div(double,VectorMask)
1357      * @apiNote Because the underlying scalar operator is an IEEE
1358      * floating point number, division by zero in fact will
1359      * not throw an exception, but will yield a signed
1360      * infinity or NaN.
1361      */
1362     @Override
1363     @ForceInline
1364     public final DoubleVector div(Vector<Double> v,
1365                                           VectorMask<Double> m) {
1366         return lanewise(DIV, v, m);
1367     }
1368 
1369     /**
1370      * Divides this vector by the broadcast of an input scalar,
1371      * selecting lane elements controlled by a mask.
1372      *
1373      * This is a masked lane-wise binary operation which applies
1374      * the primitive division operation ({@code /}) to each lane.
1375      *
1376      * This method is also equivalent to the expression
1377      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1378      *    lanewise}{@code (}{@link VectorOperators#DIV
1379      *    DIV}{@code , s, m)}.
1380      *
1381      * @apiNote Because the underlying scalar operator is an IEEE
1382      * floating point number, division by zero in fact will
1383      * not throw an exception, but will yield a signed
1384      * infinity or NaN.
1385      *
1386      * @param e the input scalar
1387      * @param m the mask controlling lane selection
1388      * @return the result of dividing each lane of this vector by the scalar
1389      * @see #div(Vector,VectorMask)
1390      * @see #broadcast(double)
1391      * @see #div(double)
1392      * @see VectorOperators#DIV
1393      * @see #lanewise(VectorOperators.Binary,Vector)
1394      * @see #lanewise(VectorOperators.Binary,double)
1395      */
1396     @ForceInline
1397     public final DoubleVector div(double e,
1398                                           VectorMask<Double> m) {
1399         return lanewise(DIV, e, m);
1400     }
1401 
1402     /// END OF FULL-SERVICE BINARY METHODS
1403 
1404     /// SECOND-TIER BINARY METHODS
1405     //
1406     // There are no masked versions.
1407 
1408     /**
1409      * {@inheritDoc} <!--workaround-->
1410      * @apiNote
1411      * For this method, floating point negative
1412      * zero {@code -0.0} is treated as a value distinct from, and less
1413      * than the default value(positive zero).
1414      */
1415     @Override
1416     @ForceInline
1417     public final DoubleVector min(Vector<Double> v) {
1418         return lanewise(MIN, v);
1419     }
1420 
1421     // FIXME:  "broadcast of an input scalar" is really wordy.  Reduce?
1422     /**
1423      * Computes the smaller of this vector and the broadcast of an input scalar.
1424      *
1425      * This is a lane-wise binary operation which applies the
1426      * operation {@code Math.min()} to each pair of
1427      * corresponding lane values.
1428      *
1429      * This method is also equivalent to the expression
1430      * {@link #lanewise(VectorOperators.Binary,double)
1431      *    lanewise}{@code (}{@link VectorOperators#MIN
1432      *    MIN}{@code , e)}.
1433      *
1434      * @param e the input scalar
1435      * @return the result of multiplying this vector by the given scalar
1436      * @see #min(Vector)
1437      * @see #broadcast(double)
1438      * @see VectorOperators#MIN
1439      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
1440      * @apiNote
1441      * For this method, floating point negative
1442      * zero {@code -0.0} is treated as a value distinct from, and less
1443      * than the default value(positive zero).
1444      */
1445     @ForceInline
1446     public final DoubleVector min(double e) {
1447         return lanewise(MIN, e);
1448     }
1449 
1450     /**
1451      * {@inheritDoc} <!--workaround-->
1452      * @apiNote
1453      * For this method, negative floating-point zero compares
1454      * less than the default value, positive zero.
1455      */
1456     @Override
1457     @ForceInline
1458     public final DoubleVector max(Vector<Double> v) {
1459         return lanewise(MAX, v);
1460     }
1461 
1462     /**
1463      * Computes the larger of this vector and the broadcast of an input scalar.
1464      *
1465      * This is a lane-wise binary operation which applies the
1466      * operation {@code Math.max()} to each pair of
1467      * corresponding lane values.
1468      *
1469      * This method is also equivalent to the expression
1470      * {@link #lanewise(VectorOperators.Binary,double)
1471      *    lanewise}{@code (}{@link VectorOperators#MAX
1472      *    MAX}{@code , e)}.
1473      *
1474      * @param e the input scalar
1475      * @return the result of multiplying this vector by the given scalar
1476      * @see #max(Vector)
1477      * @see #broadcast(double)
1478      * @see VectorOperators#MAX
1479      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
1480      * @apiNote
1481      * For this method, negative floating-point zero compares
1482      * less than the default value, positive zero.
1483      */
1484     @ForceInline
1485     public final DoubleVector max(double e) {
1486         return lanewise(MAX, e);
1487     }
1488 
1489 
1490     // common FP operator: pow
1491     /**
1492      * Raises this vector to the power of a second input vector.
1493      *
1494      * This is a lane-wise binary operation which applies the
1495      * method {@code Math.pow()}
1496      * to each pair of corresponding lane values.
1497      *
1498      * This method is also equivalent to the expression
1499      * {@link #lanewise(VectorOperators.Binary,Vector)
1500      *    lanewise}{@code (}{@link VectorOperators#POW
1501      *    POW}{@code , n)}.
1502      *
1503      * <p>
1504      * This is not a full-service named operation like
1505      * {@link #add(Vector) add}.  A masked version of
1506      * version of this operation is not directly available
1507      * but may be obtained via the masked version of
1508      * {@code lanewise}.
1509      *
1510      * @param n a vector exponent by which to raise this vector
1511      * @return the {@code n}-th power of this vector
1512      * @see #pow(double)
1513      * @see VectorOperators#POW
1514      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
1515      */
1516     @ForceInline
1517     public final DoubleVector pow(Vector<Double> n) {
1518         return lanewise(POW, n);
1519     }
1520 
1521     /**
1522      * Raises this vector to a scalar power.
1523      *
1524      * This is a lane-wise binary operation which applies the
1525      * method {@code Math.pow()}
1526      * to each pair of corresponding lane values.
1527      *
1528      * This method is also equivalent to the expression
1529      * {@link #lanewise(VectorOperators.Binary,Vector)
1530      *    lanewise}{@code (}{@link VectorOperators#POW
1531      *    POW}{@code , n)}.
1532      *
1533      * @param n a scalar exponent by which to raise this vector
1534      * @return the {@code n}-th power of this vector
1535      * @see #pow(Vector)
1536      * @see VectorOperators#POW
1537      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
1538      */
1539     @ForceInline
1540     public final DoubleVector pow(double n) {
1541         return lanewise(POW, n);
1542     }
1543 
1544     /// UNARY METHODS
1545 
1546     /**
1547      * {@inheritDoc} <!--workaround-->
1548      */
1549     @Override
1550     @ForceInline
1551     public final
1552     DoubleVector neg() {
1553         return lanewise(NEG);
1554     }
1555 
1556     /**
1557      * {@inheritDoc} <!--workaround-->
1558      */
1559     @Override
1560     @ForceInline
1561     public final
1562     DoubleVector abs() {
1563         return lanewise(ABS);
1564     }
1565 
1566 
1567     // sqrt
1568     /**
1569      * Computes the square root of this vector.
1570      *
1571      * This is a lane-wise unary operation which applies the
1572      * the method {@code Math.sqrt()}
1573      * to each lane value.
1574      *
1575      * This method is also equivalent to the expression
1576      * {@link #lanewise(VectorOperators.Unary)
1577      *    lanewise}{@code (}{@link VectorOperators#SQRT
1578      *    SQRT}{@code )}.
1579      *
1580      * @return the square root of this vector
1581      * @see VectorOperators#SQRT
1582      * @see #lanewise(VectorOperators.Unary,VectorMask)
1583      */
1584     @ForceInline
1585     public final DoubleVector sqrt() {
1586         return lanewise(SQRT);
1587     }
1588 
1589     /// COMPARISONS
1590 
1591     /**
1592      * {@inheritDoc} <!--workaround-->
1593      */
1594     @Override
1595     @ForceInline
1596     public final
1597     VectorMask<Double> eq(Vector<Double> v) {
1598         return compare(EQ, v);
1599     }
1600 
1601     /**
1602      * Tests if this vector is equal to an input scalar.
1603      *
1604      * This is a lane-wise binary test operation which applies
1605      * the primitive equals operation ({@code ==}) to each lane.
1606      * The result is the same as {@code compare(VectorOperators.Comparison.EQ, e)}.
1607      *
1608      * @param e the input scalar
1609      * @return the result mask of testing if this vector
1610      *         is equal to {@code e}
1611      * @see #compare(VectorOperators.Comparison,double)
1612      */
1613     @ForceInline
1614     public final
1615     VectorMask<Double> eq(double e) {
1616         return compare(EQ, e);
1617     }
1618 
1619     /**
1620      * {@inheritDoc} <!--workaround-->
1621      */
1622     @Override
1623     @ForceInline
1624     public final
1625     VectorMask<Double> lt(Vector<Double> v) {
1626         return compare(LT, v);
1627     }
1628 
1629     /**
1630      * Tests if this vector is less than an input scalar.
1631      *
1632      * This is a lane-wise binary test operation which applies
1633      * the primitive less than operation ({@code <}) to each lane.
1634      * The result is the same as {@code compare(VectorOperators.LT, e)}.
1635      *
1636      * @param e the input scalar
1637      * @return the mask result of testing if this vector
1638      *         is less than the input scalar
1639      * @see #compare(VectorOperators.Comparison,double)
1640      */
1641     @ForceInline
1642     public final
1643     VectorMask<Double> lt(double e) {
1644         return compare(LT, e);
1645     }
1646 
1647     /**
1648      * {@inheritDoc} <!--workaround-->
1649      */
1650     @Override
1651     public abstract
1652     VectorMask<Double> test(VectorOperators.Test op);
1653 
1654     /*package-private*/
1655     @ForceInline
1656     final
1657     <M extends VectorMask<Double>>
1658     M testTemplate(Class<M> maskType, Test op) {
1659         DoubleSpecies vsp = vspecies();
1660         if (opKind(op, VO_SPECIAL)) {
1661             LongVector bits = this.viewAsIntegralLanes();
1662             VectorMask<Long> m;
1663             if (op == IS_DEFAULT) {
1664                 m = bits.compare(EQ, (long) 0);
1665             } else if (op == IS_NEGATIVE) {
1666                 m = bits.compare(LT, (long) 0);
1667             }
1668             else if (op == IS_FINITE ||
1669                      op == IS_NAN ||
1670                      op == IS_INFINITE) {
1671                 // first kill the sign:
1672                 bits = bits.and(Long.MAX_VALUE);
1673                 // next find the bit pattern for infinity:
1674                 long infbits = (long) toBits(Double.POSITIVE_INFINITY);
1675                 // now compare:
1676                 if (op == IS_FINITE) {
1677                     m = bits.compare(LT, infbits);
1678                 } else if (op == IS_NAN) {
1679                     m = bits.compare(GT, infbits);
1680                 } else {
1681                     m = bits.compare(EQ, infbits);
1682                 }
1683             }
1684             else {
1685                 throw new AssertionError(op);
1686             }
1687             return maskType.cast(m.cast(this.vspecies()));
1688         }
1689         int opc = opCode(op);
1690         throw new AssertionError(op);
1691     }
1692 
1693     /**
1694      * {@inheritDoc} <!--workaround-->
1695      */
1696     @Override
1697     @ForceInline
1698     public final
1699     VectorMask<Double> test(VectorOperators.Test op,
1700                                   VectorMask<Double> m) {
1701         return test(op).and(m);
1702     }
1703 
1704     /**
1705      * {@inheritDoc} <!--workaround-->
1706      */
1707     @Override
1708     public abstract
1709     VectorMask<Double> compare(VectorOperators.Comparison op, Vector<Double> v);
1710 
1711     /*package-private*/
1712     @ForceInline
1713     final
1714     <M extends VectorMask<Double>>
1715     M compareTemplate(Class<M> maskType, Comparison op, Vector<Double> v) {
1716         Objects.requireNonNull(v);
1717         DoubleSpecies vsp = vspecies();
1718         DoubleVector that = (DoubleVector) v;
1719         that.check(this);
1720         int opc = opCode(op);
1721         return VectorIntrinsics.compare(
1722             opc, getClass(), maskType, double.class, length(),
1723             this, that,
1724             (cond, v0, v1) -> {
1725                 AbstractMask<Double> m
1726                     = v0.bTest(cond, v1, (cond_, i, a, b)
1727                                -> compareWithOp(cond, a, b));
1728                 @SuppressWarnings("unchecked")
1729                 M m2 = (M) m;
1730                 return m2;
1731             });
1732     }
1733 
1734     @ForceInline
1735     private static
1736     boolean compareWithOp(int cond, double a, double b) {
1737         switch (cond) {
1738         case VectorIntrinsics.BT_eq:  return a == b;
1739         case VectorIntrinsics.BT_ne:  return a != b;
1740         case VectorIntrinsics.BT_lt:  return a <  b;
1741         case VectorIntrinsics.BT_le:  return a <= b;
1742         case VectorIntrinsics.BT_gt:  return a >  b;
1743         case VectorIntrinsics.BT_ge:  return a >= b;
1744         }
1745         throw new AssertionError();
1746     }
1747 
1748     /**
1749      * {@inheritDoc} <!--workaround-->
1750      */
1751     @Override
1752     @ForceInline
1753     public final
1754     VectorMask<Double> compare(VectorOperators.Comparison op,
1755                                   Vector<Double> v,
1756                                   VectorMask<Double> m) {
1757         return compare(op, v).and(m);
1758     }
1759 
1760     /**
1761      * Tests this vector by comparing it with an input scalar,
1762      * according to the given comparison operation.
1763      *
1764      * This is a lane-wise binary test operation which applies
1765      * the comparison operation to each lane.
1766      * <p>
1767      * The result is the same as
1768      * {@code compare(op, broadcast(species(), e))}.
1769      * That is, the scalar may be regarded as broadcast to
1770      * a vector of the same species, and then compared
1771      * against the original vector, using the selected
1772      * comparison operation.
1773      *
1774      * @param op the operation used to compare lane values
1775      * @param e the input scalar
1776      * @return the mask result of testing lane-wise if this vector
1777      *         compares to the input, according to the selected
1778      *         comparison operator
1779      * @see DoubleVector#compare(VectorOperators.Comparison,Vector)
1780      * @see #eq(double)
1781      * @see #lt(double)
1782      */
1783     public abstract
1784     VectorMask<Double> compare(Comparison op, double e);
1785 
1786     /*package-private*/
1787     @ForceInline
1788     final
1789     <M extends VectorMask<Double>>
1790     M compareTemplate(Class<M> maskType, Comparison op, double e) {
1791         return compareTemplate(maskType, op, broadcast(e));
1792     }
1793 
1794     /**
1795      * Tests this vector by comparing it with an input scalar,
1796      * according to the given comparison operation,
1797      * in lanes selected by a mask.
1798      *
1799      * This is a masked lane-wise binary test operation which applies
1800      * to each pair of corresponding lane values.
1801      *
1802      * The returned result is equal to the expression
1803      * {@code compare(op,s).and(m)}.
1804      *
1805      * @param op the operation used to compare lane values
1806      * @param e the input scalar
1807      * @param m the mask controlling lane selection
1808      * @return the mask result of testing lane-wise if this vector
1809      *         compares to the input, according to the selected
1810      *         comparison operator,
1811      *         and only in the lanes selected by the mask
1812      * @see DoubleVector#compare(VectorOperators.Comparison,Vector,VectorMask)
1813      */
1814     @ForceInline
1815     public final VectorMask<Double> compare(VectorOperators.Comparison op,
1816                                                double e,
1817                                                VectorMask<Double> m) {
1818         return compare(op, e).and(m);
1819     }
1820 
1821     /**
1822      * {@inheritDoc} <!--workaround-->
1823      */
1824     @Override
1825     public abstract
1826     VectorMask<Double> compare(Comparison op, long e);
1827 
1828     /*package-private*/
1829     @ForceInline
1830     final
1831     <M extends VectorMask<Double>>
1832     M compareTemplate(Class<M> maskType, Comparison op, long e) {
1833         return compareTemplate(maskType, op, broadcast(e));
1834     }
1835 
1836     /**
1837      * {@inheritDoc} <!--workaround-->
1838      */
1839     @Override
1840     @ForceInline
1841     public final
1842     VectorMask<Double> compare(Comparison op, long e, VectorMask<Double> m) {
1843         return compare(op, broadcast(e), m);
1844     }
1845 
1846 
1847 
1848     /**
1849      * {@inheritDoc} <!--workaround-->
1850      */
1851     @Override public abstract
1852     DoubleVector blend(Vector<Double> v, VectorMask<Double> m);
1853 
1854     /*package-private*/
1855     @ForceInline
1856     final
1857     <M extends VectorMask<Double>>
1858     DoubleVector
1859     blendTemplate(Class<M> maskType, DoubleVector v, M m) {
1860         v.check(this);
1861         return VectorIntrinsics.blend(
1862             getClass(), maskType, double.class, length(),
1863             this, v, m,
1864             (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b));
1865     }
1866 
1867     /**
1868      * {@inheritDoc} <!--workaround-->
1869      */
1870     @Override public abstract DoubleVector addIndex(int scale);
1871 
1872     /*package-private*/
1873     @ForceInline
1874     final DoubleVector addIndexTemplate(int scale) {
1875         DoubleSpecies vsp = vspecies();
1876         // make sure VLENGTH*scale doesn't overflow:
1877         vsp.checkScale(scale);
1878         return VectorIntrinsics.indexVector(
1879             getClass(), double.class, length(),
1880             this, scale, vsp,
1881             (v, scale_, s)
1882             -> {
1883                 // If the platform doesn't support an INDEX
1884                 // instruction directly, load IOTA from memory
1885                 // and multiply.
1886                 DoubleVector iota = s.iota();
1887                 double sc = (double) scale_;
1888                 return v.add(sc == 1 ? iota : iota.mul(sc));
1889             });
1890     }
1891 
1892     /**
1893      * Replaces selected lanes of this vector with
1894      * a scalar value
1895      * under the control of a mask.
1896      *
1897      * This is a masked lane-wise binary operation which
1898      * selects each lane value from one or the other input.
1899      *
1900      * The returned result is equal to the expression
1901      * {@code blend(broadcast(e),m)}.
1902      *
1903      * @param e the input scalar, containing the replacement lane value
1904      * @param m the mask controlling lane selection of the scalar
1905      * @return the result of blending the lane elements of this vector with
1906      *         the scalar value
1907      */
1908     @ForceInline
1909     public final DoubleVector blend(double e,
1910                                             VectorMask<Double> m) {
1911         return blend(broadcast(e), m);
1912     }
1913 
1914     /**
1915      * Replaces selected lanes of this vector with
1916      * a scalar value
1917      * under the control of a mask.
1918      *
1919      * This is a masked lane-wise binary operation which
1920      * selects each lane value from one or the other input.
1921      *
1922      * The returned result is equal to the expression
1923      * {@code blend(broadcast(e),m)}.
1924      *
1925      * @param e the input scalar, containing the replacement lane value
1926      * @param m the mask controlling lane selection of the scalar
1927      * @return the result of blending the lane elements of this vector with
1928      *         the scalar value
1929      */
1930     @ForceInline
1931     public final DoubleVector blend(long e,
1932                                             VectorMask<Double> m) {
1933         return blend(broadcast(e), m);
1934     }
1935 
1936     /**
1937      * {@inheritDoc} <!--workaround-->
1938      */
1939     @Override
1940     public abstract
1941     DoubleVector slice(int origin, Vector<Double> v1);
1942 
1943     /*package-private*/
1944     final
1945     @ForceInline
1946     DoubleVector sliceTemplate(int origin, Vector<Double> v1) {
1947         DoubleVector that = (DoubleVector) v1;
1948         that.check(this);
1949         double[] a0 = this.getElements();
1950         double[] a1 = that.getElements();
1951         double[] res = new double[a0.length];
1952         int vlen = res.length;
1953         int firstPart = vlen - origin;
1954         System.arraycopy(a0, origin, res, 0, firstPart);
1955         System.arraycopy(a1, 0, res, firstPart, origin);
1956         return vectorFactory(res);
1957     }
1958 
1959     /**
1960      * {@inheritDoc} <!--workaround-->
1961      */
1962     @Override
1963     @ForceInline
1964     public final
1965     DoubleVector slice(int origin,
1966                                Vector<Double> w,
1967                                VectorMask<Double> m) {
1968         return broadcast(0).blend(slice(origin, w), m);
1969     }
1970 
1971     /**
1972      * {@inheritDoc} <!--workaround-->
1973      */
1974     @Override
1975     public abstract
1976     DoubleVector slice(int origin);
1977 
1978     /**
1979      * {@inheritDoc} <!--workaround-->
1980      */
1981     @Override
1982     public abstract
1983     DoubleVector unslice(int origin, Vector<Double> w, int part);
1984 
1985     /*package-private*/
1986     final
1987     @ForceInline
1988     DoubleVector
1989     unsliceTemplate(int origin, Vector<Double> w, int part) {
1990         DoubleVector that = (DoubleVector) w;
1991         that.check(this);
1992         double[] slice = this.getElements();
1993         double[] res = that.getElements();
1994         int vlen = res.length;
1995         int firstPart = vlen - origin;
1996         switch (part) {
1997         case 0:
1998             System.arraycopy(slice, 0, res, origin, firstPart);
1999             break;
2000         case 1:
2001             System.arraycopy(slice, firstPart, res, 0, origin);
2002             break;
2003         default:
2004             throw wrongPartForSlice(part);
2005         }
2006         return vectorFactory(res);
2007     }
2008 
2009     /*package-private*/
2010     final
2011     @ForceInline
2012     <M extends VectorMask<Double>>
2013     DoubleVector
2014     unsliceTemplate(Class<M> maskType, int origin, Vector<Double> w, int part, M m) {
2015         DoubleVector that = (DoubleVector) w;
2016         that.check(this);
2017         DoubleVector slice = that.sliceTemplate(origin, that);
2018         slice = slice.blendTemplate(maskType, this, m);
2019         return slice.unsliceTemplate(origin, w, part);
2020     }
2021 
2022     /**
2023      * {@inheritDoc} <!--workaround-->
2024      */
2025     @Override
2026     public abstract
2027     DoubleVector unslice(int origin, Vector<Double> w, int part, VectorMask<Double> m);
2028 
2029     /**
2030      * {@inheritDoc} <!--workaround-->
2031      */
2032     @Override
2033     public abstract
2034     DoubleVector unslice(int origin); 
2035 
2036     private ArrayIndexOutOfBoundsException
2037     wrongPartForSlice(int part) {
2038         String msg = String.format("bad part number %d for slice operation",
2039                                    part);
2040         return new ArrayIndexOutOfBoundsException(msg);
2041     }
2042 
2043     /**
2044      * {@inheritDoc} <!--workaround-->
2045      */
2046     @Override
2047     public abstract
2048     DoubleVector rearrange(VectorShuffle<Double> m);
2049 
2050     /*package-private*/
2051     @ForceInline
2052     final
2053     <S extends VectorShuffle<Double>>
2054     DoubleVector rearrangeTemplate(Class<S> shuffletype, S shuffle) {
2055         shuffle.checkIndexes();
2056         return VectorIntrinsics.rearrangeOp(
2057             getClass(), shuffletype, double.class, length(),
2058             this, shuffle,
2059             (v1, s_) -> v1.uOp((i, a) -> {
2060                 int ei = s_.laneSource(i);
2061                 return v1.lane(ei);
2062             }));
2063     }
2064 
2065     /**
2066      * {@inheritDoc} <!--workaround-->
2067      */
2068     @Override
2069     public abstract
2070     DoubleVector rearrange(VectorShuffle<Double> s,
2071                                    VectorMask<Double> m);
2072 
2073     /*package-private*/
2074     @ForceInline
2075     final
2076     <S extends VectorShuffle<Double>>
2077     DoubleVector rearrangeTemplate(Class<S> shuffletype,
2078                                            S shuffle,
2079                                            VectorMask<Double> m) {
2080         DoubleVector unmasked =
2081             VectorIntrinsics.rearrangeOp(
2082                 getClass(), shuffletype, double.class, length(),
2083                 this, shuffle,
2084                 (v1, s_) -> v1.uOp((i, a) -> {
2085                     int ei = s_.laneSource(i);
2086                     return ei < 0 ? 0 : v1.lane(ei);
2087                 }));
2088         VectorMask<Double> valid = shuffle.laneIsValid();
2089         if (m.andNot(valid).anyTrue()) {
2090             shuffle.checkIndexes();
2091             throw new AssertionError();
2092         }
2093         return broadcast((double)0).blend(unmasked, valid);
2094     }
2095 
2096     /**
2097      * {@inheritDoc} <!--workaround-->
2098      */
2099     @Override
2100     public abstract
2101     DoubleVector rearrange(VectorShuffle<Double> s,
2102                                    Vector<Double> v);
2103 
2104     /*package-private*/
2105     @ForceInline
2106     final
2107     <S extends VectorShuffle<Double>>
2108     DoubleVector rearrangeTemplate(Class<S> shuffletype,
2109                                            S shuffle,
2110                                            DoubleVector v) {
2111         VectorMask<Double> valid = shuffle.laneIsValid();
2112         S ws = shuffletype.cast(shuffle.wrapIndexes());
2113         DoubleVector r0 =
2114             VectorIntrinsics.rearrangeOp(
2115                 getClass(), shuffletype, double.class, length(),
2116                 this, ws,
2117                 (v0, s_) -> v0.uOp((i, a) -> {
2118                     int ei = s_.laneSource(i);
2119                     return v0.lane(ei);
2120                 }));
2121         DoubleVector r1 =
2122             VectorIntrinsics.rearrangeOp(
2123                 getClass(), shuffletype, double.class, length(),
2124                 v, ws,
2125                 (v1, s_) -> v1.uOp((i, a) -> {
2126                     int ei = s_.laneSource(i);
2127                     return v1.lane(ei);
2128                 }));
2129         return r1.blend(r0, valid);
2130     }
2131 
2132     /**
2133      * {@inheritDoc} <!--workaround-->
2134      */
2135     @Override
2136     public abstract
2137     DoubleVector selectFrom(Vector<Double> v);
2138 
2139     /*package-private*/
2140     @ForceInline
2141     final DoubleVector selectFromTemplate(DoubleVector v) {
2142         return v.rearrange(this.toShuffle());
2143     }
2144 
2145     /**
2146      * {@inheritDoc} <!--workaround-->
2147      */
2148     @Override
2149     public abstract
2150     DoubleVector selectFrom(Vector<Double> s, VectorMask<Double> m);
2151 
2152     /*package-private*/
2153     @ForceInline
2154     final DoubleVector selectFromTemplate(DoubleVector v,
2155                                                   AbstractMask<Double> m) {
2156         return v.rearrange(this.toShuffle(), m);
2157     }
2158 
2159     /// Ternary operations
2160 
2161 
2162     /**
2163      * Multiplies this vector by a second input vector, and sums
2164      * the result with a third.
2165      *
2166      * Extended precision is used for the intermediate result,
2167      * avoiding possible loss of precision from rounding once
2168      * for each of the two operations.
2169      * The result is numerically close to {@code this.mul(b).add(c)},
2170      * and is typically closer to the true mathematical result.
2171      *
2172      * This is a lane-wise ternary operation which applies the
2173      * {@link Math#fma(double,double,double) Math#fma(a,b,c)}
2174      * operation to each lane.
2175      *
2176      * This method is also equivalent to the expression
2177      * {@link #lanewise(VectorOperators.Ternary,Vector,Vector)
2178      *    lanewise}{@code (}{@link VectorOperators#FMA
2179      *    FMA}{@code , b, c)}.
2180      *
2181      * @param b the second input vector, supplying multiplier values
2182      * @param c the third input vector, supplying addend values
2183      * @return the product of this vector and the second input vector
2184      *         summed with the third input vector, using extended precision
2185      *         for the intermediate result
2186      * @see #fma(double,double)
2187      * @see VectorOperators#FMA
2188      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
2189      */
2190     @ForceInline
2191     public final
2192     DoubleVector fma(Vector<Double> b, Vector<Double> c) {
2193         return lanewise(FMA, b, c);
2194     }
2195 
2196     /**
2197      * Multiplies this vector by a scalar multiplier, and sums
2198      * the result with a scalar addend.
2199      *
2200      * Extended precision is used for the intermediate result,
2201      * avoiding possible loss of precision from rounding once
2202      * for each of the two operations.
2203      * The result is numerically close to {@code this.mul(b).add(c)},
2204      * and is typically closer to the true mathematical result.
2205      *
2206      * This is a lane-wise ternary operation which applies the
2207      * {@link Math#fma(double,double,double) Math#fma(a,b,c)}
2208      * operation to each lane.
2209      *
2210      * This method is also equivalent to the expression
2211      * {@link #lanewise(VectorOperators.Ternary,Vector,Vector)
2212      *    lanewise}{@code (}{@link VectorOperators#FMA
2213      *    FMA}{@code , b, c)}.
2214      *
2215      * @param b the scalar multiplier
2216      * @param c the scalar addend
2217      * @return the product of this vector and the scalar multiplier
2218      *         summed with scalar addend, using extended precision
2219      *         for the intermediate result
2220      * @see #fma(Vector,Vector)
2221      * @see VectorOperators#FMA
2222      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
2223      */
2224     @ForceInline
2225     public final
2226     DoubleVector fma(double b, double c) {
2227         return lanewise(FMA, b, c);
2228     }
2229 
2230     // Don't bother with (Vector,double) and (double,Vector) overloadings.
2231 
2232     // Type specific horizontal reductions
2233 
2234     /**
2235      * Returns a value accumulated from all the lanes of this vector.
2236      *
2237      * This is an associative cross-lane reduction operation which
2238      * applies the specified operation to all the lane elements.
2239      *
2240      * <p>
2241      * A few reduction operations do not support arbitrary reordering
2242      * of their operands, yet are included here because of their
2243      * usefulness.
2244      *
2245      * <ul>
2246      * <li>
2247      * In the case of {@code FIRST_NONZERO}, the reduction returns
2248      * the value from the lowest-numbered non-zero lane.
2249      *
2250      * (As with {@code MAX} and {@code MIN}, floating point negative
2251      * zero {@code -0.0} is treated as a value distinct from
2252      * the default value, positive zero. So a first-nonzero lane reduction
2253      * might return {@code -0.0} even in the presence of non-zero
2254      * lane values.)
2255      *
2256      * <li>
2257      * In the case of floating point addition and multiplication, the
2258      * precise result will reflect the choice of an arbitrary order
2259      * of operations, which may even vary over time.
2260      *
2261      * <li>
2262      * All other reduction operations are fully commutative and
2263      * associative.  The implementation can choose any order of
2264      * processing, yet it will always produce the same result.
2265      *
2266      * </ul>
2267      *
2268      * @implNote
2269      * The value of a floating-point reduction may be a function
2270      * both of the input values as well as the order of scalar
2271      * operations which combine those values, specifically in the
2272      * case of {@code ADD} and {@code MUL} operations, where
2273      * details of rounding depend on operand order.
2274      * In those cases, the order of operations of this method is
2275      * intentionally not defined.  This allows the JVM to generate
2276      * optimal machine code for the underlying platform at runtime. If
2277      * the platform supports a vector instruction to add or multiply
2278      * all values in the vector, or if there is some other efficient
2279      * machine code sequence, then the JVM has the option of
2280      * generating this machine code. Otherwise, the default
2281      * implementation is applied, which adds vector elements
2282      * sequentially from beginning to end.  For this reason, the
2283      * output of this method may vary for the same input values,
2284      * if the selected operator is {@code ADD} or {@code MUL}.
2285      *
2286      *
2287      * @param op the operation used to combine lane values
2288      * @return the accumulated result
2289      * @throws UnsupportedOperationException if this vector does
2290      *         not support the requested operation
2291      * @see #reduceLanes(VectorOperators.Associative,VectorMask)
2292      * @see #add(Vector)
2293      * @see #mul(Vector)
2294      * @see #min(Vector)
2295      * @see #max(Vector)
2296      * @see VectorOperators#FIRST_NONZERO
2297      */
2298     public abstract double reduceLanes(VectorOperators.Associative op);
2299 
2300     /**
2301      * Returns a value accumulated from selected lanes of this vector,
2302      * controlled by a mask.
2303      *
2304      * This is an associative cross-lane reduction operation which
2305      * applies the specified operation to the selected lane elements.
2306      * <p>
2307      * If no elements are selected, an operation-specific identity
2308      * value is returned.
2309      * <ul>
2310      * <li>
2311      * If the operation is
2312      *  {@code ADD}
2313      * or {@code FIRST_NONZERO},
2314      * then the identity value is positive zero, the default {@code double} value.
2315      * <li>
2316      * If the operation is {@code MUL},
2317      * then the identity value is one.
2318      * <li>
2319      * If the operation is {@code MAX},
2320      * then the identity value is {@code Double.NEGATIVE_INFINITY}.
2321      * <li>
2322      * If the operation is {@code MIN},
2323      * then the identity value is {@code Double.POSITIVE_INFINITY}.
2324      * </ul>
2325      *
2326      * @implNote
2327      * The value of a floating-point reduction may be a function
2328      * both of the input values as well as the order of scalar
2329      * operations which combine those values, specifically in the
2330      * case of {@code ADD} and {@code MUL} operations, where
2331      * details of rounding depend on operand order.
2332      * See {@linkplain #reduceLanes(VectorOperators.Associative)
2333      * the unmasked version of this method}
2334      * for a discussion.
2335      *
2336      *
2337      * @param op the operation used to combine lane values
2338      * @param m the mask controlling lane selection
2339      * @return the reduced result accumulated from the selected lane values
2340      * @throws UnsupportedOperationException if this vector does
2341      *         not support the requested operation
2342      * @see #reduceLanes(VectorOperators.Associative)
2343      */
2344     public abstract double reduceLanes(VectorOperators.Associative op,
2345                                        VectorMask<Double> m);
2346 
2347     /*package-private*/
2348     @ForceInline
2349     final
2350     double reduceLanesTemplate(VectorOperators.Associative op,
2351                                VectorMask<Double> m) {
2352         DoubleVector v = reduceIdentityVector(op).blend(this, m);
2353         return v.reduceLanesTemplate(op);
2354     }
2355 
2356     /*package-private*/
2357     @ForceInline
2358     final
2359     double reduceLanesTemplate(VectorOperators.Associative op) {
2360         if (op == FIRST_NONZERO) {
2361             // FIXME:  The JIT should handle this, and other scan ops alos.
2362             VectorMask<Long> thisNZ
2363                 = this.viewAsIntegralLanes().compare(NE, (long) 0);
2364             return this.lane(thisNZ.firstTrue());
2365         }
2366         int opc = opCode(op);
2367         return fromBits(VectorIntrinsics.reductionCoerced(
2368             opc, getClass(), double.class, length(),
2369             this,
2370             REDUCE_IMPL.find(op, opc, (opc_) -> {
2371               switch (opc_) {
2372               case VECTOR_OP_ADD: return v ->
2373                       toBits(v.rOp((double)0, (i, a, b) -> (double)(a + b)));
2374               case VECTOR_OP_MUL: return v ->
2375                       toBits(v.rOp((double)1, (i, a, b) -> (double)(a * b)));
2376               case VECTOR_OP_MIN: return v ->
2377                       toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (double) Math.min(a, b)));
2378               case VECTOR_OP_MAX: return v ->
2379                       toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (double) Math.max(a, b)));
2380               case VECTOR_OP_FIRST_NONZERO: return v ->
2381                       toBits(v.rOp((double)0, (i, a, b) -> toBits(a) != 0 ? a : b));
2382               case VECTOR_OP_OR: return v ->
2383                       toBits(v.rOp((double)0, (i, a, b) -> fromBits(toBits(a) | toBits(b))));
2384               default: return null;
2385               }})));
2386     }
2387     private static final
2388     ImplCache<Associative,Function<DoubleVector,Long>> REDUCE_IMPL
2389         = new ImplCache<>(Associative.class, DoubleVector.class);
2390 
2391     private
2392     @ForceInline
2393     DoubleVector reduceIdentityVector(VectorOperators.Associative op) {
2394         int opc = opCode(op);
2395         UnaryOperator<DoubleVector> fn
2396             = REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
2397                 switch (opc_) {
2398                 case VECTOR_OP_ADD:
2399                 case VECTOR_OP_OR:
2400                 case VECTOR_OP_XOR:
2401                 case VECTOR_OP_FIRST_NONZERO:
2402                     return v -> v.broadcast(0);
2403                 case VECTOR_OP_MUL:
2404                     return v -> v.broadcast(1);
2405                 case VECTOR_OP_AND:
2406                     return v -> v.broadcast(-1);
2407                 case VECTOR_OP_MIN:
2408                     return v -> v.broadcast(MAX_OR_INF);
2409                 case VECTOR_OP_MAX:
2410                     return v -> v.broadcast(MIN_OR_INF);
2411                 default: return null;
2412                 }
2413             });
2414         return fn.apply(this);
2415     }
2416     private static final
2417     ImplCache<Associative,UnaryOperator<DoubleVector>> REDUCE_ID_IMPL
2418         = new ImplCache<>(Associative.class, DoubleVector.class);
2419 
2420     private static final double MIN_OR_INF = Double.NEGATIVE_INFINITY;
2421     private static final double MAX_OR_INF = Double.POSITIVE_INFINITY;
2422 
2423     public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);
2424     public @Override abstract long reduceLanesToLong(VectorOperators.Associative op,
2425                                                      VectorMask<Double> m);
2426 
2427     // Type specific accessors
2428 
2429     /**
2430      * Gets the lane element at lane index {@code i}
2431      *
2432      * @param i the lane index
2433      * @return the lane element at lane index {@code i}
2434      * @throws IllegalArgumentException if the index is is out of range
2435      * ({@code < 0 || >= length()})
2436      */
2437     public abstract double lane(int i);
2438 
2439     /**
2440      * Replaces the lane element of this vector at lane index {@code i} with
2441      * value {@code e}.
2442      *
2443      * This is a cross-lane operation and behaves as if it returns the result
2444      * of blending this vector with an input vector that is the result of
2445      * broadcasting {@code e} and a mask that has only one lane set at lane
2446      * index {@code i}.
2447      *
2448      * @param i the lane index of the lane element to be replaced
2449      * @param e the value to be placed
2450      * @return the result of replacing the lane element of this vector at lane
2451      * index {@code i} with value {@code e}.
2452      * @throws IllegalArgumentException if the index is is out of range
2453      * ({@code < 0 || >= length()})
2454      */
2455     public abstract DoubleVector withLane(int i, double e);
2456 
2457     // Memory load operations
2458 
2459     /**
2460      * Returns an array of type {@code double[]}
2461      * containing all the lane values.
2462      * The array length is the same as the vector length.
2463      * The array elements are stored in lane order.
2464      * <p>
2465      * This method behaves as if it stores
2466      * this vector into an allocated array
2467      * (using {@link #intoArray(double[], int) intoArray})
2468      * and returns the array as follows:
2469      * <pre>{@code
2470      *   double[] a = new double[this.length()];
2471      *   this.intoArray(a, 0);
2472      *   return a;
2473      * }</pre>
2474      *
2475      * @return an array containing the lane values of this vector
2476      */
2477     @ForceInline
2478     @Override
2479     public final double[] toArray() {
2480         double[] a = new double[vspecies().laneCount()];
2481         intoArray(a, 0);
2482         return a;
2483     }
2484 
2485     /** {@inheritDoc} <!--workaround-->
2486      */
2487     @ForceInline
2488     @Override
2489     public final int[] toIntArray() {
2490         double[] a = toArray();
2491         int[] res = new int[a.length];
2492         for (int i = 0; i < a.length; i++) {
2493             double e = a[i];
2494             res[i] = (int) DoubleSpecies.toIntegralChecked(e, true);
2495         }
2496         return res;
2497     }
2498 
2499     /** {@inheritDoc} <!--workaround-->
2500      */
2501     @ForceInline
2502     @Override
2503     public final long[] toLongArray() {
2504         double[] a = toArray();
2505         long[] res = new long[a.length];
2506         for (int i = 0; i < a.length; i++) {
2507             double e = a[i];
2508             res[i] = DoubleSpecies.toIntegralChecked(e, false);
2509         }
2510         return res;
2511     }
2512 
2513     /** {@inheritDoc} <!--workaround-->
2514      * @implNote
2515      * This is an alias for {@link #toArray()}
2516      * When this method is used on used on vectors
2517      * of type {@code DoubleVector},
2518      * there will be no loss of precision.
2519      */
2520     @ForceInline
2521     @Override
2522     public final double[] toDoubleArray() {
2523         return toArray();
2524     }
2525 
2526     /**
2527      * Loads a vector from a byte array starting at an offset.
2528      * Bytes are composed into primitive lane elements according
2529      * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering.
2530      * The vector is arranged into lanes according to
2531      * <a href="Vector.html#lane-order">memory ordering</a>.
2532      * <p>
2533      * This method behaves as if it returns the result of calling
2534      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2535      * fromByteBuffer()} as follows:
2536      * <pre>{@code
2537      * var bb = ByteBuffer.wrap(a);
2538      * var bo = ByteOrder.LITTLE_ENDIAN;
2539      * var m = species.maskAll(true);
2540      * return fromByteBuffer(species, bb, offset, m, bo);
2541      * }</pre>
2542      *
2543      * @param species species of desired vector
2544      * @param a the byte array
2545      * @param offset the offset into the array
2546      * @return a vector loaded from a byte array
2547      * @throws IndexOutOfBoundsException
2548      *         if {@code offset+N*ESIZE < 0}
2549      *         or {@code offset+(N+1)*ESIZE > a.length}
2550      *         for any lane {@code N} in the vector
2551      */
2552     @ForceInline
2553     public static
2554     DoubleVector fromByteArray(VectorSpecies<Double> species,
2555                                        byte[] a, int offset) {
2556         return fromByteArray(species, a, offset, ByteOrder.LITTLE_ENDIAN);
2557     }
2558 
2559     /**
2560      * Loads a vector from a byte array starting at an offset.
2561      * Bytes are composed into primitive lane elements according
2562      * to the specified byte order.
2563      * The vector is arranged into lanes according to
2564      * <a href="Vector.html#lane-order">memory ordering</a>.
2565      * <p>
2566      * This method behaves as if it returns the result of calling
2567      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2568      * fromByteBuffer()} as follows:
2569      * <pre>{@code
2570      * var bb = ByteBuffer.wrap(a);
2571      * var m = species.maskAll(true);
2572      * return fromByteBuffer(species, bb, offset, m, bo);
2573      * }</pre>
2574      *
2575      * @param species species of desired vector
2576      * @param a the byte array
2577      * @param offset the offset into the array
2578      * @param bo the intended byte order
2579      * @return a vector loaded from a byte array
2580      * @throws IndexOutOfBoundsException
2581      *         if {@code offset+N*ESIZE < 0}
2582      *         or {@code offset+(N+1)*ESIZE > a.length}
2583      *         for any lane {@code N} in the vector
2584      */
2585     @ForceInline
2586     public static
2587     DoubleVector fromByteArray(VectorSpecies<Double> species,
2588                                        byte[] a, int offset,
2589                                        ByteOrder bo) {
2590         DoubleSpecies vsp = (DoubleSpecies) species;
2591         offset = checkFromIndexSize(offset,
2592                                     vsp.vectorBitSize() / Byte.SIZE,
2593                                     a.length);
2594         return vsp.dummyVector()
2595             .fromByteArray0(a, offset).maybeSwap(bo);
2596     }
2597 
2598     /**
2599      * Loads a vector from a byte array starting at an offset
2600      * and using a mask.
2601      * Lanes where the mask is unset are filled with the default
2602      * value of {@code double} (positive zero).
2603      * Bytes are composed into primitive lane elements according
2604      * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering.
2605      * The vector is arranged into lanes according to
2606      * <a href="Vector.html#lane-order">memory ordering</a>.
2607      * <p>
2608      * This method behaves as if it returns the result of calling
2609      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2610      * fromByteBuffer()} as follows:
2611      * <pre>{@code
2612      * var bb = ByteBuffer.wrap(a);
2613      * var bo = ByteOrder.LITTLE_ENDIAN;
2614      * return fromByteBuffer(species, bb, offset, bo, m);
2615      * }</pre>
2616      *
2617      * @param species species of desired vector
2618      * @param a the byte array
2619      * @param offset the offset into the array
2620      * @param m the mask controlling lane selection
2621      * @return a vector loaded from a byte array
2622      * @throws IndexOutOfBoundsException
2623      *         if {@code offset+N*ESIZE < 0}
2624      *         or {@code offset+(N+1)*ESIZE > a.length}
2625      *         for any lane {@code N} in the vector where
2626      *         the mask is set
2627      */
2628     @ForceInline
2629     public static
2630     DoubleVector fromByteArray(VectorSpecies<Double> species,
2631                                        byte[] a, int offset,
2632                                        VectorMask<Double> m) {
2633         return fromByteArray(species, a, offset, ByteOrder.LITTLE_ENDIAN, m);
2634     }
2635 
2636     /**
2637      * Loads a vector from a byte array starting at an offset
2638      * and using a mask.
2639      * Lanes where the mask is unset are filled with the default
2640      * value of {@code double} (positive zero).
2641      * Bytes are composed into primitive lane elements according
2642      * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering.
2643      * The vector is arranged into lanes according to
2644      * <a href="Vector.html#lane-order">memory ordering</a>.
2645      * <p>
2646      * This method behaves as if it returns the result of calling
2647      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2648      * fromByteBuffer()} as follows:
2649      * <pre>{@code
2650      * var bb = ByteBuffer.wrap(a);
2651      * return fromByteBuffer(species, bb, offset, m, bo);
2652      * }</pre>
2653      *
2654      * @param species species of desired vector
2655      * @param a the byte array
2656      * @param offset the offset into the array
2657      * @param bo the intended byte order
2658      * @param m the mask controlling lane selection
2659      * @return a vector loaded from a byte array
2660      * @throws IndexOutOfBoundsException
2661      *         if {@code offset+N*ESIZE < 0}
2662      *         or {@code offset+(N+1)*ESIZE > a.length}
2663      *         for any lane {@code N} in the vector
2664      *         where the mask is set
2665      */
2666     @ForceInline
2667     public static
2668     DoubleVector fromByteArray(VectorSpecies<Double> species,
2669                                        byte[] a, int offset,
2670                                        ByteOrder bo,
2671                                        VectorMask<Double> m) {
2672         DoubleSpecies vsp = (DoubleSpecies) species;
2673         DoubleVector zero = vsp.zero();
2674 
2675         if (offset >= 0 && offset <= (a.length - vsp.length() * 8)) {
2676             DoubleVector v = zero.fromByteArray0(a, offset);
2677             return zero.blend(v.maybeSwap(bo), m);
2678         }
2679         DoubleVector iota = zero.addIndex(1);
2680         ((AbstractMask<Double>)m)
2681             .checkIndexByLane(offset, a.length, iota, 8);
2682         DoubleBuffer tb = wrapper(a, offset, bo);
2683         return vsp.ldOp(tb, 0, (AbstractMask<Double>)m,
2684                    (tb_, __, i)  -> tb_.get(i));
2685     }
2686 
2687     /**
2688      * Loads a vector from an array of type {@code double[]}
2689      * starting at an offset.
2690      * For each vector lane, where {@code N} is the vector lane index, the
2691      * array element at index {@code offset + N} is placed into the
2692      * resulting vector at lane index {@code N}.
2693      *
2694      * @param species species of desired vector
2695      * @param a the array
2696      * @param offset the offset into the array
2697      * @return the vector loaded from an array
2698      * @throws IndexOutOfBoundsException
2699      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2700      *         for any lane {@code N} in the vector
2701      */
2702     @ForceInline
2703     public static
2704     DoubleVector fromArray(VectorSpecies<Double> species,
2705                                    double[] a, int offset) {
2706         DoubleSpecies vsp = (DoubleSpecies) species;
2707         offset = checkFromIndexSize(offset,
2708                                     vsp.laneCount(),
2709                                     a.length);
2710         return vsp.dummyVector().fromArray0(a, offset);
2711     }
2712 
2713     /**
2714      * Loads a vector from an array of type {@code double[]}
2715      * starting at an offset and using a mask.
2716      * Lanes where the mask is unset are filled with the default
2717      * value of {@code double} (positive zero).
2718      * For each vector lane, where {@code N} is the vector lane index,
2719      * if the mask lane at index {@code N} is set then the array element at
2720      * index {@code offset + N} is placed into the resulting vector at lane index
2721      * {@code N}, otherwise the default element value is placed into the
2722      * resulting vector at lane index {@code N}.
2723      *
2724      * @param species species of desired vector
2725      * @param a the array
2726      * @param offset the offset into the array
2727      * @param m the mask controlling lane selection
2728      * @return the vector loaded from an array
2729      * @throws IndexOutOfBoundsException
2730      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2731      *         for any lane {@code N} in the vector
2732      *         where the mask is set
2733      */
2734     @ForceInline
2735     public static
2736     DoubleVector fromArray(VectorSpecies<Double> species,
2737                                    double[] a, int offset,
2738                                    VectorMask<Double> m) {
2739         DoubleSpecies vsp = (DoubleSpecies) species;
2740         if (offset >= 0 && offset <= (a.length - species.length())) {
2741             DoubleVector zero = vsp.zero();
2742             return zero.blend(zero.fromArray0(a, offset), m);
2743         }
2744         DoubleVector iota = vsp.iota();
2745         ((AbstractMask<Double>)m)
2746             .checkIndexByLane(offset, a.length, iota, 1);
2747         return vsp.vOp(m, i -> a[offset + i]);
2748     }
2749 
2750     /**
2751      * Gathers a new vector composed of elements from an array of type
2752      * {@code double[]},
2753      * using indexes obtained by adding a fixed {@code offset} to a
2754      * series of secondary offsets from an <em>index map</em>.
2755      * The index map is a contiguous sequence of {@code VLENGTH}
2756      * elements in a second array of {@code int}s, starting at a given
2757      * {@code mapOffset}.
2758      * <p>
2759      * For each vector lane, where {@code N} is the vector lane index,
2760      * the lane is loaded from the array
2761      * element {@code a[f(N)]}, where {@code f(N)} is the
2762      * index mapping expression
2763      * {@code offset + indexMap[mapOffset + N]]}.
2764      *
2765      * @param species species of desired vector
2766      * @param a the array
2767      * @param offset the offset into the array, may be negative if relative
2768      * indexes in the index map compensate to produce a value within the
2769      * array bounds
2770      * @param indexMap the index map
2771      * @param mapOffset the offset into the index map
2772      * @return the vector loaded from the indexed elements of the array
2773      * @throws IndexOutOfBoundsException
2774      *         if {@code mapOffset+N < 0}
2775      *         or if {@code mapOffset+N >= indexMap.length},
2776      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
2777      *         is an invalid index into {@code a},
2778      *         for any lane {@code N} in the vector
2779      * @see DoubleVector#toIntArray()
2780      */
2781     @ForceInline
2782     public static
2783     DoubleVector fromArray(VectorSpecies<Double> species,
2784                                    double[] a, int offset,
2785                                    int[] indexMap, int mapOffset) {
2786         DoubleSpecies vsp = (DoubleSpecies) species;
2787         Objects.requireNonNull(a);
2788         Objects.requireNonNull(indexMap);
2789         Class<? extends DoubleVector> vectorType = vsp.vectorType();
2790 
2791         if (vsp.laneCount() == 1) {
2792           return DoubleVector.fromArray(vsp, a, offset + indexMap[mapOffset]);
2793         }
2794 
2795         // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k]
2796         IntVector vix = IntVector.fromArray(IntVector.species(vsp.indexShape()), indexMap, mapOffset).add(offset);
2797 
2798         vix = VectorIntrinsics.checkIndex(vix, a.length);
2799 
2800         return VectorIntrinsics.loadWithMap(
2801             vectorType, double.class, vsp.laneCount(),
2802             IntVector.species(vsp.indexShape()).vectorType(),
2803             a, ARRAY_BASE, vix,
2804             a, offset, indexMap, mapOffset, vsp,
2805             (double[] c, int idx, int[] iMap, int idy, DoubleSpecies s) ->
2806             s.vOp(n -> c[idx + iMap[idy+n]]));
2807         }
2808 
2809     /**
2810      * Gathers a new vector composed of elements from an array of type
2811      * {@code double[]},
2812      * under the control of a mask, and
2813      * using indexes obtained by adding a fixed {@code offset} to a
2814      * series of secondary offsets from an <em>index map</em>.
2815      * The index map is a contiguous sequence of {@code VLENGTH}
2816      * elements in a second array of {@code int}s, starting at a given
2817      * {@code mapOffset}.
2818      * <p>
2819      * For each vector lane, where {@code N} is the vector lane index,
2820      * if the lane is set in the mask,
2821      * the lane is loaded from the array
2822      * element {@code a[f(N)]}, where {@code f(N)} is the
2823      * index mapping expression
2824      * {@code offset + indexMap[mapOffset + N]]}.
2825      * Unset lanes in the resulting vector are set to zero.
2826      *
2827      * @param species species of desired vector
2828      * @param a the array
2829      * @param offset the offset into the array, may be negative if relative
2830      * indexes in the index map compensate to produce a value within the
2831      * array bounds
2832      * @param indexMap the index map
2833      * @param mapOffset the offset into the index map
2834      * @param m the mask controlling lane selection
2835      * @return the vector loaded from the indexed elements of the array
2836      * @throws IndexOutOfBoundsException
2837      *         if {@code mapOffset+N < 0}
2838      *         or if {@code mapOffset+N >= indexMap.length},
2839      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
2840      *         is an invalid index into {@code a},
2841      *         for any lane {@code N} in the vector
2842      *         where the mask is set
2843      * @see DoubleVector#toIntArray()
2844      */
2845     @ForceInline
2846     public static
2847     DoubleVector fromArray(VectorSpecies<Double> species,
2848                                    double[] a, int offset,
2849                                    int[] indexMap, int mapOffset,
2850                                    VectorMask<Double> m) {
2851         DoubleSpecies vsp = (DoubleSpecies) species;
2852 
2853         // FIXME This can result in out of bounds errors for unset mask lanes
2854         // FIX = Use a scatter instruction which routes the unwanted lanes
2855         // into a bit-bucket variable (private to implementation).
2856         // This requires a 2-D scatter in order to set a second base address.
2857         // See notes in https://bugs.openjdk.java.net/browse/JDK-8223367
2858         assert(m.allTrue());
2859         return (DoubleVector)
2860             zero(species).blend(fromArray(species, a, offset, indexMap, mapOffset), m);
2861 
2862     }
2863 
2864     /**
2865      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
2866      * starting at an offset into the byte buffer.
2867      * <p>
2868      * Bytes are composed into primitive lane elements according to
2869      * {@link ByteOrder#LITTLE_ENDIAN little endian} byte order.
2870      * To avoid errors, the
2871      * {@linkplain ByteBuffer#order() intrinsic byte order}
2872      * of the buffer must be little-endian.
2873      * <p>
2874      * This method behaves as if it returns the result of calling
2875      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2876      * fromByteBuffer()} as follows:
2877      * <pre>{@code
2878      * var bb = ByteBuffer.wrap(a);
2879      * var bo = ByteOrder.LITTLE_ENDIAN;
2880      * var m = species.maskAll(true);
2881      * return fromByteBuffer(species, bb, offset, m, bo);
2882      * }</pre>
2883      *
2884      * @param species species of desired vector
2885      * @param bb the byte buffer
2886      * @param offset the offset into the byte buffer
2887      * @param bo the intended byte order
2888      * @return a vector loaded from a byte buffer
2889      * @throws IllegalArgumentException if byte order of bb
2890      *         is not {@link ByteOrder#LITTLE_ENDIAN}
2891      * @throws IndexOutOfBoundsException
2892      *         if {@code offset+N*8 < 0}
2893      *         or {@code offset+N*8 >= bb.limit()}
2894      *         for any lane {@code N} in the vector
2895      */
2896     @ForceInline
2897     public static
2898     DoubleVector fromByteBuffer(VectorSpecies<Double> species,
2899                                         ByteBuffer bb, int offset,
2900                                         ByteOrder bo) {
2901         DoubleSpecies vsp = (DoubleSpecies) species;
2902         offset = checkFromIndexSize(offset,
2903                                     vsp.laneCount(),
2904                                     bb.limit());
2905         return vsp.dummyVector()
2906             .fromByteBuffer0(bb, offset).maybeSwap(bo);
2907     }
2908 
2909     /**
2910      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
2911      * starting at an offset into the byte buffer
2912      * and using a mask.
2913      * <p>
2914      * Bytes are composed into primitive lane elements according to
2915      * {@link ByteOrder#LITTLE_ENDIAN little endian} byte order.
2916      * To avoid errors, the
2917      * {@linkplain ByteBuffer#order() intrinsic byte order}
2918      * of the buffer must be little-endian.
2919      * <p>
2920      * This method behaves as if it returns the result of calling
2921      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2922      * fromByteBuffer()} as follows:
2923      * <pre>{@code
2924      * var bb = ByteBuffer.wrap(a);
2925      * var bo = ByteOrder.LITTLE_ENDIAN;
2926      * var m = species.maskAll(true);
2927      * return fromByteBuffer(species, bb, offset, m, bo);
2928      * }</pre>
2929      *
2930      * @param species species of desired vector
2931      * @param bb the byte buffer
2932      * @param offset the offset into the byte buffer
2933      * @param bo the intended byte order
2934      * @param m the mask controlling lane selection
2935      * @return a vector loaded from a byte buffer
2936      * @throws IllegalArgumentException if byte order of bb
2937      *         is not {@link ByteOrder#LITTLE_ENDIAN}
2938      * @throws IndexOutOfBoundsException
2939      *         if {@code offset+N*8 < 0}
2940      *         or {@code offset+N*8 >= bb.limit()}
2941      *         for any lane {@code N} in the vector
2942      *         where the mask is set
2943      */
2944     @ForceInline
2945     public static
2946     DoubleVector fromByteBuffer(VectorSpecies<Double> species,
2947                                         ByteBuffer bb, int offset,
2948                                         ByteOrder bo,
2949                                         VectorMask<Double> m) {
2950         if (m.allTrue()) {
2951             return fromByteBuffer(species, bb, offset, bo);
2952         }
2953         DoubleSpecies vsp = (DoubleSpecies) species;
2954         checkMaskFromIndexSize(offset,
2955                                vsp, m, 1,
2956                                bb.limit());
2957         DoubleVector zero = zero(vsp);
2958         DoubleVector v = zero.fromByteBuffer0(bb, offset);
2959         return zero.blend(v.maybeSwap(bo), m);
2960     }
2961 
2962     // Memory store operations
2963 
2964     /**
2965      * Stores this vector into an array of type {@code double[]}
2966      * starting at an offset.
2967      * <p>
2968      * For each vector lane, where {@code N} is the vector lane index,
2969      * the lane element at index {@code N} is stored into the array
2970      * element {@code a[offset+N]}.
2971      *
2972      * @param a the array, of type {@code double[]}
2973      * @param offset the offset into the array
2974      * @throws IndexOutOfBoundsException
2975      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2976      *         for any lane {@code N} in the vector
2977      */
2978     @ForceInline
2979     public final
2980     void intoArray(double[] a, int offset) {
2981         DoubleSpecies vsp = vspecies();
2982         offset = checkFromIndexSize(offset,
2983                                     vsp.laneCount(),
2984                                     a.length);
2985         VectorIntrinsics.store(
2986             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
2987             a, arrayAddress(a, offset),
2988             this,
2989             a, offset,
2990             (arr, off, v)
2991             -> v.stOp(arr, off,
2992                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
2993     }
2994 
2995     /**
2996      * Stores this vector into an array of {@code double}
2997      * starting at offset and using a mask.
2998      * <p>
2999      * For each vector lane, where {@code N} is the vector lane index,
3000      * the lane element at index {@code N} is stored into the array
3001      * element {@code a[offset+N]}.
3002      * If the mask lane at {@code N} is unset then the corresponding
3003      * array element {@code a[offset+N]} is left unchanged.
3004      * <p>
3005      * Array range checking is done for lanes where the mask is set.
3006      * Lanes where the mask is unset are not stored and do not need
3007      * to correspond to legitimate elements of {@code a}.
3008      * That is, unset lanes may correspond to array indexes less than
3009      * zero or beyond the end of the array.
3010      *
3011      * @param a the array, of type {@code double[]}
3012      * @param offset the offset into the array
3013      * @param m the mask controlling lane storage
3014      * @throws IndexOutOfBoundsException
3015      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3016      *         for any lane {@code N} in the vector
3017      *         where the mask is set
3018      */
3019     @ForceInline
3020     public final
3021     void intoArray(double[] a, int offset,
3022                    VectorMask<Double> m) {
3023         if (m.allTrue()) {
3024             intoArray(a, offset);
3025         } else {
3026             // FIXME: Cannot vectorize yet, if there's a mask.
3027             stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v);
3028         }
3029     }
3030 
3031     /**
3032      * Scatters this vector into an array of type {@code double[]}
3033      * using indexes obtained by adding a fixed {@code offset} to a
3034      * series of secondary offsets from an <em>index map</em>.
3035      * The index map is a contiguous sequence of {@code VLENGTH}
3036      * elements in a second array of {@code int}s, starting at a given
3037      * {@code mapOffset}.
3038      * <p>
3039      * For each vector lane, where {@code N} is the vector lane index,
3040      * the lane element at index {@code N} is stored into the array
3041      * element {@code a[f(N)]}, where {@code f(N)} is the
3042      * index mapping expression
3043      * {@code offset + indexMap[mapOffset + N]]}.
3044      *
3045      * @param a the array
3046      * @param offset an offset to combine with the index map offsets
3047      * @param indexMap the index map
3048      * @param mapOffset the offset into the index map
3049      * @returns a vector of the values {@code a[f(N)]}, where
3050      *          {@code f(N) = offset + indexMap[mapOffset + N]]}.
3051      * @throws IndexOutOfBoundsException
3052      *         if {@code mapOffset+N < 0}
3053      *         or if {@code mapOffset+N >= indexMap.length},
3054      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3055      *         is an invalid index into {@code a},
3056      *         for any lane {@code N} in the vector
3057      * @see DoubleVector#toIntArray()
3058      */
3059     @ForceInline
3060     public final
3061     void intoArray(double[] a, int offset,
3062                    int[] indexMap, int mapOffset) {
3063         DoubleSpecies vsp = vspecies();
3064         if (length() == 1) {
3065             intoArray(a, offset + indexMap[mapOffset]);
3066             return;
3067         }
3068         IntVector.IntSpecies isp = (IntVector.IntSpecies) vsp.indexSpecies();
3069         if (isp.laneCount() != vsp.laneCount()) {
3070             stOp(a, offset,
3071                  (arr, off, i, e) -> {
3072                      int j = indexMap[mapOffset + i];
3073                      arr[off + j] = e;
3074                  });
3075             return;
3076         }
3077 
3078         // Index vector: vix[0:n] = i -> offset + indexMap[mo + i]
3079         IntVector vix = IntVector
3080             .fromArray(isp, indexMap, mapOffset)
3081             .add(offset);
3082 
3083         vix = VectorIntrinsics.checkIndex(vix, a.length);
3084 
3085         VectorIntrinsics.storeWithMap(
3086             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3087             isp.vectorType(),
3088             a, arrayAddress(a, 0), vix,
3089             this,
3090             a, offset, indexMap, mapOffset,
3091             (arr, off, v, map, mo)
3092             -> v.stOp(arr, off,
3093                       (arr_, off_, i, e) -> {
3094                           int j = map[mo + i];
3095                           arr[off + j] = e;
3096                       }));
3097     }
3098 
3099     /**
3100      * Scatters this vector into an array of type {@code double[]},
3101      * under the control of a mask, and
3102      * using indexes obtained by adding a fixed {@code offset} to a
3103      * series of secondary offsets from an <em>index map</em>.
3104      * The index map is a contiguous sequence of {@code VLENGTH}
3105      * elements in a second array of {@code int}s, starting at a given
3106      * {@code mapOffset}.
3107      * <p>
3108      * For each vector lane, where {@code N} is the vector lane index,
3109      * if the mask lane at index {@code N} is set then
3110      * the lane element at index {@code N} is stored into the array
3111      * element {@code a[f(N)]}, where {@code f(N)} is the
3112      * index mapping expression
3113      * {@code offset + indexMap[mapOffset + N]]}.
3114      *
3115      * @param a the array
3116      * @param offset an offset to combine with the index map offsets
3117      * @param indexMap the index map
3118      * @param mapOffset the offset into the index map
3119      * @param m the mask
3120      * @returns a vector of the values {@code m ? a[f(N)] : 0},
3121      *          {@code f(N) = offset + indexMap[mapOffset + N]]}.
3122      * @throws IndexOutOfBoundsException
3123      *         if {@code mapOffset+N < 0}
3124      *         or if {@code mapOffset+N >= indexMap.length},
3125      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3126      *         is an invalid index into {@code a},
3127      *         for any lane {@code N} in the vector
3128      *         where the mask is set
3129      * @see DoubleVector#toIntArray()
3130      */
3131     @ForceInline
3132     public final
3133     void intoArray(double[] a, int offset,
3134                    int[] indexMap, int mapOffset,
3135                    VectorMask<Double> m) {
3136         DoubleSpecies vsp = vspecies();
3137         if (m.allTrue()) {
3138             intoArray(a, offset, indexMap, mapOffset);
3139             return;
3140         }
3141         throw new AssertionError("fixme");
3142     }
3143 
3144     /**
3145      * {@inheritDoc} <!--workaround-->
3146      */
3147     @Override
3148     @ForceInline
3149     public final
3150     void intoByteArray(byte[] a, int offset) {
3151         offset = checkFromIndexSize(offset,
3152                                     bitSize() / Byte.SIZE,
3153                                     a.length);
3154         this.maybeSwap(ByteOrder.LITTLE_ENDIAN)
3155             .intoByteArray0(a, offset);
3156     }
3157 
3158     /**
3159      * {@inheritDoc} <!--workaround-->
3160      */
3161     @Override
3162     @ForceInline
3163     public final
3164     void intoByteArray(byte[] a, int offset,
3165                        VectorMask<Double> m) {
3166         if (m.allTrue()) {
3167             intoByteArray(a, offset);
3168             return;
3169         }
3170         DoubleSpecies vsp = vspecies();
3171         if (offset >= 0 && offset <= (a.length - vsp.length() * 8)) {
3172             var oldVal = fromByteArray0(a, offset);
3173             var newVal = oldVal.blend(this, m);
3174             newVal.intoByteArray0(a, offset);
3175         } else {
3176             checkMaskFromIndexSize(offset, vsp, m, 8, a.length);
3177             DoubleBuffer tb = wrapper(a, offset, NATIVE_ENDIAN);
3178             this.stOp(tb, 0, m, (tb_, __, i, e) -> tb_.put(i, e));
3179         }
3180     }
3181 
3182     /**
3183      * {@inheritDoc} <!--workaround-->
3184      */
3185     @Override
3186     @ForceInline
3187     public final
3188     void intoByteArray(byte[] a, int offset,
3189                        ByteOrder bo,
3190                        VectorMask<Double> m) {
3191         maybeSwap(bo).intoByteArray(a, offset, m);
3192     }
3193 
3194     /**
3195      * {@inheritDoc} <!--workaround-->
3196      */
3197     @Override
3198     @ForceInline
3199     public final
3200     void intoByteBuffer(ByteBuffer bb, int offset,
3201                         ByteOrder bo) {
3202         maybeSwap(bo).intoByteBuffer0(bb, offset);
3203     }
3204 
3205     /**
3206      * {@inheritDoc} <!--workaround-->
3207      */
3208     @Override
3209     @ForceInline
3210     public final
3211     void intoByteBuffer(ByteBuffer bb, int offset,
3212                         ByteOrder bo,
3213                         VectorMask<Double> m) {
3214         if (m.allTrue()) {
3215             intoByteBuffer(bb, offset, bo);
3216             return;
3217         }
3218         DoubleSpecies vsp = vspecies();
3219         checkMaskFromIndexSize(offset, vsp, m, 8, bb.limit());
3220         conditionalStoreNYI(offset, vsp, m, 8, bb.limit());
3221         var oldVal = fromByteBuffer0(bb, offset);
3222         var newVal = oldVal.blend(this.maybeSwap(bo), m);
3223         newVal.intoByteBuffer0(bb, offset);
3224     }
3225 
3226     // ================================================
3227 
3228     // Low-level memory operations.
3229     //
3230     // Note that all of these operations *must* inline into a context
3231     // where the exact species of the involved vector is a
3232     // compile-time constant.  Otherwise, the intrinsic generation
3233     // will fail and performance will suffer.
3234     //
3235     // In many cases this is achieved by re-deriving a version of the
3236     // method in each concrete subclass (per species).  The re-derived
3237     // method simply calls one of these generic methods, with exact
3238     // parameters for the controlling metadata, which is either a
3239     // typed vector or constant species instance.
3240 
3241     // Unchecked loading operations in native byte order.
3242     // Caller is reponsible for applying index checks, masking, and
3243     // byte swapping.
3244 
3245     /*package-private*/
3246     abstract
3247     DoubleVector fromArray0(double[] a, int offset);
3248     @ForceInline
3249     final
3250     DoubleVector fromArray0Template(double[] a, int offset) {
3251         DoubleSpecies vsp = vspecies();
3252         return VectorIntrinsics.load(
3253             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3254             a, arrayAddress(a, offset),
3255             a, offset, vsp,
3256             (arr, off, s) -> s.ldOp(arr, off,
3257                                     (arr_, off_, i) -> arr_[off_ + i]));
3258     }
3259 
3260     @Override
3261     abstract
3262     DoubleVector fromByteArray0(byte[] a, int offset);
3263     @ForceInline
3264     final
3265     DoubleVector fromByteArray0Template(byte[] a, int offset) {
3266         DoubleSpecies vsp = vspecies();
3267         return VectorIntrinsics.load(
3268             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3269             a, byteArrayAddress(a, offset),
3270             a, offset, vsp,
3271             (arr, off, s) -> {
3272                 DoubleBuffer tb = wrapper(arr, off, NATIVE_ENDIAN);
3273                 return s.ldOp(tb, 0, (tb_, __, i) -> tb_.get(i));
3274             });
3275     }
3276 
3277     abstract
3278     DoubleVector fromByteBuffer0(ByteBuffer bb, int offset);
3279     @ForceInline
3280     final
3281     DoubleVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
3282         DoubleSpecies vsp = vspecies();
3283         return VectorIntrinsics.load(
3284             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3285             bufferBase(bb), bufferAddress(bb, offset),
3286             bb, offset, vsp,
3287             (buf, off, s) -> {
3288                 DoubleBuffer tb = wrapper(buf, off, NATIVE_ENDIAN);
3289                 return s.ldOp(tb, 0, (tb_, __, i) -> tb_.get(i));
3290            });
3291     }
3292 
3293     // Unchecked storing operations in native byte order.
3294     // Caller is reponsible for applying index checks, masking, and
3295     // byte swapping.
3296 
3297     abstract
3298     void intoArray0(double[] a, int offset);
3299     @ForceInline
3300     final
3301     void intoArray0Template(double[] a, int offset) {
3302         DoubleSpecies vsp = vspecies();
3303         VectorIntrinsics.store(
3304             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3305             a, arrayAddress(a, offset),
3306             this, a, offset,
3307             (arr, off, v)
3308             -> v.stOp(arr, off,
3309                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3310     }
3311 
3312     abstract
3313     void intoByteArray0(byte[] a, int offset);
3314     @ForceInline
3315     final
3316     void intoByteArray0Template(byte[] a, int offset) {
3317         DoubleSpecies vsp = vspecies();
3318         VectorIntrinsics.store(
3319             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3320             a, byteArrayAddress(a, offset),
3321             this, a, offset,
3322             (arr, off, v) -> {
3323                 DoubleBuffer tb = wrapper(arr, off, NATIVE_ENDIAN);
3324                 v.stOp(tb, 0, (tb_, __, i, e) -> tb_.put(i, e));
3325             });
3326     }
3327 
3328     @ForceInline
3329     final
3330     void intoByteBuffer0(ByteBuffer bb, int offset) {
3331         DoubleSpecies vsp = vspecies();
3332         VectorIntrinsics.store(
3333             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3334             bufferBase(bb), bufferAddress(bb, offset),
3335             this, bb, offset,
3336             (buf, off, v) -> {
3337                 DoubleBuffer tb = wrapper(buf, off, NATIVE_ENDIAN);
3338                 v.stOp(tb, 0, (tb_, __, i, e) -> tb_.put(i, e));
3339             });
3340     }
3341 
3342     // End of low-level memory operations.
3343 
3344     private static
3345     void checkMaskFromIndexSize(int offset,
3346                                 DoubleSpecies vsp,
3347                                 VectorMask<Double> m,
3348                                 int scale,
3349                                 int limit) {
3350         ((AbstractMask<Double>)m)
3351             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3352     }
3353 
3354     @ForceInline
3355     private void conditionalStoreNYI(int offset,
3356                                      DoubleSpecies vsp,
3357                                      VectorMask<Double> m,
3358                                      int scale,
3359                                      int limit) {
3360         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3361             String msg =
3362                 String.format("unimplemented: store @%d in [0..%d), %s in %s",
3363                               offset, limit, m, vsp);
3364             throw new AssertionError(msg);
3365         }
3366     }
3367 
3368     /*package-private*/
3369     @Override
3370     @ForceInline
3371     final
3372     DoubleVector maybeSwap(ByteOrder bo) {
3373         if (bo != NATIVE_ENDIAN) {
3374             return this.reinterpretAsBytes()
3375                 .rearrange(swapBytesShuffle())
3376                 .reinterpretAsDoubles();
3377         }
3378         return this;
3379     }
3380 
3381     static final int ARRAY_SHIFT =
3382         31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
3383     static final long ARRAY_BASE =
3384         Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
3385 
3386     @ForceInline
3387     static long arrayAddress(double[] a, int index) {
3388         return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
3389     }
3390 
3391     @ForceInline
3392     static long byteArrayAddress(byte[] a, int index) {
3393         return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
3394     }
3395 
3396     // Byte buffer wrappers.
3397     private static DoubleBuffer wrapper(ByteBuffer bb, int offset,
3398                                         ByteOrder bo) {
3399         return bb.duplicate().position(offset).slice()
3400             .order(bo).asDoubleBuffer();
3401     }
3402     private static DoubleBuffer wrapper(byte[] a, int offset,
3403                                         ByteOrder bo) {
3404         return ByteBuffer.wrap(a, offset, a.length - offset)
3405             .order(bo).asDoubleBuffer();
3406     }
3407 
3408     // ================================================
3409 
3410     /// Reinterpreting view methods:
3411     //   lanewise reinterpret: viewAsXVector()
3412     //   keep shape, redraw lanes: reinterpretAsEs()
3413 
3414     /**
3415      * {@inheritDoc} <!--workaround-->
3416      */
3417     @ForceInline
3418     @Override
3419     public final ByteVector reinterpretAsBytes() {
3420          // Going to ByteVector, pay close attention to byte order.
3421          assert(REGISTER_ENDIAN == ByteOrder.LITTLE_ENDIAN);
3422          return asByteVectorRaw();
3423          //return asByteVectorRaw().rearrange(swapBytesShuffle());
3424     }
3425 
3426     /**
3427      * {@inheritDoc} <!--workaround-->
3428      */
3429     @ForceInline
3430     @Override
3431     public final LongVector viewAsIntegralLanes() {
3432         LaneType ilt = LaneType.DOUBLE.asIntegral();
3433         return (LongVector) asVectorRaw(ilt);
3434     }
3435 
3436     /**
3437      * {@inheritDoc} <!--workaround-->
3438      */
3439     @ForceInline
3440     @Override
3441     public final
3442     DoubleVector
3443     viewAsFloatingLanes() {
3444         return this;
3445     }
3446 
3447     // ================================================
3448 
3449     /// Object methods: toString, equals, hashCode
3450     //
3451     // Object methods are defined as if via Arrays.toString, etc.,
3452     // is applied to the array of elements.  Two equal vectors
3453     // are required to have equal species and equal lane values.
3454 
3455     /**
3456      * Returns a string representation of this vector, of the form
3457      * {@code "[0,1,2...]"}, reporting the lane values of this vector,
3458      * in lane order.
3459      *
3460      * The string is produced as if by a call to {@link
3461      * java.util.Arrays#toString(double[]) Arrays.toString()},
3462      * as appropriate to the {@code double} array returned by
3463      * {@link #toArray this.toArray()}.
3464      *
3465      * @return a string of the form {@code "[0,1,2...]"}
3466      * reporting the lane values of this vector
3467      */
3468     @Override
3469     @ForceInline
3470     public final
3471     String toString() {
3472         // now that toArray is strongly typed, we can define this
3473         return Arrays.toString(toArray());
3474     }
3475 
3476     /**
3477      * {@inheritDoc} <!--workaround-->
3478      */
3479     @Override
3480     @ForceInline
3481     public final
3482     boolean equals(Object obj) {
3483         if (obj instanceof Vector) {
3484             Vector<?> that = (Vector<?>) obj;
3485             if (this.species().equals(that.species())) {
3486                 return this.eq(that.check(this.species())).allTrue();
3487             }
3488         }
3489         return false;
3490     }
3491 
3492     /**
3493      * {@inheritDoc} <!--workaround-->
3494      */
3495     @Override
3496     @ForceInline
3497     public final
3498     int hashCode() {
3499         // now that toArray is strongly typed, we can define this
3500         return Objects.hash(species(), Arrays.hashCode(toArray()));
3501     }
3502 
3503     // ================================================
3504 
3505     // Species
3506 
3507     /**
3508      * Class representing {@link DoubleVector}'s of the same {@link VectorShape VectorShape}.
3509      */
3510     /*package-private*/
3511     static final class DoubleSpecies extends AbstractSpecies<Double> {
3512         private DoubleSpecies(VectorShape shape,
3513                 Class<? extends DoubleVector> vectorType,
3514                 Class<? extends AbstractMask<Double>> maskType,
3515                 Function<Object, DoubleVector> vectorFactory) {
3516             super(shape, LaneType.of(double.class),
3517                   vectorType, maskType,
3518                   vectorFactory);
3519             assert(this.elementSize() == Double.SIZE);
3520         }
3521 
3522         // Specializing overrides:
3523 
3524         @Override
3525         @ForceInline
3526         public final Class<Double> elementType() {
3527             return double.class;
3528         }
3529 
3530         @Override
3531         @ForceInline
3532         public final Class<Double> genericElementType() {
3533             return Double.class;
3534         }
3535 
3536         @Override
3537         @ForceInline
3538         public final Class<double[]> arrayType() {
3539             return double[].class;
3540         }
3541 
3542         @SuppressWarnings("unchecked")
3543         @Override
3544         @ForceInline
3545         public final Class<? extends DoubleVector> vectorType() {
3546             return (Class<? extends DoubleVector>) vectorType;
3547         }
3548 
3549         @Override
3550         @ForceInline
3551         public final long checkValue(long e) {
3552             longToElementBits(e);  // only for exception
3553             return e;
3554         }
3555 
3556         /*package-private*/
3557         @Override
3558         @ForceInline
3559         final DoubleVector broadcastBits(long bits) {
3560             return (DoubleVector)
3561                 VectorIntrinsics.broadcastCoerced(
3562                     vectorType, double.class, laneCount,
3563                     bits, this,
3564                     (bits_, s_) -> s_.rvOp(i -> bits_));
3565         }
3566 
3567         /*package-private*/
3568         @ForceInline
3569         
3570         final DoubleVector broadcast(double e) {
3571             return broadcastBits(toBits(e));
3572         }
3573 
3574         @Override
3575         @ForceInline
3576         public final DoubleVector broadcast(long e) {
3577             return broadcastBits(longToElementBits(e));
3578         }
3579 
3580         /*package-private*/
3581         final @Override
3582         @ForceInline
3583         long longToElementBits(long value) {
3584             // Do the conversion, and then test it for failure.
3585             double e = (double) value;
3586             if ((long) e != value) {
3587                 throw badElementBits(value, e);
3588             }
3589             return toBits(e);
3590         }
3591 
3592         /*package-private*/
3593         @ForceInline
3594         static long toIntegralChecked(double e, boolean convertToInt) {
3595             long value = convertToInt ? (int) e : (long) e;
3596             if ((double) value != e) {
3597                 throw badArrayBits(e, convertToInt, value);
3598             }
3599             return value;
3600         }
3601 
3602         @Override
3603         @ForceInline
3604         public final DoubleVector fromValues(long... values) {
3605             VectorIntrinsics.requireLength(values.length, laneCount);
3606             double[] va = new double[laneCount()];
3607             for (int i = 0; i < va.length; i++) {
3608                 long lv = values[i];
3609                 double v = (double) lv;
3610                 va[i] = v;
3611                 if ((long)v != lv) {
3612                     throw badElementBits(lv, v);
3613                 }
3614             }
3615             return dummyVector().fromArray0(va, 0);
3616         }
3617 
3618         /* this non-public one is for internal conversions */
3619         @Override
3620         @ForceInline
3621         final DoubleVector fromIntValues(int[] values) {
3622             VectorIntrinsics.requireLength(values.length, laneCount);
3623             double[] va = new double[laneCount()];
3624             for (int i = 0; i < va.length; i++) {
3625                 int lv = values[i];
3626                 double v = (double) lv;
3627                 va[i] = v;
3628                 if ((int)v != lv) {
3629                     throw badElementBits(lv, v);
3630                 }
3631             }
3632             return dummyVector().fromArray0(va, 0);
3633         }
3634 
3635         // Virtual constructors
3636 
3637         @ForceInline
3638         @Override final
3639         public DoubleVector fromArray(Object a, int offset) {
3640             // User entry point:  Be careful with inputs.
3641             return DoubleVector
3642                 .fromArray(this, (double[]) a, offset);
3643         }
3644 
3645         @Override final
3646         DoubleVector dummyVector() {
3647             return (DoubleVector) super.dummyVector();
3648         }
3649 
3650         final
3651         DoubleVector vectorFactory(double[] vec) {
3652             // Species delegates all factory requests to its dummy
3653             // vector.  The dummy knows all about it.
3654             return dummyVector().vectorFactory(vec);
3655         }
3656 
3657         /*package-private*/
3658         final @Override
3659         @ForceInline
3660         DoubleVector rvOp(RVOp f) {
3661             double[] res = new double[laneCount()];
3662             for (int i = 0; i < res.length; i++) {
3663                 long bits = (long) f.apply(i);
3664                 res[i] = fromBits(bits);
3665             }
3666             return dummyVector().vectorFactory(res);
3667         }
3668 
3669         DoubleVector vOp(FVOp f) {
3670             double[] res = new double[laneCount()];
3671             for (int i = 0; i < res.length; i++) {
3672                 res[i] = f.apply(i);
3673             }
3674             return dummyVector().vectorFactory(res);
3675         }
3676 
3677         DoubleVector vOp(VectorMask<Double> m, FVOp f) {
3678             double[] res = new double[laneCount()];
3679             boolean[] mbits = ((AbstractMask<Double>)m).getBits();
3680             for (int i = 0; i < res.length; i++) {
3681                 if (mbits[i]) {
3682                     res[i] = f.apply(i);
3683                 }
3684             }
3685             return dummyVector().vectorFactory(res);
3686         }
3687 
3688         /*package-private*/
3689         @ForceInline
3690         <M> DoubleVector ldOp(M memory, int offset,
3691                                       FLdOp<M> f) {
3692             return dummyVector().ldOp(memory, offset, f);
3693         }
3694 
3695         /*package-private*/
3696         @ForceInline
3697         <M> DoubleVector ldOp(M memory, int offset,
3698                                       AbstractMask<Double> m,
3699                                       FLdOp<M> f) {
3700             return dummyVector().ldOp(memory, offset, m, f);
3701         }
3702 
3703         /*package-private*/
3704         @ForceInline
3705         <M> void stOp(M memory, int offset, FStOp<M> f) {
3706             dummyVector().stOp(memory, offset, f);
3707         }
3708 
3709         /*package-private*/
3710         @ForceInline
3711         <M> void stOp(M memory, int offset,
3712                       AbstractMask<Double> m,
3713                       FStOp<M> f) {
3714             dummyVector().stOp(memory, offset, m, f);
3715         }
3716 
3717         // N.B. Make sure these constant vectors and
3718         // masks load up correctly into registers.
3719         //
3720         // Also, see if we can avoid all that switching.
3721         // Could we cache both vectors and both masks in
3722         // this species object?
3723 
3724         // Zero and iota vector access
3725         @Override
3726         @ForceInline
3727         public final DoubleVector zero() {
3728             if ((Class<?>) vectorType() == DoubleMaxVector.class)
3729                 return DoubleMaxVector.ZERO;
3730             switch (vectorBitSize()) {
3731                 case 64: return Double64Vector.ZERO;
3732                 case 128: return Double128Vector.ZERO;
3733                 case 256: return Double256Vector.ZERO;
3734                 case 512: return Double512Vector.ZERO;
3735             }
3736             throw new AssertionError();
3737         }        
3738 
3739         @Override
3740         @ForceInline
3741         public final DoubleVector iota() {
3742             if ((Class<?>) vectorType() == DoubleMaxVector.class)
3743                 return DoubleMaxVector.IOTA;
3744             switch (vectorBitSize()) {
3745                 case 64: return Double64Vector.IOTA;
3746                 case 128: return Double128Vector.IOTA;
3747                 case 256: return Double256Vector.IOTA;
3748                 case 512: return Double512Vector.IOTA;
3749             }
3750             throw new AssertionError();
3751         }
3752 
3753         // Mask access
3754         @Override
3755         @ForceInline
3756         public final VectorMask<Double> maskAll(boolean bit) {
3757             if ((Class<?>) vectorType() == DoubleMaxVector.class)
3758                 return DoubleMaxVector.DoubleMaxMask.maskAll(bit);
3759             switch (vectorBitSize()) {
3760                 case 64: return Double64Vector.Double64Mask.maskAll(bit);
3761                 case 128: return Double128Vector.Double128Mask.maskAll(bit);
3762                 case 256: return Double256Vector.Double256Mask.maskAll(bit);
3763                 case 512: return Double512Vector.Double512Mask.maskAll(bit);
3764             }
3765             throw new AssertionError();
3766         }
3767     }
3768 
3769     /**
3770      * Finds a species for an element type of {@code double} and shape.
3771      *
3772      * @param s the shape
3773      * @return a species for an element type of {@code double} and shape
3774      * @throws IllegalArgumentException if no such species exists for the shape
3775      */
3776     static DoubleSpecies species(VectorShape s) {
3777         Objects.requireNonNull(s);
3778         switch (s) {
3779             case S_64_BIT: return (DoubleSpecies) SPECIES_64;
3780             case S_128_BIT: return (DoubleSpecies) SPECIES_128;
3781             case S_256_BIT: return (DoubleSpecies) SPECIES_256;
3782             case S_512_BIT: return (DoubleSpecies) SPECIES_512;
3783             case S_Max_BIT: return (DoubleSpecies) SPECIES_MAX;
3784             default: throw new IllegalArgumentException("Bad shape: " + s);
3785         }
3786     }
3787 
3788     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
3789     public static final VectorSpecies<Double> SPECIES_64
3790         = new DoubleSpecies(VectorShape.S_64_BIT,
3791                             Double64Vector.class,
3792                             Double64Vector.Double64Mask.class,
3793                             Double64Vector::new);
3794 
3795     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
3796     public static final VectorSpecies<Double> SPECIES_128
3797         = new DoubleSpecies(VectorShape.S_128_BIT,
3798                             Double128Vector.class,
3799                             Double128Vector.Double128Mask.class,
3800                             Double128Vector::new);
3801 
3802     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
3803     public static final VectorSpecies<Double> SPECIES_256
3804         = new DoubleSpecies(VectorShape.S_256_BIT,
3805                             Double256Vector.class,
3806                             Double256Vector.Double256Mask.class,
3807                             Double256Vector::new);
3808 
3809     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
3810     public static final VectorSpecies<Double> SPECIES_512
3811         = new DoubleSpecies(VectorShape.S_512_BIT,
3812                             Double512Vector.class,
3813                             Double512Vector.Double512Mask.class,
3814                             Double512Vector::new);
3815 
3816     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
3817     public static final VectorSpecies<Double> SPECIES_MAX
3818         = new DoubleSpecies(VectorShape.S_Max_BIT,
3819                             DoubleMaxVector.class,
3820                             DoubleMaxVector.DoubleMaxMask.class,
3821                             DoubleMaxVector::new);
3822 
3823     /**
3824      * Preferred species for {@link DoubleVector}s.
3825      * A preferred species is a species of maximal bit-size for the platform.
3826      */
3827     public static final VectorSpecies<Double> SPECIES_PREFERRED
3828         = (DoubleSpecies) VectorSpecies.ofPreferred(double.class);
3829 }