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