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