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(VectorSpecies,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.
 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 e the input scalar
 756      * @return the result of applying the operation lane-wise
 757      *         to the two input vectors
 758      * @throws UnsupportedOperationException if this vector does
 759      *         not support the requested operation
 760      * @see #lanewise(VectorOperators.Binary,Vector)
 761      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
 762      */
 763     @ForceInline
 764     public final
 765     DoubleVector lanewise(VectorOperators.Binary op,
 766                                   double e) {
 767         int opc = opCode(op);
 768         return lanewise(op, broadcast(e));
 769     }
 770 
 771     /**
 772      * Combines the lane values of this vector
 773      * with the value of a broadcast scalar,
 774      * with selection of lane elements controlled by a mask.
 775      *
 776      * This is a masked lane-wise binary operation which applies
 777      * the selected operation to each lane.
 778      * The return value will be equal to this expression:
 779      * {@code this.lanewise(op, this.broadcast(e), m)}.
 780      *
 781      * @param e the input scalar
 782      * @param m the mask controlling lane selection
 783      * @return the result of applying the operation lane-wise
 784      *         to the input vector and the scalar
 785      * @throws UnsupportedOperationException if this vector does
 786      *         not support the requested operation
 787      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
 788      * @see #lanewise(VectorOperators.Binary,double)
 789      */
 790     @ForceInline
 791     public final
 792     DoubleVector lanewise(VectorOperators.Binary op,
 793                                   double e,
 794                                   VectorMask<Double> m) {
 795         return blend(lanewise(op, e), m);
 796     }
 797 
 798     /**
 799      * {@inheritDoc} <!--workaround-->
 800      * @apiNote
 801      * When working with vector subtypes like {@code DoubleVector},
 802      * {@linkplain #lanewise(VectorOperators.Binary,double)
 803      * the more strongly typed method}
 804      * is typically selected.  It can be explicitly selected
 805      * using a cast: {@code v.lanewise(op,(double)e)}.
 806      * The two expressions will produce numerically identical results.
 807      */
 808     @ForceInline
 809     public final
 810     DoubleVector lanewise(VectorOperators.Binary op,
 811                                   long e) {
 812         double e1 = (double) e;
 813         if ((long)e1 != e
 814             ) {
 815             vspecies().checkValue(e);  // for exception
 816         }
 817         return lanewise(op, e1);
 818     }
 819 
 820     /**
 821      * {@inheritDoc} <!--workaround-->
 822      * @apiNote
 823      * When working with vector subtypes like {@code DoubleVector},
 824      * {@linkplain #lanewise(VectorOperators.Binary,double,VectorMask)
 825      * the more strongly typed method}
 826      * is typically selected.  It can be explicitly selected
 827      * using a cast: {@code v.lanewise(op,(double)e,m)}.
 828      * The two expressions will produce numerically identical results.
 829      */
 830     @ForceInline
 831     public final
 832     DoubleVector lanewise(VectorOperators.Binary op,
 833                                   long e, VectorMask<Double> m) {
 834         return blend(lanewise(op, e), m);
 835     }
 836 
 837 
 838     // Ternary lanewise support
 839 
 840     // Ternary operators come in eight variations:
 841     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2])
 842     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask)
 843 
 844     // It is annoying to support all of these variations of masking
 845     // and broadcast, but it would be more surprising not to continue
 846     // the obvious pattern started by unary and binary.
 847 
 848    /**
 849      * {@inheritDoc} <!--workaround-->
 850      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
 851      * @see #lanewise(VectorOperators.Ternary,Vector,double,VectorMask)
 852      * @see #lanewise(VectorOperators.Ternary,double,Vector,VectorMask)
 853      * @see #lanewise(VectorOperators.Ternary,double,double)
 854      * @see #lanewise(VectorOperators.Ternary,Vector,double)
 855      * @see #lanewise(VectorOperators.Ternary,double,Vector)
 856      */
 857     @Override
 858     public abstract
 859     DoubleVector lanewise(VectorOperators.Ternary op,
 860                                                   Vector<Double> v1,
 861                                                   Vector<Double> v2);
 862     @ForceInline
 863     final
 864     DoubleVector lanewiseTemplate(VectorOperators.Ternary op,
 865                                           Vector<Double> v1,
 866                                           Vector<Double> v2) {
 867         DoubleVector that = (DoubleVector) v1;
 868         DoubleVector tother = (DoubleVector) v2;
 869         // It's a word: https://www.dictionary.com/browse/tother
 870         // See also Chapter 11 of Dickens, Our Mutual Friend:
 871         // "Totherest Governor," replied Mr Riderhood...
 872         that.check(this);
 873         tother.check(this);
 874         int opc = opCode(op);
 875         return VectorIntrinsics.ternaryOp(
 876             opc, getClass(), double.class, length(),
 877             this, that, tother,
 878             TERN_IMPL.find(op, opc, (opc_) -> {
 879               switch (opc_) {
 880                 case VECTOR_OP_FMA: return (v0, v1_, v2_) ->
 881                         v0.tOp(v1_, v2_, (i, a, b, c) -> Math.fma(a, b, c));
 882                 default: return null;
 883                 }}));
 884     }
 885     private static final
 886     ImplCache<Ternary,TernaryOperation<DoubleVector>> TERN_IMPL
 887         = new ImplCache<>(Ternary.class, DoubleVector.class);
 888 
 889     /**
 890      * {@inheritDoc} <!--workaround-->
 891      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
 892      * @see #lanewise(VectorOperators.Ternary,Vector,double,VectorMask)
 893      * @see #lanewise(VectorOperators.Ternary,double,Vector,VectorMask)
 894      */
 895     @ForceInline
 896     public final
 897     DoubleVector lanewise(VectorOperators.Ternary op,
 898                                   Vector<Double> v1,
 899                                   Vector<Double> v2,
 900                                   VectorMask<Double> m) {
 901         return blend(lanewise(op, v1, v2), m);
 902     }
 903 
 904     /**
 905      * Combines the lane values of this vector
 906      * with the values of two broadcast scalars.
 907      *
 908      * This is a lane-wise ternary operation which applies
 909      * the selected operation to each lane.
 910      * The return value will be equal to this expression:
 911      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}.
 912      *
 913      * @param e1 the first input scalar
 914      * @param e2 the second input scalar
 915      * @return the result of applying the operation lane-wise
 916      *         to the input vector and the scalars
 917      * @throws UnsupportedOperationException if this vector does
 918      *         not support the requested operation
 919      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 920      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
 921      */
 922     @ForceInline
 923     public final
 924     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,e2)
 925                                   double e1,
 926                                   double e2) {
 927         return lanewise(op, broadcast(e1), broadcast(e1));
 928     }
 929 
 930     /**
 931      * Combines the lane values of this vector
 932      * with the values of two broadcast scalars,
 933      * with selection of lane elements controlled by a mask.
 934      *
 935      * This is a masked lane-wise ternary operation which applies
 936      * the selected operation to each lane.
 937      * The return value will be equal to this expression:
 938      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}.
 939      *
 940      * @param e1 the first input scalar
 941      * @param e2 the second input scalar
 942      * @param m the mask controlling lane selection
 943      * @return the result of applying the operation lane-wise
 944      *         to the input vector and the scalars
 945      * @throws UnsupportedOperationException if this vector does
 946      *         not support the requested operation
 947      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
 948      * @see #lanewise(VectorOperators.Ternary,double,double)
 949      */
 950     @ForceInline
 951     public final
 952     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m)
 953                                   double e1,
 954                                   double e2,
 955                                   VectorMask<Double> m) {
 956         return blend(lanewise(op, e1, e2), m);
 957     }
 958 
 959     /**
 960      * Combines the lane values of this vector
 961      * with the values of another vector and a broadcast scalar.
 962      *
 963      * This is a lane-wise ternary operation which applies
 964      * the selected operation to each lane.
 965      * The return value will be equal to this expression:
 966      * {@code this.lanewise(op, v1, this.broadcast(e2))}.
 967      *
 968      * @param v1 the other input vector
 969      * @param e2 the input scalar
 970      * @return the result of applying the operation lane-wise
 971      *         to the input vectors and the scalar
 972      * @throws UnsupportedOperationException if this vector does
 973      *         not support the requested operation
 974      * @see #lanewise(VectorOperators.Ternary,double,double)
 975      * @see #lanewise(VectorOperators.Ternary,Vector,double,VectorMask)
 976      */
 977     @ForceInline
 978     public final
 979     DoubleVector lanewise(VectorOperators.Ternary op, //(op,v1,e2)
 980                                   Vector<Double> v1,
 981                                   double e2) {
 982         return lanewise(op, v1, broadcast(e2));
 983     }
 984 
 985     /**
 986      * Combines the lane values of this vector
 987      * with the values of another vector and a broadcast scalar,
 988      * with selection of lane elements controlled by a mask.
 989      *
 990      * This is a masked lane-wise ternary operation which applies
 991      * the selected operation to each lane.
 992      * The return value will be equal to this expression:
 993      * {@code this.lanewise(op, v1, this.broadcast(e2), m)}.
 994      *
 995      * @param v1 the other input vector
 996      * @param e2 the input scalar
 997      * @param m the mask controlling lane selection
 998      * @return the result of applying the operation lane-wise
 999      *         to the input vectors and the scalar
1000      * @throws UnsupportedOperationException if this vector does
1001      *         not support the requested operation
1002      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1003      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
1004      * @see #lanewise(VectorOperators.Ternary,Vector,double)
1005      */
1006     @ForceInline
1007     public final
1008     DoubleVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m)
1009                                   Vector<Double> v1,
1010                                   double e2,
1011                                   VectorMask<Double> m) {
1012         return blend(lanewise(op, v1, e2), m);
1013     }
1014 
1015     /**
1016      * Combines the lane values of this vector
1017      * with the values of another vector and a broadcast scalar.
1018      *
1019      * This is a lane-wise ternary operation which applies
1020      * the selected operation to each lane.
1021      * The return value will be equal to this expression:
1022      * {@code this.lanewise(op, this.broadcast(e1), v2)}.
1023      *
1024      * @param e1 the input scalar
1025      * @param v2 the other input vector
1026      * @return the result of applying the operation lane-wise
1027      *         to the input vectors and the scalar
1028      * @throws UnsupportedOperationException if this vector does
1029      *         not support the requested operation
1030      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1031      * @see #lanewise(VectorOperators.Ternary,double,Vector,VectorMask)
1032      */
1033     @ForceInline
1034     public final
1035     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,v2)
1036                                   double e1,
1037                                   Vector<Double> v2) {
1038         return lanewise(op, broadcast(e1), v2);
1039     }
1040 
1041     /**
1042      * Combines the lane values of this vector
1043      * with the values of another vector and a broadcast scalar,
1044      * with selection of lane elements controlled by a mask.
1045      *
1046      * This is a masked lane-wise ternary operation which applies
1047      * the selected operation to each lane.
1048      * The return value will be equal to this expression:
1049      * {@code this.lanewise(op, this.broadcast(e1), v2, m)}.
1050      *
1051      * @param e1 the input scalar
1052      * @param v2 the other input vector
1053      * @param m the mask controlling lane selection
1054      * @return the result of applying the operation lane-wise
1055      *         to the input vectors and the scalar
1056      * @throws UnsupportedOperationException if this vector does
1057      *         not support the requested operation
1058      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
1059      * @see #lanewise(VectorOperators.Ternary,double,Vector)
1060      */
1061     @ForceInline
1062     public final
1063     DoubleVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m)
1064                                   double e1,
1065                                   Vector<Double> v2,
1066                                   VectorMask<Double> m) {
1067         return blend(lanewise(op, e1, v2), m);
1068     }
1069 
1070     // (Thus endeth the Great and Mighty Ternary Ogdoad.)
1071     // https://en.wikipedia.org/wiki/Ogdoad
1072 
1073     /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV
1074     //
1075     // These include masked and non-masked versions.
1076     // This subclass adds broadcast (masked or not).
1077 
1078     /**
1079      * {@inheritDoc} <!--workaround-->
1080      * @see #add(double)
1081      */
1082     @Override
1083     @ForceInline
1084     public final DoubleVector add(Vector<Double> v) {
1085         return lanewise(ADD, v);
1086     }
1087 
1088     /**
1089      * Adds this vector to the broadcast of an input scalar.
1090      *
1091      * This is a lane-wise binary operation which applies
1092      * the primitive addition operation ({@code +}) to each lane.
1093      *
1094      * This method is also equivalent to the expression
1095      * {@link #lanewise(VectorOperators.Binary,double)
1096      *    lanewise}{@code (}{@link VectorOperators#ADD
1097      *    ADD}{@code , e)}.
1098      *
1099      * @param e the input scalar
1100      * @return the result of adding each lane of this vector to the scalar
1101      * @see #add(Vector)
1102      * @see #broadcast(double)
1103      * @see #add(int,VectorMask)
1104      * @see VectorOperators#ADD
1105      * @see #lanewise(VectorOperators.Binary,Vector)
1106      * @see #lanewise(VectorOperators.Binary,double)
1107      */
1108     @ForceInline
1109     public final
1110     DoubleVector add(double e) {
1111         return lanewise(ADD, e);
1112     }
1113 
1114     /**
1115      * {@inheritDoc} <!--workaround-->
1116      * @see #add(double,VectorMask)
1117      */
1118     @Override
1119     @ForceInline
1120     public final DoubleVector add(Vector<Double> v,
1121                                           VectorMask<Double> m) {
1122         return lanewise(ADD, v, m);
1123     }
1124 
1125     /**
1126      * Adds this vector to the broadcast of an input scalar,
1127      * selecting lane elements controlled by a mask.
1128      *
1129      * This is a masked lane-wise binary operation which applies
1130      * the primitive addition operation ({@code +}) to each lane.
1131      *
1132      * This method is also equivalent to the expression
1133      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1134      *    lanewise}{@code (}{@link VectorOperators#ADD
1135      *    ADD}{@code , s, m)}.
1136      *
1137      * @param e the input scalar
1138      * @param m the mask controlling lane selection
1139      * @return the result of adding each lane of this vector to the scalar
1140      * @see #add(Vector,VectorMask)
1141      * @see #broadcast(double)
1142      * @see #add(int)
1143      * @see VectorOperators#ADD
1144      * @see #lanewise(VectorOperators.Binary,Vector)
1145      * @see #lanewise(VectorOperators.Binary,double)
1146      */
1147     @ForceInline
1148     public final DoubleVector add(double e,
1149                                           VectorMask<Double> m) {
1150         return lanewise(ADD, e, m);
1151     }
1152 
1153     /**
1154      * {@inheritDoc} <!--workaround-->
1155      * @see #sub(double)
1156      */
1157     @Override
1158     @ForceInline
1159     public final DoubleVector sub(Vector<Double> v) {
1160         return lanewise(SUB, v);
1161     }
1162 
1163     /**
1164      * Subtracts an input scalar from this vector.
1165      *
1166      * This is a masked lane-wise binary operation which applies
1167      * the primitive subtraction operation ({@code -}) to each lane.
1168      *
1169      * This method is also equivalent to the expression
1170      * {@link #lanewise(VectorOperators.Binary,double)
1171      *    lanewise}{@code (}{@link VectorOperators#SUB
1172      *    SUB}{@code , e)}.
1173      *
1174      * @param e the input scalar
1175      * @return the result of subtracting the scalar from each lane of this vector
1176      * @see #sub(Vector)
1177      * @see #broadcast(double)
1178      * @see #sub(int,VectorMask)
1179      * @see VectorOperators#SUB
1180      * @see #lanewise(VectorOperators.Binary,Vector)
1181      * @see #lanewise(VectorOperators.Binary,double)
1182      */
1183     @ForceInline
1184     public final DoubleVector sub(double e) {
1185         return lanewise(SUB, e);
1186     }
1187 
1188     /**
1189      * {@inheritDoc} <!--workaround-->
1190      * @see #sub(double,VectorMask)
1191      */
1192     @Override
1193     @ForceInline
1194     public final DoubleVector sub(Vector<Double> v,
1195                                           VectorMask<Double> m) {
1196         return lanewise(SUB, v, m);
1197     }
1198 
1199     /**
1200      * Subtracts an input scalar from this vector
1201      * under the control of a mask.
1202      *
1203      * This is a masked lane-wise binary operation which applies
1204      * the primitive subtraction operation ({@code -}) to each lane.
1205      *
1206      * This method is also equivalent to the expression
1207      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1208      *    lanewise}{@code (}{@link VectorOperators#SUB
1209      *    SUB}{@code , s, m)}.
1210      *
1211      * @param e the input scalar
1212      * @param m the mask controlling lane selection
1213      * @return the result of subtracting the scalar from each lane of this vector
1214      * @see #sub(Vector,VectorMask)
1215      * @see #broadcast(double)
1216      * @see #sub(int)
1217      * @see VectorOperators#SUB
1218      * @see #lanewise(VectorOperators.Binary,Vector)
1219      * @see #lanewise(VectorOperators.Binary,double)
1220      */
1221     @ForceInline
1222     public final DoubleVector sub(double e,
1223                                           VectorMask<Double> m) {
1224         return lanewise(SUB, e, m);
1225     }
1226 
1227     /**
1228      * {@inheritDoc} <!--workaround-->
1229      * @see #mul(double)
1230      */
1231     @Override
1232     @ForceInline
1233     public final DoubleVector mul(Vector<Double> v) {
1234         return lanewise(MUL, v);
1235     }
1236 
1237     /**
1238      * Multiplies this vector by the broadcast of an input scalar.
1239      *
1240      * This is a lane-wise binary operation which applies
1241      * the primitive multiplication operation ({@code *}) to each lane.
1242      *
1243      * This method is also equivalent to the expression
1244      * {@link #lanewise(VectorOperators.Binary,double)
1245      *    lanewise}{@code (}{@link VectorOperators#MUL
1246      *    MUL}{@code , e)}.
1247      *
1248      * @param e the input scalar
1249      * @return the result of multiplying this vector by the given scalar
1250      * @see #mul(Vector)
1251      * @see #broadcast(double)
1252      * @see #mul(int,VectorMask)
1253      * @see VectorOperators#MUL
1254      * @see #lanewise(VectorOperators.Binary,Vector)
1255      * @see #lanewise(VectorOperators.Binary,double)
1256      */
1257     @ForceInline
1258     public final DoubleVector mul(double e) {
1259         return lanewise(MUL, e);
1260     }
1261 
1262     /**
1263      * {@inheritDoc} <!--workaround-->
1264      * @see #mul(double,VectorMask)
1265      */
1266     @Override
1267     @ForceInline
1268     public final DoubleVector mul(Vector<Double> v,
1269                                           VectorMask<Double> m) {
1270         return lanewise(MUL, v, m);
1271     }
1272 
1273     /**
1274      * Multiplies this vector by the broadcast of an input scalar,
1275      * selecting lane elements controlled by a mask.
1276      *
1277      * This is a masked lane-wise binary operation which applies
1278      * the primitive multiplication operation ({@code *}) to each lane.
1279      *
1280      * This method is also equivalent to the expression
1281      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1282      *    lanewise}{@code (}{@link VectorOperators#MUL
1283      *    MUL}{@code , s, m)}.
1284      *
1285      * @param e the input scalar
1286      * @param m the mask controlling lane selection
1287      * @return the result of muling each lane of this vector to the scalar
1288      * @see #mul(Vector,VectorMask)
1289      * @see #broadcast(double)
1290      * @see #mul(int)
1291      * @see VectorOperators#MUL
1292      * @see #lanewise(VectorOperators.Binary,Vector)
1293      * @see #lanewise(VectorOperators.Binary,double)
1294      */
1295     @ForceInline
1296     public final DoubleVector mul(double e,
1297                                           VectorMask<Double> m) {
1298         return lanewise(MUL, e, m);
1299     }
1300 
1301     /**
1302      * {@inheritDoc} <!--workaround-->
1303      * @see #div(double)
1304      * <p> Because the underlying scalar operator is an IEEE
1305      * floating point number, division by zero in fact will
1306      * not throw an exception, but will yield a signed
1307      * infinity or NaN.
1308      */
1309     @Override
1310     @ForceInline
1311     public final DoubleVector div(Vector<Double> v) {
1312         return lanewise(DIV, v);
1313     }
1314 
1315     /**
1316      * Divides this vector by the broadcast of an input scalar.
1317      *
1318      * This is a lane-wise binary operation which applies
1319      * the primitive division operation ({@code /}) to each lane.
1320      *
1321      * This method is also equivalent to the expression
1322      * {@link #lanewise(VectorOperators.Binary,double)
1323      *    lanewise}{@code (}{@link VectorOperators#DIV
1324      *    DIV}{@code , e)}.
1325      *
1326      * <p>
1327      * If the underlying scalar operator does not support
1328      * division by zero, but is presented with a zero divisor,
1329      * an {@code ArithmeticException} will be thrown.
1330      * Because the underlying scalar operator is an IEEE
1331      * floating point number, division by zero in fact will
1332      * not throw an exception, but will yield a signed
1333      * infinity or NaN.
1334      *
1335      * @param e the input scalar
1336      * @return the result of dividing each lane of this vector by the scalar
1337      * @see #div(Vector)
1338      * @see #broadcast(double)
1339      * @see #div(int,VectorMask)
1340      * @see VectorOperators#DIV
1341      * @see #lanewise(VectorOperators.Binary,Vector)
1342      * @see #lanewise(VectorOperators.Binary,double)
1343      */
1344     @ForceInline
1345     public final DoubleVector div(double e) {
1346         return lanewise(DIV, e);
1347     }
1348 
1349     /**
1350      * {@inheritDoc} <!--workaround-->
1351      * @see #div(double,VectorMask)
1352      * <p> Because the underlying scalar operator is an IEEE
1353      * floating point number, division by zero in fact will
1354      * not throw an exception, but will yield a signed
1355      * infinity or NaN.
1356      */
1357     @Override
1358     @ForceInline
1359     public final DoubleVector div(Vector<Double> v,
1360                                           VectorMask<Double> m) {
1361         return lanewise(DIV, v, m);
1362     }
1363 
1364     /**
1365      * Divides this vector by the broadcast of an input scalar,
1366      * selecting lane elements controlled by a mask.
1367      *
1368      * This is a masked lane-wise binary operation which applies
1369      * the primitive division operation ({@code /}) to each lane.
1370      *
1371      * This method is also equivalent to the expression
1372      * {@link #lanewise(VectorOperators.Binary,double,VectorMask)
1373      *    lanewise}{@code (}{@link VectorOperators#DIV
1374      *    DIV}{@code , s, m)}.
1375      *
1376      * <p>
1377      * If the underlying scalar operator does not support
1378      * division by zero, but is presented with a zero divisor,
1379      * an {@code ArithmeticException} will be thrown.
1380      * Because the underlying scalar operator is an IEEE
1381      * floating point number, division by zero in fact will
1382      * not throw an exception, but will yield a signed
1383      * infinity or NaN.
1384      *
1385      * @param e the input scalar
1386      * @param m the mask controlling lane selection
1387      * @return the result of dividing each lane of this vector by the scalar
1388      * @see #div(Vector,VectorMask)
1389      * @see #broadcast(double)
1390      * @see #div(int)
1391      * @see VectorOperators#DIV
1392      * @see #lanewise(VectorOperators.Binary,Vector)
1393      * @see #lanewise(VectorOperators.Binary,double)
1394      */
1395     @ForceInline
1396     public final DoubleVector div(double e,
1397                                           VectorMask<Double> m) {
1398         return lanewise(DIV, e, m);
1399     }
1400 
1401     /// END OF FULL-SERVICE BINARY METHODS
1402 
1403     /// SECOND-TIER BINARY METHODS
1404     //
1405     // There are no masked versions.
1406 
1407     /**
1408      * {@inheritDoc} <!--workaround-->
1409      * @apiNote
1410      * For this method, floating point negative
1411      * zero {@code -0.0} is treated as a value distinct from, and less
1412      * than, the default zero value.
1413      */
1414     @Override
1415     @ForceInline
1416     public final DoubleVector min(Vector<Double> v) {
1417         return lanewise(MIN, v);
1418     }
1419 
1420     // FIXME:  "broadcast of an input scalar" is really wordy.  Reduce?
1421     /**
1422      * Computes the smaller of this vector and the broadcast of an input scalar.
1423      *
1424      * This is a lane-wise binary operation which appliesthe
1425      * operation {@code (a, b) -> a < b ? a : b} to each pair of
1426      * corresponding lane values.
1427      *
1428      * This method is also equivalent to the expression
1429      * {@link #lanewise(VectorOperators.Binary,double)
1430      *    lanewise}{@code (}{@link VectorOperators#MIN
1431      *    MIN}{@code , e)}.
1432      *
1433      * @param e the input scalar
1434      * @return the result of multiplying this vector by the given scalar
1435      * @see #min(Vector)
1436      * @see #broadcast(double)
1437      * @see VectorOperators#MIN
1438      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
1439      * @apiNote
1440      * For this method, floating point negative
1441      * zero {@code -0.0} is treated as a value distinct from, and less
1442      * than, the default zero value.
1443      */
1444     @ForceInline
1445     public final DoubleVector min(double e) {
1446         return lanewise(MIN, e);
1447     }
1448 
1449     /**
1450      * {@inheritDoc} <!--workaround-->
1451      * @apiNote
1452      * For this method, negative floating-point zero compares
1453      * less than the default value, positive zero.
1454      */
1455     @Override
1456     @ForceInline
1457     public final DoubleVector max(Vector<Double> v) {
1458         return lanewise(MAX, v);
1459     }
1460 
1461     /**
1462      * Computes the larger of this vector and the broadcast of an input scalar.
1463      *
1464      * This is a lane-wise binary operation which appliesthe
1465      * operation {@code (a, b) -> a > b ? a : b} to each pair of
1466      * corresponding lane values.
1467      *
1468      * This method is also equivalent to the expression
1469      * {@link #lanewise(VectorOperators.Binary,double)
1470      *    lanewise}{@code (}{@link VectorOperators#MAX
1471      *    MAX}{@code , e)}.
1472      *
1473      * @param e the input scalar
1474      * @return the result of multiplying this vector by the given scalar
1475      * @see #max(Vector)
1476      * @see #broadcast(double)
1477      * @see VectorOperators#MAX
1478      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
1479      * @apiNote
1480      * For this method, negative floating-point zero compares
1481      * less than the default value, positive zero.
1482      */
1483     @ForceInline
1484     public final DoubleVector max(double e) {
1485         return lanewise(MAX, e);
1486     }
1487 
1488 
1489     // common FP operator: pow
1490     /**
1491      * Raises this vector to the power of a second input vector.
1492      *
1493      * This is a lane-wise binary operation which applies the
1494      * method {@code Math.pow()}
1495      * to each pair of corresponding lane values.
1496      *
1497      * This method is also equivalent to the expression
1498      * {@link #lanewise(VectorOperators.Binary,Vector)
1499      *    lanewise}{@code (}{@link VectorOperators#POW
1500      *    POW}{@code , n)}.
1501      *
1502      * <p>
1503      * This is not a full-service named operation like
1504      * {@link #add(Vector) add}.  A masked version of
1505      * version of this operation is not directly available
1506      * but may be obtained via the masked version of
1507      * {@code lanewise}.
1508      *
1509      * @param n a vector exponent by which to raise this vector
1510      * @return the {@code n}-th power of this vector
1511      * @see #pow(double)
1512      * @see VectorOperators#POW
1513      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
1514      */
1515     @ForceInline
1516     public final DoubleVector pow(Vector<Double> n) {
1517         return lanewise(POW, n);
1518     }
1519 
1520     /**
1521      * Raises this vector to a scalar power.
1522      *
1523      * This is a lane-wise binary operation which applies the
1524      * method {@code Math.pow()}
1525      * to each pair of corresponding lane values.
1526      *
1527      * This method is also equivalent to the expression
1528      * {@link #lanewise(VectorOperators.Binary,Vector)
1529      *    lanewise}{@code (}{@link VectorOperators#POW
1530      *    POW}{@code , n)}.
1531      *
1532      * @param n a scalar exponent by which to raise this vector
1533      * @return the {@code n}-th power of this vector
1534      * @see #pow(Vector)
1535      * @see VectorOperators#POW
1536      * @see #lanewise(VectorOperators.Binary,double,VectorMask)
1537      */
1538     @ForceInline
1539     public final DoubleVector pow(double n) {
1540         return lanewise(POW, n);
1541     }
1542 
1543     /// UNARY METHODS
1544 
1545     /**
1546      * {@inheritDoc} <!--workaround-->
1547      */
1548     @Override
1549     @ForceInline
1550     public final
1551     DoubleVector neg() {
1552         return lanewise(NEG);
1553     }
1554 
1555     /**
1556      * {@inheritDoc} <!--workaround-->
1557      */
1558     @Override
1559     @ForceInline
1560     public final
1561     DoubleVector abs() {
1562         return lanewise(ABS);
1563     }
1564 
1565 
1566     // sqrt
1567     /**
1568      * Computes the square root of this vector.
1569      *
1570      * This is a lane-wise unary operation which applies the
1571      * the method {@code Math.sqrt()}
1572      * to each lane value.
1573      *
1574      * This method is also equivalent to the expression
1575      * {@link #lanewise(VectorOperators.Unary,Vector)
1576      *    lanewise}{@code (}{@link VectorOperators#SQRT
1577      *    SQRT}{@code )}.
1578      *
1579      * @return the square root of this vector
1580      * @see VectorOperators#SQRT
1581      * @see #lanewise(VectorOperators.Unary,Vector,VectorMask)
1582      */
1583     @ForceInline
1584     public final DoubleVector sqrt() {
1585         return lanewise(SQRT);
1586     }
1587 
1588     /// COMPARISONS
1589 
1590     /**
1591      * {@inheritDoc} <!--workaround-->
1592      */
1593     @Override
1594     @ForceInline
1595     public final
1596     VectorMask<Double> eq(Vector<Double> v) {
1597         return compare(EQ, v);
1598     }
1599 
1600     /**
1601      * Tests if this vector is equal to an input scalar.
1602      *
1603      * This is a lane-wise binary test operation which applies
1604      * the primitive equals operation ({@code ==}) to each lane.
1605      * The result is the same as {@code compare(VectorOperators.Comparison.EQ, e)}.
1606      *
1607      * @param e the input scalar
1608      * @return the result mask of testing if this vector
1609      *         is equal to {@code e}
1610      * @see #compare(VectorOperators.Comparison,double)
1611      */
1612     @ForceInline
1613     public final
1614     VectorMask<Double> eq(double e) {
1615         return compare(EQ, e);
1616     }
1617 
1618     /**
1619      * {@inheritDoc} <!--workaround-->
1620      */
1621     @Override
1622     @ForceInline
1623     public final
1624     VectorMask<Double> lt(Vector<Double> v) {
1625         return compare(LT, v);
1626     }
1627 
1628     /**
1629      * Tests if this vector is less than an input scalar.
1630      *
1631      * This is a lane-wise binary test operation which applies
1632      * the primitive less than operation ({@code <}) to each lane.
1633      * The result is the same as {@code compare(VectorOperators.LT, e)}.
1634      *
1635      * @param e the input scalar
1636      * @return the mask result of testing if this vector
1637      *         is less than the input scalar
1638      * @see #compare(VectorOperators.Comparison,double)
1639      */
1640     @ForceInline
1641     public final
1642     VectorMask<Double> lt(double e) {
1643         return compare(LT, e);
1644     }
1645 
1646     /**
1647      * {@inheritDoc} <!--workaround-->
1648      */
1649     @Override
1650     public abstract
1651     VectorMask<Double> compare(VectorOperators.Comparison op, Vector<Double> v);
1652 
1653     /*package-private*/
1654     @ForceInline
1655     final
1656     <M extends VectorMask<Double>>
1657     M compareTemplate(Class<M> maskType, Comparison op, Vector<Double> v) {
1658         Objects.requireNonNull(v);
1659         DoubleSpecies vsp = vspecies();
1660         int opc = opCode(op);
1661         return VectorIntrinsics.compare(
1662             opc, getClass(), maskType, double.class, length(),
1663             this, (DoubleVector) v,
1664             (cond, v0, v1) -> {
1665                 AbstractMask<Double> m
1666                     = v0.bTest(cond, v1, (cond_, i, a, b)
1667                                -> compareWithOp(cond, a, b));
1668                 @SuppressWarnings("unchecked")
1669                 M m2 = (M) m;
1670                 return m2;
1671             });
1672     }
1673 
1674     @ForceInline
1675     private static
1676     boolean compareWithOp(int cond, double a, double b) {
1677         switch (cond) {
1678         case VectorIntrinsics.BT_eq:  return a == b;
1679         case VectorIntrinsics.BT_ne:  return a != b;
1680         case VectorIntrinsics.BT_lt:  return a <  b;
1681         case VectorIntrinsics.BT_le:  return a <= b;
1682         case VectorIntrinsics.BT_gt:  return a >  b;
1683         case VectorIntrinsics.BT_ge:  return a >= b;
1684         }
1685         throw new AssertionError();
1686     }
1687 
1688     /**
1689      * {@inheritDoc} <!--workaround-->
1690      */
1691     @Override
1692     @ForceInline
1693     public final
1694     VectorMask<Double> compare(VectorOperators.Comparison op,
1695                                   Vector<Double> v,
1696                                   VectorMask<Double> m) {
1697         return compare(op, v).and(m);
1698     }
1699 
1700     /**
1701      * Tests this vector by comparing it with an input scalar,
1702      * according to the given comparison operation.
1703      *
1704      * This is a lane-wise binary test operation which applies
1705      * the comparison operation to each lane.
1706      * <p>
1707      * The result is the same as
1708      * {@code compare(op, broadcast(species(), e))}.
1709      * That is, the scalar may be regarded as broadcast to
1710      * a vector of the same species, and then compared
1711      * against the original vector, using the selected
1712      * comparison operation.
1713      *
1714      * @param e the input scalar
1715      * @return the mask result of testing lane-wise if this vector
1716      *         compares to the input, according to the selected
1717      *         comparison operator
1718      * @see DoubleVector#compare(VectorOperators.Comparison,Vector)
1719      * @see #eq(double)
1720      * @see #lt(double)
1721      */
1722     public abstract
1723     VectorMask<Double> compare(Comparison op, double e);
1724 
1725     /*package-private*/
1726     @ForceInline
1727     final
1728     <M extends VectorMask<Double>>
1729     M compareTemplate(Class<M> maskType, Comparison op, double e) {
1730         return compareTemplate(maskType, op, broadcast(e));
1731     }
1732 
1733     /**
1734      * Tests this vector by comparing it with an input scalar,
1735      * according to the given comparison operation,
1736      * in lanes selected by a mask.
1737      *
1738      * This is a masked lane-wise binary test operation which applies
1739      * to each pair of corresponding lane values.
1740      *
1741      * The returned result is equal to the expression
1742      * {@code compare(op,s).and(m)}.
1743      *
1744      * @param e the input scalar
1745      * @param m the mask controlling lane selection
1746      * @return the mask result of testing lane-wise if this vector
1747      *         compares to the input, according to the selected
1748      *         comparison operator,
1749      *         and only in the lanes selected by the mask
1750      * @see DoubleVector#compare(VectorOperators.Comparison,Vector,VectorMask)
1751      */
1752     @ForceInline
1753     public final VectorMask<Double> compare(VectorOperators.Comparison op,
1754                                                double e,
1755                                                VectorMask<Double> m) {
1756         return compare(op, e).and(m);
1757     }
1758 
1759     /**
1760      * {@inheritDoc} <!--workaround-->
1761      */
1762     @Override
1763     public abstract
1764     VectorMask<Double> compare(Comparison op, long e);
1765 
1766     /*package-private*/
1767     @ForceInline
1768     final
1769     <M extends VectorMask<Double>>
1770     M compareTemplate(Class<M> maskType, Comparison op, long e) {
1771         return compareTemplate(maskType, op, broadcast(e));
1772     }
1773 
1774     /**
1775      * {@inheritDoc} <!--workaround-->
1776      */
1777     @Override
1778     @ForceInline
1779     public final
1780     VectorMask<Double> compare(Comparison op, long e, VectorMask<Double> m) {
1781         return compare(op, broadcast(e), m);
1782     }
1783 
1784 
1785 
1786     /**
1787      * {@inheritDoc} <!--workaround-->
1788      */
1789     @Override public abstract
1790     DoubleVector blend(Vector<Double> v, VectorMask<Double> m);
1791 
1792     /*package-private*/
1793     @ForceInline
1794     final
1795     <M extends VectorMask<Double>>
1796     DoubleVector
1797     blendTemplate(Class<M> maskType, DoubleVector v, M m) {
1798         v.check(this);
1799         return VectorIntrinsics.blend(
1800             getClass(), maskType, double.class, length(),
1801             this, v, m,
1802             (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b));
1803     }
1804 
1805     /**
1806      * {@inheritDoc} <!--workaround-->
1807      */
1808     @Override public abstract DoubleVector addIndex(int scale);
1809 
1810     /*package-private*/
1811     @ForceInline
1812     final DoubleVector addIndexTemplate(int scale) {
1813         DoubleSpecies vsp = vspecies();
1814         // make sure VLENGTH*scale doesn't overflow:
1815         vsp.checkScale(scale);
1816         return VectorIntrinsics.indexVector(
1817             getClass(), double.class, length(),
1818             this, scale, vsp,
1819             (v, scale_, s)
1820             -> {
1821                 // If the platform doesn't support an INDEX
1822                 // instruction directly, load IOTA from memory
1823                 // and multiply.
1824                 DoubleVector iota = s.iota();
1825                 double sc = (double) scale_;
1826                 return v.add(sc == 1 ? iota : iota.mul(sc));
1827             });
1828     }
1829 
1830     /**
1831      * Replaces selected lanes of this vector with
1832      * a scalar value
1833      * under the control of a mask.
1834      *
1835      * This is a masked lane-wise binary operation which
1836      * selects each lane value from one or the other input.
1837      *
1838      * The returned result is equal to the expression
1839      * {@code blend(broadcast(e),m)}.
1840      *
1841      * @param e the input scalar, containing the replacement lane value
1842      * @param m the mask controlling lane selection of the scalar
1843      * @return the result of blending the lane elements of this vector with
1844      *         the scalar value
1845      */
1846     @ForceInline
1847     public final DoubleVector blend(double e,
1848                                             VectorMask<Double> m) {
1849         return blend(broadcast(e), m);
1850     }
1851 
1852     /**
1853      * Replaces selected lanes of this vector with
1854      * a scalar value
1855      * under the control of a mask.
1856      *
1857      * This is a masked lane-wise binary operation which
1858      * selects each lane value from one or the other input.
1859      *
1860      * The returned result is equal to the expression
1861      * {@code blend(broadcast(e),m)}.
1862      *
1863      * @param e the input scalar, containing the replacement lane value
1864      * @param m the mask controlling lane selection of the scalar
1865      * @return the result of blending the lane elements of this vector with
1866      *         the scalar value
1867      */
1868     @ForceInline
1869     public final DoubleVector blend(long e,
1870                                             VectorMask<Double> m) {
1871         return blend(broadcast(e), m);
1872     }
1873 
1874     /**
1875      * {@inheritDoc} <!--workaround-->
1876      */
1877     @Override
1878     public abstract
1879     DoubleVector slice(int origin, Vector<Double> v1);
1880 
1881     /*package-private*/
1882     final
1883     @ForceInline
1884     DoubleVector sliceTemplate(int origin, Vector<Double> v1) {
1885         DoubleVector that = (DoubleVector) v1;
1886         that.check(this);
1887         double[] a0 = this.getElements();
1888         double[] a1 = that.getElements();
1889         double[] res = new double[a0.length];
1890         int vlen = res.length;
1891         int firstPart = vlen - origin;
1892         System.arraycopy(a0, origin, res, 0, firstPart);
1893         System.arraycopy(a1, 0, res, firstPart, origin);
1894         return vectorFactory(res);
1895     }
1896 
1897     /**
1898      * {@inheritDoc} <!--workaround-->
1899      */
1900     @Override
1901     @ForceInline
1902     public final
1903     DoubleVector slice(int origin,
1904                                Vector<Double> w,
1905                                VectorMask<Double> m) {
1906         return broadcast(0).blend(slice(origin, w), m);
1907     }
1908 
1909     /**
1910      * {@inheritDoc} <!--workaround-->
1911      */
1912     @Override
1913     public abstract
1914     DoubleVector slice(int origin);
1915 
1916     /**
1917      * {@inheritDoc} <!--workaround-->
1918      */
1919     @Override
1920     public abstract
1921     DoubleVector unslice(int origin, Vector<Double> w, int part);
1922 
1923     /*package-private*/
1924     final
1925     @ForceInline
1926     DoubleVector
1927     unsliceTemplate(int origin, Vector<Double> w, int part) {
1928         DoubleVector that = (DoubleVector) w;
1929         that.check(this);
1930         double[] slice = this.getElements();
1931         double[] res = that.getElements();
1932         int vlen = res.length;
1933         int firstPart = vlen - origin;
1934         switch (part) {
1935         case 0:
1936             System.arraycopy(slice, 0, res, origin, firstPart);
1937             break;
1938         case 1:
1939             System.arraycopy(slice, firstPart, res, 0, origin);
1940             break;
1941         default:
1942             throw wrongPartForSlice(part);
1943         }
1944         return vectorFactory(res);
1945     }
1946 
1947     /*package-private*/
1948     final
1949     @ForceInline
1950     <M extends VectorMask<Double>>
1951     DoubleVector
1952     unsliceTemplate(Class<M> maskType, int origin, Vector<Double> w, int part, M m) {
1953         DoubleVector that = (DoubleVector) w;
1954         that.check(this);
1955         DoubleVector slice = that.sliceTemplate(origin, that);
1956         slice = slice.blendTemplate(maskType, this, m);
1957         return slice.unsliceTemplate(origin, w, part);
1958     }
1959 
1960     /**
1961      * {@inheritDoc} <!--workaround-->
1962      */
1963     @Override
1964     public abstract
1965     DoubleVector unslice(int origin, Vector<Double> w, int part, VectorMask<Double> m);
1966 
1967     /**
1968      * {@inheritDoc} <!--workaround-->
1969      */
1970     @Override
1971     public abstract
1972     DoubleVector unslice(int origin); 
1973 
1974     private ArrayIndexOutOfBoundsException
1975     wrongPartForSlice(int part) {
1976         String msg = String.format("bad part number %d for slice operation",
1977                                    part);
1978         return new ArrayIndexOutOfBoundsException(msg);
1979     }
1980 
1981     /**
1982      * {@inheritDoc} <!--workaround-->
1983      */
1984     @Override
1985     public abstract
1986     DoubleVector rearrange(VectorShuffle<Double> m);
1987 
1988     /*package-private*/
1989     @ForceInline
1990     final
1991     <S extends VectorShuffle<Double>>
1992     DoubleVector rearrangeTemplate(Class<S> shuffletype, S shuffle) {
1993         shuffle.checkIndexes();
1994         return VectorIntrinsics.rearrangeOp(
1995             getClass(), shuffletype, double.class, length(),
1996             this, shuffle,
1997             (v1, s_) -> v1.uOp((i, a) -> {
1998                 int ei = s_.laneSource(i);
1999                 return v1.lane(ei);
2000             }));
2001     }
2002 
2003     /**
2004      * {@inheritDoc} <!--workaround-->
2005      */
2006     @Override
2007     public abstract
2008     DoubleVector rearrange(VectorShuffle<Double> s,
2009                                    VectorMask<Double> m);
2010 
2011     /*package-private*/
2012     @ForceInline
2013     final
2014     <S extends VectorShuffle<Double>>
2015     DoubleVector rearrangeTemplate(Class<S> shuffletype,
2016                                            S shuffle,
2017                                            VectorMask<Double> m) {
2018         DoubleVector unmasked =
2019             VectorIntrinsics.rearrangeOp(
2020                 getClass(), shuffletype, double.class, length(),
2021                 this, shuffle,
2022                 (v1, s_) -> v1.uOp((i, a) -> {
2023                     int ei = s_.laneSource(i);
2024                     return ei < 0 ? 0 : v1.lane(ei);
2025                 }));
2026         VectorMask<Double> valid = shuffle.laneIsValid();
2027         if (m.andNot(valid).anyTrue()) {
2028             shuffle.checkIndexes();
2029             throw new AssertionError();
2030         }
2031         return broadcast((double)0).blend(unmasked, valid);
2032     }
2033 
2034     /**
2035      * {@inheritDoc} <!--workaround-->
2036      */
2037     @Override
2038     public abstract
2039     DoubleVector rearrange(VectorShuffle<Double> s,
2040                                    Vector<Double> v);
2041 
2042     /*package-private*/
2043     @ForceInline
2044     final
2045     <S extends VectorShuffle<Double>>
2046     DoubleVector rearrangeTemplate(Class<S> shuffletype,
2047                                            S shuffle,
2048                                            DoubleVector v) {
2049         VectorMask<Double> valid = shuffle.laneIsValid();
2050         VectorShuffle<Double> ws = shuffle.wrapIndexes();
2051         DoubleVector r1 =
2052             VectorIntrinsics.rearrangeOp(
2053                 getClass(), shuffletype, double.class, length(),
2054                 this, shuffle,
2055                 (v1, s_) -> v1.uOp((i, a) -> {
2056                     int ei = s_.laneSource(i);
2057                     return v1.lane(ei);
2058                 }));
2059         DoubleVector r2 =
2060             VectorIntrinsics.rearrangeOp(
2061                 getClass(), shuffletype, double.class, length(),
2062                 v, shuffle,
2063                 (v1, s_) -> v1.uOp((i, a) -> {
2064                     int ei = s_.laneSource(i);
2065                     return v1.lane(ei);
2066                 }));
2067         return r2.blend(r1, valid);
2068     }
2069 
2070     /**
2071      * {@inheritDoc} <!--workaround-->
2072      */
2073     @Override
2074     public abstract
2075     DoubleVector selectFrom(Vector<Double> v);
2076 
2077     /*package-private*/
2078     @ForceInline
2079     final DoubleVector selectFromTemplate(DoubleVector v) {
2080         return v.rearrange(this.toShuffle());
2081     }
2082 
2083     /**
2084      * {@inheritDoc} <!--workaround-->
2085      */
2086     @Override
2087     public abstract
2088     DoubleVector selectFrom(Vector<Double> s, VectorMask<Double> m);
2089 
2090     /*package-private*/
2091     @ForceInline
2092     final DoubleVector selectFromTemplate(DoubleVector v,
2093                                                   AbstractMask<Double> m) {
2094         return v.rearrange(this.toShuffle(), m);
2095     }
2096 
2097     /// Ternary operations
2098 
2099 
2100     /**
2101      * Multiplies this vector by a second input vector, and sums
2102      * the result with a third.
2103      *
2104      * Extended precision is used for the intermediate result,
2105      * avoiding possible loss of precision from rounding once
2106      * for each of the two operations.
2107      * The result is numerically close to {@code this.mul(b).add(c)},
2108      * and is typically closer to the true mathematical result.
2109      *
2110      * This is a lane-wise ternary operation which applies the
2111      * {@link Math#fma(double,double,double) Math#fma(a,b,c)}
2112      * operation to each lane.
2113      *
2114      * This method is also equivalent to the expression
2115      * {@link #lanewise(VectorOperators.Ternary,Vector,Vector)
2116      *    lanewise}{@code (}{@link VectorOperators#FMA
2117      *    FMA}{@code , b, c)}.
2118      *
2119      * @param b the second input vector, supplying multiplier values
2120      * @param b the third input vector, supplying addend values
2121      * @return the product of this vector and the second input vector
2122      *         summed with the third input vector, using extended precision
2123      *         for the intermediate result
2124      * @see #fma(double,double)
2125      * @see VectorOperators#FMA
2126      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
2127      */
2128     @ForceInline
2129     public final
2130     DoubleVector fma(Vector<Double> b, Vector<Double> c) {
2131         return lanewise(FMA, b, c);
2132     }
2133 
2134     /**
2135      * Multiplies this vector by a scalar multiplier, and sums
2136      * the result with a scalar addend.
2137      *
2138      * Extended precision is used for the intermediate result,
2139      * avoiding possible loss of precision from rounding once
2140      * for each of the two operations.
2141      * The result is numerically close to {@code this.mul(b).add(c)},
2142      * and is typically closer to the true mathematical result.
2143      *
2144      * This is a lane-wise ternary operation which applies the
2145      * {@link Math#fma(double,double,double) Math#fma(a,b,c)}
2146      * operation to each lane.
2147      *
2148      * This method is also equivalent to the expression
2149      * {@link #lanewise(VectorOperators.Ternary,Vector,Vector)
2150      *    lanewise}{@code (}{@link VectorOperators#FMA
2151      *    FMA}{@code , b, c)}.
2152      *
2153      * @param b the scalar multiplier
2154      * @param c the scalar addend
2155      * @return the product of this vector and the scalar multiplier
2156      *         summed with scalar addend, using extended precision
2157      *         for the intermediate result
2158      * @see #fma(Vector,Vector)
2159      * @see VectorOperators#FMA
2160      * @see #lanewise(VectorOperators.Ternary,double,double,VectorMask)
2161      */
2162     @ForceInline
2163     public final
2164     DoubleVector fma(double b, double c) {
2165         return lanewise(FMA, b, c);
2166     }
2167 
2168     // Don't bother with (Vector,double) and (double,Vector) overloadings.
2169 
2170     // Type specific horizontal reductions
2171 
2172     /**
2173      * Returns a value accumulated from all the lanes of this vector.
2174      *
2175      * This is an associative cross-lane reduction operation which
2176      * applies the specified operation to all the lane elements.
2177      *
2178      * <p>
2179      * A few reduction operations do not support arbitrary reordering
2180      * of their operands, yet are included here because of their
2181      * usefulness.
2182      *
2183      * <ul>
2184      * <li>
2185      * In the case of {@code FIRST_NONZERO}, the reduction returns
2186      * the value from the lowest-numbered non-zero lane.
2187      *
2188      * (As with {@code MAX} and {@code MIN}, floating point negative
2189      * zero {@code -0.0} is treated as a value distinct from
2190      * the default zero value, so a first-nonzero lane reduction
2191      * might return {@code -0.0} even in the presence of non-zero
2192      * lane values.)
2193      *
2194      * <li>
2195      * In the case of floating point addition and multiplication, the
2196      * precise result will reflect the choice of an arbitrary order
2197      * of operations, which may even vary over time.
2198      *
2199      * <li>
2200      * All other reduction operations are fully commutative and
2201      * associative.  The implementation can choose any order of
2202      * processing, yet it will always produce the same result.
2203      *
2204      * </ul>
2205      *
2206      * @implNote
2207      * The value of a floating-point reduction may be a function
2208      * both of the input values as well as the order of scalar
2209      * operations which combine those values, specifically in the
2210      * case of {@code ADD} and {@code MUL} operations, where
2211      * details of rounding depend on operand order.
2212      * In those cases, the order of operations of this method is
2213      * intentionally not defined.  This allows the JVM to generate
2214      * optimal machine code for the underlying platform at runtime. If
2215      * the platform supports a vector instruction to add or multiply
2216      * all values in the vector, or if there is some other efficient
2217      * machine code sequence, then the JVM has the option of
2218      * generating this machine code. Otherwise, the default
2219      * implementation is applied, which adds vector elements
2220      * sequentially from beginning to end.  For this reason, the
2221      * output of this method may vary for the same input values,
2222      * if the selected operator is {@code ADD} or {@code MUL}.
2223      *
2224      *
2225      * @param op the operation used to combine lane values
2226      * @return the accumulated result
2227      * @throws UnsupportedOperationException if this vector does
2228      *         not support the requested operation
2229      * @see #reduceLanes(VectorOperators.Associative,VectorMask)
2230      * @see #add(Vector)
2231      * @see #mul(Vector)
2232      * @see #min(Vector)
2233      * @see #max(Vector)
2234      * @see VectorOperators#FIRST_NONZERO
2235      */
2236     public abstract double reduceLanes(VectorOperators.Associative op);
2237 
2238     /**
2239      * Returns a value accumulated from selected lanes of this vector,
2240      * controlled by a mask.
2241      *
2242      * This is an associative cross-lane reduction operation which
2243      * applies the specified operation to the selected lane elements.
2244      * <p>
2245      * If no elements are selected, an operation-specific identity
2246      * value is returned.
2247      * <ul>
2248      * <li>
2249      * If the operation is
2250      *  {@code ADD}
2251      * or {@code FIRST_NONZERO},
2252      * then the identity value is zero, the default {@code double} value.
2253      * <li>
2254      * If the operation is {@code MUL},
2255      * then the identity value is one.
2256      * <li>
2257      * If the operation is {@code MAX},
2258      * then the identity value is {@code Double.NEGATIVE_INFINITY}.
2259      * <li>
2260      * If the operation is {@code MIN},
2261      * then the identity value is {@code Double.POSITIVE_INFINITY}.
2262      * </ul>
2263      *
2264      * @implNote
2265      * The value of a floating-point reduction may be a function
2266      * both of the input values as well as the order of scalar
2267      * operations which combine those values, specifically in the
2268      * case of {@code ADD} and {@code MUL} operations, where
2269      * details of rounding depend on operand order.
2270      * See {@linkplain #reduceLanes(VectorOperators.Associative)
2271      * the unmasked version of this method}
2272      * for a discussion.
2273      *
2274      *
2275      * @param op the operation used to combine lane values
2276      * @param m the mask controlling lane selection
2277      * @return the reduced result accumulated from the selected lane values
2278      * @throws UnsupportedOperationException if this vector does
2279      *         not support the requested operation
2280      * @see #reduceLanes(VectorOperators.Associative)
2281      */
2282     public abstract double reduceLanes(VectorOperators.Associative op,
2283                                        VectorMask<Double> m);
2284 
2285     /*package-private*/
2286     @ForceInline
2287     final
2288     double reduceLanesTemplate(VectorOperators.Associative op,
2289                                VectorMask<Double> m) {
2290         DoubleVector v = reduceIdentityVector(op).blend(this, m);
2291         return v.reduceLanesTemplate(op);
2292     }
2293 
2294     /*package-private*/
2295     @ForceInline
2296     final
2297     double reduceLanesTemplate(VectorOperators.Associative op) {
2298         if (op == FIRST_NONZERO) {
2299             // FIXME:  The JIT should handle this, and other scan ops alos.
2300             VectorMask<Long> thisNZ
2301                 = this.viewAsIntegralLanes().compare(NE, (long) 0);
2302             return this.lane(thisNZ.firstTrue());
2303         }
2304         int opc = opCode(op);
2305         return fromBits(VectorIntrinsics.reductionCoerced(
2306             opc, getClass(), double.class, length(),
2307             this,
2308             REDUCE_IMPL.find(op, opc, (opc_) -> {
2309               switch (opc_) {
2310               case VECTOR_OP_ADD: return v ->
2311                       toBits(v.rOp((double)0, (i, a, b) -> (double)(a + b)));
2312               case VECTOR_OP_MUL: return v ->
2313                       toBits(v.rOp((double)1, (i, a, b) -> (double)(a * b)));
2314               case VECTOR_OP_MIN: return v ->
2315                       toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (double) Math.min(a, b)));
2316               case VECTOR_OP_MAX: return v ->
2317                       toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (double) Math.max(a, b)));
2318               case VECTOR_OP_FIRST_NONZERO: return v ->
2319                       toBits(v.rOp((double)0, (i, a, b) -> toBits(a) != 0 ? a : b));
2320               case VECTOR_OP_OR: return v ->
2321                       toBits(v.rOp((double)0, (i, a, b) -> fromBits(toBits(a) | toBits(b))));
2322               default: return null;
2323               }})));
2324     }
2325     private static final
2326     ImplCache<Associative,Function<DoubleVector,Long>> REDUCE_IMPL
2327         = new ImplCache<>(Associative.class, DoubleVector.class);
2328 
2329     private
2330     @ForceInline
2331     DoubleVector reduceIdentityVector(VectorOperators.Associative op) {
2332         int opc = opCode(op);
2333         UnaryOperator<DoubleVector> fn
2334             = REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
2335                 switch (opc_) {
2336                 case VECTOR_OP_ADD:
2337                 case VECTOR_OP_OR:
2338                 case VECTOR_OP_XOR:
2339                 case VECTOR_OP_FIRST_NONZERO:
2340                     return v -> v.broadcast(0);
2341                 case VECTOR_OP_MUL:
2342                     return v -> v.broadcast(1);
2343                 case VECTOR_OP_AND:
2344                     return v -> v.broadcast(-1);
2345                 case VECTOR_OP_MIN:
2346                     return v -> v.broadcast(MAX_OR_INF);
2347                 case VECTOR_OP_MAX:
2348                     return v -> v.broadcast(MIN_OR_INF);
2349                 default: return null;
2350                 }
2351             });
2352         return fn.apply(this);
2353     }
2354     private static final
2355     ImplCache<Associative,UnaryOperator<DoubleVector>> REDUCE_ID_IMPL
2356         = new ImplCache<>(Associative.class, DoubleVector.class);
2357 
2358     private static final double MIN_OR_INF = Double.NEGATIVE_INFINITY;
2359     private static final double MAX_OR_INF = Double.POSITIVE_INFINITY;
2360 
2361     public @Override abstract long reduceLanesToLong(VectorOperators.Associative op);
2362     public @Override abstract long reduceLanesToLong(VectorOperators.Associative op,
2363                                                      VectorMask<Double> m);
2364 
2365     // Type specific accessors
2366 
2367     /**
2368      * Gets the lane element at lane index {@code i}
2369      *
2370      * @param i the lane index
2371      * @return the lane element at lane index {@code i}
2372      * @throws IllegalArgumentException if the index is is out of range
2373      * ({@code < 0 || >= length()})
2374      */
2375     public abstract double lane(int i);
2376 
2377     /**
2378      * Replaces the lane element of this vector at lane index {@code i} with
2379      * value {@code e}.
2380      *
2381      * This is a cross-lane operation and behaves as if it returns the result
2382      * of blending this vector with an input vector that is the result of
2383      * broadcasting {@code e} and a mask that has only one lane set at lane
2384      * index {@code i}.
2385      *
2386      * @param i the lane index of the lane element to be replaced
2387      * @param e the value to be placed
2388      * @return the result of replacing the lane element of this vector at lane
2389      * index {@code i} with value {@code e}.
2390      * @throws IllegalArgumentException if the index is is out of range
2391      * ({@code < 0 || >= length()})
2392      */
2393     public abstract DoubleVector withLane(int i, double e);
2394 
2395     // Memory load operations
2396 
2397     /**
2398      * Returns an array of type {@code double[]}
2399      * containing all the lane values.
2400      * The array length is the same as the vector length.
2401      * The array elements are stored in lane order.
2402      * <p>
2403      * This method behaves as if it stores
2404      * this vector into an allocated array
2405      * (using {@link #intoArray(double[], int) intoArray})
2406      * and returns the array as follows:
2407      * <pre>{@code
2408      *   double[] a = new double[this.length()];
2409      *   this.intoArray(a, 0);
2410      *   return a;
2411      * }</pre>
2412      *
2413      * @return an array containing the lane values of this vector
2414      */
2415     @ForceInline
2416     @Override
2417     public final double[] toArray() {
2418         double[] a = new double[vspecies().laneCount()];
2419         intoArray(a, 0);
2420         return a;
2421     }
2422 
2423     /** {@inheritDoc} <!--workaround-->
2424      * @implNote
2425      * When this method is used on used on vectors
2426      * of type {@code DoubleVector},
2427      * fractional bits in lane values will be lost,
2428      * and lane values of large magnitude will be
2429      * clipped to {@code Long.MAX_VALUE} or
2430      * {@code Long.MIN_VALUE}.
2431      */
2432     @ForceInline
2433     @Override
2434     public final long[] toLongArray() {
2435         double[] a = toArray();
2436         long[] res = new long[a.length];
2437         for (int i = 0; i < a.length; i++) {
2438             res[i] = (long) a[i];
2439         }
2440         return res;
2441     }
2442 
2443     /** {@inheritDoc} <!--workaround-->
2444      * @implNote
2445      * This is an alias for {@link #toArray()}
2446      * When this method is used on used on vectors
2447      * of type {@code DoubleVector},
2448      * there will be no loss of precision.
2449      */
2450     @ForceInline
2451     @Override
2452     public final double[] toDoubleArray() {
2453         return toArray();
2454     }
2455 
2456     /**
2457      * Loads a vector from a byte array starting at an offset.
2458      * Bytes are composed into primitive lane elements according
2459      * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering.
2460      * The vector is arranged into lanes according to
2461      * <a href="Vector.html#lane-order">memory ordering</a>.
2462      * <p>
2463      * This method behaves as if it returns the result of calling
2464      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2465      * fromByteBuffer()} as follows:
2466      * <pre>{@code
2467      * var bb = ByteBuffer.wrap(a);
2468      * var bo = ByteOrder.LITTLE_ENDIAN;
2469      * var m = species.maskAll(true);
2470      * return fromByteBuffer(species, bb, offset, m, bo);
2471      * }</pre>
2472      *
2473      * @param species species of desired vector
2474      * @param a the byte array
2475      * @param offset the offset into the array
2476      * @return a vector loaded from a byte array
2477      * @throws IndexOutOfBoundsException
2478      *         if {@code offset+N*ESIZE < 0}
2479      *         or {@code offset+(N+1)*ESIZE > a.length}
2480      *         for any lane {@code N} in the vector
2481      */
2482     @ForceInline
2483     public static
2484     DoubleVector fromByteArray(VectorSpecies<Double> species,
2485                                        byte[] a, int offset) {
2486         return fromByteArray(species, a, offset, ByteOrder.LITTLE_ENDIAN);
2487     }
2488 
2489     /**
2490      * Loads a vector from a byte array starting at an offset.
2491      * Bytes are composed into primitive lane elements according
2492      * to the specified byte order.
2493      * The vector is arranged into lanes according to
2494      * <a href="Vector.html#lane-order">memory ordering</a>.
2495      * <p>
2496      * This method behaves as if it returns the result of calling
2497      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2498      * fromByteBuffer()} as follows:
2499      * <pre>{@code
2500      * var bb = ByteBuffer.wrap(a);
2501      * var m = species.maskAll(true);
2502      * return fromByteBuffer(species, bb, offset, m, bo);
2503      * }</pre>
2504      *
2505      * @param species species of desired vector
2506      * @param a the byte array
2507      * @param offset the offset into the array
2508      * @param bo the intended byte order
2509      * @return a vector loaded from a byte array
2510      * @throws IndexOutOfBoundsException
2511      *         if {@code offset+N*ESIZE < 0}
2512      *         or {@code offset+(N+1)*ESIZE > a.length}
2513      *         for any lane {@code N} in the vector
2514      */
2515     @ForceInline
2516     public static
2517     DoubleVector fromByteArray(VectorSpecies<Double> species,
2518                                        byte[] a, int offset,
2519                                        ByteOrder bo) {
2520         DoubleSpecies vsp = (DoubleSpecies) species;
2521         offset = checkFromIndexSize(offset,
2522                                     vsp.vectorBitSize() / Byte.SIZE,
2523                                     a.length);
2524         return vsp.dummyVector()
2525             .fromByteArray0(a, offset).maybeSwap(bo);
2526     }
2527 
2528     /**
2529      * Loads a vector from a byte array starting at an offset
2530      * and using a mask.
2531      * Lanes where the mask is unset are filled with the default
2532      * value of {@code double} (zero).
2533      * Bytes are composed into primitive lane elements according
2534      * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering.
2535      * The vector is arranged into lanes according to
2536      * <a href="Vector.html#lane-order">memory ordering</a>.
2537      * <p>
2538      * This method behaves as if it returns the result of calling
2539      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2540      * fromByteBuffer()} as follows:
2541      * <pre>{@code
2542      * var bb = ByteBuffer.wrap(a);
2543      * var bo = ByteOrder.LITTLE_ENDIAN;
2544      * return fromByteBuffer(species, bb, offset, bo, m);
2545      * }</pre>
2546      *
2547      * @param species species of desired vector
2548      * @param a the byte array
2549      * @param offset the offset into the array
2550      * @param m the mask controlling lane selection
2551      * @return a vector loaded from a byte array
2552      * @throws IndexOutOfBoundsException
2553      *         if {@code offset+N*ESIZE < 0}
2554      *         or {@code offset+(N+1)*ESIZE > a.length}
2555      *         for any lane {@code N} in the vector where
2556      *         the mask is set
2557      */
2558     @ForceInline
2559     public static
2560     DoubleVector fromByteArray(VectorSpecies<Double> species,
2561                                        byte[] a, int offset,
2562                                        VectorMask<Double> m) {
2563         return fromByteArray(species, a, offset, ByteOrder.LITTLE_ENDIAN, m);
2564     }
2565 
2566     /**
2567      * Loads a vector from a byte array starting at an offset
2568      * and using a mask.
2569      * Lanes where the mask is unset are filled with the default
2570      * value of {@code double} (zero).
2571      * Bytes are composed into primitive lane elements according
2572      * to {@linkplain ByteOrder#LITTLE_ENDIAN little endian} ordering.
2573      * The vector is arranged into lanes according to
2574      * <a href="Vector.html#lane-order">memory ordering</a>.
2575      * <p>
2576      * This method behaves as if it returns the result of calling
2577      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2578      * fromByteBuffer()} as follows:
2579      * <pre>{@code
2580      * var bb = ByteBuffer.wrap(a);
2581      * return fromByteBuffer(species, bb, offset, m, bo);
2582      * }</pre>
2583      *
2584      * @param species species of desired vector
2585      * @param a the byte array
2586      * @param offset the offset into the array
2587      * @param bo the intended byte order
2588      * @param m the mask controlling lane selection
2589      * @return a vector loaded from a byte array
2590      * @throws IndexOutOfBoundsException
2591      *         if {@code offset+N*ESIZE < 0}
2592      *         or {@code offset+(N+1)*ESIZE > a.length}
2593      *         for any lane {@code N} in the vector
2594      *         where the mask is set
2595      */
2596     @ForceInline
2597     public static
2598     DoubleVector fromByteArray(VectorSpecies<Double> species,
2599                                        byte[] a, int offset,
2600                                        ByteOrder bo,
2601                                        VectorMask<Double> m) {
2602         DoubleSpecies vsp = (DoubleSpecies) species;
2603         DoubleVector zero = vsp.zero();
2604         DoubleVector iota = zero.addIndex(1);
2605         ((AbstractMask<Double>)m)
2606             .checkIndexByLane(offset, a.length, iota, 8);
2607         DoubleVector v = zero.fromByteArray0(a, offset);
2608         return zero.blend(v.maybeSwap(bo), m);
2609     }
2610 
2611     /**
2612      * Loads a vector from an array of type {@code double[]}
2613      * starting at an offset.
2614      * For each vector lane, where {@code N} is the vector lane index, the
2615      * array element at index {@code offset + N} is placed into the
2616      * resulting vector at lane index {@code N}.
2617      *
2618      * @param species species of desired vector
2619      * @param a the array
2620      * @param offset the offset into the array
2621      * @return the vector loaded from an array
2622      * @throws IndexOutOfBoundsException
2623      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2624      *         for any lane {@code N} in the vector
2625      */
2626     @ForceInline
2627     public static
2628     DoubleVector fromArray(VectorSpecies<Double> species,
2629                                    double[] a, int offset) {
2630         DoubleSpecies vsp = (DoubleSpecies) species;
2631         offset = checkFromIndexSize(offset,
2632                                     vsp.laneCount(),
2633                                     a.length);
2634         return vsp.dummyVector().fromArray0(a, offset);
2635     }
2636 
2637     /**
2638      * Loads a vector from an array of type {@code double[]}
2639      * starting at an offset and using a mask.
2640      * Lanes where the mask is unset are filled with the default
2641      * value of {@code double} (zero).
2642      * For each vector lane, where {@code N} is the vector lane index,
2643      * if the mask lane at index {@code N} is set then the array element at
2644      * index {@code offset + N} is placed into the resulting vector at lane index
2645      * {@code N}, otherwise the default element value is placed into the
2646      * resulting vector at lane index {@code N}.
2647      *
2648      * @param species species of desired vector
2649      * @param a the array
2650      * @param offset the offset into the array
2651      * @param m the mask controlling lane selection
2652      * @return the vector loaded from an array
2653      * @throws IndexOutOfBoundsException
2654      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2655      *         for any lane {@code N} in the vector
2656      *         where the mask is set
2657      */
2658     @ForceInline
2659     public static
2660     DoubleVector fromArray(VectorSpecies<Double> species,
2661                                    double[] a, int offset,
2662                                    VectorMask<Double> m) {
2663         DoubleSpecies vsp = (DoubleSpecies) species;
2664         DoubleVector zero = vsp.zero();
2665         DoubleVector iota = vsp.iota();
2666         ((AbstractMask<Double>)m)
2667             .checkIndexByLane(offset, a.length, iota, 1);
2668         return zero.blend(zero.fromArray0(a, offset), m);
2669     }
2670 
2671     /**
2672      * FIXME: EDIT THIS
2673      * Loads a vector from an array using indexes obtained from an index
2674      * map.
2675      * <p>
2676      * For each vector lane, where {@code N} is the vector lane index, the
2677      * array element at index {@code offset + indexMap[mapOffset + N]} is placed into the
2678      * resulting vector at lane index {@code N}.
2679      *
2680      * @param species species of desired vector
2681      * @param a the array
2682      * @param offset the offset into the array, may be negative if relative
2683      * indexes in the index map compensate to produce a value within the
2684      * array bounds
2685      * @param indexMap the index map
2686      * @param mapOffset the offset into the index map
2687      * @return the vector loaded from an array
2688      * @throws IndexOutOfBoundsException if {@code mapOffset < 0}, or
2689      * {@code mapOffset > indexMap.length - species.length()},
2690      * or for any vector lane index {@code N} the result of
2691      * {@code offset + indexMap[mapOffset + N]} is {@code < 0} or {@code >= a.length}
2692      */
2693     @ForceInline
2694     public static
2695     DoubleVector fromArray(VectorSpecies<Double> species,
2696                                    double[] a, int offset,
2697                                    int[] indexMap, int mapOffset) {
2698         DoubleSpecies vsp = (DoubleSpecies) species;
2699         Objects.requireNonNull(a);
2700         Objects.requireNonNull(indexMap);
2701         Class<? extends DoubleVector> vectorType = vsp.vectorType();
2702 
2703         if (vsp.laneCount() == 1) {
2704           return DoubleVector.fromArray(vsp, a, offset + indexMap[mapOffset]);
2705         }
2706 
2707         // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k]
2708         IntVector vix = IntVector.fromArray(IntVector.species(vsp.indexShape()), indexMap, mapOffset).add(offset);
2709 
2710         vix = VectorIntrinsics.checkIndex(vix, a.length);
2711 
2712         return VectorIntrinsics.loadWithMap(
2713             vectorType, double.class, vsp.laneCount(),
2714             IntVector.species(vsp.indexShape()).vectorType(),
2715             a, ARRAY_BASE, vix,
2716             a, offset, indexMap, mapOffset, vsp,
2717             (double[] c, int idx, int[] iMap, int idy, DoubleSpecies s) ->
2718             s.vOp(n -> c[idx + iMap[idy+n]]));
2719         }
2720 
2721     /**
2722      * Loads a vector from an array using indexes obtained from an index
2723      * map and using a mask.
2724      * FIXME: EDIT THIS
2725      * <p>
2726      * For each vector lane, where {@code N} is the vector lane index,
2727      * if the mask lane at index {@code N} is set then the array element at
2728      * index {@code offset + indexMap[mapOffset + N]} is placed into the resulting vector
2729      * at lane index {@code N}.
2730      *
2731      * @param species species of desired vector
2732      * @param a the array
2733      * @param offset the offset into the array, may be negative if relative
2734      * indexes in the index map compensate to produce a value within the
2735      * array bounds
2736      * @param indexMap the index map
2737      * @param mapOffset the offset into the index map
2738      * @param m the mask controlling lane selection
2739      * @return the vector loaded from an array
2740      * @throws IndexOutOfBoundsException if {@code mapOffset < 0}, or
2741      * {@code mapOffset > indexMap.length - species.length()},
2742      * or for any vector lane index {@code N} where the mask at lane
2743      * {@code N} is set the result of {@code offset + indexMap[mapOffset + N]} is
2744      * {@code < 0} or {@code >= a.length}
2745      */
2746     public static
2747     DoubleVector fromArray(VectorSpecies<Double> species,
2748                                    double[] a, int offset,
2749                                    int[] indexMap, int mapOffset,
2750                                    VectorMask<Double> m) {
2751         DoubleSpecies vsp = (DoubleSpecies) species;
2752 
2753         // FIXME This can result in out of bounds errors for unset mask lanes
2754         // FIX = Use a scatter instruction which routes the unwanted lanes
2755         // into a bit-bucket variable (private to implementation).
2756         // This requires a 2-D scatter in order to set a second base address.
2757         // See notes in https://bugs.openjdk.java.net/browse/JDK-8223367
2758         assert(m.allTrue());
2759         return (DoubleVector)
2760             zero(species).blend(fromArray(species, a, offset, indexMap, mapOffset), m);
2761 
2762     }
2763 
2764     /**
2765      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
2766      * starting at an offset into the byte buffer.
2767      * <p>
2768      * Bytes are composed into primitive lane elements according to
2769      * {@link ByteOrder#LITTLE_ENDIAN little endian} byte order.
2770      * To avoid errors, the
2771      * {@linkplain ByteBuffer#order() intrinsic byte order}
2772      * of the buffer must be little-endian.
2773      * <p>
2774      * This method behaves as if it returns the result of calling
2775      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2776      * fromByteBuffer()} as follows:
2777      * <pre>{@code
2778      * var bb = ByteBuffer.wrap(a);
2779      * var bo = ByteOrder.LITTLE_ENDIAN;
2780      * var m = species.maskAll(true);
2781      * return fromByteBuffer(species, bb, offset, m, bo);
2782      * }</pre>
2783      *
2784      * @param species species of desired vector
2785      * @param bb the byte buffer
2786      * @param offset the offset into the byte buffer
2787      * @return a vector loaded from a byte buffer
2788      * @throws IllegalArgumentException if byte order of bb
2789      *         is not {@link ByteOrder#LITTLE_ENDIAN}
2790      * @throws IndexOutOfBoundsException
2791      *         if {@code offset+N*8 < 0}
2792      *         or {@code offset+N*8 >= bb.limit()}
2793      *         for any lane {@code N} in the vector
2794      */
2795     @ForceInline
2796     public static
2797     DoubleVector fromByteBuffer(VectorSpecies<Double> species,
2798                                         ByteBuffer bb, int offset,
2799                                         ByteOrder bo) {
2800         DoubleSpecies vsp = (DoubleSpecies) species;
2801         offset = checkFromIndexSize(offset,
2802                                     vsp.laneCount(),
2803                                     bb.limit());
2804         return vsp.dummyVector()
2805             .fromByteBuffer0(bb, offset).maybeSwap(bo);
2806     }
2807 
2808     /**
2809      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
2810      * starting at an offset into the byte buffer
2811      * and using a mask.
2812      * <p>
2813      * Bytes are composed into primitive lane elements according to
2814      * {@link ByteOrder#LITTLE_ENDIAN little endian} byte order.
2815      * To avoid errors, the
2816      * {@linkplain ByteBuffer#order() intrinsic byte order}
2817      * of the buffer must be little-endian.
2818      * <p>
2819      * This method behaves as if it returns the result of calling
2820      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2821      * fromByteBuffer()} as follows:
2822      * <pre>{@code
2823      * var bb = ByteBuffer.wrap(a);
2824      * var bo = ByteOrder.LITTLE_ENDIAN;
2825      * var m = species.maskAll(true);
2826      * return fromByteBuffer(species, bb, offset, m, bo);
2827      * }</pre>
2828      *
2829      * @param species species of desired vector
2830      * @param bb the byte buffer
2831      * @param offset the offset into the byte buffer
2832      * @param m the mask controlling lane selection
2833      * @return a vector loaded from a byte buffer
2834      * @throws IllegalArgumentException if byte order of bb
2835      *         is not {@link ByteOrder#LITTLE_ENDIAN}
2836      * @throws IndexOutOfBoundsException
2837      *         if {@code offset+N*8 < 0}
2838      *         or {@code offset+N*8 >= bb.limit()}
2839      *         for any lane {@code N} in the vector
2840      *         where the mask is set
2841      */
2842     @ForceInline
2843     public static
2844     DoubleVector fromByteBuffer(VectorSpecies<Double> species,
2845                                         ByteBuffer bb, int offset,
2846                                         ByteOrder bo,
2847                                         VectorMask<Double> m) {
2848         if (m.allTrue()) {
2849             return fromByteBuffer(species, bb, offset, bo);
2850         }
2851         DoubleSpecies vsp = (DoubleSpecies) species;
2852         checkMaskFromIndexSize(offset,
2853                                vsp, m, 1,
2854                                bb.limit());
2855         DoubleVector zero = zero(vsp);
2856         DoubleVector v = zero.fromByteBuffer0(bb, offset);
2857         return zero.blend(v.maybeSwap(bo), m);
2858     }
2859 
2860     // Memory store operations
2861 
2862     /**
2863      * Stores this vector into an array of type {@code double[]}
2864      * starting at an offset.
2865      * <p>
2866      * For each vector lane, where {@code N} is the vector lane index,
2867      * the lane element at index {@code N} is stored into the array
2868      * element {@code a[offset+N]}.
2869      *
2870      * @param a the array, of type {@code double[]}
2871      * @param offset the offset into the array
2872      * @throws IndexOutOfBoundsException
2873      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2874      *         for any lane {@code N} in the vector
2875      */
2876     @ForceInline
2877     public final
2878     void intoArray(double[] a, int offset) {
2879         DoubleSpecies vsp = vspecies();
2880         offset = checkFromIndexSize(offset,
2881                                     vsp.laneCount(),
2882                                     a.length);
2883         VectorIntrinsics.store(
2884             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
2885             a, arrayAddress(a, offset),
2886             this,
2887             a, offset,
2888             (arr, off, v)
2889             -> v.stOp(arr, off,
2890                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
2891     }
2892 
2893     /**
2894      * Stores this vector into an array of {@code double}
2895      * starting at offset and using a mask.
2896      * <p>
2897      * For each vector lane, where {@code N} is the vector lane index,
2898      * the lane element at index {@code N} is stored into the array
2899      * element {@code a[offset+N]}.
2900      * If the mask lane at {@code N} is unset then the corresponding
2901      * array element {@code a[offset+N]} is left unchanged.
2902      * <p>
2903      * Array range checking is done for lanes where the mask is set.
2904      * Lanes where the mask is unset are not stored and do not need
2905      * to correspond to legitimate elements of {@code a}.
2906      * That is, unset lanes may correspond to array indexes less than
2907      * zero or beyond the end of the array.
2908      *
2909      * @param a the array, of type {@code double[]}
2910      * @param offset the offset into the array
2911      * @param m the mask controlling lane storage
2912      * @throws IndexOutOfBoundsException
2913      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2914      *         for any lane {@code N} in the vector
2915      *         where the mask is set
2916      */
2917     @ForceInline
2918     public final
2919     void intoArray(double[] a, int offset,
2920                    VectorMask<Double> m) {
2921         if (m.allTrue()) {
2922             intoArray(a, offset);
2923         } else {
2924             // FIXME: Cannot vectorize yet, if there's a mask.
2925             stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v);
2926         }
2927     }
2928 
2929     /**
2930      * Stores this vector into an array of type {@code double[]}
2931      * using indexes obtained from an index map
2932      * and using a mask.
2933      * <p>
2934      * For each vector lane, where {@code N} is the vector lane index,
2935      * if the mask lane at index {@code N} is set then
2936      * the lane element at index {@code N} is stored into the array
2937      * element {@code a[f(N)]}, where {@code f(N)} is the
2938      * index mapping expression
2939      * {@code offset + indexMap[mapOffset + N]]}.
2940      *
2941      * @param a the array
2942      * @param offset an offset to combine with the index map offsets
2943      * @param indexMap the index map
2944      * @param mapOffset the offset into the index map
2945      * @param m the mask
2946      * @returns a vector of the values {@code m ? a[f(N)] : 0},
2947      *          {@code f(N) = offset + indexMap[mapOffset + N]]}.
2948      * @throws IndexOutOfBoundsException
2949      *         if {@code mapOffset+N < 0}
2950      *         or if {@code mapOffset+N >= indexMap.length},
2951      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
2952      *         is an invalid index into {@code a},
2953      *         for any lane {@code N} in the vector
2954      *         where the mask is set
2955      */
2956     @ForceInline
2957     public final
2958     void intoArray(double[] a, int offset,
2959                    int[] indexMap, int mapOffset) {
2960         DoubleSpecies vsp = vspecies();
2961         if (length() == 1) {
2962             intoArray(a, offset + indexMap[mapOffset]);
2963             return;
2964         }
2965         IntVector.IntSpecies isp = (IntVector.IntSpecies) vsp.indexSpecies();
2966         if (isp.laneCount() != vsp.laneCount()) {
2967             stOp(a, offset,
2968                  (arr, off, i, e) -> {
2969                      int j = indexMap[mapOffset + i];
2970                      arr[off + j] = e;
2971                  });
2972             return;
2973         }
2974 
2975         // Index vector: vix[0:n] = i -> offset + indexMap[mo + i]
2976         IntVector vix = IntVector
2977             .fromArray(isp, indexMap, mapOffset)
2978             .add(offset);
2979 
2980         vix = VectorIntrinsics.checkIndex(vix, a.length);
2981 
2982         VectorIntrinsics.storeWithMap(
2983             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
2984             isp.vectorType(),
2985             a, arrayAddress(a, 0), vix,
2986             this,
2987             a, offset, indexMap, mapOffset,
2988             (arr, off, v, map, mo)
2989             -> v.stOp(arr, off,
2990                       (arr_, off_, i, e) -> {
2991                           int j = map[mo + i];
2992                           arr[off + j] = e;
2993                       }));
2994     }
2995 
2996     /**
2997      * Stores this vector into an array of type {@code double[]}
2998      * using indexes obtained from an index map
2999      * and using a mask.
3000      * <p>
3001      * For each vector lane, where {@code N} is the vector lane index,
3002      * if the mask lane at index {@code N} is set then
3003      * the lane element at index {@code N} is stored into the array
3004      * element {@code a[f(N)]}, where {@code f(N)} is the
3005      * index mapping expression
3006      * {@code offset + indexMap[mapOffset + N]]}.
3007      *
3008      * @param a the array
3009      * @param offset an offset to combine with the index map offsets
3010      * @param indexMap the index map
3011      * @param mapOffset the offset into the index map
3012      * @param m the mask
3013      * @returns a vector of the values {@code m ? a[f(N)] : 0},
3014      *          {@code f(N) = offset + indexMap[mapOffset + N]]}.
3015      * @throws IndexOutOfBoundsException
3016      *         if {@code mapOffset+N < 0}
3017      *         or if {@code mapOffset+N >= indexMap.length},
3018      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3019      *         is an invalid index into {@code a},
3020      *         for any lane {@code N} in the vector
3021      *         where the mask is set
3022      */
3023     @ForceInline
3024     public final
3025     void intoArray(double[] a, int offset,
3026                    int[] indexMap, int mapOffset,
3027                    VectorMask<Double> m) {
3028         DoubleSpecies vsp = vspecies();
3029         if (m.allTrue()) {
3030             intoArray(a, offset, indexMap, mapOffset);
3031             return;
3032         }
3033         throw new AssertionError("fixme");
3034     }
3035 
3036     /**
3037      * {@inheritDoc} <!--workaround-->
3038      */
3039     @Override
3040     @ForceInline
3041     public final
3042     void intoByteArray(byte[] a, int offset) {
3043         offset = checkFromIndexSize(offset,
3044                                     bitSize() / Byte.SIZE,
3045                                     a.length);
3046         this.maybeSwap(ByteOrder.LITTLE_ENDIAN)
3047             .intoByteArray0(a, offset);
3048     }
3049 
3050     /**
3051      * {@inheritDoc} <!--workaround-->
3052      */
3053     @Override
3054     @ForceInline
3055     public final
3056     void intoByteArray(byte[] a, int offset,
3057                        VectorMask<Double> m) {
3058         if (m.allTrue()) {
3059             intoByteArray(a, offset);
3060             return;
3061         }
3062         DoubleSpecies vsp = vspecies();
3063         checkMaskFromIndexSize(offset, vsp, m, 8, a.length);
3064         conditionalStoreNYI(offset, vsp, m, 8, a.length);
3065         var oldVal = fromByteArray0(a, offset);
3066         var newVal = oldVal.blend(this, m);
3067         newVal.intoByteArray0(a, offset);
3068     }
3069 
3070     /**
3071      * {@inheritDoc} <!--workaround-->
3072      */
3073     @Override
3074     @ForceInline
3075     public final
3076     void intoByteArray(byte[] a, int offset,
3077                        ByteOrder bo,
3078                        VectorMask<Double> m) {
3079         maybeSwap(bo).intoByteArray(a, offset, m);
3080     }
3081 
3082     /**
3083      * {@inheritDoc} <!--workaround-->
3084      */
3085     @Override
3086     @ForceInline
3087     public final
3088     void intoByteBuffer(ByteBuffer bb, int offset,
3089                         ByteOrder bo) {
3090         maybeSwap(bo).intoByteBuffer0(bb, offset);
3091     }
3092 
3093     /**
3094      * {@inheritDoc} <!--workaround-->
3095      */
3096     @Override
3097     @ForceInline
3098     public final
3099     void intoByteBuffer(ByteBuffer bb, int offset,
3100                         ByteOrder bo,
3101                         VectorMask<Double> m) {
3102         if (m.allTrue()) {
3103             intoByteBuffer(bb, offset, bo);
3104             return;
3105         }
3106         DoubleSpecies vsp = vspecies();
3107         checkMaskFromIndexSize(offset, vsp, m, 8, bb.limit());
3108         conditionalStoreNYI(offset, vsp, m, 8, bb.limit());
3109         var oldVal = fromByteBuffer0(bb, offset);
3110         var newVal = oldVal.blend(this.maybeSwap(bo), m);
3111         newVal.intoByteBuffer0(bb, offset);
3112     }
3113 
3114     // ================================================
3115 
3116     // Low-level memory operations.
3117     //
3118     // Note that all of these operations *must* inline into a context
3119     // where the exact species of the involved vector is a
3120     // compile-time constant.  Otherwise, the intrinsic generation
3121     // will fail and performance will suffer.
3122     //
3123     // In many cases this is achieved by re-deriving a version of the
3124     // method in each concrete subclass (per species).  The re-derived
3125     // method simply calls one of these generic methods, with exact
3126     // parameters for the controlling metadata, which is either a
3127     // typed vector or constant species instance.
3128 
3129     // Unchecked loading operations in native byte order.
3130     // Caller is reponsible for applying index checks, masking, and
3131     // byte swapping.
3132 
3133     /*package-private*/
3134     abstract
3135     DoubleVector fromArray0(double[] a, int offset);
3136     @ForceInline
3137     final
3138     DoubleVector fromArray0Template(double[] a, int offset) {
3139         DoubleSpecies vsp = vspecies();
3140         return VectorIntrinsics.load(
3141             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3142             a, arrayAddress(a, offset),
3143             a, offset, vsp,
3144             (arr, off, s) -> s.ldOp(arr, off,
3145                                     (arr_, off_, i) -> arr_[off_ + i]));
3146     }
3147 
3148     @Override
3149     abstract
3150     DoubleVector fromByteArray0(byte[] a, int offset);
3151     @ForceInline
3152     final
3153     DoubleVector fromByteArray0Template(byte[] a, int offset) {
3154         DoubleSpecies vsp = vspecies();
3155         return VectorIntrinsics.load(
3156             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3157             a, byteArrayAddress(a, offset),
3158             a, offset, vsp,
3159             (arr, off, s) -> {
3160                 DoubleBuffer tb = wrapper(arr, off, NATIVE_ENDIAN);
3161                 return s.ldOp(tb, 0, (tb_, __, i) -> tb_.get(i));
3162             });
3163     }
3164 
3165     abstract
3166     DoubleVector fromByteBuffer0(ByteBuffer bb, int offset);
3167     @ForceInline
3168     final
3169     DoubleVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
3170         DoubleSpecies vsp = vspecies();
3171         return VectorIntrinsics.load(
3172             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3173             bufferBase(bb), bufferAddress(bb, offset),
3174             bb, offset, vsp,
3175             (buf, off, s) -> {
3176                 DoubleBuffer tb = wrapper(buf, off, NATIVE_ENDIAN);
3177                 return s.ldOp(tb, 0, (tb_, __, i) -> tb_.get(i));
3178            });
3179     }
3180 
3181     // Unchecked storing operations in native byte order.
3182     // Caller is reponsible for applying index checks, masking, and
3183     // byte swapping.
3184 
3185     abstract
3186     void intoArray0(double[] a, int offset);
3187     @ForceInline
3188     final
3189     void intoArray0Template(double[] a, int offset) {
3190         DoubleSpecies vsp = vspecies();
3191         VectorIntrinsics.store(
3192             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3193             a, arrayAddress(a, offset),
3194             this, a, offset,
3195             (arr, off, v)
3196             -> v.stOp(arr, off,
3197                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3198     }
3199 
3200     abstract
3201     void intoByteArray0(byte[] a, int offset);
3202     @ForceInline
3203     final
3204     void intoByteArray0Template(byte[] a, int offset) {
3205         DoubleSpecies vsp = vspecies();
3206         VectorIntrinsics.store(
3207             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3208             a, byteArrayAddress(a, offset),
3209             this, a, offset,
3210             (arr, off, v) -> {
3211                 DoubleBuffer tb = wrapper(arr, off, NATIVE_ENDIAN);
3212                 v.stOp(tb, 0, (tb_, __, i, e) -> tb_.put(i, e));
3213             });
3214     }
3215 
3216     @ForceInline
3217     final
3218     void intoByteBuffer0(ByteBuffer bb, int offset) {
3219         DoubleSpecies vsp = vspecies();
3220         VectorIntrinsics.store(
3221             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3222             bufferBase(bb), bufferAddress(bb, offset),
3223             this, bb, offset,
3224             (buf, off, v) -> {
3225                 DoubleBuffer tb = wrapper(buf, off, NATIVE_ENDIAN);
3226                 v.stOp(tb, 0, (tb_, __, i, e) -> tb_.put(i, e));
3227             });
3228     }
3229 
3230     // End of low-level memory operations.
3231 
3232     private static
3233     void checkMaskFromIndexSize(int offset,
3234                                 DoubleSpecies vsp,
3235                                 VectorMask<Double> m,
3236                                 int scale,
3237                                 int limit) {
3238         ((AbstractMask<Double>)m)
3239             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3240     }
3241 
3242     @ForceInline
3243     private void conditionalStoreNYI(int offset,
3244                                      DoubleSpecies vsp,
3245                                      VectorMask<Double> m,
3246                                      int scale,
3247                                      int limit) {
3248         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3249             String msg =
3250                 String.format("unimplemented: store @%d in [0..%d), %s in %s",
3251                               offset, limit, m, vsp);
3252             throw new AssertionError(msg);
3253         }
3254     }
3255 
3256     /*package-private*/
3257     @Override
3258     @ForceInline
3259     final
3260     DoubleVector maybeSwap(ByteOrder bo) {
3261         if (bo != NATIVE_ENDIAN) {
3262             return this.reinterpretAsBytes()
3263                 .rearrange(swapBytesShuffle())
3264                 .reinterpretAsDoubles();
3265         }
3266         return this;
3267     }
3268 
3269     static final int ARRAY_SHIFT =
3270         31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
3271     static final long ARRAY_BASE =
3272         Unsafe.ARRAY_DOUBLE_BASE_OFFSET;
3273 
3274     @ForceInline
3275     static long arrayAddress(double[] a, int index) {
3276         return ARRAY_BASE + (((long)index) << ARRAY_SHIFT);
3277     }
3278 
3279     @ForceInline
3280     static long byteArrayAddress(byte[] a, int index) {
3281         return Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
3282     }
3283 
3284     // Byte buffer wrappers.
3285     private static DoubleBuffer wrapper(ByteBuffer bb, int offset,
3286                                         ByteOrder bo) {
3287         return bb.duplicate().position(offset).slice()
3288             .order(bo).asDoubleBuffer();
3289     }
3290     private static DoubleBuffer wrapper(byte[] a, int offset,
3291                                         ByteOrder bo) {
3292         return ByteBuffer.wrap(a, offset, a.length - offset)
3293             .order(bo).asDoubleBuffer();
3294     }
3295 
3296     // ================================================
3297 
3298     /// Reinterpreting view methods:
3299     //   lanewise reinterpret: viewAsXVector()
3300     //   keep shape, redraw lanes: reinterpretAsEs()
3301 
3302     /**
3303      * {@inheritDoc} <!--workaround-->
3304      */
3305     @ForceInline
3306     @Override
3307     public final ByteVector reinterpretAsBytes() {
3308          // Going to ByteVector, pay close attention to byte order.
3309          assert(REGISTER_ENDIAN == ByteOrder.LITTLE_ENDIAN);
3310          return asByteVectorRaw();
3311          //return asByteVectorRaw().rearrange(swapBytesShuffle());
3312     }
3313 
3314     /**
3315      * {@inheritDoc} <!--workaround-->
3316      */
3317     @ForceInline
3318     @Override
3319     public final LongVector viewAsIntegralLanes() {
3320         LaneType ilt = LaneType.DOUBLE.asIntegral();
3321         return (LongVector) asVectorRaw(ilt);
3322     }
3323 
3324     /**
3325      * {@inheritDoc} <!--workaround-->
3326      */
3327     @ForceInline
3328     @Override
3329     public final
3330     DoubleVector
3331     viewAsFloatingLanes() {
3332         return this;
3333     }
3334 
3335     // ================================================
3336 
3337     /// Object methods: toString, equals, hashCode
3338     //
3339     // Object methods are defined as if via Arrays.toString, etc.,
3340     // is applied to the array of elements.  Two equal vectors
3341     // are required to have equal species and equal lane values.
3342 
3343     /**
3344      * Returns a string representation of this vector, of the form
3345      * {@code "[0,1,2...]"}, reporting the lane values of this vector,
3346      * in lane order.
3347      *
3348      * The string is produced as if by a call to {@link
3349      * java.util.Arrays#toString(double[]) Arrays.toString()},
3350      * as appropriate to the {@code double} array returned by
3351      * {@link #toArray this.toArray()}.
3352      *
3353      * @return a string of the form {@code "[0,1,2...]"}
3354      * reporting the lane values of this vector
3355      */
3356     @Override
3357     @ForceInline
3358     public final
3359     String toString() {
3360         // now that toArray is strongly typed, we can define this
3361         return Arrays.toString(toArray());
3362     }
3363 
3364     /**
3365      * {@inheritDoc} <!--workaround-->
3366      */
3367     @Override
3368     @ForceInline
3369     public final
3370     boolean equals(Object obj) {
3371         if (obj instanceof Vector) {
3372             Vector<?> that = (Vector<?>) obj;
3373             if (this.species().equals(that.species())) {
3374                 return this.eq(that.check(this.species())).allTrue();
3375             }
3376         }
3377         return false;
3378     }
3379 
3380     /**
3381      * {@inheritDoc} <!--workaround-->
3382      */
3383     @Override
3384     @ForceInline
3385     public final
3386     int hashCode() {
3387         // now that toArray is strongly typed, we can define this
3388         return Objects.hash(species(), Arrays.hashCode(toArray()));
3389     }
3390 
3391     // ================================================
3392 
3393     // Species
3394 
3395     /**
3396      * Class representing {@link DoubleVector}'s of the same {@link VectorShape VectorShape}.
3397      */
3398     /*package-private*/
3399     static final class DoubleSpecies extends AbstractSpecies<Double> {
3400         private DoubleSpecies(VectorShape shape,
3401                 Class<? extends DoubleVector> vectorType,
3402                 Class<? extends AbstractMask<Double>> maskType,
3403                 Function<Object, DoubleVector> vectorFactory) {
3404             super(shape, LaneType.of(double.class),
3405                   vectorType, maskType,
3406                   vectorFactory);
3407             assert(this.elementSize() == Double.SIZE);
3408         }
3409 
3410         // Specializing overrides:
3411 
3412         @Override
3413         @ForceInline
3414         public final Class<Double> elementType() {
3415             return double.class;
3416         }
3417 
3418         @Override
3419         @ForceInline
3420         public final Class<Double> genericElementType() {
3421             return Double.class;
3422         }
3423 
3424         @Override
3425         @ForceInline
3426         public final Class<double[]> arrayType() {
3427             return double[].class;
3428         }
3429 
3430         @SuppressWarnings("unchecked")
3431         @Override
3432         @ForceInline
3433         public final Class<? extends DoubleVector> vectorType() {
3434             return (Class<? extends DoubleVector>) vectorType;
3435         }
3436 
3437         @Override
3438         @ForceInline
3439         public final long checkValue(long e) {
3440             longToElementBits(e);  // only for exception
3441             return e;
3442         }
3443 
3444         /*package-private*/
3445         @Override
3446         @ForceInline
3447         final DoubleVector broadcastBits(long bits) {
3448             return (DoubleVector)
3449                 VectorIntrinsics.broadcastCoerced(
3450                     vectorType, double.class, laneCount,
3451                     bits, this,
3452                     (bits_, s_) -> s_.rvOp(i -> bits_));
3453         }
3454 
3455         /*package-private*/
3456         @ForceInline
3457         
3458         final DoubleVector broadcast(double e) {
3459             return broadcastBits(toBits(e));
3460         }
3461 
3462         @Override
3463         @ForceInline
3464         public final DoubleVector broadcast(long e) {
3465             return broadcastBits(longToElementBits(e));
3466         }
3467 
3468         /*package-private*/
3469         final @Override
3470         @ForceInline
3471         long longToElementBits(long value) {
3472             // Do the conversion, and then test it for failure.
3473             double e = (double) value;
3474             if ((long) e != value) {
3475                 throw badElementBits(value, e);
3476             }
3477             return toBits(e);
3478         }
3479 
3480         @Override
3481         @ForceInline
3482         public final DoubleVector fromValues(long... values) {
3483             VectorIntrinsics.requireLength(values.length, laneCount);
3484             double[] va = new double[laneCount()];
3485             for (int i = 0; i < va.length; i++) {
3486                 long lv = values[i];
3487                 double v = (double) lv;
3488                 va[i] = v;
3489                 if ((long)v != lv) {
3490                     throw badElementBits(lv, v);
3491                 }
3492             }
3493             return dummyVector().fromArray0(va, 0);
3494         }
3495 
3496         /* this non-public one is for internal conversions */
3497         @Override
3498         @ForceInline
3499         final DoubleVector fromIntValues(int[] values) {
3500             VectorIntrinsics.requireLength(values.length, laneCount);
3501             double[] va = new double[laneCount()];
3502             for (int i = 0; i < va.length; i++) {
3503                 int lv = values[i];
3504                 double v = (double) lv;
3505                 va[i] = v;
3506                 if ((int)v != lv) {
3507                     throw badElementBits(lv, v);
3508                 }
3509             }
3510             return dummyVector().fromArray0(va, 0);
3511         }
3512 
3513         // Virtual constructors
3514 
3515         @ForceInline
3516         @Override final
3517         public DoubleVector fromArray(Object a, int offset) {
3518             // User entry point:  Be careful with inputs.
3519             return DoubleVector
3520                 .fromArray(this, (double[]) a, offset);
3521         }
3522 
3523         @Override final
3524         DoubleVector dummyVector() {
3525             return (DoubleVector) super.dummyVector();
3526         }
3527 
3528         final
3529         DoubleVector vectorFactory(double[] vec) {
3530             // Species delegates all factory requests to its dummy
3531             // vector.  The dummy knows all about it.
3532             return dummyVector().vectorFactory(vec);
3533         }
3534 
3535         /*package-private*/
3536         final @Override
3537         @ForceInline
3538         DoubleVector rvOp(RVOp f) {
3539             double[] res = new double[laneCount()];
3540             for (int i = 0; i < res.length; i++) {
3541                 long bits = (long) f.apply(i);
3542                 res[i] = fromBits(bits);
3543             }
3544             return dummyVector().vectorFactory(res);
3545         }
3546 
3547         DoubleVector vOp(FVOp f) {
3548             double[] res = new double[laneCount()];
3549             for (int i = 0; i < res.length; i++) {
3550                 res[i] = f.apply(i);
3551             }
3552             return dummyVector().vectorFactory(res);
3553         }
3554 
3555         DoubleVector vOp(VectorMask<Double> m, FVOp f) {
3556             double[] res = new double[laneCount()];
3557             boolean[] mbits = ((AbstractMask<Double>)m).getBits();
3558             for (int i = 0; i < res.length; i++) {
3559                 if (mbits[i]) {
3560                     res[i] = f.apply(i);
3561                 }
3562             }
3563             return dummyVector().vectorFactory(res);
3564         }
3565 
3566         /*package-private*/
3567         @ForceInline
3568         <M> DoubleVector ldOp(M memory, int offset,
3569                                       FLdOp<M> f) {
3570             return dummyVector().ldOp(memory, offset, f);
3571         }
3572 
3573         /*package-private*/
3574         @ForceInline
3575         <M> DoubleVector ldOp(M memory, int offset,
3576                                       AbstractMask<Double> m,
3577                                       FLdOp<M> f) {
3578             return dummyVector().ldOp(memory, offset, m, f);
3579         }
3580 
3581         /*package-private*/
3582         @ForceInline
3583         <M> void stOp(M memory, int offset, FStOp<M> f) {
3584             dummyVector().stOp(memory, offset, f);
3585         }
3586 
3587         /*package-private*/
3588         @ForceInline
3589         <M> void stOp(M memory, int offset,
3590                       AbstractMask<Double> m,
3591                       FStOp<M> f) {
3592             dummyVector().stOp(memory, offset, m, f);
3593         }
3594 
3595         // N.B. Make sure these constant vectors and
3596         // masks load up correctly into registers.
3597         //
3598         // Also, see if we can avoid all that switching.
3599         // Could we cache both vectors and both masks in
3600         // this species object?
3601 
3602         // Zero and iota vector access
3603         @Override
3604         @ForceInline
3605         public final DoubleVector zero() {
3606             if ((Class<?>) vectorType() == DoubleMaxVector.class)
3607                 return DoubleMaxVector.ZERO;
3608             switch (vectorBitSize()) {
3609                 case 64: return Double64Vector.ZERO;
3610                 case 128: return Double128Vector.ZERO;
3611                 case 256: return Double256Vector.ZERO;
3612                 case 512: return Double512Vector.ZERO;
3613             }
3614             throw new AssertionError();
3615         }        
3616 
3617         @Override
3618         @ForceInline
3619         public final DoubleVector iota() {
3620             if ((Class<?>) vectorType() == DoubleMaxVector.class)
3621                 return DoubleMaxVector.IOTA;
3622             switch (vectorBitSize()) {
3623                 case 64: return Double64Vector.IOTA;
3624                 case 128: return Double128Vector.IOTA;
3625                 case 256: return Double256Vector.IOTA;
3626                 case 512: return Double512Vector.IOTA;
3627             }
3628             throw new AssertionError();
3629         }
3630 
3631         // Mask access
3632         @Override
3633         @ForceInline
3634         public final VectorMask<Double> maskAll(boolean bit) {
3635             if ((Class<?>) vectorType() == DoubleMaxVector.class)
3636                 return DoubleMaxVector.DoubleMaxMask.maskAll(bit);
3637             switch (vectorBitSize()) {
3638                 case 64: return Double64Vector.Double64Mask.maskAll(bit);
3639                 case 128: return Double128Vector.Double128Mask.maskAll(bit);
3640                 case 256: return Double256Vector.Double256Mask.maskAll(bit);
3641                 case 512: return Double512Vector.Double512Mask.maskAll(bit);
3642             }
3643             throw new AssertionError();
3644         }
3645     }
3646 
3647     /**
3648      * Finds a species for an element type of {@code double} and shape.
3649      *
3650      * @param s the shape
3651      * @return a species for an element type of {@code double} and shape
3652      * @throws IllegalArgumentException if no such species exists for the shape
3653      */
3654     static DoubleSpecies species(VectorShape s) {
3655         Objects.requireNonNull(s);
3656         switch (s) {
3657             case S_64_BIT: return (DoubleSpecies) SPECIES_64;
3658             case S_128_BIT: return (DoubleSpecies) SPECIES_128;
3659             case S_256_BIT: return (DoubleSpecies) SPECIES_256;
3660             case S_512_BIT: return (DoubleSpecies) SPECIES_512;
3661             case S_Max_BIT: return (DoubleSpecies) SPECIES_MAX;
3662             default: throw new IllegalArgumentException("Bad shape: " + s);
3663         }
3664     }
3665 
3666     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
3667     public static final VectorSpecies<Double> SPECIES_64
3668         = new DoubleSpecies(VectorShape.S_64_BIT,
3669                             Double64Vector.class,
3670                             Double64Vector.Double64Mask.class,
3671                             Double64Vector::new);
3672 
3673     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
3674     public static final VectorSpecies<Double> SPECIES_128
3675         = new DoubleSpecies(VectorShape.S_128_BIT,
3676                             Double128Vector.class,
3677                             Double128Vector.Double128Mask.class,
3678                             Double128Vector::new);
3679 
3680     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
3681     public static final VectorSpecies<Double> SPECIES_256
3682         = new DoubleSpecies(VectorShape.S_256_BIT,
3683                             Double256Vector.class,
3684                             Double256Vector.Double256Mask.class,
3685                             Double256Vector::new);
3686 
3687     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
3688     public static final VectorSpecies<Double> SPECIES_512
3689         = new DoubleSpecies(VectorShape.S_512_BIT,
3690                             Double512Vector.class,
3691                             Double512Vector.Double512Mask.class,
3692                             Double512Vector::new);
3693 
3694     /** Species representing {@link DoubleVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
3695     public static final VectorSpecies<Double> SPECIES_MAX
3696         = new DoubleSpecies(VectorShape.S_Max_BIT,
3697                             DoubleMaxVector.class,
3698                             DoubleMaxVector.DoubleMaxMask.class,
3699                             DoubleMaxVector::new);
3700 
3701     /**
3702      * Preferred species for {@link DoubleVector}s.
3703      * A preferred species is a species of maximal bit-size for the platform.
3704      */
3705     public static final VectorSpecies<Double> SPECIES_PREFERRED
3706         = (DoubleSpecies) VectorSpecies.ofPreferred(double.class);
3707 
3708 
3709     // ==== JROSE NAME CHANGES ====
3710 
3711     /** Use lanewise(NEG, m). */
3712     @Deprecated
3713     public final DoubleVector neg(VectorMask<Double> m) {
3714         return lanewise(NEG, m);
3715     }
3716 
3717     /** Use lanewise(ABS, m). */
3718     @Deprecated
3719     public final DoubleVector abs(VectorMask<Double> m) {
3720         return lanewise(ABS, m);
3721     }
3722 
3723     /** Use explicit argument of ByteOrder.LITTLE_ENDIAN */
3724     @Deprecated
3725     public static
3726     DoubleVector fromByteBuffer(VectorSpecies<Double> species,
3727                                         ByteBuffer bb, int offset) {
3728         ByteOrder bo = ByteOrder.LITTLE_ENDIAN;
3729         if (bb.order() != bo)  throw new IllegalArgumentException();
3730         return fromByteBuffer(species, bb, offset, bo);
3731     }
3732 
3733     /** Use explicit argument of ByteOrder.LITTLE_ENDIAN */
3734     @Deprecated
3735     public static
3736     DoubleVector fromByteBuffer(VectorSpecies<Double> species,
3737                                         ByteBuffer bb, int offset,
3738                                         VectorMask<Double> m) {
3739         ByteOrder bo = ByteOrder.LITTLE_ENDIAN;
3740         if (bb.order() != bo)  throw new IllegalArgumentException();
3741         return fromByteBuffer(species, bb, offset, bo, m);
3742     }
3743 
3744     /** Use fromValues(s, value...) */
3745     @Deprecated
3746     public static
3747     DoubleVector scalars(VectorSpecies<Double> species,
3748                                  double... values) {
3749         return fromValues(species, values);
3750     }
3751 
3752     @Deprecated public final double addLanes() { return reduceLanes(ADD); }
3753     @Deprecated public final double addLanes(VectorMask<Double> m) { return reduceLanes(ADD, m); }
3754     @Deprecated public final double mulLanes() { return reduceLanes(MUL); }
3755     @Deprecated public final double mulLanes(VectorMask<Double> m) { return reduceLanes(MUL, m); }
3756     @Deprecated public final double minLanes() { return reduceLanes(MIN); }
3757     @Deprecated public final double minLanes(VectorMask<Double> m) { return reduceLanes(MIN, m); }
3758     @Deprecated public final double maxLanes() { return reduceLanes(MAX); }
3759     @Deprecated public final double maxLanes(VectorMask<Double> m) { return reduceLanes(MAX, m); }
3760     @Deprecated public final double orLanes() { return reduceLanes(OR); }
3761     @Deprecated public final double orLanes(VectorMask<Double> m) { return reduceLanes(OR, m); }
3762     @Deprecated public final double andLanes() { return reduceLanes(AND); }
3763     @Deprecated public final double andLanes(VectorMask<Double> m) { return reduceLanes(AND, m); }
3764     @Deprecated public final double xorLanes() { return reduceLanes(XOR); }
3765     @Deprecated public final double xorLanes(VectorMask<Double> m) { return reduceLanes(XOR, m); }
3766     @Deprecated public final DoubleVector sqrt(VectorMask<Double> m) { return lanewise(SQRT, m); }
3767     @Deprecated public final DoubleVector tan() { return lanewise(TAN); }
3768     @Deprecated public final DoubleVector tan(VectorMask<Double> m) { return lanewise(TAN, m); }
3769     @Deprecated public final DoubleVector tanh() { return lanewise(TANH); }
3770     @Deprecated public final DoubleVector tanh(VectorMask<Double> m) { return lanewise(TANH, m); }
3771     @Deprecated public final DoubleVector sin() { return lanewise(SIN); }
3772     @Deprecated public final DoubleVector sin(VectorMask<Double> m) { return lanewise(SIN, m); }
3773     @Deprecated public final DoubleVector sinh() { return lanewise(SINH); }
3774     @Deprecated public final DoubleVector sinh(VectorMask<Double> m) { return lanewise(SINH, m); }
3775     @Deprecated public final DoubleVector cos() { return lanewise(COS); }
3776     @Deprecated public final DoubleVector cos(VectorMask<Double> m) { return lanewise(COS, m); }
3777     @Deprecated public final DoubleVector cosh() { return lanewise(COSH); }
3778     @Deprecated public final DoubleVector cosh(VectorMask<Double> m) { return lanewise(COSH, m); }
3779     @Deprecated public final DoubleVector asin() { return lanewise(ASIN); }
3780     @Deprecated public final DoubleVector asin(VectorMask<Double> m) { return lanewise(ASIN, m); }
3781     @Deprecated public final DoubleVector acos() { return lanewise(ACOS); }
3782     @Deprecated public final DoubleVector acos(VectorMask<Double> m) { return lanewise(ACOS, m); }
3783     @Deprecated public final DoubleVector atan() { return lanewise(ATAN); }
3784     @Deprecated public final DoubleVector atan(VectorMask<Double> m) { return lanewise(ATAN, m); }
3785     @Deprecated public final DoubleVector atan2(Vector<Double> v) { return lanewise(ATAN2, v); }
3786     @Deprecated public final DoubleVector atan2(double s) { return lanewise(ATAN2, s); }
3787     @Deprecated public final DoubleVector atan2(Vector<Double> v, VectorMask<Double> m) { return lanewise(ATAN2, v, m); }
3788     @Deprecated public final DoubleVector atan2(double s, VectorMask<Double> m) { return lanewise(ATAN2, s, m); }
3789     @Deprecated public final DoubleVector cbrt() { return lanewise(CBRT); }
3790     @Deprecated public final DoubleVector cbrt(VectorMask<Double> m) { return lanewise(CBRT, m); }
3791     @Deprecated public final DoubleVector log() { return lanewise(LOG); }
3792     @Deprecated public final DoubleVector log(VectorMask<Double> m) { return lanewise(LOG, m); }
3793     @Deprecated public final DoubleVector log10() { return lanewise(LOG10); }
3794     @Deprecated public final DoubleVector log10(VectorMask<Double> m) { return lanewise(LOG10, m); }
3795     @Deprecated public final DoubleVector log1p() { return lanewise(LOG1P); }
3796     @Deprecated public final DoubleVector log1p(VectorMask<Double> m) { return lanewise(LOG1P, m); }
3797     @Deprecated public final DoubleVector pow(Vector<Double> v, VectorMask<Double> m) { return lanewise(POW, v, m); }
3798     @Deprecated public final DoubleVector pow(double s, VectorMask<Double> m) { return lanewise(POW, s, m); }
3799     @Deprecated public final DoubleVector exp() { return lanewise(EXP); }
3800     @Deprecated public final DoubleVector exp(VectorMask<Double> m) { return lanewise(EXP, m); }
3801     @Deprecated public final DoubleVector expm1() { return lanewise(EXPM1); }
3802     @Deprecated public final DoubleVector expm1(VectorMask<Double> m) { return lanewise(EXPM1, m); }
3803     @Deprecated public final DoubleVector hypot(Vector<Double> v) { return lanewise(HYPOT, v); }
3804     @Deprecated public final DoubleVector hypot(double s) { return lanewise(HYPOT, s); }
3805     @Deprecated public final DoubleVector hypot(Vector<Double> v, VectorMask<Double> m) { return lanewise(HYPOT, v, m); }
3806     @Deprecated public final DoubleVector hypot(double s, VectorMask<Double> m) { return lanewise(HYPOT, s, m); }
3807     @Deprecated public final DoubleVector and(Vector<Double> v, VectorMask<Double> m) { return lanewise(AND, v, m); }
3808     @Deprecated public final DoubleVector and(double s, VectorMask<Double> m) { return lanewise(AND, s, m); }
3809     @Deprecated public final DoubleVector or(Vector<Double> v, VectorMask<Double> m) { return lanewise(OR, v, m); }
3810     @Deprecated public final DoubleVector or(double s, VectorMask<Double> m) { return lanewise(OR, s, m); }
3811     @Deprecated public final DoubleVector xor(Vector<Double> v) { return lanewise(XOR, v); }
3812     @Deprecated public final DoubleVector xor(double s) { return lanewise(XOR, s); }
3813     @Deprecated public final DoubleVector xor(Vector<Double> v, VectorMask<Double> m) { return lanewise(XOR, v, m); }
3814     @Deprecated public final DoubleVector xor(double s, VectorMask<Double> m) { return lanewise(XOR, s, m); }
3815     @Deprecated public final DoubleVector not(VectorMask<Double> m) { return lanewise(NOT, m); }
3816     @Deprecated public final DoubleVector shiftLeft(int s) { return lanewise(LSHL, (double) s); }
3817     @Deprecated public final DoubleVector shiftLeft(int s, VectorMask<Double> m) { return lanewise(LSHL, (double) s, m); }
3818     @Deprecated public final DoubleVector shiftLeft(Vector<Double> v) { return lanewise(LSHL, v); }
3819     @Deprecated public final DoubleVector shiftLeft(Vector<Double> v, VectorMask<Double> m) { return lanewise(LSHL, v, m); }
3820     @Deprecated public final DoubleVector shiftRight(int s) { return lanewise(LSHR, (double) s); }
3821     @Deprecated public final DoubleVector shiftRight(int s, VectorMask<Double> m) { return lanewise(LSHR, (double) s, m); }
3822     @Deprecated public final DoubleVector shiftRight(Vector<Double> v) { return lanewise(LSHR, v); }
3823     @Deprecated public final DoubleVector shiftRight(Vector<Double> v, VectorMask<Double> m) { return lanewise(LSHR, v, m); }
3824     @Deprecated public final DoubleVector shiftArithmeticRight(int s) { return lanewise(ASHR, (double) s); }
3825     @Deprecated public final DoubleVector shiftArithmeticRight(int s, VectorMask<Double> m) { return lanewise(ASHR, (double) s, m); }
3826     @Deprecated public final DoubleVector shiftArithmeticRight(Vector<Double> v) { return lanewise(ASHR, v); }
3827     @Deprecated public final DoubleVector shiftArithmeticRight(Vector<Double> v, VectorMask<Double> m) { return lanewise(ASHR, v, m); }
3828     @Deprecated public final DoubleVector rotateLeft(int s) { return lanewise(ROL, (double) s); }
3829     @Deprecated public final DoubleVector rotateLeft(int s, VectorMask<Double> m) { return lanewise(ROL, (double) s, m); }
3830     @Deprecated public final DoubleVector rotateRight(int s) { return lanewise(ROR, (double) s); }
3831     @Deprecated public final DoubleVector rotateRight(int s, VectorMask<Double> m) { return lanewise(ROR, (double) s, m); }
3832     @Deprecated @Override public DoubleVector rotateLanesLeft(int i) { return (DoubleVector) super.rotateLanesLeft(i); }
3833     @Deprecated @Override public DoubleVector rotateLanesRight(int i) { return (DoubleVector) super.rotateLanesRight(i); }
3834     @Deprecated @Override public DoubleVector shiftLanesLeft(int i) { return (DoubleVector) super.shiftLanesLeft(i); }
3835     @Deprecated @Override public DoubleVector shiftLanesRight(int i) { return (DoubleVector) super.shiftLanesRight(i); }
3836     @Deprecated public DoubleVector with(int i, double e) { return withLane(i, e); }
3837 }