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