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.util.Arrays;
  29 import java.util.Objects;
  30 import jdk.internal.vm.annotation.ForceInline;
  31 import static jdk.incubator.vector.VectorIntrinsics.*;
  32 
  33 @SuppressWarnings("cast")
  34 final class Long512Vector extends LongVector<Shapes.S512Bit> {
  35     static final Long512Species SPECIES = new Long512Species();
  36 
  37     static final Long512Vector ZERO = new Long512Vector();
  38 
  39     static final int LENGTH = SPECIES.length();
  40 
  41     private final long[] vec; // Don't access directly, use getElements() instead.
  42 
  43     private long[] getElements() {
  44         return VectorIntrinsics.maybeRebox(this).vec;
  45     }
  46 
  47     Long512Vector() {
  48         vec = new long[SPECIES.length()];
  49     }
  50 
  51     Long512Vector(long[] v) {
  52         vec = v;
  53     }
  54 
  55     @Override
  56     public int length() { return LENGTH; }
  57 
  58     // Unary operator
  59 
  60     @Override
  61     Long512Vector uOp(FUnOp f) {
  62         long[] vec = getElements();
  63         long[] res = new long[length()];
  64         for (int i = 0; i < length(); i++) {
  65             res[i] = f.apply(i, vec[i]);
  66         }
  67         return new Long512Vector(res);
  68     }
  69 
  70     @Override
  71     Long512Vector uOp(Mask<Long, Shapes.S512Bit> o, FUnOp f) {
  72         long[] vec = getElements();
  73         long[] res = new long[length()];
  74         boolean[] mbits = ((Long512Mask)o).getBits();
  75         for (int i = 0; i < length(); i++) {
  76             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  77         }
  78         return new Long512Vector(res);
  79     }
  80 
  81     // Binary operator
  82 
  83     @Override
  84     Long512Vector bOp(Vector<Long, Shapes.S512Bit> o, FBinOp f) {
  85         long[] res = new long[length()];
  86         long[] vec1 = this.getElements();
  87         long[] vec2 = ((Long512Vector)o).getElements();
  88         for (int i = 0; i < length(); i++) {
  89             res[i] = f.apply(i, vec1[i], vec2[i]);
  90         }
  91         return new Long512Vector(res);
  92     }
  93 
  94     @Override
  95     Long512Vector bOp(Vector<Long, Shapes.S512Bit> o1, Mask<Long, Shapes.S512Bit> o2, FBinOp f) {
  96         long[] res = new long[length()];
  97         long[] vec1 = this.getElements();
  98         long[] vec2 = ((Long512Vector)o1).getElements();
  99         boolean[] mbits = ((Long512Mask)o2).getBits();
 100         for (int i = 0; i < length(); i++) {
 101             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 102         }
 103         return new Long512Vector(res);
 104     }
 105 
 106     // Trinary operator
 107 
 108     @Override
 109     Long512Vector tOp(Vector<Long, Shapes.S512Bit> o1, Vector<Long, Shapes.S512Bit> o2, FTriOp f) {
 110         long[] res = new long[length()];
 111         long[] vec1 = this.getElements();
 112         long[] vec2 = ((Long512Vector)o1).getElements();
 113         long[] vec3 = ((Long512Vector)o2).getElements();
 114         for (int i = 0; i < length(); i++) {
 115             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 116         }
 117         return new Long512Vector(res);
 118     }
 119 
 120     @Override
 121     Long512Vector tOp(Vector<Long, Shapes.S512Bit> o1, Vector<Long, Shapes.S512Bit> o2, Mask<Long, Shapes.S512Bit> o3, FTriOp f) {
 122         long[] res = new long[length()];
 123         long[] vec1 = getElements();
 124         long[] vec2 = ((Long512Vector)o1).getElements();
 125         long[] vec3 = ((Long512Vector)o2).getElements();
 126         boolean[] mbits = ((Long512Mask)o3).getBits();
 127         for (int i = 0; i < length(); i++) {
 128             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 129         }
 130         return new Long512Vector(res);
 131     }
 132 
 133     @Override
 134     long rOp(long v, FBinOp f) {
 135         long[] vec = getElements();
 136         for (int i = 0; i < length(); i++) {
 137             v = f.apply(i, v, vec[i]);
 138         }
 139         return v;
 140     }
 141 
 142     // Binary operations with scalars
 143 
 144     @Override
 145     @ForceInline
 146     public LongVector<Shapes.S512Bit> add(long o) {
 147         return add(SPECIES.broadcast(o));
 148     }
 149 
 150     @Override
 151     @ForceInline
 152     public LongVector<Shapes.S512Bit> add(long o, Mask<Long,Shapes.S512Bit> m) {
 153         return add(SPECIES.broadcast(o), m);
 154     }
 155 
 156     @Override
 157     @ForceInline
 158     public LongVector<Shapes.S512Bit> addSaturate(long o) {
 159         return addSaturate(SPECIES.broadcast(o));
 160     }
 161 
 162     @Override
 163     @ForceInline
 164     public LongVector<Shapes.S512Bit> addSaturate(long o, Mask<Long,Shapes.S512Bit> m) {
 165         return addSaturate(SPECIES.broadcast(o), m);
 166     }
 167 
 168     @Override
 169     @ForceInline
 170     public LongVector<Shapes.S512Bit> sub(long o) {
 171         return sub(SPECIES.broadcast(o));
 172     }
 173 
 174     @Override
 175     @ForceInline
 176     public LongVector<Shapes.S512Bit> sub(long o, Mask<Long,Shapes.S512Bit> m) {
 177         return sub(SPECIES.broadcast(o), m);
 178     }
 179 
 180     @Override
 181     @ForceInline
 182     public LongVector<Shapes.S512Bit> subSaturate(long o) {
 183         return subSaturate(SPECIES.broadcast(o));
 184     }
 185 
 186     @Override
 187     @ForceInline
 188     public LongVector<Shapes.S512Bit> subSaturate(long o, Mask<Long,Shapes.S512Bit> m) {
 189         return subSaturate(SPECIES.broadcast(o), m);
 190     }
 191 
 192     @Override
 193     @ForceInline
 194     public LongVector<Shapes.S512Bit> mul(long o) {
 195         return mul(SPECIES.broadcast(o));
 196     }
 197 
 198     @Override
 199     @ForceInline
 200     public LongVector<Shapes.S512Bit> mul(long o, Mask<Long,Shapes.S512Bit> m) {
 201         return mul(SPECIES.broadcast(o), m);
 202     }
 203 
 204     @Override
 205     @ForceInline
 206     public LongVector<Shapes.S512Bit> min(long o) {
 207         return min(SPECIES.broadcast(o));
 208     }
 209 
 210     @Override
 211     @ForceInline
 212     public LongVector<Shapes.S512Bit> max(long o) {
 213         return max(SPECIES.broadcast(o));
 214     }
 215 
 216     @Override
 217     @ForceInline
 218     public Mask<Long, Shapes.S512Bit> equal(long o) {
 219         return equal(SPECIES.broadcast(o));
 220     }
 221 
 222     @Override
 223     @ForceInline
 224     public Mask<Long, Shapes.S512Bit> notEqual(long o) {
 225         return notEqual(SPECIES.broadcast(o));
 226     }
 227 
 228     @Override
 229     @ForceInline
 230     public Mask<Long, Shapes.S512Bit> lessThan(long o) {
 231         return lessThan(SPECIES.broadcast(o));
 232     }
 233 
 234     @Override
 235     @ForceInline
 236     public Mask<Long, Shapes.S512Bit> lessThanEq(long o) {
 237         return lessThanEq(SPECIES.broadcast(o));
 238     }
 239 
 240     @Override
 241     @ForceInline
 242     public Mask<Long, Shapes.S512Bit> greaterThan(long o) {
 243         return greaterThan(SPECIES.broadcast(o));
 244     }
 245 
 246     @Override
 247     @ForceInline
 248     public Mask<Long, Shapes.S512Bit> greaterThanEq(long o) {
 249         return greaterThanEq(SPECIES.broadcast(o));
 250     }
 251 
 252     @Override
 253     @ForceInline
 254     public LongVector<Shapes.S512Bit> blend(long o, Mask<Long,Shapes.S512Bit> m) {
 255         return blend(SPECIES.broadcast(o), m);
 256     }
 257 
 258 
 259     @Override
 260     @ForceInline
 261     public LongVector<Shapes.S512Bit> and(long o) {
 262         return and(SPECIES.broadcast(o));
 263     }
 264 
 265     @Override
 266     @ForceInline
 267     public LongVector<Shapes.S512Bit> and(long o, Mask<Long,Shapes.S512Bit> m) {
 268         return and(SPECIES.broadcast(o), m);
 269     }
 270 
 271     @Override
 272     @ForceInline
 273     public LongVector<Shapes.S512Bit> or(long o) {
 274         return or(SPECIES.broadcast(o));
 275     }
 276 
 277     @Override
 278     @ForceInline
 279     public LongVector<Shapes.S512Bit> or(long o, Mask<Long,Shapes.S512Bit> m) {
 280         return or(SPECIES.broadcast(o), m);
 281     }
 282 
 283     @Override
 284     @ForceInline
 285     public LongVector<Shapes.S512Bit> xor(long o) {
 286         return xor(SPECIES.broadcast(o));
 287     }
 288 
 289     @Override
 290     @ForceInline
 291     public LongVector<Shapes.S512Bit> xor(long o, Mask<Long,Shapes.S512Bit> m) {
 292         return xor(SPECIES.broadcast(o), m);
 293     }
 294 
 295 
 296     // Unary operations
 297 
 298 
 299 
 300     @Override
 301     @ForceInline
 302     public Long512Vector not() {
 303         return (Long512Vector) VectorIntrinsics.unaryOp(
 304             VECTOR_OP_NOT, Long512Vector.class, long.class, LENGTH,
 305             this,
 306             v1 -> ((Long512Vector)v1).uOp((i, a) -> (long) ~a));
 307     }
 308     // Binary operations
 309 
 310     @Override
 311     @ForceInline
 312     public Long512Vector add(Vector<Long,Shapes.S512Bit> o) {
 313         Objects.requireNonNull(o);
 314         Long512Vector v = (Long512Vector)o;
 315         return (Long512Vector) VectorIntrinsics.binaryOp(
 316             VECTOR_OP_ADD, Long512Vector.class, long.class, LENGTH,
 317             this, v,
 318             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long)(a + b)));
 319     }
 320 
 321     @Override
 322     @ForceInline
 323     public Long512Vector sub(Vector<Long,Shapes.S512Bit> o) {
 324         Objects.requireNonNull(o);
 325         Long512Vector v = (Long512Vector)o;
 326         return (Long512Vector) VectorIntrinsics.binaryOp(
 327             VECTOR_OP_SUB, Long512Vector.class, long.class, LENGTH,
 328             this, v,
 329             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long)(a - b)));
 330     }
 331 
 332     @Override
 333     @ForceInline
 334     public Long512Vector mul(Vector<Long,Shapes.S512Bit> o) {
 335         Objects.requireNonNull(o);
 336         Long512Vector v = (Long512Vector)o;
 337         return (Long512Vector) VectorIntrinsics.binaryOp(
 338             VECTOR_OP_MUL, Long512Vector.class, long.class, LENGTH,
 339             this, v,
 340             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long)(a * b)));
 341     }
 342 
 343     @Override
 344     @ForceInline
 345     public Long512Vector min(Vector<Long,Shapes.S512Bit> o) {
 346         Objects.requireNonNull(o);
 347         Long512Vector v = (Long512Vector)o;
 348         return (Long512Vector) VectorIntrinsics.binaryOp(
 349             VECTOR_OP_MIN, Long512Vector.class, long.class, LENGTH,
 350             this, v,
 351             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long) ((a < b) ? a : b)));
 352     }
 353 
 354     @Override
 355     @ForceInline
 356     public Long512Vector max(Vector<Long,Shapes.S512Bit> o) {
 357         Objects.requireNonNull(o);
 358         Long512Vector v = (Long512Vector)o;
 359         return (Long512Vector) VectorIntrinsics.binaryOp(
 360             VECTOR_OP_MAX, Long512Vector.class, long.class, LENGTH,
 361             this, v,
 362             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long) ((a > b) ? a : b)));
 363         }
 364 
 365 
 366 
 367     @Override
 368     @ForceInline
 369     public Long512Vector and(Vector<Long,Shapes.S512Bit> o) {
 370         Objects.requireNonNull(o);
 371         Long512Vector v = (Long512Vector)o;
 372         return (Long512Vector) VectorIntrinsics.binaryOp(
 373             VECTOR_OP_AND, Long512Vector.class, long.class, LENGTH,
 374             this, v,
 375             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long)(a & b)));
 376     }
 377 
 378     @Override
 379     @ForceInline
 380     public Long512Vector or(Vector<Long,Shapes.S512Bit> o) {
 381         Objects.requireNonNull(o);
 382         Long512Vector v = (Long512Vector)o;
 383         return (Long512Vector) VectorIntrinsics.binaryOp(
 384             VECTOR_OP_OR, Long512Vector.class, long.class, LENGTH,
 385             this, v,
 386             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long)(a | b)));
 387     }
 388 
 389     @Override
 390     @ForceInline
 391     public Long512Vector xor(Vector<Long,Shapes.S512Bit> o) {
 392         Objects.requireNonNull(o);
 393         Long512Vector v = (Long512Vector)o;
 394         return (Long512Vector) VectorIntrinsics.binaryOp(
 395             VECTOR_OP_XOR, Long512Vector.class, long.class, LENGTH,
 396             this, v,
 397             (v1, v2) -> ((Long512Vector)v1).bOp(v2, (i, a, b) -> (long)(a ^ b)));
 398     }
 399 
 400     @Override
 401     @ForceInline
 402     public Long512Vector and(Vector<Long,Shapes.S512Bit> v, Mask<Long, Shapes.S512Bit> m) {
 403         return blend(and(v), m);
 404     }
 405 
 406     @Override
 407     @ForceInline
 408     public Long512Vector or(Vector<Long,Shapes.S512Bit> v, Mask<Long, Shapes.S512Bit> m) {
 409         return blend(or(v), m);
 410     }
 411 
 412     @Override
 413     @ForceInline
 414     public Long512Vector xor(Vector<Long,Shapes.S512Bit> v, Mask<Long, Shapes.S512Bit> m) {
 415         return blend(xor(v), m);
 416     }
 417 
 418     @Override
 419     @ForceInline
 420     public Long512Vector shiftL(int s) {
 421         return (Long512Vector) VectorIntrinsics.broadcastInt(
 422             VECTOR_OP_LSHIFT, Long512Vector.class, long.class, LENGTH,
 423             this, s,
 424             (v, i) -> v.uOp((__, a) -> (long) (a << i)));
 425     }
 426 
 427     @Override
 428     @ForceInline
 429     public Long512Vector shiftR(int s) {
 430         return (Long512Vector) VectorIntrinsics.broadcastInt(
 431             VECTOR_OP_URSHIFT, Long512Vector.class, long.class, LENGTH,
 432             this, s,
 433             (v, i) -> v.uOp((__, a) -> (long) (a >>> i)));
 434     }
 435 
 436     @Override
 437     @ForceInline
 438     public Long512Vector aShiftR(int s) {
 439         return (Long512Vector) VectorIntrinsics.broadcastInt(
 440             VECTOR_OP_RSHIFT, Long512Vector.class, long.class, LENGTH,
 441             this, s,
 442             (v, i) -> v.uOp((__, a) -> (long) (a >> i)));
 443     }
 444 
 445     // Ternary operations
 446 
 447 
 448     // Type specific horizontal reductions
 449 
 450     @Override
 451     @ForceInline
 452     public long addAll() {
 453         return (long) VectorIntrinsics.reductionCoerced(
 454             VECTOR_OP_ADD, Long512Vector.class, long.class, LENGTH,
 455             this,
 456             v -> (long) v.rOp((long) 0, (i, a, b) -> (long) (a + b)));
 457     }
 458 
 459     @Override
 460     @ForceInline
 461     public long andAll() {
 462         return (long) VectorIntrinsics.reductionCoerced(
 463             VECTOR_OP_AND, Long512Vector.class, long.class, LENGTH,
 464             this,
 465             v -> (long) v.rOp((long) -1, (i, a, b) -> (long) (a & b)));
 466     }
 467 
 468     @Override
 469     @ForceInline
 470     public long mulAll() {
 471         return (long) VectorIntrinsics.reductionCoerced(
 472             VECTOR_OP_MUL, Long512Vector.class, long.class, LENGTH,
 473             this,
 474             v -> (long) v.rOp((long) 1, (i, a, b) -> (long) (a * b)));
 475     }
 476 
 477     @Override
 478     @ForceInline
 479     public long orAll() {
 480         return (long) VectorIntrinsics.reductionCoerced(
 481             VECTOR_OP_OR, Long512Vector.class, long.class, LENGTH,
 482             this,
 483             v -> (long) v.rOp((long) 0, (i, a, b) -> (long) (a | b)));
 484     }
 485 
 486     @Override
 487     @ForceInline
 488     public long xorAll() {
 489         return (long) VectorIntrinsics.reductionCoerced(
 490             VECTOR_OP_XOR, Long512Vector.class, long.class, LENGTH,
 491             this,
 492             v -> (long) v.rOp((long) 0, (i, a, b) -> (long) (a ^ b)));
 493     }
 494 
 495     @Override
 496     @ForceInline
 497     public long subAll() {
 498         return (long) VectorIntrinsics.reductionCoerced(
 499             VECTOR_OP_SUB, Long512Vector.class, long.class, LENGTH,
 500             this,
 501             v -> (long) v.rOp((long) 0, (i, a, b) -> (long) (a - b)));
 502     }
 503 
 504     // Memory operations
 505 
 506     @Override
 507     @ForceInline
 508     public void intoArray(long[] a, int ix) {
 509         Objects.requireNonNull(a);
 510         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 511         VectorIntrinsics.store(Long512Vector.class, long.class, LENGTH,
 512                                a, ix, this,
 513                                (arr, idx, v) -> v.forEach((i, a_) -> ((long[])arr)[idx + i] = a_));
 514     }
 515 
 516     @Override
 517     @ForceInline
 518     public void intoArray(long[] a, int ax, Mask<Long, Shapes.S512Bit> m) {
 519         // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_);
 520         Long512Vector oldVal = SPECIES.fromArray(a, ax);
 521         Long512Vector newVal = oldVal.blend(this, m);
 522         newVal.intoArray(a, ax);
 523     }
 524 
 525     //
 526 
 527     @Override
 528     public String toString() {
 529         return Arrays.toString(getElements());
 530     }
 531 
 532     @Override
 533     public boolean equals(Object o) {
 534         if (this == o) return true;
 535         if (o == null || this.getClass() != o.getClass()) return false;
 536 
 537         Long512Vector that = (Long512Vector) o;
 538         return Arrays.equals(this.getElements(), that.getElements());
 539     }
 540 
 541     @Override
 542     public int hashCode() {
 543         return Arrays.hashCode(vec);
 544     }
 545 
 546     // Binary test
 547 
 548     @Override
 549     Long512Mask bTest(Vector<Long, Shapes.S512Bit> o, FBinTest f) {
 550         long[] vec1 = getElements();
 551         long[] vec2 = ((Long512Vector)o).getElements();
 552         boolean[] bits = new boolean[length()];
 553         for (int i = 0; i < length(); i++){
 554             bits[i] = f.apply(i, vec1[i], vec2[i]);
 555         }
 556         return new Long512Mask(bits);
 557     }
 558 
 559     // Comparisons
 560 
 561     @Override
 562     @ForceInline
 563     public Long512Mask equal(Vector<Long, Shapes.S512Bit> o) {
 564         Objects.requireNonNull(o);
 565         Long512Vector v = (Long512Vector)o;
 566 
 567         return (Long512Mask) VectorIntrinsics.compare(
 568             BT_eq, Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 569             this, v,
 570             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
 571     }
 572 
 573     @Override
 574     @ForceInline
 575     public Long512Mask notEqual(Vector<Long, Shapes.S512Bit> o) {
 576         Objects.requireNonNull(o);
 577         Long512Vector v = (Long512Vector)o;
 578 
 579         return (Long512Mask) VectorIntrinsics.compare(
 580             BT_ne, Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 581             this, v,
 582             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
 583     }
 584 
 585     @Override
 586     @ForceInline
 587     public Long512Mask lessThan(Vector<Long, Shapes.S512Bit> o) {
 588         Objects.requireNonNull(o);
 589         Long512Vector v = (Long512Vector)o;
 590 
 591         return (Long512Mask) VectorIntrinsics.compare(
 592             BT_lt, Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 593             this, v,
 594             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
 595     }
 596 
 597     @Override
 598     @ForceInline
 599     public Long512Mask lessThanEq(Vector<Long, Shapes.S512Bit> o) {
 600         Objects.requireNonNull(o);
 601         Long512Vector v = (Long512Vector)o;
 602 
 603         return (Long512Mask) VectorIntrinsics.compare(
 604             BT_le, Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 605             this, v,
 606             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
 607     }
 608 
 609     @Override
 610     @ForceInline
 611     public Long512Mask greaterThan(Vector<Long, Shapes.S512Bit> o) {
 612         Objects.requireNonNull(o);
 613         Long512Vector v = (Long512Vector)o;
 614 
 615         return (Long512Mask) VectorIntrinsics.compare(
 616             BT_gt, Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 617             this, v,
 618             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
 619     }
 620 
 621     @Override
 622     @ForceInline
 623     public Long512Mask greaterThanEq(Vector<Long, Shapes.S512Bit> o) {
 624         Objects.requireNonNull(o);
 625         Long512Vector v = (Long512Vector)o;
 626 
 627         return (Long512Mask) VectorIntrinsics.compare(
 628             BT_ge, Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 629             this, v,
 630             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
 631     }
 632 
 633     // Foreach
 634 
 635     @Override
 636     void forEach(FUnCon f) {
 637         long[] vec = getElements();
 638         for (int i = 0; i < length(); i++) {
 639             f.apply(i, vec[i]);
 640         }
 641     }
 642 
 643     @Override
 644     void forEach(Mask<Long, Shapes.S512Bit> o, FUnCon f) {
 645         boolean[] mbits = ((Long512Mask)o).getBits();
 646         forEach((i, a) -> {
 647             if (mbits[i]) { f.apply(i, a); }
 648         });
 649     }
 650 
 651 
 652     Double512Vector toFP() {
 653         long[] vec = getElements();
 654         double[] res = new double[this.species().length()];
 655         for(int i = 0; i < this.species().length(); i++){
 656             res[i] = Double.longBitsToDouble(vec[i]);
 657         }
 658         return new Double512Vector(res);
 659     }
 660 
 661     @Override
 662     public Long512Vector rotateEL(int j) {
 663         long[] vec = getElements();
 664         long[] res = new long[length()];
 665         for (int i = 0; i < length(); i++){
 666             res[(j + i) % length()] = vec[i];
 667         }
 668         return new Long512Vector(res);
 669     }
 670 
 671     @Override
 672     public Long512Vector rotateER(int j) {
 673         long[] vec = getElements();
 674         long[] res = new long[length()];
 675         for (int i = 0; i < length(); i++){
 676             int z = i - j;
 677             if(j < 0) {
 678                 res[length() + z] = vec[i];
 679             } else {
 680                 res[z] = vec[i];
 681             }
 682         }
 683         return new Long512Vector(res);
 684     }
 685 
 686     @Override
 687     public Long512Vector shiftEL(int j) {
 688         long[] vec = getElements();
 689         long[] res = new long[length()];
 690         for (int i = 0; i < length() - j; i++) {
 691             res[i] = vec[i + j];
 692         }
 693         return new Long512Vector(res);
 694     }
 695 
 696     @Override
 697     public Long512Vector shiftER(int j) {
 698         long[] vec = getElements();
 699         long[] res = new long[length()];
 700         for (int i = 0; i < length() - j; i++){
 701             res[i + j] = vec[i];
 702         }
 703         return new Long512Vector(res);
 704     }
 705 
 706     @Override
 707     public Long512Vector shuffle(Vector<Long, Shapes.S512Bit> o, Shuffle<Long, Shapes.S512Bit> s) {
 708         Long512Vector v = (Long512Vector) o;
 709         return uOp((i, a) -> {
 710             long[] vec = this.getElements();
 711             int e = s.getElement(i);
 712             if(e >= 0 && e < length()) {
 713                 //from this
 714                 return vec[e];
 715             } else if(e < length() * 2) {
 716                 //from o
 717                 return v.getElements()[e - length()];
 718             } else {
 719                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 720             }
 721         });
 722     }
 723 
 724     @Override
 725     public Long512Vector swizzle(Shuffle<Long, Shapes.S512Bit> s) {
 726         return uOp((i, a) -> {
 727             long[] vec = this.getElements();
 728             int e = s.getElement(i);
 729             if(e >= 0 && e < length()) {
 730                 return vec[e];
 731             } else {
 732                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 733             }
 734         });
 735     }
 736 
 737     @Override
 738     @ForceInline
 739     public Long512Vector blend(Vector<Long, Shapes.S512Bit> o1, Mask<Long, Shapes.S512Bit> o2) {
 740         Objects.requireNonNull(o1);
 741         Objects.requireNonNull(o2);
 742         Long512Vector v = (Long512Vector)o1;
 743         Long512Mask   m = (Long512Mask)o2;
 744 
 745         return (Long512Vector) VectorIntrinsics.blend(
 746             Long512Vector.class, Long512Mask.class, long.class, LENGTH,
 747             this, v, m,
 748             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
 749     }
 750 
 751     // Accessors
 752 
 753     @Override
 754     public long get(int i) {
 755         long[] vec = getElements();
 756         return vec[i];
 757     }
 758 
 759     @Override
 760     public Long512Vector with(int i, long e) {
 761         long[] res = vec.clone();
 762         res[i] = e;
 763         return new Long512Vector(res);
 764     }
 765 
 766     // Mask
 767 
 768     static final class Long512Mask extends AbstractMask<Long, Shapes.S512Bit> {
 769         static final Long512Mask TRUE_MASK = new Long512Mask(true);
 770         static final Long512Mask FALSE_MASK = new Long512Mask(false);
 771 
 772         // FIXME: was temporarily put here to simplify rematerialization support in the JVM
 773         private final boolean[] bits; // Don't access directly, use getBits() instead.
 774 
 775         public Long512Mask(boolean[] bits) {
 776             this(bits, 0);
 777         }
 778 
 779         public Long512Mask(boolean[] bits, int i) {
 780             this.bits = Arrays.copyOfRange(bits, i, i + species().length());
 781         }
 782 
 783         public Long512Mask(boolean val) {
 784             boolean[] bits = new boolean[species().length()];
 785             Arrays.fill(bits, val);
 786             this.bits = bits;
 787         }
 788 
 789         boolean[] getBits() {
 790             return VectorIntrinsics.maybeRebox(this).bits;
 791         }
 792 
 793         @Override
 794         Long512Mask uOp(MUnOp f) {
 795             boolean[] res = new boolean[species().length()];
 796             boolean[] bits = getBits();
 797             for (int i = 0; i < species().length(); i++) {
 798                 res[i] = f.apply(i, bits[i]);
 799             }
 800             return new Long512Mask(res);
 801         }
 802 
 803         @Override
 804         Long512Mask bOp(Mask<Long, Shapes.S512Bit> o, MBinOp f) {
 805             boolean[] res = new boolean[species().length()];
 806             boolean[] bits = getBits();
 807             boolean[] mbits = ((Long512Mask)o).getBits();
 808             for (int i = 0; i < species().length(); i++) {
 809                 res[i] = f.apply(i, bits[i], mbits[i]);
 810             }
 811             return new Long512Mask(res);
 812         }
 813 
 814         @Override
 815         public Long512Species species() {
 816             return SPECIES;
 817         }
 818 
 819         @Override
 820         public Long512Vector toVector() {
 821             long[] res = new long[species().length()];
 822             boolean[] bits = getBits();
 823             for (int i = 0; i < species().length(); i++) {
 824                 res[i] = (long) (bits[i] ? -1 : 0);
 825             }
 826             return new Long512Vector(res);
 827         }
 828 
 829         @Override
 830         @ForceInline
 831         @SuppressWarnings("unchecked")
 832         public <Z> Mask<Z, Shapes.S512Bit> rebracket(Species<Z, Shapes.S512Bit> species) {
 833             Objects.requireNonNull(species);
 834             // TODO: check proper element type
 835             return VectorIntrinsics.reinterpret(
 836                 Long512Mask.class, long.class, LENGTH,
 837                 species.elementType(), species.length(), this,
 838                 (m, t) -> m.reshape(species)
 839             );
 840         }
 841 
 842         // Unary operations
 843 
 844         //Mask<E, S> not();
 845 
 846         // Binary operations
 847 
 848         @Override
 849         @ForceInline
 850         public Long512Mask and(Mask<Long,Shapes.S512Bit> o) {
 851             Objects.requireNonNull(o);
 852             Long512Mask m = (Long512Mask)o;
 853             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Long512Mask.class, long.class, LENGTH,
 854                                              this, m,
 855                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
 856         }
 857 
 858         @Override
 859         @ForceInline
 860         public Long512Mask or(Mask<Long,Shapes.S512Bit> o) {
 861             Objects.requireNonNull(o);
 862             Long512Mask m = (Long512Mask)o;
 863             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Long512Mask.class, long.class, LENGTH,
 864                                              this, m,
 865                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
 866         }
 867 
 868         // Reductions
 869 
 870         @Override
 871         @ForceInline
 872         public boolean anyTrue() {
 873             return VectorIntrinsics.test(COND_notZero, Long512Mask.class, long.class, LENGTH,
 874                                          this, this,
 875                                          (m1, m2) -> super.anyTrue());
 876         }
 877 
 878         @Override
 879         @ForceInline
 880         public boolean allTrue() {
 881             return VectorIntrinsics.test(COND_carrySet, Long512Mask.class, long.class, LENGTH,
 882                                          this, species().maskAllTrue(),
 883                                          (m1, m2) -> super.allTrue());
 884         }
 885     }
 886 
 887     // Shuffle
 888 
 889     static final class Long512Shuffle extends AbstractShuffle<Long, Shapes.S512Bit> {
 890         static final IntVector.IntSpecies<Shapes.S512Bit> INT_SPECIES = IntVector.speciesInstance(Shapes.S_512_BIT);
 891 
 892         public Long512Shuffle(int[] reorder) {
 893             super(reorder);
 894         }
 895 
 896         public Long512Shuffle(int[] reorder, int i) {
 897             super(reorder, i);
 898         }
 899 
 900         @Override
 901         public Long512Species species() {
 902             return SPECIES;
 903         }
 904 
 905         @Override
 906         public IntVector.IntSpecies<Shapes.S512Bit> intSpecies() {
 907             return INT_SPECIES;
 908         }
 909     }
 910 
 911     // Species
 912 
 913     @Override
 914     public Long512Species species() {
 915         return SPECIES;
 916     }
 917 
 918     static final class Long512Species extends LongSpecies<Shapes.S512Bit> {
 919         static final int BIT_SIZE = Shapes.S_512_BIT.bitSize();
 920 
 921         static final int LENGTH = BIT_SIZE / Long.SIZE;
 922 
 923         @Override
 924         public String toString() {
 925            StringBuilder sb = new StringBuilder("Shape[");
 926            sb.append(bitSize()).append(" bits, ");
 927            sb.append(length()).append(" ").append(long.class.getSimpleName()).append("s x ");
 928            sb.append(elementSize()).append(" bits");
 929            sb.append("]");
 930            return sb.toString();
 931         }
 932 
 933         @Override
 934         @ForceInline
 935         public int bitSize() {
 936             return BIT_SIZE;
 937         }
 938 
 939         @Override
 940         @ForceInline
 941         public int length() {
 942             return LENGTH;
 943         }
 944 
 945         @Override
 946         @ForceInline
 947         public Class<Long> elementType() {
 948             return long.class;
 949         }
 950 
 951         @Override
 952         @ForceInline
 953         public int elementSize() {
 954             return Long.SIZE;
 955         }
 956 
 957         @Override
 958         @ForceInline
 959         public Shapes.S512Bit shape() {
 960             return Shapes.S_512_BIT;
 961         }
 962 
 963         @Override
 964         Long512Vector op(FOp f) {
 965             long[] res = new long[length()];
 966             for (int i = 0; i < length(); i++) {
 967                 res[i] = f.apply(i);
 968             }
 969             return new Long512Vector(res);
 970         }
 971 
 972         @Override
 973         Long512Vector op(Mask<Long, Shapes.S512Bit> o, FOp f) {
 974             long[] res = new long[length()];
 975             boolean[] mbits = ((Long512Mask)o).getBits();
 976             for (int i = 0; i < length(); i++) {
 977                 if (mbits[i]) {
 978                     res[i] = f.apply(i);
 979                 }
 980             }
 981             return new Long512Vector(res);
 982         }
 983 
 984         // Factories
 985 
 986         @Override
 987         public Long512Mask maskFromValues(boolean... bits) {
 988             return new Long512Mask(bits);
 989         }
 990 
 991         @Override
 992         public Long512Mask maskFromArray(boolean[] bits, int i) {
 993             return new Long512Mask(bits, i);
 994         }
 995 
 996         @Override
 997         public Long512Shuffle shuffleFromValues(int... ixs) {
 998             return new Long512Shuffle(ixs);
 999         }
1000 
1001         @Override
1002         public Long512Shuffle shuffleFromArray(int[] ixs, int i) {
1003             return new Long512Shuffle(ixs, i);
1004         }
1005 
1006         @Override
1007         public Long512Shuffle shuffleFromVector(Vector<Integer, Shapes.S512Bit> v) {
1008             int[] a = ((IntVector<Shapes.S512Bit>) v).toArray();
1009             return new Long512Shuffle(a, 0);
1010         }
1011 
1012         @Override
1013         @ForceInline
1014         public Long512Vector zero() {
1015             return VectorIntrinsics.broadcastCoerced(Long512Vector.class, long.class, LENGTH,
1016                                                      0,
1017                                                      (z -> ZERO));
1018         }
1019 
1020         @Override
1021         @ForceInline
1022         public Long512Vector broadcast(long e) {
1023             return VectorIntrinsics.broadcastCoerced(
1024                 Long512Vector.class, long.class, LENGTH,
1025                 e,
1026                 ((long bits) -> SPECIES.op(i -> (long)bits)));
1027         }
1028 
1029         @Override
1030         @ForceInline
1031         public Long512Mask maskAllTrue() {
1032             return VectorIntrinsics.broadcastCoerced(Long512Mask.class, long.class, LENGTH,
1033                                                      (long)-1,
1034                                                      (z -> Long512Mask.TRUE_MASK));
1035         }
1036 
1037         @Override
1038         @ForceInline
1039         public Long512Mask maskAllFalse() {
1040             return VectorIntrinsics.broadcastCoerced(Long512Mask.class, long.class, LENGTH,
1041                                                      0,
1042                                                      (z -> Long512Mask.FALSE_MASK));
1043         }
1044 
1045         @Override
1046         @ForceInline
1047         public Long512Vector fromArray(long[] a, int ix) {
1048             Objects.requireNonNull(a);
1049             ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
1050             return (Long512Vector) VectorIntrinsics.load(Long512Vector.class, long.class, LENGTH,
1051                                                         a, ix,
1052                                                         (arr, idx) -> super.fromArray((long[]) arr, idx));
1053         }
1054 
1055         @Override
1056         @ForceInline
1057         public Long512Vector fromArray(long[] a, int ax, Mask<Long, Shapes.S512Bit> m) {
1058             return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]);
1059         }
1060 
1061         @Override
1062         @ForceInline
1063         @SuppressWarnings("unchecked")
1064         public <F> Long512Vector rebracket(Vector<F, Shapes.S512Bit> o) {
1065             Objects.requireNonNull(o);
1066             if (o.elementType() == byte.class) {
1067                 Byte512Vector so = (Byte512Vector)o;
1068                 return VectorIntrinsics.reinterpret(
1069                     Byte512Vector.class, byte.class, so.length(),
1070                     long.class, LENGTH, so,
1071                     (v, t) -> (Long512Vector)reshape(v)
1072                 );
1073             } else if (o.elementType() == short.class) {
1074                 Short512Vector so = (Short512Vector)o;
1075                 return VectorIntrinsics.reinterpret(
1076                     Short512Vector.class, short.class, so.length(),
1077                     long.class, LENGTH, so,
1078                     (v, t) -> (Long512Vector)reshape(v)
1079                 );
1080             } else if (o.elementType() == int.class) {
1081                 Int512Vector so = (Int512Vector)o;
1082                 return VectorIntrinsics.reinterpret(
1083                     Int512Vector.class, int.class, so.length(),
1084                     long.class, LENGTH, so,
1085                     (v, t) -> (Long512Vector)reshape(v)
1086                 );
1087             } else if (o.elementType() == long.class) {
1088                 Long512Vector so = (Long512Vector)o;
1089                 return VectorIntrinsics.reinterpret(
1090                     Long512Vector.class, long.class, so.length(),
1091                     long.class, LENGTH, so,
1092                     (v, t) -> (Long512Vector)reshape(v)
1093                 );
1094             } else if (o.elementType() == float.class) {
1095                 Float512Vector so = (Float512Vector)o;
1096                 return VectorIntrinsics.reinterpret(
1097                     Float512Vector.class, float.class, so.length(),
1098                     long.class, LENGTH, so,
1099                     (v, t) -> (Long512Vector)reshape(v)
1100                 );
1101             } else if (o.elementType() == double.class) {
1102                 Double512Vector so = (Double512Vector)o;
1103                 return VectorIntrinsics.reinterpret(
1104                     Double512Vector.class, double.class, so.length(),
1105                     long.class, LENGTH, so,
1106                     (v, t) -> (Long512Vector)reshape(v)
1107                 );
1108             } else {
1109                 throw new InternalError("Unimplemented size");
1110             }
1111         }
1112 
1113         @Override
1114         @ForceInline
1115         @SuppressWarnings("unchecked")
1116         public <T extends Shape> Long512Vector resize(Vector<Long, T> o) {
1117             Objects.requireNonNull(o);
1118             if (o.bitSize() == 64) {
1119                 Long64Vector so = (Long64Vector)o;
1120                 return VectorIntrinsics.reinterpret(
1121                     Long64Vector.class, long.class, so.length(),
1122                     long.class, LENGTH, so,
1123                     (v, t) -> (Long512Vector)reshape(v)
1124                 );
1125             } else if (o.bitSize() == 128) {
1126                 Long128Vector so = (Long128Vector)o;
1127                 return VectorIntrinsics.reinterpret(
1128                     Long128Vector.class, long.class, so.length(),
1129                     long.class, LENGTH, so,
1130                     (v, t) -> (Long512Vector)reshape(v)
1131                 );
1132             } else if (o.bitSize() == 256) {
1133                 Long256Vector so = (Long256Vector)o;
1134                 return VectorIntrinsics.reinterpret(
1135                     Long256Vector.class, long.class, so.length(),
1136                     long.class, LENGTH, so,
1137                     (v, t) -> (Long512Vector)reshape(v)
1138                 );
1139             } else if (o.bitSize() == 512) {
1140                 Long512Vector so = (Long512Vector)o;
1141                 return VectorIntrinsics.reinterpret(
1142                     Long512Vector.class, long.class, so.length(),
1143                     long.class, LENGTH, so,
1144                     (v, t) -> (Long512Vector)reshape(v)
1145                 );
1146             } else {
1147                 throw new InternalError("Unimplemented size");
1148             }
1149         }
1150     }
1151 }