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