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 mulAll() {
 858         long bits = (long) VectorIntrinsics.reductionCoerced(
 859                                 VECTOR_OP_MUL, Double64Vector.class, double.class, LENGTH,
 860                                 this,
 861                                 v -> {
 862                                     double r = v.rOp((double) 1, (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 minAll() {
 871         long bits = (long) VectorIntrinsics.reductionCoerced(
 872                                 VECTOR_OP_MIN, Double64Vector.class, double.class, LENGTH,
 873                                 this,
 874                                 v -> {
 875                                     double r = v.rOp(Double.MAX_VALUE , (i, a, b) -> (double) Math.min(a, b));
 876                                     return (long)Double.doubleToLongBits(r);
 877                                 });
 878         return Double.longBitsToDouble(bits);
 879     }
 880 
 881     @Override
 882     @ForceInline
 883     public double maxAll() {
 884         long bits = (long) VectorIntrinsics.reductionCoerced(
 885                                 VECTOR_OP_MAX, Double64Vector.class, double.class, LENGTH,
 886                                 this,
 887                                 v -> {
 888                                     double r = v.rOp(Double.MIN_VALUE , (i, a, b) -> (double) Math.max(a, b));
 889                                     return (long)Double.doubleToLongBits(r);
 890                                 });
 891         return Double.longBitsToDouble(bits);
 892     }
 893 
 894 
 895     @Override
 896     @ForceInline
 897     public double addAll(Mask<Double> m) {
 898         return blend(SPECIES.broadcast((double) 0), m).addAll();
 899     }
 900 
 901     @Override
 902     @ForceInline
 903     public double mulAll(Mask<Double> m) {
 904         return blend(SPECIES.broadcast((double) 1), m).mulAll();
 905     }
 906 
 907     @Override
 908     @ForceInline
 909     public double minAll(Mask<Double> m) {
 910         return blend(SPECIES.broadcast(Double.MAX_VALUE), m).minAll();
 911     }
 912 
 913     @Override
 914     @ForceInline
 915     public double maxAll(Mask<Double> m) {
 916         return blend(SPECIES.broadcast(Double.MIN_VALUE), m).maxAll();
 917     }
 918 
 919     @Override
 920     @ForceInline
 921     public Shuffle<Double> toShuffle() {
 922         double[] a = toArray();
 923         int[] sa = new int[a.length];
 924         for (int i = 0; i < a.length; i++) {
 925             sa[i] = (int) a[i];
 926         }
 927         return DoubleVector.shuffleFromArray(SPECIES, sa, 0);
 928     }
 929 
 930     // Memory operations
 931 
 932     private static final int ARRAY_SHIFT         = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_DOUBLE_INDEX_SCALE);
 933     private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
 934 
 935     @Override
 936     @ForceInline
 937     public void intoArray(double[] a, int ix) {
 938         Objects.requireNonNull(a);
 939         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 940         VectorIntrinsics.store(Double64Vector.class, double.class, LENGTH,
 941                                a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
 942                                this,
 943                                a, ix,
 944                                (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
 945     }
 946 
 947     @Override
 948     @ForceInline
 949     public final void intoArray(double[] a, int ax, Mask<Double> m) {
 950         DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax);
 951         DoubleVector newVal = oldVal.blend(this, m);
 952         newVal.intoArray(a, ax);
 953     }
 954     @Override
 955     @ForceInline
 956     public void intoArray(double[] a, int ix, int[] b, int iy) {
 957         this.intoArray(a, ix + b[iy]);
 958     }
 959 
 960      @Override
 961      @ForceInline
 962      public final void intoArray(double[] a, int ax, Mask<Double> m, int[] b, int iy) {
 963          // @@@ This can result in out of bounds errors for unset mask lanes
 964          DoubleVector oldVal = DoubleVector.fromArray(SPECIES, a, ax, b, iy);
 965          DoubleVector newVal = oldVal.blend(this, m);
 966          newVal.intoArray(a, ax, b, iy);
 967      }
 968 
 969     @Override
 970     @ForceInline
 971     public void intoByteArray(byte[] a, int ix) {
 972         Objects.requireNonNull(a);
 973         ix = VectorIntrinsics.checkIndex(ix, a.length, bitSize() / Byte.SIZE);
 974         VectorIntrinsics.store(Double64Vector.class, double.class, LENGTH,
 975                                a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 976                                this,
 977                                a, ix,
 978                                (c, idx, v) -> {
 979                                    ByteBuffer bbc = ByteBuffer.wrap(c, idx, c.length - idx).order(ByteOrder.nativeOrder());
 980                                    DoubleBuffer tb = bbc.asDoubleBuffer();
 981                                    v.forEach((i, e) -> tb.put(e));
 982                                });
 983     }
 984 
 985     @Override
 986     @ForceInline
 987     public final void intoByteArray(byte[] a, int ix, Mask<Double> m) {
 988         Double64Vector oldVal = (Double64Vector) DoubleVector.fromByteArray(SPECIES, a, ix);
 989         Double64Vector newVal = oldVal.blend(this, m);
 990         newVal.intoByteArray(a, ix);
 991     }
 992 
 993     @Override
 994     @ForceInline
 995     public void intoByteBuffer(ByteBuffer bb, int ix) {
 996         if (bb.order() != ByteOrder.nativeOrder()) {
 997             throw new IllegalArgumentException();
 998         }
 999         if (bb.isReadOnly()) {
1000             throw new ReadOnlyBufferException();
1001         }
1002         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), bitSize() / Byte.SIZE);
1003         VectorIntrinsics.store(Double64Vector.class, double.class, LENGTH,
1004                                U.getReference(bb, BYTE_BUFFER_HB), ix + U.getLong(bb, BUFFER_ADDRESS),
1005                                this,
1006                                bb, ix,
1007                                (c, idx, v) -> {
1008                                    ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
1009                                    DoubleBuffer tb = bbc.asDoubleBuffer();
1010                                    v.forEach((i, e) -> tb.put(e));
1011                                });
1012     }
1013 
1014     @Override
1015     @ForceInline
1016     public void intoByteBuffer(ByteBuffer bb, int ix, Mask<Double> m) {
1017         Double64Vector oldVal = (Double64Vector) DoubleVector.fromByteBuffer(SPECIES, bb, ix);
1018         Double64Vector newVal = oldVal.blend(this, m);
1019         newVal.intoByteBuffer(bb, ix);
1020     }
1021 
1022     //
1023 
1024     @Override
1025     public String toString() {
1026         return Arrays.toString(getElements());
1027     }
1028 
1029     @Override
1030     public boolean equals(Object o) {
1031         if (this == o) return true;
1032         if (o == null || this.getClass() != o.getClass()) return false;
1033 
1034         Double64Vector that = (Double64Vector) o;
1035         return this.equal(that).allTrue();
1036     }
1037 
1038     @Override
1039     public int hashCode() {
1040         return Arrays.hashCode(vec);
1041     }
1042 
1043     // Binary test
1044 
1045     @Override
1046     Double64Mask bTest(Vector<Double> o, FBinTest f) {
1047         double[] vec1 = getElements();
1048         double[] vec2 = ((Double64Vector)o).getElements();
1049         boolean[] bits = new boolean[length()];
1050         for (int i = 0; i < length(); i++){
1051             bits[i] = f.apply(i, vec1[i], vec2[i]);
1052         }
1053         return new Double64Mask(bits);
1054     }
1055 
1056     // Comparisons
1057 
1058     @Override
1059     @ForceInline
1060     public Double64Mask equal(Vector<Double> o) {
1061         Objects.requireNonNull(o);
1062         Double64Vector v = (Double64Vector)o;
1063 
1064         return VectorIntrinsics.compare(
1065             BT_eq, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1066             this, v,
1067             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
1068     }
1069 
1070     @Override
1071     @ForceInline
1072     public Double64Mask notEqual(Vector<Double> o) {
1073         Objects.requireNonNull(o);
1074         Double64Vector v = (Double64Vector)o;
1075 
1076         return VectorIntrinsics.compare(
1077             BT_ne, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1078             this, v,
1079             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
1080     }
1081 
1082     @Override
1083     @ForceInline
1084     public Double64Mask lessThan(Vector<Double> o) {
1085         Objects.requireNonNull(o);
1086         Double64Vector v = (Double64Vector)o;
1087 
1088         return VectorIntrinsics.compare(
1089             BT_lt, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1090             this, v,
1091             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
1092     }
1093 
1094     @Override
1095     @ForceInline
1096     public Double64Mask lessThanEq(Vector<Double> o) {
1097         Objects.requireNonNull(o);
1098         Double64Vector v = (Double64Vector)o;
1099 
1100         return VectorIntrinsics.compare(
1101             BT_le, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1102             this, v,
1103             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
1104     }
1105 
1106     @Override
1107     @ForceInline
1108     public Double64Mask greaterThan(Vector<Double> o) {
1109         Objects.requireNonNull(o);
1110         Double64Vector v = (Double64Vector)o;
1111 
1112         return (Double64Mask) VectorIntrinsics.compare(
1113             BT_gt, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1114             this, v,
1115             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
1116     }
1117 
1118     @Override
1119     @ForceInline
1120     public Double64Mask greaterThanEq(Vector<Double> o) {
1121         Objects.requireNonNull(o);
1122         Double64Vector v = (Double64Vector)o;
1123 
1124         return VectorIntrinsics.compare(
1125             BT_ge, Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1126             this, v,
1127             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
1128     }
1129 
1130     // Foreach
1131 
1132     @Override
1133     void forEach(FUnCon f) {
1134         double[] vec = getElements();
1135         for (int i = 0; i < length(); i++) {
1136             f.apply(i, vec[i]);
1137         }
1138     }
1139 
1140     @Override
1141     void forEach(Mask<Double> o, FUnCon f) {
1142         boolean[] mbits = ((Double64Mask)o).getBits();
1143         forEach((i, a) -> {
1144             if (mbits[i]) { f.apply(i, a); }
1145         });
1146     }
1147 
1148     Long64Vector toBits() {
1149         double[] vec = getElements();
1150         long[] res = new long[this.species().length()];
1151         for(int i = 0; i < this.species().length(); i++){
1152             res[i] = Double.doubleToLongBits(vec[i]);
1153         }
1154         return new Long64Vector(res);
1155     }
1156 
1157 
1158     @Override
1159     public Double64Vector rotateEL(int j) {
1160         double[] vec = getElements();
1161         double[] res = new double[length()];
1162         for (int i = 0; i < length(); i++){
1163             res[(j + i) % length()] = vec[i];
1164         }
1165         return new Double64Vector(res);
1166     }
1167 
1168     @Override
1169     public Double64Vector rotateER(int j) {
1170         double[] vec = getElements();
1171         double[] res = new double[length()];
1172         for (int i = 0; i < length(); i++){
1173             int z = i - j;
1174             if(j < 0) {
1175                 res[length() + z] = vec[i];
1176             } else {
1177                 res[z] = vec[i];
1178             }
1179         }
1180         return new Double64Vector(res);
1181     }
1182 
1183     @Override
1184     public Double64Vector shiftEL(int j) {
1185         double[] vec = getElements();
1186         double[] res = new double[length()];
1187         for (int i = 0; i < length() - j; i++) {
1188             res[i] = vec[i + j];
1189         }
1190         return new Double64Vector(res);
1191     }
1192 
1193     @Override
1194     public Double64Vector shiftER(int j) {
1195         double[] vec = getElements();
1196         double[] res = new double[length()];
1197         for (int i = 0; i < length() - j; i++){
1198             res[i + j] = vec[i];
1199         }
1200         return new Double64Vector(res);
1201     }
1202 
1203     @Override
1204     @ForceInline
1205     public Double64Vector rearrange(Vector<Double> v,
1206                                   Shuffle<Double> s, Mask<Double> m) {
1207         return this.rearrange(s).blend(v.rearrange(s), m);
1208     }
1209 
1210     @Override
1211     @ForceInline
1212     public Double64Vector rearrange(Shuffle<Double> o1) {
1213         Objects.requireNonNull(o1);
1214         Double64Shuffle s =  (Double64Shuffle)o1;
1215 
1216         return VectorIntrinsics.rearrangeOp(
1217             Double64Vector.class, Double64Shuffle.class, double.class, LENGTH,
1218             this, s,
1219             (v1, s_) -> v1.uOp((i, a) -> {
1220                 int ei = s_.getElement(i);
1221                 return v1.get(ei);
1222             }));
1223     }
1224 
1225     @Override
1226     @ForceInline
1227     public Double64Vector blend(Vector<Double> o1, Mask<Double> o2) {
1228         Objects.requireNonNull(o1);
1229         Objects.requireNonNull(o2);
1230         Double64Vector v = (Double64Vector)o1;
1231         Double64Mask   m = (Double64Mask)o2;
1232 
1233         return VectorIntrinsics.blend(
1234             Double64Vector.class, Double64Mask.class, double.class, LENGTH,
1235             this, v, m,
1236             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
1237     }
1238 
1239     // Accessors
1240 
1241     @Override
1242     public double get(int i) {
1243         if (i < 0 || i >= LENGTH) {
1244             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1245         }
1246         long bits = (long) VectorIntrinsics.extract(
1247                                 Double64Vector.class, double.class, LENGTH,
1248                                 this, i,
1249                                 (vec, ix) -> {
1250                                     double[] vecarr = vec.getElements();
1251                                     return (long)Double.doubleToLongBits(vecarr[ix]);
1252                                 });
1253         return Double.longBitsToDouble(bits);
1254     }
1255 
1256     @Override
1257     public Double64Vector with(int i, double e) {
1258         if (i < 0 || i >= LENGTH) {
1259             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1260         }
1261         return VectorIntrinsics.insert(
1262                                 Double64Vector.class, double.class, LENGTH,
1263                                 this, i, (long)Double.doubleToLongBits(e),
1264                                 (v, ix, bits) -> {
1265                                     double[] res = v.getElements().clone();
1266                                     res[ix] = Double.longBitsToDouble((long)bits);
1267                                     return new Double64Vector(res);
1268                                 });
1269     }
1270 
1271     // Mask
1272 
1273     static final class Double64Mask extends AbstractMask<Double> {
1274         static final Double64Mask TRUE_MASK = new Double64Mask(true);
1275         static final Double64Mask FALSE_MASK = new Double64Mask(false);
1276 
1277         private final boolean[] bits; // Don't access directly, use getBits() instead.
1278 
1279         public Double64Mask(boolean[] bits) {
1280             this(bits, 0);
1281         }
1282 
1283         public Double64Mask(boolean[] bits, int offset) {
1284             boolean[] a = new boolean[species().length()];
1285             for (int i = 0; i < a.length; i++) {
1286                 a[i] = bits[offset + i];
1287             }
1288             this.bits = a;
1289         }
1290 
1291         public Double64Mask(boolean val) {
1292             boolean[] bits = new boolean[species().length()];
1293             Arrays.fill(bits, val);
1294             this.bits = bits;
1295         }
1296 
1297         boolean[] getBits() {
1298             return VectorIntrinsics.maybeRebox(this).bits;
1299         }
1300 
1301         @Override
1302         Double64Mask uOp(MUnOp f) {
1303             boolean[] res = new boolean[species().length()];
1304             boolean[] bits = getBits();
1305             for (int i = 0; i < species().length(); i++) {
1306                 res[i] = f.apply(i, bits[i]);
1307             }
1308             return new Double64Mask(res);
1309         }
1310 
1311         @Override
1312         Double64Mask bOp(Mask<Double> o, MBinOp f) {
1313             boolean[] res = new boolean[species().length()];
1314             boolean[] bits = getBits();
1315             boolean[] mbits = ((Double64Mask)o).getBits();
1316             for (int i = 0; i < species().length(); i++) {
1317                 res[i] = f.apply(i, bits[i], mbits[i]);
1318             }
1319             return new Double64Mask(res);
1320         }
1321 
1322         @Override
1323         public Double64Species species() {
1324             return SPECIES;
1325         }
1326 
1327         @Override
1328         public Double64Vector toVector() {
1329             double[] res = new double[species().length()];
1330             boolean[] bits = getBits();
1331             for (int i = 0; i < species().length(); i++) {
1332                 // -1 will result in the most significant bit being set in
1333                 // addition to some or all other bits
1334                 res[i] = (double) (bits[i] ? -1 : 0);
1335             }
1336             return new Double64Vector(res);
1337         }
1338 
1339         // Unary operations
1340 
1341         @Override
1342         @ForceInline
1343         public Double64Mask not() {
1344             return (Double64Mask) VectorIntrinsics.unaryOp(
1345                                              VECTOR_OP_NOT, Double64Mask.class, long.class, LENGTH,
1346                                              this,
1347                                              (m1) -> m1.uOp((i, a) -> !a));
1348         }
1349 
1350         // Binary operations
1351 
1352         @Override
1353         @ForceInline
1354         public Double64Mask and(Mask<Double> o) {
1355             Objects.requireNonNull(o);
1356             Double64Mask m = (Double64Mask)o;
1357             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Double64Mask.class, long.class, LENGTH,
1358                                              this, m,
1359                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
1360         }
1361 
1362         @Override
1363         @ForceInline
1364         public Double64Mask or(Mask<Double> o) {
1365             Objects.requireNonNull(o);
1366             Double64Mask m = (Double64Mask)o;
1367             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Double64Mask.class, long.class, LENGTH,
1368                                              this, m,
1369                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
1370         }
1371 
1372         // Reductions
1373 
1374         @Override
1375         @ForceInline
1376         public boolean anyTrue() {
1377             return VectorIntrinsics.test(BT_ne, Double64Mask.class, long.class, LENGTH,
1378                                          this, this,
1379                                          (m, __) -> anyTrueHelper(((Double64Mask)m).getBits()));
1380         }
1381 
1382         @Override
1383         @ForceInline
1384         public boolean allTrue() {
1385             return VectorIntrinsics.test(BT_overflow, Double64Mask.class, long.class, LENGTH,
1386                                          this, DoubleVector.maskAllTrue(species()),
1387                                          (m, __) -> allTrueHelper(((Double64Mask)m).getBits()));
1388         }
1389     }
1390 
1391     // Shuffle
1392 
1393     static final class Double64Shuffle extends AbstractShuffle<Double> {
1394         Double64Shuffle(byte[] reorder) {
1395             super(reorder);
1396         }
1397 
1398         public Double64Shuffle(int[] reorder) {
1399             super(reorder);
1400         }
1401 
1402         public Double64Shuffle(int[] reorder, int i) {
1403             super(reorder, i);
1404         }
1405 
1406         public Double64Shuffle(IntUnaryOperator f) {
1407             super(f);
1408         }
1409 
1410         @Override
1411         public Double64Species species() {
1412             return SPECIES;
1413         }
1414 
1415         @Override
1416         public DoubleVector toVector() {
1417             double[] va = new double[SPECIES.length()];
1418             for (int i = 0; i < va.length; i++) {
1419               va[i] = (double) getElement(i);
1420             }
1421             return DoubleVector.fromArray(SPECIES, va, 0);
1422         }
1423 
1424         @Override
1425         public Double64Shuffle rearrange(Vector.Shuffle<Double> o) {
1426             Double64Shuffle s = (Double64Shuffle) o;
1427             byte[] r = new byte[reorder.length];
1428             for (int i = 0; i < reorder.length; i++) {
1429                 r[i] = reorder[s.reorder[i]];
1430             }
1431             return new Double64Shuffle(r);
1432         }
1433     }
1434 
1435     // Species
1436 
1437     @Override
1438     public Double64Species species() {
1439         return SPECIES;
1440     }
1441 
1442     static final class Double64Species extends DoubleSpecies {
1443         static final int BIT_SIZE = Shape.S_64_BIT.bitSize();
1444 
1445         static final int LENGTH = BIT_SIZE / Double.SIZE;
1446 
1447         @Override
1448         public String toString() {
1449            StringBuilder sb = new StringBuilder("Shape[");
1450            sb.append(bitSize()).append(" bits, ");
1451            sb.append(length()).append(" ").append(double.class.getSimpleName()).append("s x ");
1452            sb.append(elementSize()).append(" bits");
1453            sb.append("]");
1454            return sb.toString();
1455         }
1456 
1457         @Override
1458         @ForceInline
1459         public int bitSize() {
1460             return BIT_SIZE;
1461         }
1462 
1463         @Override
1464         @ForceInline
1465         public int length() {
1466             return LENGTH;
1467         }
1468 
1469         @Override
1470         @ForceInline
1471         public Class<Double> elementType() {
1472             return double.class;
1473         }
1474 
1475         @Override
1476         @ForceInline
1477         public Class<?> boxType() {
1478             return Double64Vector.class;
1479         }
1480 
1481         @Override
1482         @ForceInline
1483         public Class<?> maskType() {
1484             return Double64Mask.class;
1485         }
1486 
1487         @Override
1488         @ForceInline
1489         public int elementSize() {
1490             return Double.SIZE;
1491         }
1492 
1493         @Override
1494         @ForceInline
1495         @SuppressWarnings("unchecked")
1496         Class<?> vectorType() {
1497             return Double64Vector.class;
1498         }
1499 
1500         @Override
1501         @ForceInline
1502         public Shape shape() {
1503             return Shape.S_64_BIT;
1504         }
1505 
1506        @Override
1507        IntVector.IntSpecies indexSpecies() {
1508           return INDEX_SPEC;
1509        }
1510 
1511         @Override
1512         Double64Vector op(FOp f) {
1513             double[] res = new double[length()];
1514             for (int i = 0; i < length(); i++) {
1515                 res[i] = f.apply(i);
1516             }
1517             return new Double64Vector(res);
1518         }
1519 
1520         @Override
1521         Double64Vector op(Mask<Double> o, FOp f) {
1522             double[] res = new double[length()];
1523             boolean[] mbits = ((Double64Mask)o).getBits();
1524             for (int i = 0; i < length(); i++) {
1525                 if (mbits[i]) {
1526                     res[i] = f.apply(i);
1527                 }
1528             }
1529             return new Double64Vector(res);
1530         }
1531 
1532         @Override
1533         Double64Mask opm(FOpm f) {
1534             boolean[] res = new boolean[length()];
1535             for (int i = 0; i < length(); i++) {
1536                 res[i] = (boolean)f.apply(i);
1537             }
1538             return new Double64Mask(res);
1539         }
1540 
1541         // Factories
1542 
1543         @Override
1544         @ForceInline
1545         public Double64Vector zero() {
1546             return VectorIntrinsics.broadcastCoerced(Double64Vector.class, double.class, LENGTH,
1547                                                      Double.doubleToLongBits(0.0f), SPECIES, 
1548                                                      ((bits, s) -> ((Double64Species)s).op(i -> Double.longBitsToDouble((long)bits))));
1549         }
1550 
1551         @Override
1552         @ForceInline
1553         public Double64Vector broadcast(double e) {
1554             return VectorIntrinsics.broadcastCoerced(
1555                 Double64Vector.class, double.class, LENGTH,
1556                 Double.doubleToLongBits(e), SPECIES,
1557                 ((bits, s) -> ((Double64Species)s).op(i -> Double.longBitsToDouble((long)bits))));
1558         }
1559 
1560         @Override
1561         @ForceInline
1562         public Double64Vector scalars(double... es) {
1563             Objects.requireNonNull(es);
1564             int ix = VectorIntrinsics.checkIndex(0, es.length, LENGTH);
1565             return VectorIntrinsics.load(Double64Vector.class, double.class, LENGTH,
1566                                          es, Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
1567                                          es, ix, SPECIES,
1568                                          (c, idx, s) -> ((Double64Species)s).op(n -> c[idx + n]));
1569         }
1570 
1571         @Override
1572         @ForceInline
1573         public <E> Double64Mask cast(Mask<E> m) {
1574             if (m.length() != LENGTH)
1575                 throw new IllegalArgumentException("Mask length this species length differ");
1576             return new Double64Mask(m.toArray());
1577         }
1578 
1579         @Override
1580         @ForceInline
1581         public <E> Double64Shuffle cast(Shuffle<E> s) {
1582             if (s.length() != LENGTH)
1583                 throw new IllegalArgumentException("Shuffle length this species length differ");
1584             return new Double64Shuffle(s.toArray());
1585         }
1586     }
1587 }