1 /*
   2  * Copyright (c) 2017, 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.ByteOrder;
  29 import java.nio.DoubleBuffer;
  30 import java.nio.ReadOnlyBufferException;
  31 import java.util.Arrays;
  32 import java.util.Objects;
  33 import java.util.function.IntUnaryOperator;
  34 
  35 import jdk.internal.misc.Unsafe;
  36 import jdk.internal.vm.annotation.ForceInline;
  37 import static jdk.incubator.vector.VectorIntrinsics.*;
  38 
  39 @SuppressWarnings("cast")
  40 final class Double64Vector extends DoubleVector {
  41     static final Double64Species SPECIES = new Double64Species();
  42 
  43     static final Double64Vector ZERO = new Double64Vector();
  44 
  45     static final int LENGTH = SPECIES.length();
  46 
  47     // Index vector species
  48     private static final IntVector.IntSpecies INDEX_SPEC;
  49     static {
  50         INDEX_SPEC = (IntVector.IntSpecies) Species.of(int.class, Shape.S_64_BIT);
  51     }
  52     private final double[] vec; // Don't access directly, use getElements() instead.
  53 
  54     private double[] getElements() {
  55         return VectorIntrinsics.maybeRebox(this).vec;
  56     }
  57 
  58     Double64Vector() {
  59         vec = new double[SPECIES.length()];
  60     }
  61 
  62     Double64Vector(double[] v) {
  63         vec = v;
  64     }
  65 
  66     @Override
  67     public int length() { return LENGTH; }
  68 
  69     // Unary operator
  70 
  71     @Override
  72     Double64Vector uOp(FUnOp f) {
  73         double[] vec = getElements();
  74         double[] res = new double[length()];
  75         for (int i = 0; i < length(); i++) {
  76             res[i] = f.apply(i, vec[i]);
  77         }
  78         return new Double64Vector(res);
  79     }
  80 
  81     @Override
  82     Double64Vector uOp(Mask<Double> o, FUnOp f) {
  83         double[] vec = getElements();
  84         double[] res = new double[length()];
  85         boolean[] mbits = ((Double64Mask)o).getBits();
  86         for (int i = 0; i < length(); i++) {
  87             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  88         }
  89         return new Double64Vector(res);
  90     }
  91 
  92     // Binary operator
  93 
  94     @Override
  95     Double64Vector bOp(Vector<Double> o, FBinOp f) {
  96         double[] res = new double[length()];
  97         double[] vec1 = this.getElements();
  98         double[] vec2 = ((Double64Vector)o).getElements();
  99         for (int i = 0; i < length(); i++) {
 100             res[i] = f.apply(i, vec1[i], vec2[i]);
 101         }
 102         return new Double64Vector(res);
 103     }
 104 
 105     @Override
 106     Double64Vector bOp(Vector<Double> o1, Mask<Double> o2, FBinOp f) {
 107         double[] res = new double[length()];
 108         double[] vec1 = this.getElements();
 109         double[] vec2 = ((Double64Vector)o1).getElements();
 110         boolean[] mbits = ((Double64Mask)o2).getBits();
 111         for (int i = 0; i < length(); i++) {
 112             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 113         }
 114         return new Double64Vector(res);
 115     }
 116 
 117     // Trinary operator
 118 
 119     @Override
 120     Double64Vector tOp(Vector<Double> o1, Vector<Double> o2, FTriOp f) {
 121         double[] res = new double[length()];
 122         double[] vec1 = this.getElements();
 123         double[] vec2 = ((Double64Vector)o1).getElements();
 124         double[] vec3 = ((Double64Vector)o2).getElements();
 125         for (int i = 0; i < length(); i++) {
 126             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 127         }
 128         return new Double64Vector(res);
 129     }
 130 
 131     @Override
 132     Double64Vector tOp(Vector<Double> o1, Vector<Double> o2, Mask<Double> o3, FTriOp f) {
 133         double[] res = new double[length()];
 134         double[] vec1 = getElements();
 135         double[] vec2 = ((Double64Vector)o1).getElements();
 136         double[] vec3 = ((Double64Vector)o2).getElements();
 137         boolean[] mbits = ((Double64Mask)o3).getBits();
 138         for (int i = 0; i < length(); i++) {
 139             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 140         }
 141         return new Double64Vector(res);
 142     }
 143 
 144     @Override
 145     double rOp(double v, FBinOp f) {
 146         double[] vec = getElements();
 147         for (int i = 0; i < length(); i++) {
 148             v = f.apply(i, v, vec[i]);
 149         }
 150         return v;
 151     }
 152 
 153     @Override
 154     @ForceInline
 155     public <F> Vector<F> cast(Species<F> s) {
 156         Objects.requireNonNull(s);
 157         if (s.length() != LENGTH)
 158             throw new IllegalArgumentException("Vector length this species length differ");
 159 
 160         return VectorIntrinsics.cast(
 161             Double64Vector.class,
 162             double.class, LENGTH,
 163             s.vectorType(),
 164             s.elementType(), LENGTH,
 165             this, s,
 166             (species, vector) -> vector.castDefault(species)
 167         );
 168     }
 169 
 170     @SuppressWarnings("unchecked")
 171     @ForceInline
 172     private <F> Vector<F> castDefault(Species<F> s) {
 173         int limit = s.length();
 174 
 175         Class<?> stype = s.elementType();
 176         if (stype == byte.class) {
 177             byte[] a = new byte[limit];
 178             for (int i = 0; i < limit; i++) {
 179                 a[i] = (byte) this.get(i);
 180             }
 181             return (Vector) ByteVector.fromArray((ByteVector.ByteSpecies) s, a, 0);
 182         } else if (stype == short.class) {
 183             short[] a = new short[limit];
 184             for (int i = 0; i < limit; i++) {
 185                 a[i] = (short) this.get(i);
 186             }
 187             return (Vector) ShortVector.fromArray((ShortVector.ShortSpecies) s, a, 0);
 188         } else if (stype == int.class) {
 189             int[] a = new int[limit];
 190             for (int i = 0; i < limit; i++) {
 191                 a[i] = (int) this.get(i);
 192             }
 193             return (Vector) IntVector.fromArray((IntVector.IntSpecies) s, a, 0);
 194         } else if (stype == long.class) {
 195             long[] a = new long[limit];
 196             for (int i = 0; i < limit; i++) {
 197                 a[i] = (long) this.get(i);
 198             }
 199             return (Vector) LongVector.fromArray((LongVector.LongSpecies) s, a, 0);
 200         } else if (stype == float.class) {
 201             float[] a = new float[limit];
 202             for (int i = 0; i < limit; i++) {
 203                 a[i] = (float) this.get(i);
 204             }
 205             return (Vector) FloatVector.fromArray((FloatVector.FloatSpecies) s, a, 0);
 206         } else if (stype == double.class) {
 207             double[] a = new double[limit];
 208             for (int i = 0; i < limit; i++) {
 209                 a[i] = (double) this.get(i);
 210             }
 211             return (Vector) DoubleVector.fromArray((DoubleVector.DoubleSpecies) s, a, 0);
 212         } else {
 213             throw new UnsupportedOperationException("Bad lane type for casting.");
 214         }
 215     }
 216 
 217     @Override
 218     @ForceInline
 219     @SuppressWarnings("unchecked")
 220     public <F> Vector<F> reinterpret(Species<F> s) {
 221         Objects.requireNonNull(s);
 222 
 223         if(s.elementType().equals(double.class)) {
 224             return (Vector<F>) reshape((Species<Double>)s);
 225         }
 226         if(s.bitSize() == bitSize()) {
 227             return reinterpretType(s);
 228         }
 229 
 230         return defaultReinterpret(s);
 231     }
 232 
 233     @ForceInline
 234     private <F> Vector<F> reinterpretType(Species<F> s) {
 235         Objects.requireNonNull(s);
 236 
 237         Class<?> stype = s.elementType();
 238         if (stype == byte.class) {
 239             return VectorIntrinsics.reinterpret(
 240                 Double64Vector.class,
 241                 double.class, LENGTH,
 242                 Byte64Vector.class,
 243                 byte.class, Byte64Vector.LENGTH,
 244                 this, s,
 245                 (species, vector) -> vector.defaultReinterpret(species)
 246             );
 247         } else if (stype == short.class) {
 248             return VectorIntrinsics.reinterpret(
 249                 Double64Vector.class,
 250                 double.class, LENGTH,
 251                 Short64Vector.class,
 252                 short.class, Short64Vector.LENGTH,
 253                 this, s,
 254                 (species, vector) -> vector.defaultReinterpret(species)
 255             );
 256         } else if (stype == int.class) {
 257             return VectorIntrinsics.reinterpret(
 258                 Double64Vector.class,
 259                 double.class, LENGTH,
 260                 Int64Vector.class,
 261                 int.class, Int64Vector.LENGTH,
 262                 this, s,
 263                 (species, vector) -> vector.defaultReinterpret(species)
 264             );
 265         } else if (stype == long.class) {
 266             return VectorIntrinsics.reinterpret(
 267                 Double64Vector.class,
 268                 double.class, LENGTH,
 269                 Long64Vector.class,
 270                 long.class, Long64Vector.LENGTH,
 271                 this, s,
 272                 (species, vector) -> vector.defaultReinterpret(species)
 273             );
 274         } else if (stype == float.class) {
 275             return VectorIntrinsics.reinterpret(
 276                 Double64Vector.class,
 277                 double.class, LENGTH,
 278                 Float64Vector.class,
 279                 float.class, Float64Vector.LENGTH,
 280                 this, s,
 281                 (species, vector) -> vector.defaultReinterpret(species)
 282             );
 283         } else if (stype == double.class) {
 284             return VectorIntrinsics.reinterpret(
 285                 Double64Vector.class,
 286                 double.class, LENGTH,
 287                 Double64Vector.class,
 288                 double.class, Double64Vector.LENGTH,
 289                 this, s,
 290                 (species, vector) -> vector.defaultReinterpret(species)
 291             );
 292         } else {
 293             throw new UnsupportedOperationException("Bad lane type for casting.");
 294         }
 295     }
 296 
 297     @Override
 298     @ForceInline
 299     public DoubleVector reshape(Species<Double> s) {
 300         Objects.requireNonNull(s);
 301         if (s.bitSize() == 64 && (s instanceof Double64Vector.Double64Species)) {
 302             Double64Vector.Double64Species ts = (Double64Vector.Double64Species)s;
 303             return VectorIntrinsics.reinterpret(
 304                 Double64Vector.class,
 305                 double.class, LENGTH,
 306                 Double64Vector.class,
 307                 double.class, Double64Vector.LENGTH,
 308                 this, ts,
 309                 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
 310             );
 311         } else if (s.bitSize() == 128 && (s instanceof Double128Vector.Double128Species)) {
 312             Double128Vector.Double128Species ts = (Double128Vector.Double128Species)s;
 313             return VectorIntrinsics.reinterpret(
 314                 Double64Vector.class,
 315                 double.class, LENGTH,
 316                 Double128Vector.class,
 317                 double.class, Double128Vector.LENGTH,
 318                 this, ts,
 319                 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
 320             );
 321         } else if (s.bitSize() == 256 && (s instanceof Double256Vector.Double256Species)) {
 322             Double256Vector.Double256Species ts = (Double256Vector.Double256Species)s;
 323             return VectorIntrinsics.reinterpret(
 324                 Double64Vector.class,
 325                 double.class, LENGTH,
 326                 Double256Vector.class,
 327                 double.class, Double256Vector.LENGTH,
 328                 this, ts,
 329                 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
 330             );
 331         } else if (s.bitSize() == 512 && (s instanceof Double512Vector.Double512Species)) {
 332             Double512Vector.Double512Species ts = (Double512Vector.Double512Species)s;
 333             return VectorIntrinsics.reinterpret(
 334                 Double64Vector.class,
 335                 double.class, LENGTH,
 336                 Double512Vector.class,
 337                 double.class, Double512Vector.LENGTH,
 338                 this, ts,
 339                 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
 340             );
 341         } else if ((s.bitSize() > 0) && (s.bitSize() <= 2048)
 342                 && (s.bitSize() % 128 == 0) && (s instanceof DoubleMaxVector.DoubleMaxSpecies)) {
 343             DoubleMaxVector.DoubleMaxSpecies ts = (DoubleMaxVector.DoubleMaxSpecies)s;
 344             return VectorIntrinsics.reinterpret(
 345                 Double64Vector.class,
 346                 double.class, LENGTH,
 347                 DoubleMaxVector.class,
 348                 double.class, DoubleMaxVector.LENGTH,
 349                 this, ts,
 350                 (species, vector) -> (DoubleVector) vector.defaultReinterpret(species)
 351             );
 352         } else {
 353             throw new InternalError("Unimplemented size");
 354         }
 355     }
 356 
 357     // Binary operations with scalars
 358 
 359     @Override
 360     @ForceInline
 361     public DoubleVector add(double o) {
 362         return add(SPECIES.broadcast(o));
 363     }
 364 
 365     @Override
 366     @ForceInline
 367     public DoubleVector add(double o, Mask<Double> m) {
 368         return add(SPECIES.broadcast(o), m);
 369     }
 370 
 371     @Override
 372     @ForceInline
 373     public DoubleVector sub(double o) {
 374         return sub(SPECIES.broadcast(o));
 375     }
 376 
 377     @Override
 378     @ForceInline
 379     public DoubleVector sub(double o, Mask<Double> m) {
 380         return sub(SPECIES.broadcast(o), m);
 381     }
 382 
 383     @Override
 384     @ForceInline
 385     public DoubleVector mul(double o) {
 386         return mul(SPECIES.broadcast(o));
 387     }
 388 
 389     @Override
 390     @ForceInline
 391     public DoubleVector mul(double o, Mask<Double> m) {
 392         return mul(SPECIES.broadcast(o), m);
 393     }
 394 
 395     @Override
 396     @ForceInline
 397     public DoubleVector min(double o) {
 398         return min(SPECIES.broadcast(o));
 399     }
 400 
 401     @Override
 402     @ForceInline
 403     public DoubleVector max(double o) {
 404         return max(SPECIES.broadcast(o));
 405     }
 406 
 407     @Override
 408     @ForceInline
 409     public Mask<Double> equal(double o) {
 410         return equal(SPECIES.broadcast(o));
 411     }
 412 
 413     @Override
 414     @ForceInline
 415     public Mask<Double> notEqual(double o) {
 416         return notEqual(SPECIES.broadcast(o));
 417     }
 418 
 419     @Override
 420     @ForceInline
 421     public Mask<Double> lessThan(double o) {
 422         return lessThan(SPECIES.broadcast(o));
 423     }
 424 
 425     @Override
 426     @ForceInline
 427     public Mask<Double> lessThanEq(double o) {
 428         return lessThanEq(SPECIES.broadcast(o));
 429     }
 430 
 431     @Override
 432     @ForceInline
 433     public Mask<Double> greaterThan(double o) {
 434         return greaterThan(SPECIES.broadcast(o));
 435     }
 436 
 437     @Override
 438     @ForceInline
 439     public Mask<Double> greaterThanEq(double o) {
 440         return greaterThanEq(SPECIES.broadcast(o));
 441     }
 442 
 443     @Override
 444     @ForceInline
 445     public DoubleVector blend(double o, Mask<Double> m) {
 446         return blend(SPECIES.broadcast(o), m);
 447     }
 448 
 449     @Override
 450     @ForceInline
 451     public DoubleVector div(double o) {
 452         return div(SPECIES.broadcast(o));
 453     }
 454 
 455     @Override
 456     @ForceInline
 457     public DoubleVector div(double o, Mask<Double> m) {
 458         return div(SPECIES.broadcast(o), m);
 459     }
 460 
 461     @Override
 462     @ForceInline
 463     public Double64Vector div(Vector<Double> v, Mask<Double> m) {
 464         return blend(div(v), m);
 465     }
 466 
 467     @Override
 468     @ForceInline
 469     public DoubleVector atan2(double o) {
 470         return atan2(SPECIES.broadcast(o));
 471     }
 472 
 473     @Override
 474     @ForceInline
 475     public DoubleVector atan2(double o, Mask<Double> m) {
 476         return atan2(SPECIES.broadcast(o), m);
 477     }
 478 
 479     @Override
 480     @ForceInline
 481     public DoubleVector pow(double o) {
 482         return pow(SPECIES.broadcast(o));
 483     }
 484 
 485     @Override
 486     @ForceInline
 487     public DoubleVector pow(double o, Mask<Double> m) {
 488         return pow(SPECIES.broadcast(o), m);
 489     }
 490 
 491     @Override
 492     @ForceInline
 493     public DoubleVector fma(double o1, double o2) {
 494         return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2));
 495     }
 496 
 497     @Override
 498     @ForceInline
 499     public DoubleVector fma(double o1, double o2, Mask<Double> m) {
 500         return fma(SPECIES.broadcast(o1), SPECIES.broadcast(o2), m);
 501     }
 502 
 503     @Override
 504     @ForceInline
 505     public DoubleVector hypot(double o) {
 506         return hypot(SPECIES.broadcast(o));
 507     }
 508 
 509     @Override
 510     @ForceInline
 511     public DoubleVector hypot(double o, Mask<Double> m) {
 512         return hypot(SPECIES.broadcast(o), m);
 513     }
 514 
 515 
 516     // Unary operations
 517 
 518     @ForceInline
 519     @Override
 520     public Double64Vector neg(Mask<Double> m) {
 521         return blend(neg(), m);
 522     }
 523 
 524     @Override
 525     @ForceInline
 526     public Double64Vector abs() {
 527         return VectorIntrinsics.unaryOp(
 528             VECTOR_OP_ABS, Double64Vector.class, double.class, LENGTH,
 529             this,
 530             v1 -> v1.uOp((i, a) -> (double) Math.abs(a)));
 531     }
 532 
 533     @ForceInline
 534     @Override
 535     public Double64Vector abs(Mask<Double> m) {
 536         return blend(abs(), m);
 537     }
 538 
 539     @Override
 540     @ForceInline
 541     public Double64Vector neg() {
 542         return VectorIntrinsics.unaryOp(
 543             VECTOR_OP_NEG, Double64Vector.class, double.class, LENGTH,
 544             this,
 545             v1 -> v1.uOp((i, a) -> (double) -a));
 546     }
 547 
 548     @Override
 549     @ForceInline
 550     public Double64Vector div(Vector<Double> o) {
 551         Objects.requireNonNull(o);
 552         Double64Vector v = (Double64Vector)o;
 553         return VectorIntrinsics.binaryOp(
 554             VECTOR_OP_DIV, Double64Vector.class, double.class, LENGTH,
 555             this, v,
 556             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (double)(a / b)));
 557     }
 558 
 559     @Override
 560     @ForceInline
 561     public Double64Vector sqrt() {
 562         return VectorIntrinsics.unaryOp(
 563             VECTOR_OP_SQRT, Double64Vector.class, double.class, LENGTH,
 564             this,
 565             v1 -> v1.uOp((i, a) -> (double) Math.sqrt((double) a)));
 566     }
 567 
 568     @Override
 569     @ForceInline
 570     public Double64Vector exp() {
 571         return (Double64Vector) VectorIntrinsics.unaryOp(
 572             VECTOR_OP_EXP, Double64Vector.class, double.class, LENGTH,
 573             this,
 574             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.exp((double) a)));
 575     }
 576 
 577     @Override
 578     @ForceInline
 579     public Double64Vector log1p() {
 580         return (Double64Vector) VectorIntrinsics.unaryOp(
 581             VECTOR_OP_LOG1P, Double64Vector.class, double.class, LENGTH,
 582             this,
 583             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.log1p((double) a)));
 584     }
 585 
 586     @Override
 587     @ForceInline
 588     public Double64Vector log() {
 589         return (Double64Vector) VectorIntrinsics.unaryOp(
 590             VECTOR_OP_LOG, Double64Vector.class, double.class, LENGTH,
 591             this,
 592             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.log((double) a)));
 593     }
 594 
 595     @Override
 596     @ForceInline
 597     public Double64Vector log10() {
 598         return (Double64Vector) VectorIntrinsics.unaryOp(
 599             VECTOR_OP_LOG10, Double64Vector.class, double.class, LENGTH,
 600             this,
 601             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.log10((double) a)));
 602     }
 603 
 604     @Override
 605     @ForceInline
 606     public Double64Vector expm1() {
 607         return (Double64Vector) VectorIntrinsics.unaryOp(
 608             VECTOR_OP_EXPM1, Double64Vector.class, double.class, LENGTH,
 609             this,
 610             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.expm1((double) a)));
 611     }
 612 
 613     @Override
 614     @ForceInline
 615     public Double64Vector cbrt() {
 616         return (Double64Vector) VectorIntrinsics.unaryOp(
 617             VECTOR_OP_CBRT, Double64Vector.class, double.class, LENGTH,
 618             this,
 619             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.cbrt((double) a)));
 620     }
 621 
 622     @Override
 623     @ForceInline
 624     public Double64Vector sin() {
 625         return (Double64Vector) VectorIntrinsics.unaryOp(
 626             VECTOR_OP_SIN, Double64Vector.class, double.class, LENGTH,
 627             this,
 628             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.sin((double) a)));
 629     }
 630 
 631     @Override
 632     @ForceInline
 633     public Double64Vector cos() {
 634         return (Double64Vector) VectorIntrinsics.unaryOp(
 635             VECTOR_OP_COS, Double64Vector.class, double.class, LENGTH,
 636             this,
 637             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.cos((double) a)));
 638     }
 639 
 640     @Override
 641     @ForceInline
 642     public Double64Vector tan() {
 643         return (Double64Vector) VectorIntrinsics.unaryOp(
 644             VECTOR_OP_TAN, Double64Vector.class, double.class, LENGTH,
 645             this,
 646             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.tan((double) a)));
 647     }
 648 
 649     @Override
 650     @ForceInline
 651     public Double64Vector asin() {
 652         return (Double64Vector) VectorIntrinsics.unaryOp(
 653             VECTOR_OP_ASIN, Double64Vector.class, double.class, LENGTH,
 654             this,
 655             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.asin((double) a)));
 656     }
 657 
 658     @Override
 659     @ForceInline
 660     public Double64Vector acos() {
 661         return (Double64Vector) VectorIntrinsics.unaryOp(
 662             VECTOR_OP_ACOS, Double64Vector.class, double.class, LENGTH,
 663             this,
 664             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.acos((double) a)));
 665     }
 666 
 667     @Override
 668     @ForceInline
 669     public Double64Vector atan() {
 670         return (Double64Vector) VectorIntrinsics.unaryOp(
 671             VECTOR_OP_ATAN, Double64Vector.class, double.class, LENGTH,
 672             this,
 673             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.atan((double) a)));
 674     }
 675 
 676     @Override
 677     @ForceInline
 678     public Double64Vector sinh() {
 679         return (Double64Vector) VectorIntrinsics.unaryOp(
 680             VECTOR_OP_SINH, Double64Vector.class, double.class, LENGTH,
 681             this,
 682             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.sinh((double) a)));
 683     }
 684 
 685     @Override
 686     @ForceInline
 687     public Double64Vector cosh() {
 688         return (Double64Vector) VectorIntrinsics.unaryOp(
 689             VECTOR_OP_COSH, Double64Vector.class, double.class, LENGTH,
 690             this,
 691             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.cosh((double) a)));
 692     }
 693 
 694     @Override
 695     @ForceInline
 696     public Double64Vector tanh() {
 697         return (Double64Vector) VectorIntrinsics.unaryOp(
 698             VECTOR_OP_TANH, Double64Vector.class, double.class, LENGTH,
 699             this,
 700             v1 -> ((Double64Vector)v1).uOp((i, a) -> (double) Math.tanh((double) a)));
 701     }
 702 
 703     @Override
 704     @ForceInline
 705     public Double64Vector pow(Vector<Double> o) {
 706         Objects.requireNonNull(o);
 707         Double64Vector v = (Double64Vector)o;
 708         return (Double64Vector) VectorIntrinsics.binaryOp(
 709             VECTOR_OP_POW, Double64Vector.class, double.class, LENGTH,
 710             this, v,
 711             (v1, v2) -> ((Double64Vector)v1).bOp(v2, (i, a, b) -> (double)(Math.pow(a,b))));
 712     }
 713 
 714     @Override
 715     @ForceInline
 716     public Double64Vector hypot(Vector<Double> o) {
 717         Objects.requireNonNull(o);
 718         Double64Vector v = (Double64Vector)o;
 719         return (Double64Vector) VectorIntrinsics.binaryOp(
 720             VECTOR_OP_HYPOT, Double64Vector.class, double.class, LENGTH,
 721             this, v,
 722             (v1, v2) -> ((Double64Vector)v1).bOp(v2, (i, a, b) -> (double)(Math.hypot(a,b))));
 723     }
 724 
 725     @Override
 726     @ForceInline
 727     public Double64Vector atan2(Vector<Double> o) {
 728         Objects.requireNonNull(o);
 729         Double64Vector v = (Double64Vector)o;
 730         return (Double64Vector) VectorIntrinsics.binaryOp(
 731             VECTOR_OP_ATAN2, Double64Vector.class, double.class, LENGTH,
 732             this, v,
 733             (v1, v2) -> ((Double64Vector)v1).bOp(v2, (i, a, b) -> (double)(Math.atan2(a,b))));
 734     }
 735 
 736 
 737     // Binary operations
 738 
 739     @Override
 740     @ForceInline
 741     public Double64Vector add(Vector<Double> o) {
 742         Objects.requireNonNull(o);
 743         Double64Vector v = (Double64Vector)o;
 744         return VectorIntrinsics.binaryOp(
 745             VECTOR_OP_ADD, Double64Vector.class, double.class, LENGTH,
 746             this, v,
 747             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (double)(a + b)));
 748     }
 749 
 750     @Override
 751     @ForceInline
 752     public Double64Vector add(Vector<Double> v, Mask<Double> m) {
 753         return blend(add(v), m);
 754     }
 755 
 756     @Override
 757     @ForceInline
 758     public Double64Vector sub(Vector<Double> o) {
 759         Objects.requireNonNull(o);
 760         Double64Vector v = (Double64Vector)o;
 761         return VectorIntrinsics.binaryOp(
 762             VECTOR_OP_SUB, Double64Vector.class, double.class, LENGTH,
 763             this, v,
 764             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (double)(a - b)));
 765     }
 766 
 767     @Override
 768     @ForceInline
 769     public Double64Vector sub(Vector<Double> v, Mask<Double> m) {
 770         return blend(sub(v), m);
 771     }
 772 
 773     @Override
 774     @ForceInline
 775     public Double64Vector mul(Vector<Double> o) {
 776         Objects.requireNonNull(o);
 777         Double64Vector v = (Double64Vector)o;
 778         return VectorIntrinsics.binaryOp(
 779             VECTOR_OP_MUL, Double64Vector.class, double.class, LENGTH,
 780             this, v,
 781             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (double)(a * b)));
 782     }
 783 
 784     @Override
 785     @ForceInline
 786     public Double64Vector mul(Vector<Double> v, Mask<Double> m) {
 787         return blend(mul(v), m);
 788     }
 789 
 790     @Override
 791     @ForceInline
 792     public Double64Vector min(Vector<Double> o) {
 793         Objects.requireNonNull(o);
 794         Double64Vector v = (Double64Vector)o;
 795         return (Double64Vector) VectorIntrinsics.binaryOp(
 796             VECTOR_OP_MIN, Double64Vector.class, double.class, LENGTH,
 797             this, v,
 798             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (double) Math.min(a, b)));
 799     }
 800 
 801     @Override
 802     @ForceInline
 803     public Double64Vector min(Vector<Double> v, Mask<Double> m) {
 804         return blend(min(v), m);
 805     }
 806 
 807     @Override
 808     @ForceInline
 809     public Double64Vector max(Vector<Double> o) {
 810         Objects.requireNonNull(o);
 811         Double64Vector v = (Double64Vector)o;
 812         return VectorIntrinsics.binaryOp(
 813             VECTOR_OP_MAX, Double64Vector.class, double.class, LENGTH,
 814             this, v,
 815             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (double) Math.max(a, b)));
 816         }
 817 
 818     @Override
 819     @ForceInline
 820     public Double64Vector max(Vector<Double> v, Mask<Double> m) {
 821         return blend(max(v), m);
 822     }
 823 
 824 
 825     // Ternary operations
 826 
 827     @Override
 828     @ForceInline
 829     public Double64Vector fma(Vector<Double> o1, Vector<Double> o2) {
 830         Objects.requireNonNull(o1);
 831         Objects.requireNonNull(o2);
 832         Double64Vector v1 = (Double64Vector)o1;
 833         Double64Vector v2 = (Double64Vector)o2;
 834         return VectorIntrinsics.ternaryOp(
 835             VECTOR_OP_FMA, Double64Vector.class, double.class, LENGTH,
 836             this, v1, v2,
 837             (w1, w2, w3) -> w1.tOp(w2, w3, (i, a, b, c) -> Math.fma(a, b, c)));
 838     }
 839 
 840     // Type specific horizontal reductions
 841 
 842     @Override
 843     @ForceInline
 844     public double addAll() {
 845         long bits = (long) VectorIntrinsics.reductionCoerced(
 846                                 VECTOR_OP_ADD, Double64Vector.class, double.class, LENGTH,
 847                                 this,
 848                                 v -> {
 849                                     double r = v.rOp((double) 0, (i, a, b) -> (double) (a + b));
 850                                     return (long)Double.doubleToLongBits(r);
 851                                 });
 852         return Double.longBitsToDouble(bits);
 853     }
 854 
 855     @Override
 856     @ForceInline
 857     public double subAll() {
 858         long bits = (long) VectorIntrinsics.reductionCoerced(
 859                                 VECTOR_OP_SUB, Double64Vector.class, double.class, LENGTH,
 860                                 this,
 861                                 v -> {
 862                                     double r = v.rOp((double) 0, (i, a, b) -> (double) (a - b));
 863                                     return (long)Double.doubleToLongBits(r);
 864                                 });
 865         return Double.longBitsToDouble(bits);
 866     }
 867 
 868     @Override
 869     @ForceInline
 870     public double mulAll() {
 871         long bits = (long) VectorIntrinsics.reductionCoerced(
 872                                 VECTOR_OP_MUL, Double64Vector.class, double.class, LENGTH,
 873                                 this,
 874                                 v -> {
 875                                     double r = v.rOp((double) 1, (i, a, b) -> (double) (a * b));
 876                                     return (long)Double.doubleToLongBits(r);
 877                                 });
 878         return Double.longBitsToDouble(bits);
 879     }
 880 
 881     @Override
 882     @ForceInline
 883     public double minAll() {
 884         long bits = (long) VectorIntrinsics.reductionCoerced(
 885                                 VECTOR_OP_MIN, Double64Vector.class, double.class, LENGTH,
 886                                 this,
 887                                 v -> {
 888                                     double r = v.rOp(Double.MAX_VALUE , (i, a, b) -> (double) Math.min(a, b));
 889                                     return (long)Double.doubleToLongBits(r);
 890                                 });
 891         return Double.longBitsToDouble(bits);
 892     }
 893 
 894     @Override
 895     @ForceInline
 896     public double maxAll() {
 897         long bits = (long) VectorIntrinsics.reductionCoerced(
 898                                 VECTOR_OP_MAX, Double64Vector.class, double.class, LENGTH,
 899                                 this,
 900                                 v -> {
 901                                     double r = v.rOp(Double.MIN_VALUE , (i, a, b) -> (double) Math.max(a, b));
 902                                     return (long)Double.doubleToLongBits(r);
 903                                 });
 904         return Double.longBitsToDouble(bits);
 905     }
 906 
 907 
 908     @Override
 909     @ForceInline
 910     public double addAll(Mask<Double> m) {
 911         return blend(SPECIES.broadcast((double) 0), m).addAll();
 912     }
 913 
 914     @Override
 915     @ForceInline
 916     public double subAll(Mask<Double> m) {
 917         return blend(SPECIES.broadcast((double) 0), m).subAll();
 918     }
 919 
 920     @Override
 921     @ForceInline
 922     public double mulAll(Mask<Double> m) {
 923         return blend(SPECIES.broadcast((double) 1), m).mulAll();
 924     }
 925 
 926     @Override
 927     @ForceInline
 928     public double minAll(Mask<Double> m) {
 929         return blend(SPECIES.broadcast(Double.MAX_VALUE), m).minAll();
 930     }
 931 
 932     @Override
 933     @ForceInline
 934     public double maxAll(Mask<Double> m) {
 935         return blend(SPECIES.broadcast(Double.MIN_VALUE), m).maxAll();
 936     }
 937 
 938     @Override
 939     @ForceInline
 940     public Shuffle<Double> toShuffle() {
 941         double[] a = toArray();
 942         int[] sa = new int[a.length];
 943         for (int i = 0; i < a.length; i++) {
 944             sa[i] = (int) a[i];
 945         }
 946         return DoubleVector.shuffleFromArray(SPECIES, sa, 0);
 947     }
 948 
 949     // Memory operations
 950 
 951     private static final int ARRAY_SHIFT         = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
 952     private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
 953 
 954     @Override
 955     @ForceInline
 956     public void intoArray(double[] a, int ix) {
 957         Objects.requireNonNull(a);
 958         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 959         VectorIntrinsics.store(Double64Vector.class, double.class, LENGTH,
 960                                a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 961                                this,
 962                                a, ix,
 963                                (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
 964     }
 965 
 966     @Override
 967     @ForceInline
 968     public final void intoArray(double[] a, int ax, Mask<Double> m) {
 969         DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax);
 970         DoubleVector newVal = oldVal.blend(this, m);
 971         newVal.intoArray(a, ax);
 972     }
 973     @Override
 974     @ForceInline
 975     public void intoArray(double[] a, int ix, int[] b, int iy) {
 976         this.intoArray(a, ix + b[iy]);
 977     }
 978 
 979      @Override
 980      @ForceInline
 981      public final void intoArray(double[] a, int ax, Mask<Double> m, int[] b, int iy) {
 982          // @@@ This can result in out of bounds errors for unset mask lanes
 983          DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax, b, iy);
 984          DoubleVector newVal = oldVal.blend(this, m);
 985          newVal.intoArray(a, ax, b, iy);
 986      }
 987 
 988     @Override
 989     @ForceInline
 990     public void intoByteArray(byte[] a, int ix) {
 991         Objects.requireNonNull(a);
 992         ix = VectorIntrinsics.checkIndex(ix, a.length, bitSize() / Byte.SIZE);
 993         VectorIntrinsics.store(Double64Vector.class, double.class, LENGTH,
 994                                a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 995                                this,
 996                                a, ix,
 997                                (c, idx, v) -> {
 998                                    ByteBuffer bbc = ByteBuffer.wrap(c, idx, c.length - idx).order(ByteOrder.nativeOrder());
 999                                    DoubleBuffer tb = bbc.asDoubleBuffer();
1000                                    v.forEach((i, e) -> tb.put(e));
1001                                });
1002     }
1003 
1004     @Override
1005     @ForceInline
1006     public final void intoByteArray(byte[] a, int ix, Mask<Double> m) {
1007         Double64Vector oldVal = (Double64Vector) DoubleVector.fromByteArray(SPECIES, a, ix);
1008         Double64Vector newVal = oldVal.blend(this, m);
1009         newVal.intoByteArray(a, ix);
1010     }
1011 
1012     @Override
1013     @ForceInline
1014     public void intoByteBuffer(ByteBuffer bb, int ix) {
1015         if (bb.order() != ByteOrder.nativeOrder()) {
1016             throw new IllegalArgumentException();
1017         }
1018         if (bb.isReadOnly()) {
1019             throw new ReadOnlyBufferException();
1020         }
1021         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), bitSize() / Byte.SIZE);
1022         VectorIntrinsics.store(Double64Vector.class, double.class, LENGTH,
1023                                U.getReference(bb, BYTE_BUFFER_HB), ix + U.getLong(bb, BUFFER_ADDRESS),
1024                                this,
1025                                bb, ix,
1026                                (c, idx, v) -> {
1027                                    ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
1028                                    DoubleBuffer tb = bbc.asDoubleBuffer();
1029                                    v.forEach((i, e) -> tb.put(e));
1030                                });
1031     }
1032 
1033     @Override
1034     @ForceInline
1035     public void intoByteBuffer(ByteBuffer bb, int ix, Mask<Double> m) {
1036         Double64Vector oldVal = (Double64Vector) DoubleVector.fromByteBuffer(SPECIES, bb, ix);
1037         Double64Vector newVal = oldVal.blend(this, m);
1038         newVal.intoByteBuffer(bb, ix);
1039     }
1040 
1041     //
1042 
1043     @Override
1044     public String toString() {
1045         return Arrays.toString(getElements());
1046     }
1047 
1048     @Override
1049     public boolean equals(Object o) {
1050         if (this == o) return true;
1051         if (o == null || this.getClass() != o.getClass()) return false;
1052 
1053         Double64Vector that = (Double64Vector) o;
1054         return this.equal(that).allTrue();
1055     }
1056 
1057     @Override
1058     public int hashCode() {
1059         return Arrays.hashCode(vec);
1060     }
1061 
1062     // Binary test
1063 
1064     @Override
1065     Double64Mask bTest(Vector<Double> o, FBinTest f) {
1066         double[] vec1 = getElements();
1067         double[] vec2 = ((Double64Vector)o).getElements();
1068         boolean[] bits = new boolean[length()];
1069         for (int i = 0; i < length(); i++){
1070             bits[i] = f.apply(i, vec1[i], vec2[i]);
1071         }
1072         return new Double64Mask(bits);
1073     }
1074 
1075     // Comparisons
1076 
1077     @Override
1078     @ForceInline
1079     public Double64Mask equal(Vector<Double> o) {
1080         Objects.requireNonNull(o);
1081         Double64Vector v = (Double64Vector)o;
1082 
1083         return VectorIntrinsics.compare(
1084             BT_eq, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1085             this, v,
1086             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
1087     }
1088 
1089     @Override
1090     @ForceInline
1091     public Double64Mask notEqual(Vector<Double> o) {
1092         Objects.requireNonNull(o);
1093         Double64Vector v = (Double64Vector)o;
1094 
1095         return VectorIntrinsics.compare(
1096             BT_ne, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1097             this, v,
1098             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
1099     }
1100 
1101     @Override
1102     @ForceInline
1103     public Double64Mask lessThan(Vector<Double> o) {
1104         Objects.requireNonNull(o);
1105         Double64Vector v = (Double64Vector)o;
1106 
1107         return VectorIntrinsics.compare(
1108             BT_lt, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1109             this, v,
1110             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
1111     }
1112 
1113     @Override
1114     @ForceInline
1115     public Double64Mask lessThanEq(Vector<Double> o) {
1116         Objects.requireNonNull(o);
1117         Double64Vector v = (Double64Vector)o;
1118 
1119         return VectorIntrinsics.compare(
1120             BT_le, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1121             this, v,
1122             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
1123     }
1124 
1125     @Override
1126     @ForceInline
1127     public Double64Mask greaterThan(Vector<Double> o) {
1128         Objects.requireNonNull(o);
1129         Double64Vector v = (Double64Vector)o;
1130 
1131         return (Double64Mask) VectorIntrinsics.compare(
1132             BT_gt, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1133             this, v,
1134             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
1135     }
1136 
1137     @Override
1138     @ForceInline
1139     public Double64Mask greaterThanEq(Vector<Double> o) {
1140         Objects.requireNonNull(o);
1141         Double64Vector v = (Double64Vector)o;
1142 
1143         return VectorIntrinsics.compare(
1144             BT_ge, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1145             this, v,
1146             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
1147     }
1148 
1149     // Foreach
1150 
1151     @Override
1152     void forEach(FUnCon f) {
1153         double[] vec = getElements();
1154         for (int i = 0; i < length(); i++) {
1155             f.apply(i, vec[i]);
1156         }
1157     }
1158 
1159     @Override
1160     void forEach(Mask<Double> o, FUnCon f) {
1161         boolean[] mbits = ((Double64Mask)o).getBits();
1162         forEach((i, a) -> {
1163             if (mbits[i]) { f.apply(i, a); }
1164         });
1165     }
1166 
1167     Long64Vector toBits() {
1168         double[] vec = getElements();
1169         long[] res = new long[this.species().length()];
1170         for(int i = 0; i < this.species().length(); i++){
1171             res[i] = Double.doubleToLongBits(vec[i]);
1172         }
1173         return new Long64Vector(res);
1174     }
1175 
1176 
1177     @Override
1178     public Double64Vector rotateEL(int j) {
1179         double[] vec = getElements();
1180         double[] res = new double[length()];
1181         for (int i = 0; i < length(); i++){
1182             res[(j + i) % length()] = vec[i];
1183         }
1184         return new Double64Vector(res);
1185     }
1186 
1187     @Override
1188     public Double64Vector rotateER(int j) {
1189         double[] vec = getElements();
1190         double[] res = new double[length()];
1191         for (int i = 0; i < length(); i++){
1192             int z = i - j;
1193             if(j < 0) {
1194                 res[length() + z] = vec[i];
1195             } else {
1196                 res[z] = vec[i];
1197             }
1198         }
1199         return new Double64Vector(res);
1200     }
1201 
1202     @Override
1203     public Double64Vector shiftEL(int j) {
1204         double[] vec = getElements();
1205         double[] res = new double[length()];
1206         for (int i = 0; i < length() - j; i++) {
1207             res[i] = vec[i + j];
1208         }
1209         return new Double64Vector(res);
1210     }
1211 
1212     @Override
1213     public Double64Vector shiftER(int j) {
1214         double[] vec = getElements();
1215         double[] res = new double[length()];
1216         for (int i = 0; i < length() - j; i++){
1217             res[i + j] = vec[i];
1218         }
1219         return new Double64Vector(res);
1220     }
1221 
1222     @Override
1223     @ForceInline
1224     public Double64Vector rearrange(Vector<Double> v,
1225                                   Shuffle<Double> s, Mask<Double> m) {
1226         return this.rearrange(s).blend(v.rearrange(s), m);
1227     }
1228 
1229     @Override
1230     @ForceInline
1231     public Double64Vector rearrange(Shuffle<Double> o1) {
1232         Objects.requireNonNull(o1);
1233         Double64Shuffle s =  (Double64Shuffle)o1;
1234 
1235         return VectorIntrinsics.rearrangeOp(
1236             Double64Vector.class, Double64Shuffle.class, double.class, LENGTH,
1237             this, s,
1238             (v1, s_) -> v1.uOp((i, a) -> {
1239                 int ei = s_.getElement(i);
1240                 return v1.get(ei);
1241             }));
1242     }
1243 
1244     @Override
1245     @ForceInline
1246     public Double64Vector blend(Vector<Double> o1, Mask<Double> o2) {
1247         Objects.requireNonNull(o1);
1248         Objects.requireNonNull(o2);
1249         Double64Vector v = (Double64Vector)o1;
1250         Double64Mask   m = (Double64Mask)o2;
1251 
1252         return VectorIntrinsics.blend(
1253             Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1254             this, v, m,
1255             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
1256     }
1257 
1258     // Accessors
1259 
1260     @Override
1261     public double get(int i) {
1262         if (i < 0 || i >= LENGTH) {
1263             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1264         }
1265         long bits = (long) VectorIntrinsics.extract(
1266                                 Double64Vector.class, double.class, LENGTH,
1267                                 this, i,
1268                                 (vec, ix) -> {
1269                                     double[] vecarr = vec.getElements();
1270                                     return (long)Double.doubleToLongBits(vecarr[ix]);
1271                                 });
1272         return Double.longBitsToDouble(bits);
1273     }
1274 
1275     @Override
1276     public Double64Vector with(int i, double e) {
1277         if (i < 0 || i >= LENGTH) {
1278             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1279         }
1280         return VectorIntrinsics.insert(
1281                                 Double64Vector.class, double.class, LENGTH,
1282                                 this, i, (long)Double.doubleToLongBits(e),
1283                                 (v, ix, bits) -> {
1284                                     double[] res = v.getElements().clone();
1285                                     res[ix] = Double.longBitsToDouble((long)bits);
1286                                     return new Double64Vector(res);
1287                                 });
1288     }
1289 
1290     // Mask
1291 
1292     static final class Double64Mask extends AbstractMask<Double> {
1293         static final Double64Mask TRUE_MASK = new Double64Mask(true);
1294         static final Double64Mask FALSE_MASK = new Double64Mask(false);
1295 
1296         private final boolean[] bits; // Don't access directly, use getBits() instead.
1297 
1298         public Double64Mask(boolean[] bits) {
1299             this(bits, 0);
1300         }
1301 
1302         public Double64Mask(boolean[] bits, int offset) {
1303             boolean[] a = new boolean[species().length()];
1304             for (int i = 0; i < a.length; i++) {
1305                 a[i] = bits[offset + i];
1306             }
1307             this.bits = a;
1308         }
1309 
1310         public Double64Mask(boolean val) {
1311             boolean[] bits = new boolean[species().length()];
1312             Arrays.fill(bits, val);
1313             this.bits = bits;
1314         }
1315 
1316         boolean[] getBits() {
1317             return VectorIntrinsics.maybeRebox(this).bits;
1318         }
1319 
1320         @Override
1321         Double64Mask uOp(MUnOp f) {
1322             boolean[] res = new boolean[species().length()];
1323             boolean[] bits = getBits();
1324             for (int i = 0; i < species().length(); i++) {
1325                 res[i] = f.apply(i, bits[i]);
1326             }
1327             return new Double64Mask(res);
1328         }
1329 
1330         @Override
1331         Double64Mask bOp(Mask<Double> o, MBinOp f) {
1332             boolean[] res = new boolean[species().length()];
1333             boolean[] bits = getBits();
1334             boolean[] mbits = ((Double64Mask)o).getBits();
1335             for (int i = 0; i < species().length(); i++) {
1336                 res[i] = f.apply(i, bits[i], mbits[i]);
1337             }
1338             return new Double64Mask(res);
1339         }
1340 
1341         @Override
1342         public Double64Species species() {
1343             return SPECIES;
1344         }
1345 
1346         @Override
1347         public Double64Vector toVector() {
1348             double[] res = new double[species().length()];
1349             boolean[] bits = getBits();
1350             for (int i = 0; i < species().length(); i++) {
1351                 // -1 will result in the most significant bit being set in
1352                 // addition to some or all other bits
1353                 res[i] = (double) (bits[i] ? -1 : 0);
1354             }
1355             return new Double64Vector(res);
1356         }
1357 
1358         // Unary operations
1359 
1360         @Override
1361         @ForceInline
1362         public Double64Mask not() {
1363             return (Double64Mask) VectorIntrinsics.unaryOp(
1364                                              VECTOR_OP_NOT, Double64Mask.class, long.class, LENGTH,
1365                                              this,
1366                                              (m1) -> m1.uOp((i, a) -> !a));
1367         }
1368 
1369         // Binary operations
1370 
1371         @Override
1372         @ForceInline
1373         public Double64Mask and(Mask<Double> o) {
1374             Objects.requireNonNull(o);
1375             Double64Mask m = (Double64Mask)o;
1376             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Double64Mask.class, long.class, LENGTH,
1377                                              this, m,
1378                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
1379         }
1380 
1381         @Override
1382         @ForceInline
1383         public Double64Mask or(Mask<Double> o) {
1384             Objects.requireNonNull(o);
1385             Double64Mask m = (Double64Mask)o;
1386             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Double64Mask.class, long.class, LENGTH,
1387                                              this, m,
1388                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
1389         }
1390 
1391         // Reductions
1392 
1393         @Override
1394         @ForceInline
1395         public boolean anyTrue() {
1396             return VectorIntrinsics.test(BT_ne, Double64Mask.class, long.class, LENGTH,
1397                                          this, this,
1398                                          (m, __) -> anyTrueHelper(((Double64Mask)m).getBits()));
1399         }
1400 
1401         @Override
1402         @ForceInline
1403         public boolean allTrue() {
1404             return VectorIntrinsics.test(BT_overflow, Double64Mask.class, long.class, LENGTH,
1405                                          this, DoubleVector.maskAllTrue(species()),
1406                                          (m, __) -> allTrueHelper(((Double64Mask)m).getBits()));
1407         }
1408     }
1409 
1410     // Shuffle
1411 
1412     static final class Double64Shuffle extends AbstractShuffle<Double> {
1413         Double64Shuffle(byte[] reorder) {
1414             super(reorder);
1415         }
1416 
1417         public Double64Shuffle(int[] reorder) {
1418             super(reorder);
1419         }
1420 
1421         public Double64Shuffle(int[] reorder, int i) {
1422             super(reorder, i);
1423         }
1424 
1425         public Double64Shuffle(IntUnaryOperator f) {
1426             super(f);
1427         }
1428 
1429         @Override
1430         public Double64Species species() {
1431             return SPECIES;
1432         }
1433 
1434         @Override
1435         public DoubleVector toVector() {
1436             double[] va = new double[SPECIES.length()];
1437             for (int i = 0; i < va.length; i++) {
1438               va[i] = (double) getElement(i);
1439             }
1440             return DoubleVector.fromArray(SPECIES, va, 0);
1441         }
1442 
1443         @Override
1444         public Double64Shuffle rearrange(Vector.Shuffle<Double> o) {
1445             Double64Shuffle s = (Double64Shuffle) o;
1446             byte[] r = new byte[reorder.length];
1447             for (int i = 0; i < reorder.length; i++) {
1448                 r[i] = reorder[s.reorder[i]];
1449             }
1450             return new Double64Shuffle(r);
1451         }
1452     }
1453 
1454     // Species
1455 
1456     @Override
1457     public Double64Species species() {
1458         return SPECIES;
1459     }
1460 
1461     static final class Double64Species extends DoubleSpecies {
1462         static final int BIT_SIZE = Shape.S_64_BIT.bitSize();
1463 
1464         static final int LENGTH = BIT_SIZE / Double.SIZE;
1465 
1466         @Override
1467         public String toString() {
1468            StringBuilder sb = new StringBuilder("Shape[");
1469            sb.append(bitSize()).append(" bits, ");
1470            sb.append(length()).append(" ").append(double.class.getSimpleName()).append("s x ");
1471            sb.append(elementSize()).append(" bits");
1472            sb.append("]");
1473            return sb.toString();
1474         }
1475 
1476         @Override
1477         @ForceInline
1478         public int bitSize() {
1479             return BIT_SIZE;
1480         }
1481 
1482         @Override
1483         @ForceInline
1484         public int length() {
1485             return LENGTH;
1486         }
1487 
1488         @Override
1489         @ForceInline
1490         public Class<Double> elementType() {
1491             return double.class;
1492         }
1493 
1494         @Override
1495         @ForceInline
1496         public Class<?> boxType() {
1497             return Double64Vector.class;
1498         }
1499 
1500         @Override
1501         @ForceInline
1502         public Class<?> maskType() {
1503             return Double64Mask.class;
1504         }
1505 
1506         @Override
1507         @ForceInline
1508         public int elementSize() {
1509             return Double.SIZE;
1510         }
1511 
1512         @Override
1513         @ForceInline
1514         @SuppressWarnings("unchecked")
1515         Class<?> vectorType() {
1516             return Double64Vector.class;
1517         }
1518 
1519         @Override
1520         @ForceInline
1521         public Shape shape() {
1522             return Shape.S_64_BIT;
1523         }
1524 
1525        @Override
1526        IntVector.IntSpecies indexSpecies() {
1527           return INDEX_SPEC;
1528        }
1529 
1530         @Override
1531         Double64Vector op(FOp f) {
1532             double[] res = new double[length()];
1533             for (int i = 0; i < length(); i++) {
1534                 res[i] = f.apply(i);
1535             }
1536             return new Double64Vector(res);
1537         }
1538 
1539         @Override
1540         Double64Vector op(Mask<Double> o, FOp f) {
1541             double[] res = new double[length()];
1542             boolean[] mbits = ((Double64Mask)o).getBits();
1543             for (int i = 0; i < length(); i++) {
1544                 if (mbits[i]) {
1545                     res[i] = f.apply(i);
1546                 }
1547             }
1548             return new Double64Vector(res);
1549         }
1550 
1551         @Override
1552         Double64Mask opm(FOpm f) {
1553             boolean[] res = new boolean[length()];
1554             for (int i = 0; i < length(); i++) {
1555                 res[i] = (boolean)f.apply(i);
1556             }
1557             return new Double64Mask(res);
1558         }
1559 
1560         // Factories
1561 
1562         @Override
1563         @ForceInline
1564         public Double64Vector zero() {
1565             return VectorIntrinsics.broadcastCoerced(Double64Vector.class, double.class, LENGTH,
1566                                                      Double.doubleToLongBits(0.0f), SPECIES, 
1567                                                      ((bits, s) -> ((Double64Species)s).op(i -> Double.longBitsToDouble((long)bits))));
1568         }
1569 
1570         @Override
1571         @ForceInline
1572         public Double64Vector broadcast(double e) {
1573             return VectorIntrinsics.broadcastCoerced(
1574                 Double64Vector.class, double.class, LENGTH,
1575                 Double.doubleToLongBits(e), SPECIES,
1576                 ((bits, s) -> ((Double64Species)s).op(i -> Double.longBitsToDouble((long)bits))));
1577         }
1578 
1579         @Override
1580         @ForceInline
1581         public Double64Vector scalars(double... es) {
1582             Objects.requireNonNull(es);
1583             int ix = VectorIntrinsics.checkIndex(0, es.length, LENGTH);
1584             return VectorIntrinsics.load(Double64Vector.class, double.class, LENGTH,
1585                                          es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
1586                                          es, ix, SPECIES,
1587                                          (c, idx, s) -> ((Double64Species)s).op(n -> c[idx + n]));
1588         }
1589 
1590         @Override
1591         @ForceInline
1592         public <E> Double64Mask cast(Mask<E> m) {
1593             if (m.length() != LENGTH)
1594                 throw new IllegalArgumentException("Mask length this species length differ");
1595             return new Double64Mask(m.toArray());
1596         }
1597 
1598         @Override
1599         @ForceInline
1600         public <E> Double64Shuffle cast(Shuffle<E> s) {
1601             if (s.length() != LENGTH)
1602                 throw new IllegalArgumentException("Shuffle length this species length differ");
1603             return new Double64Shuffle(s.toArray());
1604         }
1605     }
1606 }