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