1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.ByteOrder;
  29 import java.nio.IntBuffer;
  30 import java.nio.ReadOnlyBufferException;
  31 import java.util.Arrays;
  32 import java.util.Objects;
  33 import java.util.function.IntUnaryOperator;
  34 
  35 import jdk.internal.misc.Unsafe;
  36 import jdk.internal.vm.annotation.ForceInline;
  37 import static jdk.incubator.vector.VectorIntrinsics.*;
  38 
  39 @SuppressWarnings("cast")
  40 final class Int128Vector extends IntVector {
  41     private static final VectorSpecies<Integer> SPECIES = IntVector.SPECIES_128;
  42 
  43     static final Int128Vector ZERO = new Int128Vector();
  44 
  45     static final int LENGTH = SPECIES.length();
  46 
  47     // Index vector species
  48     private static final IntVector.IntSpecies INDEX_SPECIES;
  49 
  50     static {
  51         int bitSize = Vector.bitSizeForVectorLength(int.class, LENGTH);
  52         INDEX_SPECIES = (IntVector.IntSpecies) IntVector.species(VectorShape.forBitSize(bitSize));
  53     }
  54 
  55     private final int[] vec; // Don't access directly, use getElements() instead.
  56 
  57     private int[] getElements() {
  58         return VectorIntrinsics.maybeRebox(this).vec;
  59     }
  60 
  61     Int128Vector() {
  62         vec = new int[SPECIES.length()];
  63     }
  64 
  65     Int128Vector(int[] v) {
  66         vec = v;
  67     }
  68 
  69     @Override
  70     public int length() { return LENGTH; }
  71 
  72     // Unary operator
  73 
  74     @Override
  75     Int128Vector uOp(FUnOp f) {
  76         int[] vec = getElements();
  77         int[] res = new int[length()];
  78         for (int i = 0; i < length(); i++) {
  79             res[i] = f.apply(i, vec[i]);
  80         }
  81         return new Int128Vector(res);
  82     }
  83 
  84     @Override
  85     Int128Vector uOp(VectorMask<Integer> o, FUnOp f) {
  86         int[] vec = getElements();
  87         int[] res = new int[length()];
  88         boolean[] mbits = ((Int128Mask)o).getBits();
  89         for (int i = 0; i < length(); i++) {
  90             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  91         }
  92         return new Int128Vector(res);
  93     }
  94 
  95     // Binary operator
  96 
  97     @Override
  98     Int128Vector bOp(Vector<Integer> o, FBinOp f) {
  99         int[] res = new int[length()];
 100         int[] vec1 = this.getElements();
 101         int[] vec2 = ((Int128Vector)o).getElements();
 102         for (int i = 0; i < length(); i++) {
 103             res[i] = f.apply(i, vec1[i], vec2[i]);
 104         }
 105         return new Int128Vector(res);
 106     }
 107 
 108     @Override
 109     Int128Vector bOp(Vector<Integer> o1, VectorMask<Integer> o2, FBinOp f) {
 110         int[] res = new int[length()];
 111         int[] vec1 = this.getElements();
 112         int[] vec2 = ((Int128Vector)o1).getElements();
 113         boolean[] mbits = ((Int128Mask)o2).getBits();
 114         for (int i = 0; i < length(); i++) {
 115             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 116         }
 117         return new Int128Vector(res);
 118     }
 119 
 120     // Trinary operator
 121 
 122     @Override
 123     Int128Vector tOp(Vector<Integer> o1, Vector<Integer> o2, FTriOp f) {
 124         int[] res = new int[length()];
 125         int[] vec1 = this.getElements();
 126         int[] vec2 = ((Int128Vector)o1).getElements();
 127         int[] vec3 = ((Int128Vector)o2).getElements();
 128         for (int i = 0; i < length(); i++) {
 129             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 130         }
 131         return new Int128Vector(res);
 132     }
 133 
 134     @Override
 135     Int128Vector tOp(Vector<Integer> o1, Vector<Integer> o2, VectorMask<Integer> o3, FTriOp f) {
 136         int[] res = new int[length()];
 137         int[] vec1 = getElements();
 138         int[] vec2 = ((Int128Vector)o1).getElements();
 139         int[] vec3 = ((Int128Vector)o2).getElements();
 140         boolean[] mbits = ((Int128Mask)o3).getBits();
 141         for (int i = 0; i < length(); i++) {
 142             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 143         }
 144         return new Int128Vector(res);
 145     }
 146 
 147     @Override
 148     int rOp(int v, FBinOp f) {
 149         int[] vec = getElements();
 150         for (int i = 0; i < length(); i++) {
 151             v = f.apply(i, v, vec[i]);
 152         }
 153         return v;
 154     }
 155 
 156     @Override
 157     @ForceInline
 158     public <F> Vector<F> cast(VectorSpecies<F> s) {
 159         Objects.requireNonNull(s);
 160         if (s.length() != LENGTH)
 161             throw new IllegalArgumentException("Vector length this species length differ");
 162 
 163         return VectorIntrinsics.cast(
 164             Int128Vector.class,
 165             int.class, LENGTH,
 166             s.vectorType(),
 167             s.elementType(), LENGTH,
 168             this, s,
 169             (species, vector) -> vector.castDefault(species)
 170         );
 171     }
 172 
 173     @SuppressWarnings("unchecked")
 174     @ForceInline
 175     private <F> Vector<F> castDefault(VectorSpecies<F> s) {
 176         int limit = s.length();
 177 
 178         Class<?> stype = s.elementType();
 179         if (stype == byte.class) {
 180             byte[] a = new byte[limit];
 181             for (int i = 0; i < limit; i++) {
 182                 a[i] = (byte) this.lane(i);
 183             }
 184             return (Vector) ByteVector.fromArray((VectorSpecies<Byte>) s, a, 0);
 185         } else if (stype == short.class) {
 186             short[] a = new short[limit];
 187             for (int i = 0; i < limit; i++) {
 188                 a[i] = (short) this.lane(i);
 189             }
 190             return (Vector) ShortVector.fromArray((VectorSpecies<Short>) s, a, 0);
 191         } else if (stype == int.class) {
 192             int[] a = new int[limit];
 193             for (int i = 0; i < limit; i++) {
 194                 a[i] = (int) this.lane(i);
 195             }
 196             return (Vector) IntVector.fromArray((VectorSpecies<Integer>) s, a, 0);
 197         } else if (stype == long.class) {
 198             long[] a = new long[limit];
 199             for (int i = 0; i < limit; i++) {
 200                 a[i] = (long) this.lane(i);
 201             }
 202             return (Vector) LongVector.fromArray((VectorSpecies<Long>) s, a, 0);
 203         } else if (stype == float.class) {
 204             float[] a = new float[limit];
 205             for (int i = 0; i < limit; i++) {
 206                 a[i] = (float) this.lane(i);
 207             }
 208             return (Vector) FloatVector.fromArray((VectorSpecies<Float>) s, a, 0);
 209         } else if (stype == double.class) {
 210             double[] a = new double[limit];
 211             for (int i = 0; i < limit; i++) {
 212                 a[i] = (double) this.lane(i);
 213             }
 214             return (Vector) DoubleVector.fromArray((VectorSpecies<Double>) s, a, 0);
 215         } else {
 216             throw new UnsupportedOperationException("Bad lane type for casting.");
 217         }
 218     }
 219 
 220     @Override
 221     @ForceInline
 222     @SuppressWarnings("unchecked")
 223     public <F> Vector<F> reinterpret(VectorSpecies<F> s) {
 224         Objects.requireNonNull(s);
 225 
 226         if(s.elementType().equals(int.class)) {
 227             return (Vector<F>) reshape((VectorSpecies<Integer>)s);
 228         }
 229         if(s.bitSize() == bitSize()) {
 230             return reinterpretType(s);
 231         }
 232 
 233         return defaultReinterpret(s);
 234     }
 235 
 236     @ForceInline
 237     private <F> Vector<F> reinterpretType(VectorSpecies<F> s) {
 238         Objects.requireNonNull(s);
 239 
 240         Class<?> stype = s.elementType();
 241         if (stype == byte.class) {
 242             return VectorIntrinsics.reinterpret(
 243                 Int128Vector.class,
 244                 int.class, LENGTH,
 245                 Byte128Vector.class,
 246                 byte.class, Byte128Vector.LENGTH,
 247                 this, s,
 248                 (species, vector) -> vector.defaultReinterpret(species)
 249             );
 250         } else if (stype == short.class) {
 251             return VectorIntrinsics.reinterpret(
 252                 Int128Vector.class,
 253                 int.class, LENGTH,
 254                 Short128Vector.class,
 255                 short.class, Short128Vector.LENGTH,
 256                 this, s,
 257                 (species, vector) -> vector.defaultReinterpret(species)
 258             );
 259         } else if (stype == int.class) {
 260             return VectorIntrinsics.reinterpret(
 261                 Int128Vector.class,
 262                 int.class, LENGTH,
 263                 Int128Vector.class,
 264                 int.class, Int128Vector.LENGTH,
 265                 this, s,
 266                 (species, vector) -> vector.defaultReinterpret(species)
 267             );
 268         } else if (stype == long.class) {
 269             return VectorIntrinsics.reinterpret(
 270                 Int128Vector.class,
 271                 int.class, LENGTH,
 272                 Long128Vector.class,
 273                 long.class, Long128Vector.LENGTH,
 274                 this, s,
 275                 (species, vector) -> vector.defaultReinterpret(species)
 276             );
 277         } else if (stype == float.class) {
 278             return VectorIntrinsics.reinterpret(
 279                 Int128Vector.class,
 280                 int.class, LENGTH,
 281                 Float128Vector.class,
 282                 float.class, Float128Vector.LENGTH,
 283                 this, s,
 284                 (species, vector) -> vector.defaultReinterpret(species)
 285             );
 286         } else if (stype == double.class) {
 287             return VectorIntrinsics.reinterpret(
 288                 Int128Vector.class,
 289                 int.class, LENGTH,
 290                 Double128Vector.class,
 291                 double.class, Double128Vector.LENGTH,
 292                 this, s,
 293                 (species, vector) -> vector.defaultReinterpret(species)
 294             );
 295         } else {
 296             throw new UnsupportedOperationException("Bad lane type for casting.");
 297         }
 298     }
 299 
 300     @Override
 301     @ForceInline
 302     public IntVector reshape(VectorSpecies<Integer> s) {
 303         Objects.requireNonNull(s);
 304         if (s.bitSize() == 64 && (s.vectorType() == Int64Vector.class)) {
 305             return VectorIntrinsics.reinterpret(
 306                 Int128Vector.class,
 307                 int.class, LENGTH,
 308                 Int64Vector.class,
 309                 int.class, Int64Vector.LENGTH,
 310                 this, s,
 311                 (species, vector) -> (IntVector) vector.defaultReinterpret(species)
 312             );
 313         } else if (s.bitSize() == 128 && (s.vectorType() == Int128Vector.class)) {
 314             return VectorIntrinsics.reinterpret(
 315                 Int128Vector.class,
 316                 int.class, LENGTH,
 317                 Int128Vector.class,
 318                 int.class, Int128Vector.LENGTH,
 319                 this, s,
 320                 (species, vector) -> (IntVector) vector.defaultReinterpret(species)
 321             );
 322         } else if (s.bitSize() == 256 && (s.vectorType() == Int256Vector.class)) {
 323             return VectorIntrinsics.reinterpret(
 324                 Int128Vector.class,
 325                 int.class, LENGTH,
 326                 Int256Vector.class,
 327                 int.class, Int256Vector.LENGTH,
 328                 this, s,
 329                 (species, vector) -> (IntVector) vector.defaultReinterpret(species)
 330             );
 331         } else if (s.bitSize() == 512 && (s.vectorType() == Int512Vector.class)) {
 332             return VectorIntrinsics.reinterpret(
 333                 Int128Vector.class,
 334                 int.class, LENGTH,
 335                 Int512Vector.class,
 336                 int.class, Int512Vector.LENGTH,
 337                 this, s,
 338                 (species, vector) -> (IntVector) vector.defaultReinterpret(species)
 339             );
 340         } else if ((s.bitSize() > 0) && (s.bitSize() <= 2048)
 341                 && (s.bitSize() % 128 == 0) && (s.vectorType() == IntMaxVector.class)) {
 342             return VectorIntrinsics.reinterpret(
 343                 Int128Vector.class,
 344                 int.class, LENGTH,
 345                 IntMaxVector.class,
 346                 int.class, IntMaxVector.LENGTH,
 347                 this, s,
 348                 (species, vector) -> (IntVector) vector.defaultReinterpret(species)
 349             );
 350         } else {
 351             throw new InternalError("Unimplemented size");
 352         }
 353     }
 354 
 355     // Binary operations with scalars
 356 
 357     @Override
 358     @ForceInline
 359     public IntVector add(int o) {
 360         return add((Int128Vector)IntVector.broadcast(SPECIES, o));
 361     }
 362 
 363     @Override
 364     @ForceInline
 365     public IntVector add(int o, VectorMask<Integer> m) {
 366         return add((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 367     }
 368 
 369     @Override
 370     @ForceInline
 371     public IntVector sub(int o) {
 372         return sub((Int128Vector)IntVector.broadcast(SPECIES, o));
 373     }
 374 
 375     @Override
 376     @ForceInline
 377     public IntVector sub(int o, VectorMask<Integer> m) {
 378         return sub((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 379     }
 380 
 381     @Override
 382     @ForceInline
 383     public IntVector mul(int o) {
 384         return mul((Int128Vector)IntVector.broadcast(SPECIES, o));
 385     }
 386 
 387     @Override
 388     @ForceInline
 389     public IntVector mul(int o, VectorMask<Integer> m) {
 390         return mul((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 391     }
 392 
 393     @Override
 394     @ForceInline
 395     public IntVector min(int o) {
 396         return min((Int128Vector)IntVector.broadcast(SPECIES, o));
 397     }
 398 
 399     @Override
 400     @ForceInline
 401     public IntVector max(int o) {
 402         return max((Int128Vector)IntVector.broadcast(SPECIES, o));
 403     }
 404 
 405     @Override
 406     @ForceInline
 407     public VectorMask<Integer> equal(int o) {
 408         return equal((Int128Vector)IntVector.broadcast(SPECIES, o));
 409     }
 410 
 411     @Override
 412     @ForceInline
 413     public VectorMask<Integer> notEqual(int o) {
 414         return notEqual((Int128Vector)IntVector.broadcast(SPECIES, o));
 415     }
 416 
 417     @Override
 418     @ForceInline
 419     public VectorMask<Integer> lessThan(int o) {
 420         return lessThan((Int128Vector)IntVector.broadcast(SPECIES, o));
 421     }
 422 
 423     @Override
 424     @ForceInline
 425     public VectorMask<Integer> lessThanEq(int o) {
 426         return lessThanEq((Int128Vector)IntVector.broadcast(SPECIES, o));
 427     }
 428 
 429     @Override
 430     @ForceInline
 431     public VectorMask<Integer> greaterThan(int o) {
 432         return greaterThan((Int128Vector)IntVector.broadcast(SPECIES, o));
 433     }
 434 
 435     @Override
 436     @ForceInline
 437     public VectorMask<Integer> greaterThanEq(int o) {
 438         return greaterThanEq((Int128Vector)IntVector.broadcast(SPECIES, o));
 439     }
 440 
 441     @Override
 442     @ForceInline
 443     public IntVector blend(int o, VectorMask<Integer> m) {
 444         return blend((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 445     }
 446 
 447 
 448     @Override
 449     @ForceInline
 450     public IntVector and(int o) {
 451         return and((Int128Vector)IntVector.broadcast(SPECIES, o));
 452     }
 453 
 454     @Override
 455     @ForceInline
 456     public IntVector and(int o, VectorMask<Integer> m) {
 457         return and((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 458     }
 459 
 460     @Override
 461     @ForceInline
 462     public IntVector or(int o) {
 463         return or((Int128Vector)IntVector.broadcast(SPECIES, o));
 464     }
 465 
 466     @Override
 467     @ForceInline
 468     public IntVector or(int o, VectorMask<Integer> m) {
 469         return or((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 470     }
 471 
 472     @Override
 473     @ForceInline
 474     public IntVector xor(int o) {
 475         return xor((Int128Vector)IntVector.broadcast(SPECIES, o));
 476     }
 477 
 478     @Override
 479     @ForceInline
 480     public IntVector xor(int o, VectorMask<Integer> m) {
 481         return xor((Int128Vector)IntVector.broadcast(SPECIES, o), m);
 482     }
 483 
 484     @Override
 485     @ForceInline
 486     public Int128Vector neg() {
 487         return (Int128Vector)zero(SPECIES).sub(this);
 488     }
 489 
 490     // Unary operations
 491 
 492     @ForceInline
 493     @Override
 494     public Int128Vector neg(VectorMask<Integer> m) {
 495         return blend(neg(), m);
 496     }
 497 
 498     @Override
 499     @ForceInline
 500     public Int128Vector abs() {
 501         return VectorIntrinsics.unaryOp(
 502             VECTOR_OP_ABS, Int128Vector.class, int.class, LENGTH,
 503             this,
 504             v1 -> v1.uOp((i, a) -> (int) Math.abs(a)));
 505     }
 506 
 507     @ForceInline
 508     @Override
 509     public Int128Vector abs(VectorMask<Integer> m) {
 510         return blend(abs(), m);
 511     }
 512 
 513 
 514     @Override
 515     @ForceInline
 516     public Int128Vector not() {
 517         return VectorIntrinsics.unaryOp(
 518             VECTOR_OP_NOT, Int128Vector.class, int.class, LENGTH,
 519             this,
 520             v1 -> v1.uOp((i, a) -> (int) ~a));
 521     }
 522 
 523     @ForceInline
 524     @Override
 525     public Int128Vector not(VectorMask<Integer> m) {
 526         return blend(not(), m);
 527     }
 528     // Binary operations
 529 
 530     @Override
 531     @ForceInline
 532     public Int128Vector add(Vector<Integer> o) {
 533         Objects.requireNonNull(o);
 534         Int128Vector v = (Int128Vector)o;
 535         return VectorIntrinsics.binaryOp(
 536             VECTOR_OP_ADD, Int128Vector.class, int.class, LENGTH,
 537             this, v,
 538             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int)(a + b)));
 539     }
 540 
 541     @Override
 542     @ForceInline
 543     public Int128Vector add(Vector<Integer> v, VectorMask<Integer> m) {
 544         return blend(add(v), m);
 545     }
 546 
 547     @Override
 548     @ForceInline
 549     public Int128Vector sub(Vector<Integer> o) {
 550         Objects.requireNonNull(o);
 551         Int128Vector v = (Int128Vector)o;
 552         return VectorIntrinsics.binaryOp(
 553             VECTOR_OP_SUB, Int128Vector.class, int.class, LENGTH,
 554             this, v,
 555             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int)(a - b)));
 556     }
 557 
 558     @Override
 559     @ForceInline
 560     public Int128Vector sub(Vector<Integer> v, VectorMask<Integer> m) {
 561         return blend(sub(v), m);
 562     }
 563 
 564     @Override
 565     @ForceInline
 566     public Int128Vector mul(Vector<Integer> o) {
 567         Objects.requireNonNull(o);
 568         Int128Vector v = (Int128Vector)o;
 569         return VectorIntrinsics.binaryOp(
 570             VECTOR_OP_MUL, Int128Vector.class, int.class, LENGTH,
 571             this, v,
 572             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int)(a * b)));
 573     }
 574 
 575     @Override
 576     @ForceInline
 577     public Int128Vector mul(Vector<Integer> v, VectorMask<Integer> m) {
 578         return blend(mul(v), m);
 579     }
 580 
 581     @Override
 582     @ForceInline
 583     public Int128Vector min(Vector<Integer> o) {
 584         Objects.requireNonNull(o);
 585         Int128Vector v = (Int128Vector)o;
 586         return (Int128Vector) VectorIntrinsics.binaryOp(
 587             VECTOR_OP_MIN, Int128Vector.class, int.class, LENGTH,
 588             this, v,
 589             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int) Math.min(a, b)));
 590     }
 591 
 592     @Override
 593     @ForceInline
 594     public Int128Vector min(Vector<Integer> v, VectorMask<Integer> m) {
 595         return blend(min(v), m);
 596     }
 597 
 598     @Override
 599     @ForceInline
 600     public Int128Vector max(Vector<Integer> o) {
 601         Objects.requireNonNull(o);
 602         Int128Vector v = (Int128Vector)o;
 603         return VectorIntrinsics.binaryOp(
 604             VECTOR_OP_MAX, Int128Vector.class, int.class, LENGTH,
 605             this, v,
 606             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int) Math.max(a, b)));
 607         }
 608 
 609     @Override
 610     @ForceInline
 611     public Int128Vector max(Vector<Integer> v, VectorMask<Integer> m) {
 612         return blend(max(v), m);
 613     }
 614 
 615     @Override
 616     @ForceInline
 617     public Int128Vector and(Vector<Integer> o) {
 618         Objects.requireNonNull(o);
 619         Int128Vector v = (Int128Vector)o;
 620         return VectorIntrinsics.binaryOp(
 621             VECTOR_OP_AND, Int128Vector.class, int.class, LENGTH,
 622             this, v,
 623             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int)(a & b)));
 624     }
 625 
 626     @Override
 627     @ForceInline
 628     public Int128Vector or(Vector<Integer> o) {
 629         Objects.requireNonNull(o);
 630         Int128Vector v = (Int128Vector)o;
 631         return VectorIntrinsics.binaryOp(
 632             VECTOR_OP_OR, Int128Vector.class, int.class, LENGTH,
 633             this, v,
 634             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int)(a | b)));
 635     }
 636 
 637     @Override
 638     @ForceInline
 639     public Int128Vector xor(Vector<Integer> o) {
 640         Objects.requireNonNull(o);
 641         Int128Vector v = (Int128Vector)o;
 642         return VectorIntrinsics.binaryOp(
 643             VECTOR_OP_XOR, Int128Vector.class, int.class, LENGTH,
 644             this, v,
 645             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (int)(a ^ b)));
 646     }
 647 
 648     @Override
 649     @ForceInline
 650     public Int128Vector and(Vector<Integer> v, VectorMask<Integer> m) {
 651         return blend(and(v), m);
 652     }
 653 
 654     @Override
 655     @ForceInline
 656     public Int128Vector or(Vector<Integer> v, VectorMask<Integer> m) {
 657         return blend(or(v), m);
 658     }
 659 
 660     @Override
 661     @ForceInline
 662     public Int128Vector xor(Vector<Integer> v, VectorMask<Integer> m) {
 663         return blend(xor(v), m);
 664     }
 665 
 666     @Override
 667     @ForceInline
 668     public Int128Vector shiftLeft(int s) {
 669         return VectorIntrinsics.broadcastInt(
 670             VECTOR_OP_LSHIFT, Int128Vector.class, int.class, LENGTH,
 671             this, s,
 672             (v, i) -> v.uOp((__, a) -> (int) (a << i)));
 673     }
 674 
 675     @Override
 676     @ForceInline
 677     public Int128Vector shiftLeft(int s, VectorMask<Integer> m) {
 678         return blend(shiftLeft(s), m);
 679     }
 680 
 681     @Override
 682     @ForceInline
 683     public Int128Vector shiftRight(int s) {
 684         return VectorIntrinsics.broadcastInt(
 685             VECTOR_OP_URSHIFT, Int128Vector.class, int.class, LENGTH,
 686             this, s,
 687             (v, i) -> v.uOp((__, a) -> (int) (a >>> i)));
 688     }
 689 
 690     @Override
 691     @ForceInline
 692     public Int128Vector shiftRight(int s, VectorMask<Integer> m) {
 693         return blend(shiftRight(s), m);
 694     }
 695 
 696     @Override
 697     @ForceInline
 698     public Int128Vector shiftArithmeticRight(int s) {
 699         return VectorIntrinsics.broadcastInt(
 700             VECTOR_OP_RSHIFT, Int128Vector.class, int.class, LENGTH,
 701             this, s,
 702             (v, i) -> v.uOp((__, a) -> (int) (a >> i)));
 703     }
 704 
 705     @Override
 706     @ForceInline
 707     public Int128Vector shiftArithmeticRight(int s, VectorMask<Integer> m) {
 708         return blend(shiftArithmeticRight(s), m);
 709     }
 710 
 711     @Override
 712     @ForceInline
 713     public Int128Vector shiftLeft(Vector<Integer> s) {
 714         Int128Vector shiftv = (Int128Vector)s;
 715         // As per shift specification for Java, mask the shift count.
 716         shiftv = shiftv.and(IntVector.broadcast(SPECIES, 0x1f));
 717         return VectorIntrinsics.binaryOp(
 718             VECTOR_OP_LSHIFT, Int128Vector.class, int.class, LENGTH,
 719             this, shiftv,
 720             (v1, v2) -> v1.bOp(v2,(i,a, b) -> (int) (a << b)));
 721     }
 722 
 723     @Override
 724     @ForceInline
 725     public Int128Vector shiftRight(Vector<Integer> s) {
 726         Int128Vector shiftv = (Int128Vector)s;
 727         // As per shift specification for Java, mask the shift count.
 728         shiftv = shiftv.and(IntVector.broadcast(SPECIES, 0x1f));
 729         return VectorIntrinsics.binaryOp(
 730             VECTOR_OP_URSHIFT, Int128Vector.class, int.class, LENGTH,
 731             this, shiftv,
 732             (v1, v2) -> v1.bOp(v2,(i,a, b) -> (int) (a >>> b)));
 733     }
 734 
 735     @Override
 736     @ForceInline
 737     public Int128Vector shiftArithmeticRight(Vector<Integer> s) {
 738         Int128Vector shiftv = (Int128Vector)s;
 739         // As per shift specification for Java, mask the shift count.
 740         shiftv = shiftv.and(IntVector.broadcast(SPECIES, 0x1f));
 741         return VectorIntrinsics.binaryOp(
 742             VECTOR_OP_RSHIFT, Int128Vector.class, int.class, LENGTH,
 743             this, shiftv,
 744             (v1, v2) -> v1.bOp(v2,(i,a, b) -> (int) (a >> b)));
 745     }
 746     // Ternary operations
 747 
 748 
 749     // Type specific horizontal reductions
 750 
 751     @Override
 752     @ForceInline
 753     public int addLanes() {
 754         return (int) VectorIntrinsics.reductionCoerced(
 755             VECTOR_OP_ADD, Int128Vector.class, int.class, LENGTH,
 756             this,
 757             v -> (long) v.rOp((int) 0, (i, a, b) -> (int) (a + b)));
 758     }
 759 
 760     @Override
 761     @ForceInline
 762     public int andLanes() {
 763         return (int) VectorIntrinsics.reductionCoerced(
 764             VECTOR_OP_AND, Int128Vector.class, int.class, LENGTH,
 765             this,
 766             v -> (long) v.rOp((int) -1, (i, a, b) -> (int) (a & b)));
 767     }
 768 
 769     @Override
 770     @ForceInline
 771     public int andLanes(VectorMask<Integer> m) {
 772         return IntVector.broadcast(SPECIES, (int) -1).blend(this, m).andLanes();
 773     }
 774 
 775     @Override
 776     @ForceInline
 777     public int minLanes() {
 778         return (int) VectorIntrinsics.reductionCoerced(
 779             VECTOR_OP_MIN, Int128Vector.class, int.class, LENGTH,
 780             this,
 781             v -> (long) v.rOp(Integer.MAX_VALUE , (i, a, b) -> (int) Math.min(a, b)));
 782     }
 783 
 784     @Override
 785     @ForceInline
 786     public int maxLanes() {
 787         return (int) VectorIntrinsics.reductionCoerced(
 788             VECTOR_OP_MAX, Int128Vector.class, int.class, LENGTH,
 789             this,
 790             v -> (long) v.rOp(Integer.MIN_VALUE , (i, a, b) -> (int) Math.max(a, b)));
 791     }
 792 
 793     @Override
 794     @ForceInline
 795     public int mulLanes() {
 796         return (int) VectorIntrinsics.reductionCoerced(
 797             VECTOR_OP_MUL, Int128Vector.class, int.class, LENGTH,
 798             this,
 799             v -> (long) v.rOp((int) 1, (i, a, b) -> (int) (a * b)));
 800     }
 801 
 802     @Override
 803     @ForceInline
 804     public int orLanes() {
 805         return (int) VectorIntrinsics.reductionCoerced(
 806             VECTOR_OP_OR, Int128Vector.class, int.class, LENGTH,
 807             this,
 808             v -> (long) v.rOp((int) 0, (i, a, b) -> (int) (a | b)));
 809     }
 810 
 811     @Override
 812     @ForceInline
 813     public int orLanes(VectorMask<Integer> m) {
 814         return IntVector.broadcast(SPECIES, (int) 0).blend(this, m).orLanes();
 815     }
 816 
 817     @Override
 818     @ForceInline
 819     public int xorLanes() {
 820         return (int) VectorIntrinsics.reductionCoerced(
 821             VECTOR_OP_XOR, Int128Vector.class, int.class, LENGTH,
 822             this,
 823             v -> (long) v.rOp((int) 0, (i, a, b) -> (int) (a ^ b)));
 824     }
 825 
 826     @Override
 827     @ForceInline
 828     public int xorLanes(VectorMask<Integer> m) {
 829         return IntVector.broadcast(SPECIES, (int) 0).blend(this, m).xorLanes();
 830     }
 831 
 832 
 833     @Override
 834     @ForceInline
 835     public int addLanes(VectorMask<Integer> m) {
 836         return IntVector.broadcast(SPECIES, (int) 0).blend(this, m).addLanes();
 837     }
 838 
 839 
 840     @Override
 841     @ForceInline
 842     public int mulLanes(VectorMask<Integer> m) {
 843         return IntVector.broadcast(SPECIES, (int) 1).blend(this, m).mulLanes();
 844     }
 845 
 846     @Override
 847     @ForceInline
 848     public int minLanes(VectorMask<Integer> m) {
 849         return IntVector.broadcast(SPECIES, Integer.MAX_VALUE).blend(this, m).minLanes();
 850     }
 851 
 852     @Override
 853     @ForceInline
 854     public int maxLanes(VectorMask<Integer> m) {
 855         return IntVector.broadcast(SPECIES, Integer.MIN_VALUE).blend(this, m).maxLanes();
 856     }
 857 
 858     @Override
 859     @ForceInline
 860     public VectorShuffle<Integer> toShuffle() {
 861         int[] a = toArray();
 862         int[] sa = new int[a.length];
 863         for (int i = 0; i < a.length; i++) {
 864             sa[i] = (int) a[i];
 865         }
 866         return VectorShuffle.fromArray(SPECIES, sa, 0);
 867     }
 868 
 869     // Memory operations
 870 
 871     private static final int ARRAY_SHIFT         = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
 872     private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
 873 
 874     @Override
 875     @ForceInline
 876     public void intoArray(int[] a, int ix) {
 877         Objects.requireNonNull(a);
 878         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 879         VectorIntrinsics.store(Int128Vector.class, int.class, LENGTH,
 880                                a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_INT_BASE_OFFSET,
 881                                this,
 882                                a, ix,
 883                                (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
 884     }
 885 
 886     @Override
 887     @ForceInline
 888     public final void intoArray(int[] a, int ax, VectorMask<Integer> m) {
 889         IntVector oldVal = IntVector.fromArray(SPECIES, a, ax);
 890         IntVector newVal = oldVal.blend(this, m);
 891         newVal.intoArray(a, ax);
 892     }
 893     @Override
 894     @ForceInline
 895     public void intoArray(int[] a, int ix, int[] b, int iy) {
 896         Objects.requireNonNull(a);
 897         Objects.requireNonNull(b);
 898 
 899         // Index vector: vix[0:n] = i -> ix + indexMap[iy + i]
 900         IntVector vix = IntVector.fromArray(INDEX_SPECIES, b, iy).add(ix);
 901 
 902         vix = VectorIntrinsics.checkIndex(vix, a.length);
 903 
 904         VectorIntrinsics.storeWithMap(Int128Vector.class, int.class, LENGTH, Int128Vector.class,
 905                                a, Unsafe.ARRAY_INT_BASE_OFFSET, vix,
 906                                this,
 907                                a, ix, b, iy,
 908                                (arr, idx, v, indexMap, idy) -> v.forEach((i, e) -> arr[idx+indexMap[idy+i]] = e));
 909     }
 910 
 911      @Override
 912      @ForceInline
 913      public final void intoArray(int[] a, int ax, VectorMask<Integer> m, int[] b, int iy) {
 914          // @@@ This can result in out of bounds errors for unset mask lanes
 915          IntVector oldVal = IntVector.fromArray(SPECIES, a, ax, b, iy);
 916          IntVector newVal = oldVal.blend(this, m);
 917          newVal.intoArray(a, ax, b, iy);
 918      }
 919 
 920     @Override
 921     @ForceInline
 922     public void intoByteArray(byte[] a, int ix) {
 923         Objects.requireNonNull(a);
 924         ix = VectorIntrinsics.checkIndex(ix, a.length, bitSize() / Byte.SIZE);
 925         VectorIntrinsics.store(Int128Vector.class, int.class, LENGTH,
 926                                a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 927                                this,
 928                                a, ix,
 929                                (c, idx, v) -> {
 930                                    ByteBuffer bbc = ByteBuffer.wrap(c, idx, c.length - idx).order(ByteOrder.nativeOrder());
 931                                    IntBuffer tb = bbc.asIntBuffer();
 932                                    v.forEach((i, e) -> tb.put(e));
 933                                });
 934     }
 935 
 936     @Override
 937     @ForceInline
 938     public final void intoByteArray(byte[] a, int ix, VectorMask<Integer> m) {
 939         Int128Vector oldVal = (Int128Vector) IntVector.fromByteArray(SPECIES, a, ix);
 940         Int128Vector newVal = oldVal.blend(this, m);
 941         newVal.intoByteArray(a, ix);
 942     }
 943 
 944     @Override
 945     @ForceInline
 946     public void intoByteBuffer(ByteBuffer bb, int ix) {
 947         if (bb.order() != ByteOrder.nativeOrder()) {
 948             throw new IllegalArgumentException();
 949         }
 950         if (bb.isReadOnly()) {
 951             throw new ReadOnlyBufferException();
 952         }
 953         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), bitSize() / Byte.SIZE);
 954         VectorIntrinsics.store(Int128Vector.class, int.class, LENGTH,
 955                                U.getReference(bb, BYTE_BUFFER_HB), ix + U.getLong(bb, BUFFER_ADDRESS),
 956                                this,
 957                                bb, ix,
 958                                (c, idx, v) -> {
 959                                    ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 960                                    IntBuffer tb = bbc.asIntBuffer();
 961                                    v.forEach((i, e) -> tb.put(e));
 962                                });
 963     }
 964 
 965     @Override
 966     @ForceInline
 967     public void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Integer> m) {
 968         Int128Vector oldVal = (Int128Vector) IntVector.fromByteBuffer(SPECIES, bb, ix);
 969         Int128Vector newVal = oldVal.blend(this, m);
 970         newVal.intoByteBuffer(bb, ix);
 971     }
 972 
 973     //
 974 
 975     @Override
 976     public String toString() {
 977         return Arrays.toString(getElements());
 978     }
 979 
 980     @Override
 981     public boolean equals(Object o) {
 982         if (this == o) return true;
 983         if (o == null || this.getClass() != o.getClass()) return false;
 984 
 985         Int128Vector that = (Int128Vector) o;
 986         return this.equal(that).allTrue();
 987     }
 988 
 989     @Override
 990     public int hashCode() {
 991         return Arrays.hashCode(vec);
 992     }
 993 
 994     // Binary test
 995 
 996     @Override
 997     Int128Mask bTest(Vector<Integer> o, FBinTest f) {
 998         int[] vec1 = getElements();
 999         int[] vec2 = ((Int128Vector)o).getElements();
1000         boolean[] bits = new boolean[length()];
1001         for (int i = 0; i < length(); i++){
1002             bits[i] = f.apply(i, vec1[i], vec2[i]);
1003         }
1004         return new Int128Mask(bits);
1005     }
1006 
1007     // Comparisons
1008 
1009     @Override
1010     @ForceInline
1011     public Int128Mask equal(Vector<Integer> o) {
1012         Objects.requireNonNull(o);
1013         Int128Vector v = (Int128Vector)o;
1014 
1015         return VectorIntrinsics.compare(
1016             BT_eq, Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1017             this, v,
1018             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
1019     }
1020 
1021     @Override
1022     @ForceInline
1023     public Int128Mask notEqual(Vector<Integer> o) {
1024         Objects.requireNonNull(o);
1025         Int128Vector v = (Int128Vector)o;
1026 
1027         return VectorIntrinsics.compare(
1028             BT_ne, Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1029             this, v,
1030             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
1031     }
1032 
1033     @Override
1034     @ForceInline
1035     public Int128Mask lessThan(Vector<Integer> o) {
1036         Objects.requireNonNull(o);
1037         Int128Vector v = (Int128Vector)o;
1038 
1039         return VectorIntrinsics.compare(
1040             BT_lt, Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1041             this, v,
1042             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
1043     }
1044 
1045     @Override
1046     @ForceInline
1047     public Int128Mask lessThanEq(Vector<Integer> o) {
1048         Objects.requireNonNull(o);
1049         Int128Vector v = (Int128Vector)o;
1050 
1051         return VectorIntrinsics.compare(
1052             BT_le, Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1053             this, v,
1054             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
1055     }
1056 
1057     @Override
1058     @ForceInline
1059     public Int128Mask greaterThan(Vector<Integer> o) {
1060         Objects.requireNonNull(o);
1061         Int128Vector v = (Int128Vector)o;
1062 
1063         return (Int128Mask) VectorIntrinsics.compare(
1064             BT_gt, Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1065             this, v,
1066             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
1067     }
1068 
1069     @Override
1070     @ForceInline
1071     public Int128Mask greaterThanEq(Vector<Integer> o) {
1072         Objects.requireNonNull(o);
1073         Int128Vector v = (Int128Vector)o;
1074 
1075         return VectorIntrinsics.compare(
1076             BT_ge, Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1077             this, v,
1078             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
1079     }
1080 
1081     // Foreach
1082 
1083     @Override
1084     void forEach(FUnCon f) {
1085         int[] vec = getElements();
1086         for (int i = 0; i < length(); i++) {
1087             f.apply(i, vec[i]);
1088         }
1089     }
1090 
1091     @Override
1092     void forEach(VectorMask<Integer> o, FUnCon f) {
1093         boolean[] mbits = ((Int128Mask)o).getBits();
1094         forEach((i, a) -> {
1095             if (mbits[i]) { f.apply(i, a); }
1096         });
1097     }
1098 
1099 
1100     Float128Vector toFP() {
1101         int[] vec = getElements();
1102         float[] res = new float[this.species().length()];
1103         for(int i = 0; i < this.species().length(); i++){
1104             res[i] = Float.intBitsToFloat(vec[i]);
1105         }
1106         return new Float128Vector(res);
1107     }
1108 
1109     @Override
1110     @ForceInline
1111     public Int128Vector rotateLanesLeft(int j) {
1112       int L = length();
1113       if (j < 0) {
1114          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1115       } else {
1116         j = j & (L-1);
1117         VectorShuffle<Integer> PermMask  = VectorShuffle.shuffleIota(SPECIES, L - j);
1118         return this.rearrange(PermMask);
1119       }
1120     }
1121 
1122     @Override
1123     @ForceInline
1124     public Int128Vector rotateLanesRight(int j) {
1125       int L = length();
1126       if (j < 0) {
1127          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1128       } else {
1129         j = j & (L-1);
1130         VectorShuffle<Integer> PermMask = VectorShuffle.shuffleIota(SPECIES, j);
1131         return this.rearrange(PermMask);
1132       }
1133     }
1134 
1135     @Override
1136     @ForceInline
1137     @SuppressWarnings("unchecked")
1138     public Int128Vector shiftLanesLeft(int j) {
1139        int L = length();
1140        if (j < 0) {
1141          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1142        } else if ( j >= L ) {
1143          return ZERO;
1144        } else {
1145          Int128Shuffle     Iota    = (Int128Shuffle)(VectorShuffle.shuffleIota(SPECIES, L-j));
1146          VectorMask<Integer> BlendMask = Iota.toVector().lessThan(Int128Vector.broadcast(SPECIES, (int)(L-j)));
1147          Iota    = (Int128Shuffle)(VectorShuffle.shuffleIota(SPECIES, L -j));
1148          return ZERO.blend(this.rearrange(Iota),BlendMask);
1149        }
1150     }
1151 
1152     @Override
1153     @ForceInline
1154     @SuppressWarnings("unchecked")
1155     public Int128Vector shiftLanesRight(int j) {
1156        int L = length();
1157        if (j < 0) {
1158          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1159        } else if ( j >= L ) {
1160          return ZERO;
1161        } else {
1162          Int128Shuffle     Iota    = (Int128Shuffle)(VectorShuffle.shuffleIota(SPECIES, j));
1163          VectorMask<Integer> BlendMask = Iota.toVector().greaterThanEq(Int128Vector.broadcast(SPECIES, (int)(j)));
1164          Iota    = (Int128Shuffle)(VectorShuffle.shuffleIota(SPECIES, j));
1165          return ZERO.blend(this.rearrange(Iota),BlendMask);
1166        }
1167     }
1168 
1169     @Override
1170     @ForceInline
1171     public Int128Vector rearrange(Vector<Integer> v,
1172                                   VectorShuffle<Integer> s, VectorMask<Integer> m) {
1173         return this.rearrange(s).blend(v.rearrange(s), m);
1174     }
1175 
1176     @Override
1177     @ForceInline
1178     public Int128Vector rearrange(VectorShuffle<Integer> o1) {
1179         Objects.requireNonNull(o1);
1180         Int128Shuffle s =  (Int128Shuffle)o1;
1181 
1182         return VectorIntrinsics.rearrangeOp(
1183             Int128Vector.class, Int128Shuffle.class, int.class, LENGTH,
1184             this, s,
1185             (v1, s_) -> v1.uOp((i, a) -> {
1186                 int ei = s_.lane(i);
1187                 return v1.lane(ei);
1188             }));
1189     }
1190 
1191     @Override
1192     @ForceInline
1193     public Int128Vector blend(Vector<Integer> o1, VectorMask<Integer> o2) {
1194         Objects.requireNonNull(o1);
1195         Objects.requireNonNull(o2);
1196         Int128Vector v = (Int128Vector)o1;
1197         Int128Mask   m = (Int128Mask)o2;
1198 
1199         return VectorIntrinsics.blend(
1200             Int128Vector.class, Int128Mask.class, int.class, LENGTH,
1201             this, v, m,
1202             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.lane(i) ? b : a));
1203     }
1204 
1205     // Accessors
1206 
1207     @Override
1208     public int lane(int i) {
1209         if (i < 0 || i >= LENGTH) {
1210             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1211         }
1212         return (int) VectorIntrinsics.extract(
1213                                 Int128Vector.class, int.class, LENGTH,
1214                                 this, i,
1215                                 (vec, ix) -> {
1216                                     int[] vecarr = vec.getElements();
1217                                     return (long)vecarr[ix];
1218                                 });
1219     }
1220 
1221     @Override
1222     public Int128Vector with(int i, int e) {
1223         if (i < 0 || i >= LENGTH) {
1224             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1225         }
1226         return VectorIntrinsics.insert(
1227                                 Int128Vector.class, int.class, LENGTH,
1228                                 this, i, (long)e,
1229                                 (v, ix, bits) -> {
1230                                     int[] res = v.getElements().clone();
1231                                     res[ix] = (int)bits;
1232                                     return new Int128Vector(res);
1233                                 });
1234     }
1235 
1236     // Mask
1237 
1238     static final class Int128Mask extends AbstractMask<Integer> {
1239         static final Int128Mask TRUE_MASK = new Int128Mask(true);
1240         static final Int128Mask FALSE_MASK = new Int128Mask(false);
1241 
1242         private final boolean[] bits; // Don't access directly, use getBits() instead.
1243 
1244         public Int128Mask(boolean[] bits) {
1245             this(bits, 0);
1246         }
1247 
1248         public Int128Mask(boolean[] bits, int offset) {
1249             boolean[] a = new boolean[species().length()];
1250             for (int i = 0; i < a.length; i++) {
1251                 a[i] = bits[offset + i];
1252             }
1253             this.bits = a;
1254         }
1255 
1256         public Int128Mask(boolean val) {
1257             boolean[] bits = new boolean[species().length()];
1258             Arrays.fill(bits, val);
1259             this.bits = bits;
1260         }
1261 
1262         boolean[] getBits() {
1263             return VectorIntrinsics.maybeRebox(this).bits;
1264         }
1265 
1266         @Override
1267         Int128Mask uOp(MUnOp f) {
1268             boolean[] res = new boolean[species().length()];
1269             boolean[] bits = getBits();
1270             for (int i = 0; i < species().length(); i++) {
1271                 res[i] = f.apply(i, bits[i]);
1272             }
1273             return new Int128Mask(res);
1274         }
1275 
1276         @Override
1277         Int128Mask bOp(VectorMask<Integer> o, MBinOp f) {
1278             boolean[] res = new boolean[species().length()];
1279             boolean[] bits = getBits();
1280             boolean[] mbits = ((Int128Mask)o).getBits();
1281             for (int i = 0; i < species().length(); i++) {
1282                 res[i] = f.apply(i, bits[i], mbits[i]);
1283             }
1284             return new Int128Mask(res);
1285         }
1286 
1287         @Override
1288         public VectorSpecies<Integer> species() {
1289             return SPECIES;
1290         }
1291 
1292         @Override
1293         public Int128Vector toVector() {
1294             int[] res = new int[species().length()];
1295             boolean[] bits = getBits();
1296             for (int i = 0; i < species().length(); i++) {
1297                 // -1 will result in the most significant bit being set in
1298                 // addition to some or all other bits
1299                 res[i] = (int) (bits[i] ? -1 : 0);
1300             }
1301             return new Int128Vector(res);
1302         }
1303 
1304         @Override
1305         @ForceInline
1306         @SuppressWarnings("unchecked")
1307         public <E> VectorMask<E> cast(VectorSpecies<E> species) {
1308             if (length() != species.length())
1309                 throw new IllegalArgumentException("VectorMask length and species length differ");
1310             Class<?> stype = species.elementType();
1311             boolean [] maskArray = toArray();
1312             if (stype == byte.class) {
1313                 return (VectorMask <E>) new Byte128Vector.Byte128Mask(maskArray);
1314             } else if (stype == short.class) {
1315                 return (VectorMask <E>) new Short128Vector.Short128Mask(maskArray);
1316             } else if (stype == int.class) {
1317                 return (VectorMask <E>) new Int128Vector.Int128Mask(maskArray);
1318             } else if (stype == long.class) {
1319                 return (VectorMask <E>) new Long128Vector.Long128Mask(maskArray);
1320             } else if (stype == float.class) {
1321                 return (VectorMask <E>) new Float128Vector.Float128Mask(maskArray);
1322             } else if (stype == double.class) {
1323                 return (VectorMask <E>) new Double128Vector.Double128Mask(maskArray);
1324             } else {
1325                 throw new UnsupportedOperationException("Bad lane type for casting.");
1326             }
1327         }
1328 
1329         // Unary operations
1330 
1331         @Override
1332         @ForceInline
1333         public Int128Mask not() {
1334             return (Int128Mask) VectorIntrinsics.unaryOp(
1335                                              VECTOR_OP_NOT, Int128Mask.class, int.class, LENGTH,
1336                                              this,
1337                                              (m1) -> m1.uOp((i, a) -> !a));
1338         }
1339 
1340         // Binary operations
1341 
1342         @Override
1343         @ForceInline
1344         public Int128Mask and(VectorMask<Integer> o) {
1345             Objects.requireNonNull(o);
1346             Int128Mask m = (Int128Mask)o;
1347             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Int128Mask.class, int.class, LENGTH,
1348                                              this, m,
1349                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
1350         }
1351 
1352         @Override
1353         @ForceInline
1354         public Int128Mask or(VectorMask<Integer> o) {
1355             Objects.requireNonNull(o);
1356             Int128Mask m = (Int128Mask)o;
1357             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Int128Mask.class, int.class, LENGTH,
1358                                              this, m,
1359                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
1360         }
1361 
1362         // Reductions
1363 
1364         @Override
1365         @ForceInline
1366         public boolean anyTrue() {
1367             return VectorIntrinsics.test(BT_ne, Int128Mask.class, int.class, LENGTH,
1368                                          this, this,
1369                                          (m, __) -> anyTrueHelper(((Int128Mask)m).getBits()));
1370         }
1371 
1372         @Override
1373         @ForceInline
1374         public boolean allTrue() {
1375             return VectorIntrinsics.test(BT_overflow, Int128Mask.class, int.class, LENGTH,
1376                                          this, VectorMask.maskAllTrue(species()),
1377                                          (m, __) -> allTrueHelper(((Int128Mask)m).getBits()));
1378         }
1379     }
1380 
1381     // Shuffle
1382 
1383     static final class Int128Shuffle extends AbstractShuffle<Integer> {
1384         Int128Shuffle(byte[] reorder) {
1385             super(reorder);
1386         }
1387 
1388         public Int128Shuffle(int[] reorder) {
1389             super(reorder);
1390         }
1391 
1392         public Int128Shuffle(int[] reorder, int i) {
1393             super(reorder, i);
1394         }
1395 
1396         public Int128Shuffle(IntUnaryOperator f) {
1397             super(f);
1398         }
1399 
1400         @Override
1401         public VectorSpecies<Integer> species() {
1402             return SPECIES;
1403         }
1404 
1405         private IntVector toVector_helper() {
1406             int[] va = new int[SPECIES.length()];
1407             for (int i = 0; i < va.length; i++) {
1408               va[i] = (int) lane(i);
1409             }
1410             return IntVector.fromArray(SPECIES, va, 0);
1411         }
1412 
1413         @Override
1414         @ForceInline
1415         public IntVector toVector() {
1416             return VectorIntrinsics.shuffleToVector(Int128Vector.class, int.class, Int128Shuffle.class, this,
1417                                                     SPECIES.length(), 
1418                                                     (s) -> (((Int128Shuffle)(s)).toVector_helper()));
1419         }
1420 
1421         @Override
1422         @ForceInline
1423         @SuppressWarnings("unchecked")
1424         public <F> VectorShuffle<F> cast(VectorSpecies<F> species) {
1425             if (length() != species.length())
1426                 throw new IllegalArgumentException("Shuffle length and species length differ");
1427             Class<?> stype = species.elementType();
1428             int [] shuffleArray = toArray();
1429             if (stype == byte.class) {
1430                 return (VectorShuffle<F>) new Byte128Vector.Byte128Shuffle(shuffleArray);
1431             } else if (stype == short.class) {
1432                 return (VectorShuffle<F>) new Short128Vector.Short128Shuffle(shuffleArray);
1433             } else if (stype == int.class) {
1434                 return (VectorShuffle<F>) new Int128Vector.Int128Shuffle(shuffleArray);
1435             } else if (stype == long.class) {
1436                 return (VectorShuffle<F>) new Long128Vector.Long128Shuffle(shuffleArray);
1437             } else if (stype == float.class) {
1438                 return (VectorShuffle<F>) new Float128Vector.Float128Shuffle(shuffleArray);
1439             } else if (stype == double.class) {
1440                 return (VectorShuffle<F>) new Double128Vector.Double128Shuffle(shuffleArray);
1441             } else {
1442                 throw new UnsupportedOperationException("Bad lane type for casting.");
1443             }
1444         }
1445 
1446 
1447         @Override
1448         public Int128Shuffle rearrange(VectorShuffle<Integer> o) {
1449             Int128Shuffle s = (Int128Shuffle) o;
1450             byte[] r = new byte[reorder.length];
1451             for (int i = 0; i < reorder.length; i++) {
1452                 r[i] = reorder[s.reorder[i]];
1453             }
1454             return new Int128Shuffle(r);
1455         }
1456     }
1457 
1458     // VectorSpecies
1459 
1460     @Override
1461     public VectorSpecies<Integer> species() {
1462         return SPECIES;
1463     }
1464 }