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 mulAll() {
 440         return (long) VectorIntrinsics.reductionCoerced(
 441             VECTOR_OP_MUL, 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 andAll() {
 449         return (long) VectorIntrinsics.reductionCoerced(
 450             VECTOR_OP_AND, Long128Vector.class, long.class, LENGTH,
 451             this,
 452             v -> (long) v.rOp((long) -1, (i, a, b) -> (long) (a & b)));
 453     }
 454 
 455     // Memory operations
 456 
 457     @Override
 458     @ForceInline
 459     public void intoArray(long[] a, int ix) {
 460         Objects.requireNonNull(a);
 461         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 462         VectorIntrinsics.store(Long128Vector.class, long.class, LENGTH,
 463                                a, ix, this,
 464                                (arr, idx, v) -> v.forEach((i, a_) -> ((long[])arr)[idx + i] = a_));
 465     }
 466 
 467     @Override
 468     @ForceInline
 469     public void intoArray(long[] a, int ax, Mask<Long, Shapes.S128Bit> m) {
 470         // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_);
 471         Long128Vector oldVal = SPECIES.fromArray(a, ax);
 472         Long128Vector newVal = oldVal.blend(this, m);
 473         newVal.intoArray(a, ax);
 474     }
 475 
 476     //
 477 
 478     @Override
 479     public String toString() {
 480         return Arrays.toString(getElements());
 481     }
 482 
 483     @Override
 484     public boolean equals(Object o) {
 485         if (this == o) return true;
 486         if (o == null || this.getClass() != o.getClass()) return false;
 487 
 488         Long128Vector that = (Long128Vector) o;
 489         return Arrays.equals(this.getElements(), that.getElements());
 490     }
 491 
 492     @Override
 493     public int hashCode() {
 494         return Arrays.hashCode(vec);
 495     }
 496 
 497     // Binary test
 498 
 499     @Override
 500     Long128Mask bTest(Vector<Long, Shapes.S128Bit> o, FBinTest f) {
 501         long[] vec1 = getElements();
 502         long[] vec2 = ((Long128Vector)o).getElements();
 503         boolean[] bits = new boolean[length()];
 504         for (int i = 0; i < length(); i++){
 505             bits[i] = f.apply(i, vec1[i], vec2[i]);
 506         }
 507         return new Long128Mask(bits);
 508     }
 509 
 510     // Comparisons
 511 
 512     @Override
 513     @ForceInline
 514     public Long128Mask equal(Vector<Long, Shapes.S128Bit> o) {
 515         Objects.requireNonNull(o);
 516         Long128Vector v = (Long128Vector)o;
 517 
 518         return (Long128Mask) VectorIntrinsics.compare(
 519             BT_eq, Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 520             this, v,
 521             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
 522     }
 523 
 524     @Override
 525     @ForceInline
 526     public Long128Mask notEqual(Vector<Long, Shapes.S128Bit> o) {
 527         Objects.requireNonNull(o);
 528         Long128Vector v = (Long128Vector)o;
 529 
 530         return (Long128Mask) VectorIntrinsics.compare(
 531             BT_ne, Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 532             this, v,
 533             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
 534     }
 535 
 536     @Override
 537     @ForceInline
 538     public Long128Mask lessThan(Vector<Long, Shapes.S128Bit> o) {
 539         Objects.requireNonNull(o);
 540         Long128Vector v = (Long128Vector)o;
 541 
 542         return (Long128Mask) VectorIntrinsics.compare(
 543             BT_lt, Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 544             this, v,
 545             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
 546     }
 547 
 548     @Override
 549     @ForceInline
 550     public Long128Mask lessThanEq(Vector<Long, Shapes.S128Bit> o) {
 551         Objects.requireNonNull(o);
 552         Long128Vector v = (Long128Vector)o;
 553 
 554         return (Long128Mask) VectorIntrinsics.compare(
 555             BT_le, Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 556             this, v,
 557             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
 558     }
 559 
 560     @Override
 561     @ForceInline
 562     public Long128Mask greaterThan(Vector<Long, Shapes.S128Bit> o) {
 563         Objects.requireNonNull(o);
 564         Long128Vector v = (Long128Vector)o;
 565 
 566         return (Long128Mask) VectorIntrinsics.compare(
 567             BT_gt, Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 568             this, v,
 569             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
 570     }
 571 
 572     @Override
 573     @ForceInline
 574     public Long128Mask greaterThanEq(Vector<Long, Shapes.S128Bit> o) {
 575         Objects.requireNonNull(o);
 576         Long128Vector v = (Long128Vector)o;
 577 
 578         return (Long128Mask) VectorIntrinsics.compare(
 579             BT_ge, Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 580             this, v,
 581             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
 582     }
 583 
 584     // Foreach
 585 
 586     @Override
 587     void forEach(FUnCon f) {
 588         long[] vec = getElements();
 589         for (int i = 0; i < length(); i++) {
 590             f.apply(i, vec[i]);
 591         }
 592     }
 593 
 594     @Override
 595     void forEach(Mask<Long, Shapes.S128Bit> o, FUnCon f) {
 596         boolean[] mbits = ((Long128Mask)o).getBits();
 597         forEach((i, a) -> {
 598             if (mbits[i]) { f.apply(i, a); }
 599         });
 600     }
 601 
 602 
 603     Double128Vector toFP() {
 604         long[] vec = getElements();
 605         double[] res = new double[this.species().length()];
 606         for(int i = 0; i < this.species().length(); i++){
 607             res[i] = Double.longBitsToDouble(vec[i]);
 608         }
 609         return new Double128Vector(res);
 610     }
 611 
 612     @Override
 613     public Long128Vector rotateEL(int j) {
 614         long[] vec = getElements();
 615         long[] res = new long[length()];
 616         for (int i = 0; i < length(); i++){
 617             res[j + i % length()] = vec[i];
 618         }
 619         return new Long128Vector(res);
 620     }
 621 
 622     @Override
 623     public Long128Vector rotateER(int j) {
 624         long[] vec = getElements();
 625         long[] res = new long[length()];
 626         for (int i = 0; i < length(); i++){
 627             int z = i - j;
 628             if(j < 0) {
 629                 res[length() + z] = vec[i];
 630             } else {
 631                 res[z] = vec[i];
 632             }
 633         }
 634         return new Long128Vector(res);
 635     }
 636 
 637     @Override
 638     public Long128Vector shiftEL(int j) {
 639         long[] vec = getElements();
 640         long[] res = new long[length()];
 641         for (int i = 0; i < length() - j; i++) {
 642             res[i] = vec[i + j];
 643         }
 644         return new Long128Vector(res);
 645     }
 646 
 647     @Override
 648     public Long128Vector shiftER(int j) {
 649         long[] vec = getElements();
 650         long[] res = new long[length()];
 651         for (int i = 0; i < length() - j; i++){
 652             res[i + j] = vec[i];
 653         }
 654         return new Long128Vector(res);
 655     }
 656 
 657     @Override
 658     public Long128Vector shuffle(Vector<Long, Shapes.S128Bit> o, Shuffle<Long, Shapes.S128Bit> s) {
 659         Long128Vector v = (Long128Vector) o;
 660         return uOp((i, a) -> {
 661             long[] vec = this.getElements();
 662             int e = s.getElement(i);
 663             if(e >= 0 && e < length()) {
 664                 //from this
 665                 return vec[e];
 666             } else if(e < length() * 2) {
 667                 //from o
 668                 return v.getElements()[e - length()];
 669             } else {
 670                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 671             }
 672         });
 673     }
 674 
 675     @Override
 676     public Long128Vector swizzle(Shuffle<Long, Shapes.S128Bit> s) {
 677         return uOp((i, a) -> {
 678             long[] vec = this.getElements();
 679             int e = s.getElement(i);
 680             if(e >= 0 && e < length()) {
 681                 return vec[e];
 682             } else {
 683                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 684             }
 685         });
 686     }
 687 
 688     @Override
 689     @ForceInline
 690     public Long128Vector blend(Vector<Long, Shapes.S128Bit> o1, Mask<Long, Shapes.S128Bit> o2) {
 691         Objects.requireNonNull(o1);
 692         Objects.requireNonNull(o2);
 693         Long128Vector v = (Long128Vector)o1;
 694         Long128Mask   m = (Long128Mask)o2;
 695 
 696         return (Long128Vector) VectorIntrinsics.blend(
 697             Long128Vector.class, Long128Mask.class, long.class, LENGTH,
 698             this, v, m,
 699             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
 700     }
 701 
 702     @Override
 703     @ForceInline
 704     @SuppressWarnings("unchecked")
 705     public <F> Vector<F, Shapes.S128Bit> rebracket(Species<F, Shapes.S128Bit> species) {
 706         Objects.requireNonNull(species);
 707         // TODO: check proper element type
 708         // TODO: update to pass the two species as an arguments and ideally
 709         // push down intrinsic call into species implementation
 710         return VectorIntrinsics.reinterpret(
 711             Long128Vector.class, long.class, LENGTH,
 712             species.elementType(), species.length(), this,
 713             (v, t) -> species.reshape(v)
 714         );
 715     }
 716 
 717     // Accessors
 718 
 719     @Override
 720     public long get(int i) {
 721         long[] vec = getElements();
 722         return vec[i];
 723     }
 724 
 725     @Override
 726     public Long128Vector with(int i, long e) {
 727         long[] res = vec.clone();
 728         res[i] = e;
 729         return new Long128Vector(res);
 730     }
 731 
 732     // Mask
 733 
 734     static final class Long128Mask extends AbstractMask<Long, Shapes.S128Bit> {
 735         static final Long128Mask TRUE_MASK = new Long128Mask(true);
 736         static final Long128Mask FALSE_MASK = new Long128Mask(false);
 737 
 738         // FIXME: was temporarily put here to simplify rematerialization support in the JVM
 739         private final boolean[] bits; // Don't access directly, use getBits() instead.
 740 
 741         public Long128Mask(boolean[] bits) {
 742             this(bits, 0);
 743         }
 744 
 745         public Long128Mask(boolean[] bits, int i) {
 746             this.bits = Arrays.copyOfRange(bits, i, i + species().length());
 747         }
 748 
 749         public Long128Mask(boolean val) {
 750             boolean[] bits = new boolean[species().length()];
 751             Arrays.fill(bits, val);
 752             this.bits = bits;
 753         }
 754 
 755         boolean[] getBits() {
 756             return VectorIntrinsics.maybeRebox(this).bits;
 757         }
 758 
 759         @Override
 760         Long128Mask uOp(MUnOp f) {
 761             boolean[] res = new boolean[species().length()];
 762             boolean[] bits = getBits();
 763             for (int i = 0; i < species().length(); i++) {
 764                 res[i] = f.apply(i, bits[i]);
 765             }
 766             return new Long128Mask(res);
 767         }
 768 
 769         @Override
 770         Long128Mask bOp(Mask<Long, Shapes.S128Bit> o, MBinOp f) {
 771             boolean[] res = new boolean[species().length()];
 772             boolean[] bits = getBits();
 773             boolean[] mbits = ((Long128Mask)o).getBits();
 774             for (int i = 0; i < species().length(); i++) {
 775                 res[i] = f.apply(i, bits[i], mbits[i]);
 776             }
 777             return new Long128Mask(res);
 778         }
 779 
 780         @Override
 781         public Long128Species species() {
 782             return SPECIES;
 783         }
 784 
 785         @Override
 786         public Long128Vector toVector() {
 787             long[] res = new long[species().length()];
 788             boolean[] bits = getBits();
 789             for (int i = 0; i < species().length(); i++) {
 790                 res[i] = (long) (bits[i] ? -1 : 0);
 791             }
 792             return new Long128Vector(res);
 793         }
 794 
 795         @Override
 796         @ForceInline
 797         @SuppressWarnings("unchecked")
 798         public <Z> Mask<Z, Shapes.S128Bit> rebracket(Species<Z, Shapes.S128Bit> species) {
 799             Objects.requireNonNull(species);
 800             // TODO: check proper element type
 801             return VectorIntrinsics.reinterpret(
 802                 Long128Mask.class, long.class, LENGTH,
 803                 species.elementType(), species.length(), this,
 804                 (m, t) -> m.reshape(species)
 805             );
 806         }
 807 
 808         // Unary operations
 809 
 810         //Mask<E, S> not();
 811 
 812         // Binary operations
 813 
 814         @Override
 815         @ForceInline
 816         public Long128Mask and(Mask<Long,Shapes.S128Bit> o) {
 817             Objects.requireNonNull(o);
 818             Long128Mask m = (Long128Mask)o;
 819             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Long128Mask.class, long.class, LENGTH,
 820                                              this, m,
 821                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
 822         }
 823 
 824         @Override
 825         @ForceInline
 826         public Long128Mask or(Mask<Long,Shapes.S128Bit> o) {
 827             Objects.requireNonNull(o);
 828             Long128Mask m = (Long128Mask)o;
 829             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Long128Mask.class, long.class, LENGTH,
 830                                              this, m,
 831                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
 832         }
 833 
 834         // Reductions
 835 
 836         @Override
 837         @ForceInline
 838         public boolean anyTrue() {
 839             return VectorIntrinsics.test(COND_notZero, Long128Mask.class, long.class, LENGTH,
 840                                          this, this,
 841                                          (m1, m2) -> super.anyTrue());
 842         }
 843 
 844         @Override
 845         @ForceInline
 846         public boolean allTrue() {
 847             return VectorIntrinsics.test(COND_carrySet, Long128Mask.class, long.class, LENGTH,
 848                                          this, species().maskAllTrue(),
 849                                          (m1, m2) -> super.allTrue());
 850         }
 851     }
 852 
 853     // Shuffle
 854 
 855     static final class Long128Shuffle extends AbstractShuffle<Long, Shapes.S128Bit> {
 856         static final IntVector.IntSpecies<Shapes.S128Bit> INT_SPECIES = (IntVector.IntSpecies<Shapes.S128Bit>) Vector.speciesInstance(Integer.class, Shapes.S_128_BIT);
 857 
 858         public Long128Shuffle(int[] reorder) {
 859             super(reorder);
 860         }
 861 
 862         public Long128Shuffle(int[] reorder, int i) {
 863             super(reorder, i);
 864         }
 865 
 866         @Override
 867         public Long128Species species() {
 868             return SPECIES;
 869         }
 870 
 871         @Override
 872         public IntVector.IntSpecies<Shapes.S128Bit> intSpecies() {
 873             return INT_SPECIES;
 874         }
 875     }
 876 
 877     // Species
 878 
 879     @Override
 880     public Long128Species species() {
 881         return SPECIES;
 882     }
 883 
 884     static final class Long128Species extends LongSpecies<Shapes.S128Bit> {
 885         static final int BIT_SIZE = Shapes.S_128_BIT.bitSize();
 886 
 887         static final int LENGTH = BIT_SIZE / Long.SIZE;
 888 
 889         @Override
 890         public String toString() {
 891            StringBuilder sb = new StringBuilder("Shape[");
 892            sb.append(bitSize()).append(" bits, ");
 893            sb.append(length()).append(" ").append(long.class.getSimpleName()).append("s x ");
 894            sb.append(elementSize()).append(" bits");
 895            sb.append("]");
 896            return sb.toString();
 897         }
 898 
 899         @Override
 900         @ForceInline
 901         public int bitSize() {
 902             return BIT_SIZE;
 903         }
 904 
 905         @Override
 906         @ForceInline
 907         public int length() {
 908             return LENGTH;
 909         }
 910 
 911         @Override
 912         @ForceInline
 913         public Class<Long> elementType() {
 914             return Long.class;
 915         }
 916 
 917         @Override
 918         @ForceInline
 919         public int elementSize() {
 920             return Long.SIZE;
 921         }
 922 
 923         @Override
 924         @ForceInline
 925         public Shapes.S128Bit shape() {
 926             return Shapes.S_128_BIT;
 927         }
 928 
 929         @Override
 930         Long128Vector op(FOp f) {
 931             long[] res = new long[length()];
 932             for (int i = 0; i < length(); i++) {
 933                 res[i] = f.apply(i);
 934             }
 935             return new Long128Vector(res);
 936         }
 937 
 938         @Override
 939         Long128Vector op(Mask<Long, Shapes.S128Bit> o, FOp f) {
 940             long[] res = new long[length()];
 941             boolean[] mbits = ((Long128Mask)o).getBits();
 942             for (int i = 0; i < length(); i++) {
 943                 if (mbits[i]) {
 944                     res[i] = f.apply(i);
 945                 }
 946             }
 947             return new Long128Vector(res);
 948         }
 949 
 950         // Factories
 951 
 952         @Override
 953         public Long128Mask maskFromValues(boolean... bits) {
 954             return new Long128Mask(bits);
 955         }
 956 
 957         @Override
 958         public Long128Mask maskFromArray(boolean[] bits, int i) {
 959             return new Long128Mask(bits, i);
 960         }
 961 
 962         @Override
 963         public Long128Shuffle shuffleFromValues(int... ixs) {
 964             return new Long128Shuffle(ixs);
 965         }
 966 
 967         @Override
 968         public Long128Shuffle shuffleFromArray(int[] ixs, int i) {
 969             return new Long128Shuffle(ixs, i);
 970         }
 971 
 972         @Override
 973         @ForceInline
 974         public Long128Vector zero() {
 975             return VectorIntrinsics.broadcastCoerced(Long128Vector.class, long.class, LENGTH,
 976                                                      0,
 977                                                      (z -> ZERO));
 978         }
 979 
 980         @Override
 981         @ForceInline
 982         public Long128Vector broadcast(long e) {
 983             return VectorIntrinsics.broadcastCoerced(
 984                 Long128Vector.class, long.class, LENGTH,
 985                 e,
 986                 ((long bits) -> SPECIES.op(i -> (long)bits)));
 987         }
 988 
 989         @Override
 990         @ForceInline
 991         public Long128Mask maskAllTrue() {
 992             return VectorIntrinsics.broadcastCoerced(Long128Mask.class, long.class, LENGTH,
 993                                                      (long)-1,
 994                                                      (z -> Long128Mask.TRUE_MASK));
 995         }
 996 
 997         @Override
 998         @ForceInline
 999         public Long128Mask maskAllFalse() {
1000             return VectorIntrinsics.broadcastCoerced(Long128Mask.class, long.class, LENGTH,
1001                                                      0,
1002                                                      (z -> Long128Mask.FALSE_MASK));
1003         }
1004 
1005         @Override
1006         @ForceInline
1007         public Long128Vector fromArray(long[] a, int ix) {
1008             Objects.requireNonNull(a);
1009             ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
1010             return (Long128Vector) VectorIntrinsics.load(Long128Vector.class, long.class, LENGTH,
1011                                                         a, ix,
1012                                                         (arr, idx) -> super.fromArray((long[]) arr, idx));
1013         }
1014 
1015         @Override
1016         @ForceInline
1017         public Long128Vector fromArray(long[] a, int ax, Mask<Long, Shapes.S128Bit> m) {
1018             return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]);
1019         }
1020 
1021         @Override
1022         @ForceInline
1023         @SuppressWarnings("unchecked")
1024         public <T extends Shape> Long128Vector resize(Vector<Long, T> o) {
1025             Objects.requireNonNull(o);
1026             if (o.bitSize() == 64) {
1027                 Long64Vector so = (Long64Vector)o;
1028                 return VectorIntrinsics.reinterpret(
1029                     Long64Vector.class, long.class, so.length(),
1030                     Long.class, LENGTH, so,
1031                     (v, t) -> (Long128Vector)reshape(v)
1032                 );
1033             } else if (o.bitSize() == 128) {
1034                 Long128Vector so = (Long128Vector)o;
1035                 return VectorIntrinsics.reinterpret(
1036                     Long128Vector.class, long.class, so.length(),
1037                     Long.class, LENGTH, so,
1038                     (v, t) -> (Long128Vector)reshape(v)
1039                 );
1040             } else if (o.bitSize() == 256) {
1041                 Long256Vector so = (Long256Vector)o;
1042                 return VectorIntrinsics.reinterpret(
1043                     Long256Vector.class, long.class, so.length(),
1044                     Long.class, LENGTH, so,
1045                     (v, t) -> (Long128Vector)reshape(v)
1046                 );
1047             } else if (o.bitSize() == 512) {
1048                 Long512Vector so = (Long512Vector)o;
1049                 return VectorIntrinsics.reinterpret(
1050                     Long512Vector.class, long.class, so.length(),
1051                     Long.class, LENGTH, so,
1052                     (v, t) -> (Long128Vector)reshape(v)
1053                 );
1054             } else {
1055                 throw new InternalError("Unimplemented size");
1056             }
1057         }
1058     }
1059 }