< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/IntVector.java

Print this page
rev 54658 : refactored mask and shuffle creation methods, moved classes to top-level


  39 
  40 /**
  41  * A specialized {@link Vector} representing an ordered immutable sequence of
  42  * {@code int} values.
  43  */
  44 @SuppressWarnings("cast")
  45 public abstract class IntVector extends Vector<Integer> {
  46 
  47     IntVector() {}
  48 
  49     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
  50 
  51     // Unary operator
  52 
  53     interface FUnOp {
  54         int apply(int i, int a);
  55     }
  56 
  57     abstract IntVector uOp(FUnOp f);
  58 
  59     abstract IntVector uOp(Mask<Integer> m, FUnOp f);
  60 
  61     // Binary operator
  62 
  63     interface FBinOp {
  64         int apply(int i, int a, int b);
  65     }
  66 
  67     abstract IntVector bOp(Vector<Integer> v, FBinOp f);
  68 
  69     abstract IntVector bOp(Vector<Integer> v, Mask<Integer> m, FBinOp f);
  70 
  71     // Trinary operator
  72 
  73     interface FTriOp {
  74         int apply(int i, int a, int b, int c);
  75     }
  76 
  77     abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, FTriOp f);
  78 
  79     abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, Mask<Integer> m, FTriOp f);
  80 
  81     // Reduction operator
  82 
  83     abstract int rOp(int v, FBinOp f);
  84 
  85     // Binary test
  86 
  87     interface FBinTest {
  88         boolean apply(int i, int a, int b);
  89     }
  90 
  91     abstract Mask<Integer> bTest(Vector<Integer> v, FBinTest f);
  92 
  93     // Foreach
  94 
  95     interface FUnCon {
  96         void apply(int i, int a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(Mask<Integer> m, FUnCon f);
 102 
 103     // Static factories
 104 
 105     /**
 106      * Returns a vector where all lane elements are set to the default
 107      * primitive value.
 108      *
 109      * @param species species of desired vector
 110      * @return a zero vector of given species
 111      */
 112     @ForceInline
 113     @SuppressWarnings("unchecked")
 114     public static IntVector zero(Species<Integer> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<IntVector>) species.boxType(), int.class, species.length(),
 116                                                  0, species,
 117                                                  ((bits, s) -> ((IntSpecies)s).op(i -> (int)bits)));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(Species<Integer>, ByteBuffer, int, Mask) method} as follows:
 129      * <pre>{@code
 130      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param ix the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static IntVector fromByteArray(Species<Integer> species, byte[] a, int ix) {
 143         Objects.requireNonNull(a);
 144         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 146                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, ix, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          IntBuffer tb = bbc.asIntBuffer();
 151                                          return ((IntSpecies)s).op(i -> tb.get());
 152                                      });
 153     }
 154 
 155     /**
 156      * Loads a vector from a byte array starting at an offset and using a
 157      * mask.
 158      * <p>
 159      * Bytes are composed into primitive lane elements according to the
 160      * native byte order of the underlying platform.
 161      * <p>
 162      * This method behaves as if it returns the result of calling the
 163      * byte buffer, offset, and mask accepting
 164      * {@link #fromByteBuffer(Species<Integer>, ByteBuffer, int, Mask) method} as follows:
 165      * <pre>{@code
 166      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 167      * }</pre>
 168      *
 169      * @param species species of desired vector
 170      * @param a the byte array
 171      * @param ix the offset into the array
 172      * @param m the mask
 173      * @return a vector loaded from a byte array
 174      * @throws IndexOutOfBoundsException if {@code i < 0} or
 175      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 176      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 177      * or {@code > a.length},
 178      * for any vector lane index {@code N} where the mask at lane {@code N}
 179      * is set
 180      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 181      */
 182     @ForceInline
 183     public static IntVector fromByteArray(Species<Integer> species, byte[] a, int ix, Mask<Integer> m) {
 184         return zero(species).blend(fromByteArray(species, a, ix), m);
 185     }
 186 
 187     /**
 188      * Loads a vector from an array starting at offset.
 189      * <p>
 190      * For each vector lane, where {@code N} is the vector lane index, the
 191      * array element at index {@code i + N} is placed into the
 192      * resulting vector at lane index {@code N}.
 193      *
 194      * @param species species of desired vector
 195      * @param a the array
 196      * @param i the offset into the array
 197      * @return the vector loaded from an array
 198      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 199      * {@code i > a.length - this.length()}
 200      */
 201     @ForceInline
 202     @SuppressWarnings("unchecked")
 203     public static IntVector fromArray(Species<Integer> species, int[] a, int i){
 204         Objects.requireNonNull(a);
 205         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 206         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 207                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_INT_BASE_OFFSET,
 208                                      a, i, species,
 209                                      (c, idx, s) -> ((IntSpecies)s).op(n -> c[idx + n]));
 210     }
 211 
 212 
 213     /**
 214      * Loads a vector from an array starting at offset and using a mask.
 215      * <p>
 216      * For each vector lane, where {@code N} is the vector lane index,
 217      * if the mask lane at index {@code N} is set then the array element at
 218      * index {@code i + N} is placed into the resulting vector at lane index
 219      * {@code N}, otherwise the default element value is placed into the
 220      * resulting vector at lane index {@code N}.
 221      *
 222      * @param species species of desired vector
 223      * @param a the array
 224      * @param i the offset into the array
 225      * @param m the mask
 226      * @return the vector loaded from an array
 227      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 228      * for any vector lane index {@code N} where the mask at lane {@code N}
 229      * is set {@code i > a.length - N}
 230      */
 231     @ForceInline
 232     public static IntVector fromArray(Species<Integer> species, int[] a, int i, Mask<Integer> m) {
 233         return zero(species).blend(fromArray(species, a, i), m);
 234     }
 235 
 236     /**
 237      * Loads a vector from an array using indexes obtained from an index
 238      * map.
 239      * <p>
 240      * For each vector lane, where {@code N} is the vector lane index, the
 241      * array element at index {@code i + indexMap[j + N]} is placed into the
 242      * resulting vector at lane index {@code N}.
 243      *
 244      * @param species species of desired vector
 245      * @param a the array
 246      * @param i the offset into the array, may be negative if relative
 247      * indexes in the index map compensate to produce a value within the
 248      * array bounds
 249      * @param indexMap the index map
 250      * @param j the offset into the index map
 251      * @return the vector loaded from an array
 252      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 253      * {@code j > indexMap.length - this.length()},
 254      * or for any vector lane index {@code N} the result of
 255      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 256      */
 257     @ForceInline
 258     @SuppressWarnings("unchecked")
 259     public static IntVector fromArray(Species<Integer> species, int[] a, int i, int[] indexMap, int j) {
 260         Objects.requireNonNull(a);
 261         Objects.requireNonNull(indexMap);
 262 
 263 
 264         // Index vector: vix[0:n] = k -> i + indexMap[j + k]
 265         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
 266 
 267         vix = VectorIntrinsics.checkIndex(vix, a.length);
 268 
 269         return VectorIntrinsics.loadWithMap((Class<IntVector>) species.boxType(), int.class, species.length(),
 270                                             IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_INT_BASE_OFFSET, vix,
 271                                             a, i, indexMap, j, species,
 272                                             (int[] c, int idx, int[] iMap, int idy, Species<Integer> s) ->
 273                                                 ((IntSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 274         }
 275 
 276     /**
 277      * Loads a vector from an array using indexes obtained from an index
 278      * map and using a mask.
 279      * <p>
 280      * For each vector lane, where {@code N} is the vector lane index,
 281      * if the mask lane at index {@code N} is set then the array element at
 282      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 283      * at lane index {@code N}.
 284      *
 285      * @param species species of desired vector
 286      * @param a the array
 287      * @param i the offset into the array, may be negative if relative
 288      * indexes in the index map compensate to produce a value within the
 289      * array bounds
 290      * @param m the mask
 291      * @param indexMap the index map
 292      * @param j the offset into the index map
 293      * @return the vector loaded from an array
 294      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 295      * {@code j > indexMap.length - this.length()},
 296      * or for any vector lane index {@code N} where the mask at lane
 297      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 298      * {@code < 0} or {@code >= a.length}
 299      */
 300     @ForceInline
 301     @SuppressWarnings("unchecked")
 302     public static IntVector fromArray(Species<Integer> species, int[] a, int i, Mask<Integer> m, int[] indexMap, int j) {
 303         // @@@ This can result in out of bounds errors for unset mask lanes
 304         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 305     }
 306 
 307 
 308     /**
 309      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 310      * offset into the byte buffer.
 311      * <p>
 312      * Bytes are composed into primitive lane elements according to the
 313      * native byte order of the underlying platform.
 314      * <p>
 315      * This method behaves as if it returns the result of calling the
 316      * byte buffer, offset, and mask accepting
 317      * {@link #fromByteBuffer(Species<Integer>, ByteBuffer, int, Mask)} method} as follows:
 318      * <pre>{@code
 319      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 320      * }</pre>
 321      *
 322      * @param species species of desired vector
 323      * @param bb the byte buffer
 324      * @param ix the offset into the byte buffer
 325      * @return a vector loaded from a byte buffer
 326      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 327      * or {@code > b.limit()},
 328      * or if there are fewer than
 329      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 330      * remaining in the byte buffer from the given offset
 331      */
 332     @ForceInline
 333     @SuppressWarnings("unchecked")
 334     public static IntVector fromByteBuffer(Species<Integer> species, ByteBuffer bb, int ix) {
 335         if (bb.order() != ByteOrder.nativeOrder()) {
 336             throw new IllegalArgumentException();
 337         }
 338         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 339         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 340                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 341                                      bb, ix, species,
 342                                      (c, idx, s) -> {
 343                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 344                                          IntBuffer tb = bbc.asIntBuffer();
 345                                          return ((IntSpecies)s).op(i -> tb.get());
 346                                      });
 347     }
 348 
 349     /**
 350      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 351      * offset into the byte buffer and using a mask.
 352      * <p>
 353      * This method behaves as if the byte buffer is viewed as a primitive
 354      * {@link java.nio.Buffer buffer} for the primitive element type,


 366      * e[] es = new e[this.length()];
 367      * for (int n = 0; n < t.length; n++) {
 368      *     if (m.isSet(n))
 369      *         es[n] = eb.get(n);
 370      * }
 371      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 372      * }</pre>
 373      *
 374      * @param species species of desired vector
 375      * @param bb the byte buffer
 376      * @param ix the offset into the byte buffer
 377      * @param m the mask
 378      * @return a vector loaded from a byte buffer
 379      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 380      * or {@code > b.limit()},
 381      * for any vector lane index {@code N} where the mask at lane {@code N}
 382      * is set
 383      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 384      */
 385     @ForceInline
 386     public static IntVector fromByteBuffer(Species<Integer> species, ByteBuffer bb, int ix, Mask<Integer> m) {
 387         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 388     }
 389 
 390     /**
 391      * Returns a vector where all lane elements are set to the primitive
 392      * value {@code e}.
 393      *
 394      * @param s species of the desired vector
 395      * @param e the value
 396      * @return a vector of vector where all lane elements are set to
 397      * the primitive value {@code e}
 398      */
 399     @ForceInline
 400     @SuppressWarnings("unchecked")
 401     public static IntVector broadcast(Species<Integer> s, int e) {
 402         return VectorIntrinsics.broadcastCoerced(
 403             (Class<IntVector>) s.boxType(), int.class, s.length(),
 404             e, s,
 405             ((bits, sp) -> ((IntSpecies)sp).op(i -> (int)bits)));
 406     }
 407 
 408     /**
 409      * Returns a vector where each lane element is set to a given
 410      * primitive value.
 411      * <p>
 412      * For each vector lane, where {@code N} is the vector lane index, the
 413      * the primitive value at index {@code N} is placed into the resulting
 414      * vector at lane index {@code N}.
 415      *
 416      * @param s species of the desired vector
 417      * @param es the given primitive values
 418      * @return a vector where each lane element is set to a given primitive
 419      * value
 420      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 421      */
 422     @ForceInline
 423     @SuppressWarnings("unchecked")
 424     public static IntVector scalars(Species<Integer> s, int... es) {
 425         Objects.requireNonNull(es);
 426         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 427         return VectorIntrinsics.load((Class<IntVector>) s.boxType(), int.class, s.length(),
 428                                      es, Unsafe.ARRAY_INT_BASE_OFFSET,
 429                                      es, ix, s,
 430                                      (c, idx, sp) -> ((IntSpecies)sp).op(n -> c[idx + n]));
 431     }
 432 
 433     /**
 434      * Returns a vector where the first lane element is set to the primtive
 435      * value {@code e}, all other lane elements are set to the default
 436      * value.
 437      *
 438      * @param s species of the desired vector
 439      * @param e the value
 440      * @return a vector where the first lane element is set to the primitive
 441      * value {@code e}
 442      */
 443     @ForceInline
 444     public static final IntVector single(Species<Integer> s, int e) {
 445         return zero(s).with(0, e);
 446     }
 447 
 448     /**
 449      * Returns a vector where each lane element is set to a randomly
 450      * generated primitive value.
 451      *
 452      * The semantics are equivalent to calling
 453      * {@link ThreadLocalRandom#nextInt()}
 454      *
 455      * @param s species of the desired vector
 456      * @return a vector where each lane elements is set to a randomly
 457      * generated primitive value
 458      */
 459     public static IntVector random(Species<Integer> s) {
 460         ThreadLocalRandom r = ThreadLocalRandom.current();
 461         return ((IntSpecies)s).op(i -> r.nextInt());
 462     }
 463 
 464     /**
 465      * Returns a mask where each lane is set or unset according to given
 466      * {@code boolean} values
 467      * <p>
 468      * For each mask lane, where {@code N} is the mask lane index,
 469      * if the given {@code boolean} value at index {@code N} is {@code true}
 470      * then the mask lane at index {@code N} is set, otherwise it is unset.
 471      *
 472      * @param species mask species
 473      * @param bits the given {@code boolean} values
 474      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 475      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 476      */
 477     @ForceInline
 478     public static Mask<Integer> maskFromValues(Species<Integer> species, boolean... bits) {
 479         if (species.boxType() == IntMaxVector.class)
 480             return new IntMaxVector.IntMaxMask(bits);
 481         switch (species.bitSize()) {
 482             case 64: return new Int64Vector.Int64Mask(bits);
 483             case 128: return new Int128Vector.Int128Mask(bits);
 484             case 256: return new Int256Vector.Int256Mask(bits);
 485             case 512: return new Int512Vector.Int512Mask(bits);
 486             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 487         }
 488     }
 489 
 490     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 491     static Mask<Integer> trueMask(Species<Integer> species) {
 492         if (species.boxType() == IntMaxVector.class)
 493             return IntMaxVector.IntMaxMask.TRUE_MASK;
 494         switch (species.bitSize()) {
 495             case 64: return Int64Vector.Int64Mask.TRUE_MASK;
 496             case 128: return Int128Vector.Int128Mask.TRUE_MASK;
 497             case 256: return Int256Vector.Int256Mask.TRUE_MASK;
 498             case 512: return Int512Vector.Int512Mask.TRUE_MASK;
 499             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 500         }
 501     }
 502 
 503     static Mask<Integer> falseMask(Species<Integer> species) {
 504         if (species.boxType() == IntMaxVector.class)
 505             return IntMaxVector.IntMaxMask.FALSE_MASK;
 506         switch (species.bitSize()) {
 507             case 64: return Int64Vector.Int64Mask.FALSE_MASK;
 508             case 128: return Int128Vector.Int128Mask.FALSE_MASK;
 509             case 256: return Int256Vector.Int256Mask.FALSE_MASK;
 510             case 512: return Int512Vector.Int512Mask.FALSE_MASK;
 511             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 512         }
 513     }
 514 
 515     /**
 516      * Loads a mask from a {@code boolean} array starting at an offset.
 517      * <p>
 518      * For each mask lane, where {@code N} is the mask lane index,
 519      * if the array element at index {@code ix + N} is {@code true} then the
 520      * mask lane at index {@code N} is set, otherwise it is unset.
 521      *
 522      * @param species mask species
 523      * @param bits the {@code boolean} array
 524      * @param ix the offset into the array
 525      * @return the mask loaded from a {@code boolean} array
 526      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 527      * {@code ix > bits.length - species.length()}
 528      */
 529     @ForceInline
 530     @SuppressWarnings("unchecked")
 531     public static Mask<Integer> maskFromArray(Species<Integer> species, boolean[] bits, int ix) {
 532         Objects.requireNonNull(bits);
 533         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 534         return VectorIntrinsics.load((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
 535                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 536                                      bits, ix, species,
 537                                      (c, idx, s) -> (Mask<Integer>) ((IntSpecies)s).opm(n -> c[idx + n]));
 538     }
 539 
 540     /**
 541      * Returns a mask where all lanes are set.
 542      *
 543      * @param species mask species
 544      * @return a mask where all lanes are set
 545      */
 546     @ForceInline
 547     @SuppressWarnings("unchecked")
 548     public static Mask<Integer> maskAllTrue(Species<Integer> species) {
 549         return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
 550                                                  (int)-1,  species,
 551                                                  ((z, s) -> trueMask(s)));
 552     }
 553 
 554     /**
 555      * Returns a mask where all lanes are unset.
 556      *
 557      * @param species mask species
 558      * @return a mask where all lanes are unset
 559      */
 560     @ForceInline
 561     @SuppressWarnings("unchecked")
 562     public static Mask<Integer> maskAllFalse(Species<Integer> species) {
 563         return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
 564                                                  0, species, 
 565                                                  ((z, s) -> falseMask(s)));
 566     }
 567 
 568     /**
 569      * Returns a shuffle of mapped indexes where each lane element is
 570      * the result of applying a mapping function to the corresponding lane
 571      * index.
 572      * <p>
 573      * Care should be taken to ensure Shuffle values produced from this
 574      * method are consumed as constants to ensure optimal generation of
 575      * code.  For example, values held in static final fields or values
 576      * held in loop constant local variables.
 577      * <p>
 578      * This method behaves as if a shuffle is created from an array of
 579      * mapped indexes as follows:
 580      * <pre>{@code
 581      *   int[] a = new int[species.length()];
 582      *   for (int i = 0; i < a.length; i++) {
 583      *       a[i] = f.applyAsInt(i);
 584      *   }
 585      *   return this.shuffleFromValues(a);
 586      * }</pre>
 587      *
 588      * @param species shuffle species
 589      * @param f the lane index mapping function
 590      * @return a shuffle of mapped indexes
 591      */
 592     @ForceInline
 593     public static Shuffle<Integer> shuffle(Species<Integer> species, IntUnaryOperator f) {
 594         if (species.boxType() == IntMaxVector.class)
 595             return new IntMaxVector.IntMaxShuffle(f);
 596         switch (species.bitSize()) {
 597             case 64: return new Int64Vector.Int64Shuffle(f);
 598             case 128: return new Int128Vector.Int128Shuffle(f);
 599             case 256: return new Int256Vector.Int256Shuffle(f);
 600             case 512: return new Int512Vector.Int512Shuffle(f);
 601             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 602         }
 603     }
 604 
 605     /**
 606      * Returns a shuffle where each lane element is the value of its
 607      * corresponding lane index.
 608      * <p>
 609      * This method behaves as if a shuffle is created from an identity
 610      * index mapping function as follows:
 611      * <pre>{@code
 612      *   return this.shuffle(i -> i);
 613      * }</pre>
 614      *
 615      * @param species shuffle species
 616      * @return a shuffle of lane indexes
 617      */
 618     @ForceInline
 619     public static Shuffle<Integer> shuffleIota(Species<Integer> species) {
 620         if (species.boxType() == IntMaxVector.class)
 621             return new IntMaxVector.IntMaxShuffle(AbstractShuffle.IDENTITY);
 622         switch (species.bitSize()) {
 623             case 64: return new Int64Vector.Int64Shuffle(AbstractShuffle.IDENTITY);
 624             case 128: return new Int128Vector.Int128Shuffle(AbstractShuffle.IDENTITY);
 625             case 256: return new Int256Vector.Int256Shuffle(AbstractShuffle.IDENTITY);
 626             case 512: return new Int512Vector.Int512Shuffle(AbstractShuffle.IDENTITY);
 627             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 628         }
 629     }
 630 
 631     /**
 632      * Returns a shuffle where each lane element is set to a given
 633      * {@code int} value logically AND'ed by the species length minus one.
 634      * <p>
 635      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 636      * the {@code int} value at index {@code N} logically AND'ed by
 637      * {@code species.length() - 1} is placed into the resulting shuffle at
 638      * lane index {@code N}.
 639      *
 640      * @param species shuffle species
 641      * @param ixs the given {@code int} values
 642      * @return a shuffle where each lane element is set to a given
 643      * {@code int} value
 644      * @throws IndexOutOfBoundsException if the number of int values is
 645      * {@code < species.length()}
 646      */
 647     @ForceInline
 648     public static Shuffle<Integer> shuffleFromValues(Species<Integer> species, int... ixs) {
 649         if (species.boxType() == IntMaxVector.class)
 650             return new IntMaxVector.IntMaxShuffle(ixs);
 651         switch (species.bitSize()) {
 652             case 64: return new Int64Vector.Int64Shuffle(ixs);
 653             case 128: return new Int128Vector.Int128Shuffle(ixs);
 654             case 256: return new Int256Vector.Int256Shuffle(ixs);
 655             case 512: return new Int512Vector.Int512Shuffle(ixs);
 656             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 657         }
 658     }
 659 
 660     /**
 661      * Loads a shuffle from an {@code int} array starting at an offset.
 662      * <p>
 663      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 664      * array element at index {@code i + N} logically AND'ed by
 665      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 666      * index {@code N}.
 667      *
 668      * @param species shuffle species
 669      * @param ixs the {@code int} array
 670      * @param i the offset into the array
 671      * @return a shuffle loaded from the {@code int} array
 672      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 673      * {@code i > a.length - species.length()}
 674      */
 675     @ForceInline
 676     public static Shuffle<Integer> shuffleFromArray(Species<Integer> species, int[] ixs, int i) {
 677         if (species.boxType() == IntMaxVector.class)
 678             return new IntMaxVector.IntMaxShuffle(ixs, i);
 679         switch (species.bitSize()) {
 680             case 64: return new Int64Vector.Int64Shuffle(ixs, i);
 681             case 128: return new Int128Vector.Int128Shuffle(ixs, i);
 682             case 256: return new Int256Vector.Int256Shuffle(ixs, i);
 683             case 512: return new Int512Vector.Int512Shuffle(ixs, i);
 684             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 685         }
 686     }
 687 
 688     // Ops
 689 
 690     @Override
 691     public abstract IntVector add(Vector<Integer> v);
 692 
 693     /**
 694      * Adds this vector to the broadcast of an input scalar.
 695      * <p>
 696      * This is a vector binary operation where the primitive addition operation
 697      * ({@code +}) is applied to lane elements.
 698      *
 699      * @param s the input scalar
 700      * @return the result of adding this vector to the broadcast of an input
 701      * scalar
 702      */
 703     public abstract IntVector add(int s);
 704 
 705     @Override
 706     public abstract IntVector add(Vector<Integer> v, Mask<Integer> m);
 707 
 708     /**
 709      * Adds this vector to broadcast of an input scalar,
 710      * selecting lane elements controlled by a mask.
 711      * <p>
 712      * This is a vector binary operation where the primitive addition operation
 713      * ({@code +}) is applied to lane elements.
 714      *
 715      * @param s the input scalar
 716      * @param m the mask controlling lane selection
 717      * @return the result of adding this vector to the broadcast of an input
 718      * scalar
 719      */
 720     public abstract IntVector add(int s, Mask<Integer> m);
 721 
 722     @Override
 723     public abstract IntVector sub(Vector<Integer> v);
 724 
 725     /**
 726      * Subtracts the broadcast of an input scalar from this vector.
 727      * <p>
 728      * This is a vector binary operation where the primitive subtraction
 729      * operation ({@code -}) is applied to lane elements.
 730      *
 731      * @param s the input scalar
 732      * @return the result of subtracting the broadcast of an input
 733      * scalar from this vector
 734      */
 735     public abstract IntVector sub(int s);
 736 
 737     @Override
 738     public abstract IntVector sub(Vector<Integer> v, Mask<Integer> m);
 739 
 740     /**
 741      * Subtracts the broadcast of an input scalar from this vector, selecting
 742      * lane elements controlled by a mask.
 743      * <p>
 744      * This is a vector binary operation where the primitive subtraction
 745      * operation ({@code -}) is applied to lane elements.
 746      *
 747      * @param s the input scalar
 748      * @param m the mask controlling lane selection
 749      * @return the result of subtracting the broadcast of an input
 750      * scalar from this vector
 751      */
 752     public abstract IntVector sub(int s, Mask<Integer> m);
 753 
 754     @Override
 755     public abstract IntVector mul(Vector<Integer> v);
 756 
 757     /**
 758      * Multiplies this vector with the broadcast of an input scalar.
 759      * <p>
 760      * This is a vector binary operation where the primitive multiplication
 761      * operation ({@code *}) is applied to lane elements.
 762      *
 763      * @param s the input scalar
 764      * @return the result of multiplying this vector with the broadcast of an
 765      * input scalar
 766      */
 767     public abstract IntVector mul(int s);
 768 
 769     @Override
 770     public abstract IntVector mul(Vector<Integer> v, Mask<Integer> m);
 771 
 772     /**
 773      * Multiplies this vector with the broadcast of an input scalar, selecting
 774      * lane elements controlled by a mask.
 775      * <p>
 776      * This is a vector binary operation where the primitive multiplication
 777      * operation ({@code *}) is applied to lane elements.
 778      *
 779      * @param s the input scalar
 780      * @param m the mask controlling lane selection
 781      * @return the result of multiplying this vector with the broadcast of an
 782      * input scalar
 783      */
 784     public abstract IntVector mul(int s, Mask<Integer> m);
 785 
 786     @Override
 787     public abstract IntVector neg();
 788 
 789     @Override
 790     public abstract IntVector neg(Mask<Integer> m);
 791 
 792     @Override
 793     public abstract IntVector abs();
 794 
 795     @Override
 796     public abstract IntVector abs(Mask<Integer> m);
 797 
 798     @Override
 799     public abstract IntVector min(Vector<Integer> v);
 800 
 801     @Override
 802     public abstract IntVector min(Vector<Integer> v, Mask<Integer> m);
 803 
 804     /**
 805      * Returns the minimum of this vector and the broadcast of an input scalar.
 806      * <p>
 807      * This is a vector binary operation where the operation
 808      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 809      *
 810      * @param s the input scalar
 811      * @return the minimum of this vector and the broadcast of an input scalar
 812      */
 813     public abstract IntVector min(int s);
 814 
 815     @Override
 816     public abstract IntVector max(Vector<Integer> v);
 817 
 818     @Override
 819     public abstract IntVector max(Vector<Integer> v, Mask<Integer> m);
 820 
 821     /**
 822      * Returns the maximum of this vector and the broadcast of an input scalar.
 823      * <p>
 824      * This is a vector binary operation where the operation
 825      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 826      *
 827      * @param s the input scalar
 828      * @return the maximum of this vector and the broadcast of an input scalar
 829      */
 830     public abstract IntVector max(int s);
 831 
 832     @Override
 833     public abstract Mask<Integer> equal(Vector<Integer> v);
 834 
 835     /**
 836      * Tests if this vector is equal to the broadcast of an input scalar.
 837      * <p>
 838      * This is a vector binary test operation where the primitive equals
 839      * operation ({@code ==}) is applied to lane elements.
 840      *
 841      * @param s the input scalar
 842      * @return the result mask of testing if this vector is equal to the
 843      * broadcast of an input scalar
 844      */
 845     public abstract Mask<Integer> equal(int s);
 846 
 847     @Override
 848     public abstract Mask<Integer> notEqual(Vector<Integer> v);
 849 
 850     /**
 851      * Tests if this vector is not equal to the broadcast of an input scalar.
 852      * <p>
 853      * This is a vector binary test operation where the primitive not equals
 854      * operation ({@code !=}) is applied to lane elements.
 855      *
 856      * @param s the input scalar
 857      * @return the result mask of testing if this vector is not equal to the
 858      * broadcast of an input scalar
 859      */
 860     public abstract Mask<Integer> notEqual(int s);
 861 
 862     @Override
 863     public abstract Mask<Integer> lessThan(Vector<Integer> v);
 864 
 865     /**
 866      * Tests if this vector is less than the broadcast of an input scalar.
 867      * <p>
 868      * This is a vector binary test operation where the primitive less than
 869      * operation ({@code <}) is applied to lane elements.
 870      *
 871      * @param s the input scalar
 872      * @return the mask result of testing if this vector is less than the
 873      * broadcast of an input scalar
 874      */
 875     public abstract Mask<Integer> lessThan(int s);
 876 
 877     @Override
 878     public abstract Mask<Integer> lessThanEq(Vector<Integer> v);
 879 
 880     /**
 881      * Tests if this vector is less or equal to the broadcast of an input scalar.
 882      * <p>
 883      * This is a vector binary test operation where the primitive less than
 884      * or equal to operation ({@code <=}) is applied to lane elements.
 885      *
 886      * @param s the input scalar
 887      * @return the mask result of testing if this vector is less than or equal
 888      * to the broadcast of an input scalar
 889      */
 890     public abstract Mask<Integer> lessThanEq(int s);
 891 
 892     @Override
 893     public abstract Mask<Integer> greaterThan(Vector<Integer> v);
 894 
 895     /**
 896      * Tests if this vector is greater than the broadcast of an input scalar.
 897      * <p>
 898      * This is a vector binary test operation where the primitive greater than
 899      * operation ({@code >}) is applied to lane elements.
 900      *
 901      * @param s the input scalar
 902      * @return the mask result of testing if this vector is greater than the
 903      * broadcast of an input scalar
 904      */
 905     public abstract Mask<Integer> greaterThan(int s);
 906 
 907     @Override
 908     public abstract Mask<Integer> greaterThanEq(Vector<Integer> v);
 909 
 910     /**
 911      * Tests if this vector is greater than or equal to the broadcast of an
 912      * input scalar.
 913      * <p>
 914      * This is a vector binary test operation where the primitive greater than
 915      * or equal to operation ({@code >=}) is applied to lane elements.
 916      *
 917      * @param s the input scalar
 918      * @return the mask result of testing if this vector is greater than or
 919      * equal to the broadcast of an input scalar
 920      */
 921     public abstract Mask<Integer> greaterThanEq(int s);
 922 
 923     @Override
 924     public abstract IntVector blend(Vector<Integer> v, Mask<Integer> m);
 925 
 926     /**
 927      * Blends the lane elements of this vector with those of the broadcast of an
 928      * input scalar, selecting lanes controlled by a mask.
 929      * <p>
 930      * For each lane of the mask, at lane index {@code N}, if the mask lane
 931      * is set then the lane element at {@code N} from the input vector is
 932      * selected and placed into the resulting vector at {@code N},
 933      * otherwise the the lane element at {@code N} from this input vector is
 934      * selected and placed into the resulting vector at {@code N}.
 935      *
 936      * @param s the input scalar
 937      * @param m the mask controlling lane selection
 938      * @return the result of blending the lane elements of this vector with
 939      * those of the broadcast of an input scalar
 940      */
 941     public abstract IntVector blend(int s, Mask<Integer> m);
 942 
 943     @Override
 944     public abstract IntVector rearrange(Vector<Integer> v,
 945                                                       Shuffle<Integer> s, Mask<Integer> m);
 946 
 947     @Override
 948     public abstract IntVector rearrange(Shuffle<Integer> m);
 949 
 950     @Override
 951     public abstract IntVector reshape(Species<Integer> s);
 952 
 953     @Override
 954     public abstract IntVector rotateEL(int i);
 955 
 956     @Override
 957     public abstract IntVector rotateER(int i);
 958 
 959     @Override
 960     public abstract IntVector shiftEL(int i);
 961 
 962     @Override
 963     public abstract IntVector shiftER(int i);
 964 
 965 
 966 
 967     /**
 968      * Bitwise ANDs this vector with an input vector.
 969      * <p>
 970      * This is a vector binary operation where the primitive bitwise AND
 971      * operation ({@code &}) is applied to lane elements.


 981      * This is a vector binary operation where the primitive bitwise AND
 982      * operation ({@code &}) is applied to lane elements.
 983      *
 984      * @param s the input scalar
 985      * @return the bitwise AND of this vector with the broadcast of an input
 986      * scalar
 987      */
 988     public abstract IntVector and(int s);
 989 
 990     /**
 991      * Bitwise ANDs this vector with an input vector, selecting lane elements
 992      * controlled by a mask.
 993      * <p>
 994      * This is a vector binary operation where the primitive bitwise AND
 995      * operation ({@code &}) is applied to lane elements.
 996      *
 997      * @param v the input vector
 998      * @param m the mask controlling lane selection
 999      * @return the bitwise AND of this vector with the input vector
1000      */
1001     public abstract IntVector and(Vector<Integer> v, Mask<Integer> m);
1002 
1003     /**
1004      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
1005      * lane elements controlled by a mask.
1006      * <p>
1007      * This is a vector binary operation where the primitive bitwise AND
1008      * operation ({@code &}) is applied to lane elements.
1009      *
1010      * @param s the input scalar
1011      * @param m the mask controlling lane selection
1012      * @return the bitwise AND of this vector with the broadcast of an input
1013      * scalar
1014      */
1015     public abstract IntVector and(int s, Mask<Integer> m);
1016 
1017     /**
1018      * Bitwise ORs this vector with an input vector.
1019      * <p>
1020      * This is a vector binary operation where the primitive bitwise OR
1021      * operation ({@code |}) is applied to lane elements.
1022      *
1023      * @param v the input vector
1024      * @return the bitwise OR of this vector with the input vector
1025      */
1026     public abstract IntVector or(Vector<Integer> v);
1027 
1028     /**
1029      * Bitwise ORs this vector with the broadcast of an input scalar.
1030      * <p>
1031      * This is a vector binary operation where the primitive bitwise OR
1032      * operation ({@code |}) is applied to lane elements.
1033      *
1034      * @param s the input scalar
1035      * @return the bitwise OR of this vector with the broadcast of an input
1036      * scalar
1037      */
1038     public abstract IntVector or(int s);
1039 
1040     /**
1041      * Bitwise ORs this vector with an input vector, selecting lane elements
1042      * controlled by a mask.
1043      * <p>
1044      * This is a vector binary operation where the primitive bitwise OR
1045      * operation ({@code |}) is applied to lane elements.
1046      *
1047      * @param v the input vector
1048      * @param m the mask controlling lane selection
1049      * @return the bitwise OR of this vector with the input vector
1050      */
1051     public abstract IntVector or(Vector<Integer> v, Mask<Integer> m);
1052 
1053     /**
1054      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
1055      * lane elements controlled by a mask.
1056      * <p>
1057      * This is a vector binary operation where the primitive bitwise OR
1058      * operation ({@code |}) is applied to lane elements.
1059      *
1060      * @param s the input scalar
1061      * @param m the mask controlling lane selection
1062      * @return the bitwise OR of this vector with the broadcast of an input
1063      * scalar
1064      */
1065     public abstract IntVector or(int s, Mask<Integer> m);
1066 
1067     /**
1068      * Bitwise XORs this vector with an input vector.
1069      * <p>
1070      * This is a vector binary operation where the primitive bitwise XOR
1071      * operation ({@code ^}) is applied to lane elements.
1072      *
1073      * @param v the input vector
1074      * @return the bitwise XOR of this vector with the input vector
1075      */
1076     public abstract IntVector xor(Vector<Integer> v);
1077 
1078     /**
1079      * Bitwise XORs this vector with the broadcast of an input scalar.
1080      * <p>
1081      * This is a vector binary operation where the primitive bitwise XOR
1082      * operation ({@code ^}) is applied to lane elements.
1083      *
1084      * @param s the input scalar
1085      * @return the bitwise XOR of this vector with the broadcast of an input
1086      * scalar
1087      */
1088     public abstract IntVector xor(int s);
1089 
1090     /**
1091      * Bitwise XORs this vector with an input vector, selecting lane elements
1092      * controlled by a mask.
1093      * <p>
1094      * This is a vector binary operation where the primitive bitwise XOR
1095      * operation ({@code ^}) is applied to lane elements.
1096      *
1097      * @param v the input vector
1098      * @param m the mask controlling lane selection
1099      * @return the bitwise XOR of this vector with the input vector
1100      */
1101     public abstract IntVector xor(Vector<Integer> v, Mask<Integer> m);
1102 
1103     /**
1104      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1105      * lane elements controlled by a mask.
1106      * <p>
1107      * This is a vector binary operation where the primitive bitwise XOR
1108      * operation ({@code ^}) is applied to lane elements.
1109      *
1110      * @param s the input scalar
1111      * @param m the mask controlling lane selection
1112      * @return the bitwise XOR of this vector with the broadcast of an input
1113      * scalar
1114      */
1115     public abstract IntVector xor(int s, Mask<Integer> m);
1116 
1117     /**
1118      * Bitwise NOTs this vector.
1119      * <p>
1120      * This is a vector unary operation where the primitive bitwise NOT
1121      * operation ({@code ~}) is applied to lane elements.
1122      *
1123      * @return the bitwise NOT of this vector
1124      */
1125     public abstract IntVector not();
1126 
1127     /**
1128      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1129      * <p>
1130      * This is a vector unary operation where the primitive bitwise NOT
1131      * operation ({@code ~}) is applied to lane elements.
1132      *
1133      * @param m the mask controlling lane selection
1134      * @return the bitwise NOT of this vector
1135      */
1136     public abstract IntVector not(Mask<Integer> m);
1137 
1138     /**
1139      * Logically left shifts this vector by the broadcast of an input scalar.
1140      * <p>
1141      * This is a vector binary operation where the primitive logical left shift
1142      * operation ({@code <<}) is applied to lane elements.
1143      *
1144      * @param s the input scalar; the number of the bits to left shift
1145      * @return the result of logically left shifting left this vector by the
1146      * broadcast of an input scalar
1147      */
1148     public abstract IntVector shiftL(int s);
1149 
1150     /**
1151      * Logically left shifts this vector by the broadcast of an input scalar,
1152      * selecting lane elements controlled by a mask.
1153      * <p>
1154      * This is a vector binary operation where the primitive logical left shift
1155      * operation ({@code <<}) is applied to lane elements.
1156      *
1157      * @param s the input scalar; the number of the bits to left shift
1158      * @param m the mask controlling lane selection
1159      * @return the result of logically left shifting this vector by the
1160      * broadcast of an input scalar
1161      */
1162     public abstract IntVector shiftL(int s, Mask<Integer> m);
1163 
1164     /**
1165      * Logically left shifts this vector by an input vector.
1166      * <p>
1167      * This is a vector binary operation where the primitive logical left shift
1168      * operation ({@code <<}) is applied to lane elements.
1169      *
1170      * @param v the input vector
1171      * @return the result of logically left shifting this vector by the input
1172      * vector
1173      */
1174     public abstract IntVector shiftL(Vector<Integer> v);
1175 
1176     /**
1177      * Logically left shifts this vector by an input vector, selecting lane
1178      * elements controlled by a mask.
1179      * <p>
1180      * This is a vector binary operation where the primitive logical left shift
1181      * operation ({@code <<}) is applied to lane elements.
1182      *
1183      * @param v the input vector
1184      * @param m the mask controlling lane selection
1185      * @return the result of logically left shifting this vector by the input
1186      * vector
1187      */
1188     public IntVector shiftL(Vector<Integer> v, Mask<Integer> m) {
1189         return bOp(v, m, (i, a, b) -> (int) (a << b));
1190     }
1191 
1192     // logical, or unsigned, shift right
1193 
1194     /**
1195      * Logically right shifts (or unsigned right shifts) this vector by the
1196      * broadcast of an input scalar.
1197      * <p>
1198      * This is a vector binary operation where the primitive logical right shift
1199      * operation ({@code >>>}) is applied to lane elements.
1200      *
1201      * @param s the input scalar; the number of the bits to right shift
1202      * @return the result of logically right shifting this vector by the
1203      * broadcast of an input scalar
1204      */
1205     public abstract IntVector shiftR(int s);
1206 
1207     /**
1208      * Logically right shifts (or unsigned right shifts) this vector by the
1209      * broadcast of an input scalar, selecting lane elements controlled by a
1210      * mask.
1211      * <p>
1212      * This is a vector binary operation where the primitive logical right shift
1213      * operation ({@code >>>}) is applied to lane elements.
1214      *
1215      * @param s the input scalar; the number of the bits to right shift
1216      * @param m the mask controlling lane selection
1217      * @return the result of logically right shifting this vector by the
1218      * broadcast of an input scalar
1219      */
1220     public abstract IntVector shiftR(int s, Mask<Integer> m);
1221 
1222     /**
1223      * Logically right shifts (or unsigned right shifts) this vector by an
1224      * input vector.
1225      * <p>
1226      * This is a vector binary operation where the primitive logical right shift
1227      * operation ({@code >>>}) is applied to lane elements.
1228      *
1229      * @param v the input vector
1230      * @return the result of logically right shifting this vector by the
1231      * input vector
1232      */
1233     public abstract IntVector shiftR(Vector<Integer> v);
1234 
1235     /**
1236      * Logically right shifts (or unsigned right shifts) this vector by an
1237      * input vector, selecting lane elements controlled by a mask.
1238      * <p>
1239      * This is a vector binary operation where the primitive logical right shift
1240      * operation ({@code >>>}) is applied to lane elements.
1241      *
1242      * @param v the input vector
1243      * @param m the mask controlling lane selection
1244      * @return the result of logically right shifting this vector by the
1245      * input vector
1246      */
1247     public IntVector shiftR(Vector<Integer> v, Mask<Integer> m) {
1248         return bOp(v, m, (i, a, b) -> (int) (a >>> b));
1249     }
1250 
1251     /**
1252      * Arithmetically right shifts (or signed right shifts) this vector by the
1253      * broadcast of an input scalar.
1254      * <p>
1255      * This is a vector binary operation where the primitive arithmetic right
1256      * shift operation ({@code >>}) is applied to lane elements.
1257      *
1258      * @param s the input scalar; the number of the bits to right shift
1259      * @return the result of arithmetically right shifting this vector by the
1260      * broadcast of an input scalar
1261      */
1262     public abstract IntVector aShiftR(int s);
1263 
1264     /**
1265      * Arithmetically right shifts (or signed right shifts) this vector by the
1266      * broadcast of an input scalar, selecting lane elements controlled by a
1267      * mask.
1268      * <p>
1269      * This is a vector binary operation where the primitive arithmetic right
1270      * shift operation ({@code >>}) is applied to lane elements.
1271      *
1272      * @param s the input scalar; the number of the bits to right shift
1273      * @param m the mask controlling lane selection
1274      * @return the result of arithmetically right shifting this vector by the
1275      * broadcast of an input scalar
1276      */
1277     public abstract IntVector aShiftR(int s, Mask<Integer> m);
1278 
1279     /**
1280      * Arithmetically right shifts (or signed right shifts) this vector by an
1281      * input vector.
1282      * <p>
1283      * This is a vector binary operation where the primitive arithmetic right
1284      * shift operation ({@code >>}) is applied to lane elements.
1285      *
1286      * @param v the input vector
1287      * @return the result of arithmetically right shifting this vector by the
1288      * input vector
1289      */
1290     public abstract IntVector aShiftR(Vector<Integer> v);
1291 
1292     /**
1293      * Arithmetically right shifts (or signed right shifts) this vector by an
1294      * input vector, selecting lane elements controlled by a mask.
1295      * <p>
1296      * This is a vector binary operation where the primitive arithmetic right
1297      * shift operation ({@code >>}) is applied to lane elements.
1298      *
1299      * @param v the input vector
1300      * @param m the mask controlling lane selection
1301      * @return the result of arithmetically right shifting this vector by the
1302      * input vector
1303      */
1304     public IntVector aShiftR(Vector<Integer> v, Mask<Integer> m) {
1305         return bOp(v, m, (i, a, b) -> (int) (a >> b));
1306     }
1307 
1308     /**
1309      * Rotates left this vector by the broadcast of an input scalar.
1310      * <p>
1311      * This is a vector binary operation where the operation
1312      * {@link Integer#rotateLeft} is applied to lane elements and where
1313      * lane elements of this vector apply to the first argument, and lane
1314      * elements of the broadcast vector apply to the second argument (the
1315      * rotation distance).
1316      *
1317      * @param s the input scalar; the number of the bits to rotate left
1318      * @return the result of rotating left this vector by the broadcast of an
1319      * input scalar
1320      */
1321     @ForceInline
1322     public final IntVector rotateL(int s) {
1323         return shiftL(s).or(shiftR(-s));
1324     }
1325 
1326     /**
1327      * Rotates left this vector by the broadcast of an input scalar, selecting
1328      * lane elements controlled by a mask.
1329      * <p>
1330      * This is a vector binary operation where the operation
1331      * {@link Integer#rotateLeft} is applied to lane elements and where
1332      * lane elements of this vector apply to the first argument, and lane
1333      * elements of the broadcast vector apply to the second argument (the
1334      * rotation distance).
1335      *
1336      * @param s the input scalar; the number of the bits to rotate left
1337      * @param m the mask controlling lane selection
1338      * @return the result of rotating left this vector by the broadcast of an
1339      * input scalar
1340      */
1341     @ForceInline
1342     public final IntVector rotateL(int s, Mask<Integer> m) {
1343         return shiftL(s, m).or(shiftR(-s, m), m);
1344     }
1345 
1346     /**
1347      * Rotates right this vector by the broadcast of an input scalar.
1348      * <p>
1349      * This is a vector binary operation where the operation
1350      * {@link Integer#rotateRight} is applied to lane elements and where
1351      * lane elements of this vector apply to the first argument, and lane
1352      * elements of the broadcast vector apply to the second argument (the
1353      * rotation distance).
1354      *
1355      * @param s the input scalar; the number of the bits to rotate right
1356      * @return the result of rotating right this vector by the broadcast of an
1357      * input scalar
1358      */
1359     @ForceInline
1360     public final IntVector rotateR(int s) {
1361         return shiftR(s).or(shiftL(-s));
1362     }
1363 
1364     /**
1365      * Rotates right this vector by the broadcast of an input scalar, selecting
1366      * lane elements controlled by a mask.
1367      * <p>
1368      * This is a vector binary operation where the operation
1369      * {@link Integer#rotateRight} is applied to lane elements and where
1370      * lane elements of this vector apply to the first argument, and lane
1371      * elements of the broadcast vector apply to the second argument (the
1372      * rotation distance).
1373      *
1374      * @param s the input scalar; the number of the bits to rotate right
1375      * @param m the mask controlling lane selection
1376      * @return the result of rotating right this vector by the broadcast of an
1377      * input scalar
1378      */
1379     @ForceInline
1380     public final IntVector rotateR(int s, Mask<Integer> m) {
1381         return shiftR(s, m).or(shiftL(-s, m), m);
1382     }
1383 
1384     @Override
1385     public abstract void intoByteArray(byte[] a, int ix);
1386 
1387     @Override
1388     public abstract void intoByteArray(byte[] a, int ix, Mask<Integer> m);
1389 
1390     @Override
1391     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1392 
1393     @Override
1394     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Integer> m);
1395 
1396 
1397     // Type specific horizontal reductions
1398     /**
1399      * Adds all lane elements of this vector.
1400      * <p>
1401      * This is an associative vector reduction operation where the addition
1402      * operation ({@code +}) is applied to lane elements,
1403      * and the identity value is {@code 0}.
1404      *
1405      * @return the addition of all the lane elements of this vector
1406      */
1407     public abstract int addAll();
1408 
1409     /**
1410      * Adds all lane elements of this vector, selecting lane elements
1411      * controlled by a mask.
1412      * <p>
1413      * This is an associative vector reduction operation where the addition
1414      * operation ({@code +}) is applied to lane elements,
1415      * and the identity value is {@code 0}.
1416      *
1417      * @param m the mask controlling lane selection
1418      * @return the addition of the selected lane elements of this vector
1419      */
1420     public abstract int addAll(Mask<Integer> m);
1421 
1422     /**
1423      * Multiplies all lane elements of this vector.
1424      * <p>
1425      * This is an associative vector reduction operation where the
1426      * multiplication operation ({@code *}) is applied to lane elements,
1427      * and the identity value is {@code 1}.
1428      *
1429      * @return the multiplication of all the lane elements of this vector
1430      */
1431     public abstract int mulAll();
1432 
1433     /**
1434      * Multiplies all lane elements of this vector, selecting lane elements
1435      * controlled by a mask.
1436      * <p>
1437      * This is an associative vector reduction operation where the
1438      * multiplication operation ({@code *}) is applied to lane elements,
1439      * and the identity value is {@code 1}.
1440      *
1441      * @param m the mask controlling lane selection
1442      * @return the multiplication of all the lane elements of this vector
1443      */
1444     public abstract int mulAll(Mask<Integer> m);
1445 
1446     /**
1447      * Returns the minimum lane element of this vector.
1448      * <p>
1449      * This is an associative vector reduction operation where the operation
1450      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1451      * and the identity value is
1452      * {@link Integer#MAX_VALUE}.
1453      *
1454      * @return the minimum lane element of this vector
1455      */
1456     public abstract int minAll();
1457 
1458     /**
1459      * Returns the minimum lane element of this vector, selecting lane elements
1460      * controlled by a mask.
1461      * <p>
1462      * This is an associative vector reduction operation where the operation
1463      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1464      * and the identity value is
1465      * {@link Integer#MAX_VALUE}.
1466      *
1467      * @param m the mask controlling lane selection
1468      * @return the minimum lane element of this vector
1469      */
1470     public abstract int minAll(Mask<Integer> m);
1471 
1472     /**
1473      * Returns the maximum lane element of this vector.
1474      * <p>
1475      * This is an associative vector reduction operation where the operation
1476      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1477      * and the identity value is
1478      * {@link Integer#MIN_VALUE}.
1479      *
1480      * @return the maximum lane element of this vector
1481      */
1482     public abstract int maxAll();
1483 
1484     /**
1485      * Returns the maximum lane element of this vector, selecting lane elements
1486      * controlled by a mask.
1487      * <p>
1488      * This is an associative vector reduction operation where the operation
1489      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1490      * and the identity value is
1491      * {@link Integer#MIN_VALUE}.
1492      *
1493      * @param m the mask controlling lane selection
1494      * @return the maximum lane element of this vector
1495      */
1496     public abstract int maxAll(Mask<Integer> m);
1497 
1498     /**
1499      * Logically ORs all lane elements of this vector.
1500      * <p>
1501      * This is an associative vector reduction operation where the logical OR
1502      * operation ({@code |}) is applied to lane elements,
1503      * and the identity value is {@code 0}.
1504      *
1505      * @return the logical OR all the lane elements of this vector
1506      */
1507     public abstract int orAll();
1508 
1509     /**
1510      * Logically ORs all lane elements of this vector, selecting lane elements
1511      * controlled by a mask.
1512      * <p>
1513      * This is an associative vector reduction operation where the logical OR
1514      * operation ({@code |}) is applied to lane elements,
1515      * and the identity value is {@code 0}.
1516      *
1517      * @param m the mask controlling lane selection
1518      * @return the logical OR all the lane elements of this vector
1519      */
1520     public abstract int orAll(Mask<Integer> m);
1521 
1522     /**
1523      * Logically ANDs all lane elements of this vector.
1524      * <p>
1525      * This is an associative vector reduction operation where the logical AND
1526      * operation ({@code |}) is applied to lane elements,
1527      * and the identity value is {@code -1}.
1528      *
1529      * @return the logical AND all the lane elements of this vector
1530      */
1531     public abstract int andAll();
1532 
1533     /**
1534      * Logically ANDs all lane elements of this vector, selecting lane elements
1535      * controlled by a mask.
1536      * <p>
1537      * This is an associative vector reduction operation where the logical AND
1538      * operation ({@code |}) is applied to lane elements,
1539      * and the identity value is {@code -1}.
1540      *
1541      * @param m the mask controlling lane selection
1542      * @return the logical AND all the lane elements of this vector
1543      */
1544     public abstract int andAll(Mask<Integer> m);
1545 
1546     /**
1547      * Logically XORs all lane elements of this vector.
1548      * <p>
1549      * This is an associative vector reduction operation where the logical XOR
1550      * operation ({@code ^}) is applied to lane elements,
1551      * and the identity value is {@code 0}.
1552      *
1553      * @return the logical XOR all the lane elements of this vector
1554      */
1555     public abstract int xorAll();
1556 
1557     /**
1558      * Logically XORs all lane elements of this vector, selecting lane elements
1559      * controlled by a mask.
1560      * <p>
1561      * This is an associative vector reduction operation where the logical XOR
1562      * operation ({@code ^}) is applied to lane elements,
1563      * and the identity value is {@code 0}.
1564      *
1565      * @param m the mask controlling lane selection
1566      * @return the logical XOR all the lane elements of this vector
1567      */
1568     public abstract int xorAll(Mask<Integer> m);
1569 
1570     // Type specific accessors
1571 
1572     /**
1573      * Gets the lane element at lane index {@code i}
1574      *
1575      * @param i the lane index
1576      * @return the lane element at lane index {@code i}
1577      * @throws IllegalArgumentException if the index is is out of range
1578      * ({@code < 0 || >= length()})
1579      */
1580     public abstract int get(int i);
1581 
1582     /**
1583      * Replaces the lane element of this vector at lane index {@code i} with
1584      * value {@code e}.
1585      * <p>
1586      * This is a cross-lane operation and behaves as if it returns the result
1587      * of blending this vector with an input vector that is the result of
1588      * broadcasting {@code e} and a mask that has only one lane set at lane


1630      * @param i the offset into the array
1631      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1632      * {@code i > a.length - this.length()}
1633      */
1634     public abstract void intoArray(int[] a, int i);
1635 
1636     /**
1637      * Stores this vector into an array starting at offset and using a mask.
1638      * <p>
1639      * For each vector lane, where {@code N} is the vector lane index,
1640      * if the mask lane at index {@code N} is set then the lane element at
1641      * index {@code N} is stored into the array index {@code i + N}.
1642      *
1643      * @param a the array
1644      * @param i the offset into the array
1645      * @param m the mask
1646      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1647      * for any vector lane index {@code N} where the mask at lane {@code N}
1648      * is set {@code i >= a.length - N}
1649      */
1650     public abstract void intoArray(int[] a, int i, Mask<Integer> m);
1651 
1652     /**
1653      * Stores this vector into an array using indexes obtained from an index
1654      * map.
1655      * <p>
1656      * For each vector lane, where {@code N} is the vector lane index, the
1657      * lane element at index {@code N} is stored into the array at index
1658      * {@code i + indexMap[j + N]}.
1659      *
1660      * @param a the array
1661      * @param i the offset into the array, may be negative if relative
1662      * indexes in the index map compensate to produce a value within the
1663      * array bounds
1664      * @param indexMap the index map
1665      * @param j the offset into the index map
1666      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1667      * {@code j > indexMap.length - this.length()},
1668      * or for any vector lane index {@code N} the result of
1669      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1670      */


1675      * map and using a mask.
1676      * <p>
1677      * For each vector lane, where {@code N} is the vector lane index,
1678      * if the mask lane at index {@code N} is set then the lane element at
1679      * index {@code N} is stored into the array at index
1680      * {@code i + indexMap[j + N]}.
1681      *
1682      * @param a the array
1683      * @param i the offset into the array, may be negative if relative
1684      * indexes in the index map compensate to produce a value within the
1685      * array bounds
1686      * @param m the mask
1687      * @param indexMap the index map
1688      * @param j the offset into the index map
1689      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1690      * {@code j > indexMap.length - this.length()},
1691      * or for any vector lane index {@code N} where the mask at lane
1692      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1693      * {@code < 0} or {@code >= a.length}
1694      */
1695     public abstract void intoArray(int[] a, int i, Mask<Integer> m, int[] indexMap, int j);
1696     // Species
1697 
1698     @Override
1699     public abstract Species<Integer> species();
1700 
1701     /**
1702      * Class representing {@link IntVector}'s of the same {@link Vector.Shape Shape}.
1703      */
1704     static final class IntSpecies extends Vector.AbstractSpecies<Integer> {
1705         final Function<int[], IntVector> vectorFactory;
1706         final Function<boolean[], Vector.Mask<Integer>> maskFactory;
1707 
1708         private IntSpecies(Vector.Shape shape,
1709                           Class<?> boxType,
1710                           Class<?> maskType,
1711                           Function<int[], IntVector> vectorFactory,
1712                           Function<boolean[], Vector.Mask<Integer>> maskFactory) {
1713             super(shape, int.class, Integer.SIZE, boxType, maskType);



1714             this.vectorFactory = vectorFactory;
1715             this.maskFactory = maskFactory;
1716         }
1717 
1718         interface FOp {
1719             int apply(int i);
1720         }
1721 
1722         interface FOpm {
1723             boolean apply(int i);
1724         }
1725 
1726         IntVector op(FOp f) {
1727             int[] res = new int[length()];
1728             for (int i = 0; i < length(); i++) {
1729                 res[i] = f.apply(i);
1730             }
1731             return vectorFactory.apply(res);
1732         }
1733 
1734         IntVector op(Vector.Mask<Integer> o, FOp f) {
1735             int[] res = new int[length()];
1736             boolean[] mbits = ((AbstractMask<Integer>)o).getBits();
1737             for (int i = 0; i < length(); i++) {
1738                 if (mbits[i]) {
1739                     res[i] = f.apply(i);
1740                 }
1741             }
1742             return vectorFactory.apply(res);
1743         }
1744 
1745         Vector.Mask<Integer> opm(IntVector.IntSpecies.FOpm f) {
1746             boolean[] res = new boolean[length()];
1747             for (int i = 0; i < length(); i++) {
1748                 res[i] = (boolean)f.apply(i);
1749             }
1750             return maskFactory.apply(res);
1751         }
1752     }
1753 
1754     /**
1755      * Finds the preferred species for an element type of {@code int}.
1756      * <p>
1757      * A preferred species is a species chosen by the platform that has a
1758      * shape of maximal bit size.  A preferred species for different element
1759      * types will have the same shape, and therefore vectors, masks, and
1760      * shuffles created from such species will be shape compatible.
1761      *
1762      * @return the preferred species for an element type of {@code int}
1763      */
1764     private static IntSpecies preferredSpecies() {
1765         return (IntSpecies) Species.ofPreferred(int.class);
1766     }
1767 
1768     /**
1769      * Finds a species for an element type of {@code int} and shape.
1770      *
1771      * @param s the shape
1772      * @return a species for an element type of {@code int} and shape
1773      * @throws IllegalArgumentException if no such species exists for the shape
1774      */
1775     static IntSpecies species(Vector.Shape s) {
1776         Objects.requireNonNull(s);
1777         switch (s) {
1778             case S_64_BIT: return (IntSpecies) SPECIES_64;
1779             case S_128_BIT: return (IntSpecies) SPECIES_128;
1780             case S_256_BIT: return (IntSpecies) SPECIES_256;
1781             case S_512_BIT: return (IntSpecies) SPECIES_512;
1782             case S_Max_BIT: return (IntSpecies) SPECIES_MAX;
1783             default: throw new IllegalArgumentException("Bad shape: " + s);
1784         }
1785     }
1786 
1787     /** Species representing {@link IntVector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */
1788     public static final Species<Integer> SPECIES_64 = new IntSpecies(Shape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class,
1789                                                                      Int64Vector::new, Int64Vector.Int64Mask::new);
1790 
1791     /** Species representing {@link IntVector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */
1792     public static final Species<Integer> SPECIES_128 = new IntSpecies(Shape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class,
1793                                                                       Int128Vector::new, Int128Vector.Int128Mask::new);
1794 
1795     /** Species representing {@link IntVector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */
1796     public static final Species<Integer> SPECIES_256 = new IntSpecies(Shape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class,
1797                                                                       Int256Vector::new, Int256Vector.Int256Mask::new);
1798 
1799     /** Species representing {@link IntVector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */
1800     public static final Species<Integer> SPECIES_512 = new IntSpecies(Shape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class,
1801                                                                       Int512Vector::new, Int512Vector.Int512Mask::new);
1802 
1803     /** Species representing {@link IntVector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */
1804     public static final Species<Integer> SPECIES_MAX = new IntSpecies(Shape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class,
1805                                                                       IntMaxVector::new, IntMaxVector.IntMaxMask::new);





1806 
1807     /**
1808      * Preferred species for {@link IntVector}s.
1809      * A preferred species is a species of maximal bit size for the platform.
1810      */
1811     public static final Species<Integer> SPECIES_PREFERRED = (Species<Integer>) preferredSpecies();
1812 }


  39 
  40 /**
  41  * A specialized {@link Vector} representing an ordered immutable sequence of
  42  * {@code int} values.
  43  */
  44 @SuppressWarnings("cast")
  45 public abstract class IntVector extends Vector<Integer> {
  46 
  47     IntVector() {}
  48 
  49     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
  50 
  51     // Unary operator
  52 
  53     interface FUnOp {
  54         int apply(int i, int a);
  55     }
  56 
  57     abstract IntVector uOp(FUnOp f);
  58 
  59     abstract IntVector uOp(VectorMask<Integer> m, FUnOp f);
  60 
  61     // Binary operator
  62 
  63     interface FBinOp {
  64         int apply(int i, int a, int b);
  65     }
  66 
  67     abstract IntVector bOp(Vector<Integer> v, FBinOp f);
  68 
  69     abstract IntVector bOp(Vector<Integer> v, VectorMask<Integer> m, FBinOp f);
  70 
  71     // Trinary operator
  72 
  73     interface FTriOp {
  74         int apply(int i, int a, int b, int c);
  75     }
  76 
  77     abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, FTriOp f);
  78 
  79     abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, VectorMask<Integer> m, FTriOp f);
  80 
  81     // Reduction operator
  82 
  83     abstract int rOp(int v, FBinOp f);
  84 
  85     // Binary test
  86 
  87     interface FBinTest {
  88         boolean apply(int i, int a, int b);
  89     }
  90 
  91     abstract VectorMask<Integer> bTest(Vector<Integer> v, FBinTest f);
  92 
  93     // Foreach
  94 
  95     interface FUnCon {
  96         void apply(int i, int a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(VectorMask<Integer> m, FUnCon f);
 102 
 103     // Static factories
 104 
 105     /**
 106      * Returns a vector where all lane elements are set to the default
 107      * primitive value.
 108      *
 109      * @param species species of desired vector
 110      * @return a zero vector of given species
 111      */
 112     @ForceInline
 113     @SuppressWarnings("unchecked")
 114     public static IntVector zero(VectorSpecies<Integer> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<IntVector>) species.boxType(), int.class, species.length(),
 116                                                  0, species,
 117                                                  ((bits, s) -> ((IntSpecies)s).op(i -> (int)bits)));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(VectorSpecies<Integer>, ByteBuffer, int, VectorMask) method} as follows:
 129      * <pre>{@code
 130      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param ix the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static IntVector fromByteArray(VectorSpecies<Integer> species, byte[] a, int ix) {
 143         Objects.requireNonNull(a);
 144         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 146                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, ix, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          IntBuffer tb = bbc.asIntBuffer();
 151                                          return ((IntSpecies)s).op(i -> tb.get());
 152                                      });
 153     }
 154 
 155     /**
 156      * Loads a vector from a byte array starting at an offset and using a
 157      * mask.
 158      * <p>
 159      * Bytes are composed into primitive lane elements according to the
 160      * native byte order of the underlying platform.
 161      * <p>
 162      * This method behaves as if it returns the result of calling the
 163      * byte buffer, offset, and mask accepting
 164      * {@link #fromByteBuffer(VectorSpecies<Integer>, ByteBuffer, int, VectorMask) method} as follows:
 165      * <pre>{@code
 166      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 167      * }</pre>
 168      *
 169      * @param species species of desired vector
 170      * @param a the byte array
 171      * @param ix the offset into the array
 172      * @param m the mask
 173      * @return a vector loaded from a byte array
 174      * @throws IndexOutOfBoundsException if {@code i < 0} or
 175      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 176      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 177      * or {@code > a.length},
 178      * for any vector lane index {@code N} where the mask at lane {@code N}
 179      * is set
 180      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 181      */
 182     @ForceInline
 183     public static IntVector fromByteArray(VectorSpecies<Integer> species, byte[] a, int ix, VectorMask<Integer> m) {
 184         return zero(species).blend(fromByteArray(species, a, ix), m);
 185     }
 186 
 187     /**
 188      * Loads a vector from an array starting at offset.
 189      * <p>
 190      * For each vector lane, where {@code N} is the vector lane index, the
 191      * array element at index {@code i + N} is placed into the
 192      * resulting vector at lane index {@code N}.
 193      *
 194      * @param species species of desired vector
 195      * @param a the array
 196      * @param i the offset into the array
 197      * @return the vector loaded from an array
 198      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 199      * {@code i > a.length - this.length()}
 200      */
 201     @ForceInline
 202     @SuppressWarnings("unchecked")
 203     public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i){
 204         Objects.requireNonNull(a);
 205         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 206         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 207                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_INT_BASE_OFFSET,
 208                                      a, i, species,
 209                                      (c, idx, s) -> ((IntSpecies)s).op(n -> c[idx + n]));
 210     }
 211 
 212 
 213     /**
 214      * Loads a vector from an array starting at offset and using a mask.
 215      * <p>
 216      * For each vector lane, where {@code N} is the vector lane index,
 217      * if the mask lane at index {@code N} is set then the array element at
 218      * index {@code i + N} is placed into the resulting vector at lane index
 219      * {@code N}, otherwise the default element value is placed into the
 220      * resulting vector at lane index {@code N}.
 221      *
 222      * @param species species of desired vector
 223      * @param a the array
 224      * @param i the offset into the array
 225      * @param m the mask
 226      * @return the vector loaded from an array
 227      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 228      * for any vector lane index {@code N} where the mask at lane {@code N}
 229      * is set {@code i > a.length - N}
 230      */
 231     @ForceInline
 232     public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i, VectorMask<Integer> m) {
 233         return zero(species).blend(fromArray(species, a, i), m);
 234     }
 235 
 236     /**
 237      * Loads a vector from an array using indexes obtained from an index
 238      * map.
 239      * <p>
 240      * For each vector lane, where {@code N} is the vector lane index, the
 241      * array element at index {@code i + indexMap[j + N]} is placed into the
 242      * resulting vector at lane index {@code N}.
 243      *
 244      * @param species species of desired vector
 245      * @param a the array
 246      * @param i the offset into the array, may be negative if relative
 247      * indexes in the index map compensate to produce a value within the
 248      * array bounds
 249      * @param indexMap the index map
 250      * @param j the offset into the index map
 251      * @return the vector loaded from an array
 252      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 253      * {@code j > indexMap.length - this.length()},
 254      * or for any vector lane index {@code N} the result of
 255      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 256      */
 257     @ForceInline
 258     @SuppressWarnings("unchecked")
 259     public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i, int[] indexMap, int j) {
 260         Objects.requireNonNull(a);
 261         Objects.requireNonNull(indexMap);
 262 
 263 
 264         // Index vector: vix[0:n] = k -> i + indexMap[j + k]
 265         IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
 266 
 267         vix = VectorIntrinsics.checkIndex(vix, a.length);
 268 
 269         return VectorIntrinsics.loadWithMap((Class<IntVector>) species.boxType(), int.class, species.length(),
 270                                             IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_INT_BASE_OFFSET, vix,
 271                                             a, i, indexMap, j, species,
 272                                             (int[] c, int idx, int[] iMap, int idy, VectorSpecies<Integer> s) ->
 273                                                 ((IntSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 274         }
 275 
 276     /**
 277      * Loads a vector from an array using indexes obtained from an index
 278      * map and using a mask.
 279      * <p>
 280      * For each vector lane, where {@code N} is the vector lane index,
 281      * if the mask lane at index {@code N} is set then the array element at
 282      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 283      * at lane index {@code N}.
 284      *
 285      * @param species species of desired vector
 286      * @param a the array
 287      * @param i the offset into the array, may be negative if relative
 288      * indexes in the index map compensate to produce a value within the
 289      * array bounds
 290      * @param m the mask
 291      * @param indexMap the index map
 292      * @param j the offset into the index map
 293      * @return the vector loaded from an array
 294      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 295      * {@code j > indexMap.length - this.length()},
 296      * or for any vector lane index {@code N} where the mask at lane
 297      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 298      * {@code < 0} or {@code >= a.length}
 299      */
 300     @ForceInline
 301     @SuppressWarnings("unchecked")
 302     public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i, VectorMask<Integer> m, int[] indexMap, int j) {
 303         // @@@ This can result in out of bounds errors for unset mask lanes
 304         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 305     }
 306 
 307 
 308     /**
 309      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 310      * offset into the byte buffer.
 311      * <p>
 312      * Bytes are composed into primitive lane elements according to the
 313      * native byte order of the underlying platform.
 314      * <p>
 315      * This method behaves as if it returns the result of calling the
 316      * byte buffer, offset, and mask accepting
 317      * {@link #fromByteBuffer(VectorSpecies<Integer>, ByteBuffer, int, VectorMask)} method} as follows:
 318      * <pre>{@code
 319      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 320      * }</pre>
 321      *
 322      * @param species species of desired vector
 323      * @param bb the byte buffer
 324      * @param ix the offset into the byte buffer
 325      * @return a vector loaded from a byte buffer
 326      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 327      * or {@code > b.limit()},
 328      * or if there are fewer than
 329      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 330      * remaining in the byte buffer from the given offset
 331      */
 332     @ForceInline
 333     @SuppressWarnings("unchecked")
 334     public static IntVector fromByteBuffer(VectorSpecies<Integer> species, ByteBuffer bb, int ix) {
 335         if (bb.order() != ByteOrder.nativeOrder()) {
 336             throw new IllegalArgumentException();
 337         }
 338         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 339         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 340                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 341                                      bb, ix, species,
 342                                      (c, idx, s) -> {
 343                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 344                                          IntBuffer tb = bbc.asIntBuffer();
 345                                          return ((IntSpecies)s).op(i -> tb.get());
 346                                      });
 347     }
 348 
 349     /**
 350      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 351      * offset into the byte buffer and using a mask.
 352      * <p>
 353      * This method behaves as if the byte buffer is viewed as a primitive
 354      * {@link java.nio.Buffer buffer} for the primitive element type,


 366      * e[] es = new e[this.length()];
 367      * for (int n = 0; n < t.length; n++) {
 368      *     if (m.isSet(n))
 369      *         es[n] = eb.get(n);
 370      * }
 371      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 372      * }</pre>
 373      *
 374      * @param species species of desired vector
 375      * @param bb the byte buffer
 376      * @param ix the offset into the byte buffer
 377      * @param m the mask
 378      * @return a vector loaded from a byte buffer
 379      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 380      * or {@code > b.limit()},
 381      * for any vector lane index {@code N} where the mask at lane {@code N}
 382      * is set
 383      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 384      */
 385     @ForceInline
 386     public static IntVector fromByteBuffer(VectorSpecies<Integer> species, ByteBuffer bb, int ix, VectorMask<Integer> m) {
 387         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 388     }
 389 
 390     /**
 391      * Returns a vector where all lane elements are set to the primitive
 392      * value {@code e}.
 393      *
 394      * @param s species of the desired vector
 395      * @param e the value
 396      * @return a vector of vector where all lane elements are set to
 397      * the primitive value {@code e}
 398      */
 399     @ForceInline
 400     @SuppressWarnings("unchecked")
 401     public static IntVector broadcast(VectorSpecies<Integer> s, int e) {
 402         return VectorIntrinsics.broadcastCoerced(
 403             (Class<IntVector>) s.boxType(), int.class, s.length(),
 404             e, s,
 405             ((bits, sp) -> ((IntSpecies)sp).op(i -> (int)bits)));
 406     }
 407 
 408     /**
 409      * Returns a vector where each lane element is set to a given
 410      * primitive value.
 411      * <p>
 412      * For each vector lane, where {@code N} is the vector lane index, the
 413      * the primitive value at index {@code N} is placed into the resulting
 414      * vector at lane index {@code N}.
 415      *
 416      * @param s species of the desired vector
 417      * @param es the given primitive values
 418      * @return a vector where each lane element is set to a given primitive
 419      * value
 420      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 421      */
 422     @ForceInline
 423     @SuppressWarnings("unchecked")
 424     public static IntVector scalars(VectorSpecies<Integer> s, int... es) {
 425         Objects.requireNonNull(es);
 426         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 427         return VectorIntrinsics.load((Class<IntVector>) s.boxType(), int.class, s.length(),
 428                                      es, Unsafe.ARRAY_INT_BASE_OFFSET,
 429                                      es, ix, s,
 430                                      (c, idx, sp) -> ((IntSpecies)sp).op(n -> c[idx + n]));
 431     }
 432 
 433     /**
 434      * Returns a vector where the first lane element is set to the primtive
 435      * value {@code e}, all other lane elements are set to the default
 436      * value.
 437      *
 438      * @param s species of the desired vector
 439      * @param e the value
 440      * @return a vector where the first lane element is set to the primitive
 441      * value {@code e}
 442      */
 443     @ForceInline
 444     public static final IntVector single(VectorSpecies<Integer> s, int e) {
 445         return zero(s).with(0, e);
 446     }
 447 
 448     /**
 449      * Returns a vector where each lane element is set to a randomly
 450      * generated primitive value.
 451      *
 452      * The semantics are equivalent to calling
 453      * {@link ThreadLocalRandom#nextInt()}
 454      *
 455      * @param s species of the desired vector
 456      * @return a vector where each lane elements is set to a randomly
 457      * generated primitive value
 458      */
 459     public static IntVector random(VectorSpecies<Integer> s) {
 460         ThreadLocalRandom r = ThreadLocalRandom.current();
 461         return ((IntSpecies)s).op(i -> r.nextInt());
 462     }
 463 
































































































































































































































 464     // Ops
 465 
 466     @Override
 467     public abstract IntVector add(Vector<Integer> v);
 468 
 469     /**
 470      * Adds this vector to the broadcast of an input scalar.
 471      * <p>
 472      * This is a vector binary operation where the primitive addition operation
 473      * ({@code +}) is applied to lane elements.
 474      *
 475      * @param s the input scalar
 476      * @return the result of adding this vector to the broadcast of an input
 477      * scalar
 478      */
 479     public abstract IntVector add(int s);
 480 
 481     @Override
 482     public abstract IntVector add(Vector<Integer> v, VectorMask<Integer> m);
 483 
 484     /**
 485      * Adds this vector to broadcast of an input scalar,
 486      * selecting lane elements controlled by a mask.
 487      * <p>
 488      * This is a vector binary operation where the primitive addition operation
 489      * ({@code +}) is applied to lane elements.
 490      *
 491      * @param s the input scalar
 492      * @param m the mask controlling lane selection
 493      * @return the result of adding this vector to the broadcast of an input
 494      * scalar
 495      */
 496     public abstract IntVector add(int s, VectorMask<Integer> m);
 497 
 498     @Override
 499     public abstract IntVector sub(Vector<Integer> v);
 500 
 501     /**
 502      * Subtracts the broadcast of an input scalar from this vector.
 503      * <p>
 504      * This is a vector binary operation where the primitive subtraction
 505      * operation ({@code -}) is applied to lane elements.
 506      *
 507      * @param s the input scalar
 508      * @return the result of subtracting the broadcast of an input
 509      * scalar from this vector
 510      */
 511     public abstract IntVector sub(int s);
 512 
 513     @Override
 514     public abstract IntVector sub(Vector<Integer> v, VectorMask<Integer> m);
 515 
 516     /**
 517      * Subtracts the broadcast of an input scalar from this vector, selecting
 518      * lane elements controlled by a mask.
 519      * <p>
 520      * This is a vector binary operation where the primitive subtraction
 521      * operation ({@code -}) is applied to lane elements.
 522      *
 523      * @param s the input scalar
 524      * @param m the mask controlling lane selection
 525      * @return the result of subtracting the broadcast of an input
 526      * scalar from this vector
 527      */
 528     public abstract IntVector sub(int s, VectorMask<Integer> m);
 529 
 530     @Override
 531     public abstract IntVector mul(Vector<Integer> v);
 532 
 533     /**
 534      * Multiplies this vector with the broadcast of an input scalar.
 535      * <p>
 536      * This is a vector binary operation where the primitive multiplication
 537      * operation ({@code *}) is applied to lane elements.
 538      *
 539      * @param s the input scalar
 540      * @return the result of multiplying this vector with the broadcast of an
 541      * input scalar
 542      */
 543     public abstract IntVector mul(int s);
 544 
 545     @Override
 546     public abstract IntVector mul(Vector<Integer> v, VectorMask<Integer> m);
 547 
 548     /**
 549      * Multiplies this vector with the broadcast of an input scalar, selecting
 550      * lane elements controlled by a mask.
 551      * <p>
 552      * This is a vector binary operation where the primitive multiplication
 553      * operation ({@code *}) is applied to lane elements.
 554      *
 555      * @param s the input scalar
 556      * @param m the mask controlling lane selection
 557      * @return the result of multiplying this vector with the broadcast of an
 558      * input scalar
 559      */
 560     public abstract IntVector mul(int s, VectorMask<Integer> m);
 561 
 562     @Override
 563     public abstract IntVector neg();
 564 
 565     @Override
 566     public abstract IntVector neg(VectorMask<Integer> m);
 567 
 568     @Override
 569     public abstract IntVector abs();
 570 
 571     @Override
 572     public abstract IntVector abs(VectorMask<Integer> m);
 573 
 574     @Override
 575     public abstract IntVector min(Vector<Integer> v);
 576 
 577     @Override
 578     public abstract IntVector min(Vector<Integer> v, VectorMask<Integer> m);
 579 
 580     /**
 581      * Returns the minimum of this vector and the broadcast of an input scalar.
 582      * <p>
 583      * This is a vector binary operation where the operation
 584      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 585      *
 586      * @param s the input scalar
 587      * @return the minimum of this vector and the broadcast of an input scalar
 588      */
 589     public abstract IntVector min(int s);
 590 
 591     @Override
 592     public abstract IntVector max(Vector<Integer> v);
 593 
 594     @Override
 595     public abstract IntVector max(Vector<Integer> v, VectorMask<Integer> m);
 596 
 597     /**
 598      * Returns the maximum of this vector and the broadcast of an input scalar.
 599      * <p>
 600      * This is a vector binary operation where the operation
 601      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 602      *
 603      * @param s the input scalar
 604      * @return the maximum of this vector and the broadcast of an input scalar
 605      */
 606     public abstract IntVector max(int s);
 607 
 608     @Override
 609     public abstract VectorMask<Integer> equal(Vector<Integer> v);
 610 
 611     /**
 612      * Tests if this vector is equal to the broadcast of an input scalar.
 613      * <p>
 614      * This is a vector binary test operation where the primitive equals
 615      * operation ({@code ==}) is applied to lane elements.
 616      *
 617      * @param s the input scalar
 618      * @return the result mask of testing if this vector is equal to the
 619      * broadcast of an input scalar
 620      */
 621     public abstract VectorMask<Integer> equal(int s);
 622 
 623     @Override
 624     public abstract VectorMask<Integer> notEqual(Vector<Integer> v);
 625 
 626     /**
 627      * Tests if this vector is not equal to the broadcast of an input scalar.
 628      * <p>
 629      * This is a vector binary test operation where the primitive not equals
 630      * operation ({@code !=}) is applied to lane elements.
 631      *
 632      * @param s the input scalar
 633      * @return the result mask of testing if this vector is not equal to the
 634      * broadcast of an input scalar
 635      */
 636     public abstract VectorMask<Integer> notEqual(int s);
 637 
 638     @Override
 639     public abstract VectorMask<Integer> lessThan(Vector<Integer> v);
 640 
 641     /**
 642      * Tests if this vector is less than the broadcast of an input scalar.
 643      * <p>
 644      * This is a vector binary test operation where the primitive less than
 645      * operation ({@code <}) is applied to lane elements.
 646      *
 647      * @param s the input scalar
 648      * @return the mask result of testing if this vector is less than the
 649      * broadcast of an input scalar
 650      */
 651     public abstract VectorMask<Integer> lessThan(int s);
 652 
 653     @Override
 654     public abstract VectorMask<Integer> lessThanEq(Vector<Integer> v);
 655 
 656     /**
 657      * Tests if this vector is less or equal to the broadcast of an input scalar.
 658      * <p>
 659      * This is a vector binary test operation where the primitive less than
 660      * or equal to operation ({@code <=}) is applied to lane elements.
 661      *
 662      * @param s the input scalar
 663      * @return the mask result of testing if this vector is less than or equal
 664      * to the broadcast of an input scalar
 665      */
 666     public abstract VectorMask<Integer> lessThanEq(int s);
 667 
 668     @Override
 669     public abstract VectorMask<Integer> greaterThan(Vector<Integer> v);
 670 
 671     /**
 672      * Tests if this vector is greater than the broadcast of an input scalar.
 673      * <p>
 674      * This is a vector binary test operation where the primitive greater than
 675      * operation ({@code >}) is applied to lane elements.
 676      *
 677      * @param s the input scalar
 678      * @return the mask result of testing if this vector is greater than the
 679      * broadcast of an input scalar
 680      */
 681     public abstract VectorMask<Integer> greaterThan(int s);
 682 
 683     @Override
 684     public abstract VectorMask<Integer> greaterThanEq(Vector<Integer> v);
 685 
 686     /**
 687      * Tests if this vector is greater than or equal to the broadcast of an
 688      * input scalar.
 689      * <p>
 690      * This is a vector binary test operation where the primitive greater than
 691      * or equal to operation ({@code >=}) is applied to lane elements.
 692      *
 693      * @param s the input scalar
 694      * @return the mask result of testing if this vector is greater than or
 695      * equal to the broadcast of an input scalar
 696      */
 697     public abstract VectorMask<Integer> greaterThanEq(int s);
 698 
 699     @Override
 700     public abstract IntVector blend(Vector<Integer> v, VectorMask<Integer> m);
 701 
 702     /**
 703      * Blends the lane elements of this vector with those of the broadcast of an
 704      * input scalar, selecting lanes controlled by a mask.
 705      * <p>
 706      * For each lane of the mask, at lane index {@code N}, if the mask lane
 707      * is set then the lane element at {@code N} from the input vector is
 708      * selected and placed into the resulting vector at {@code N},
 709      * otherwise the the lane element at {@code N} from this input vector is
 710      * selected and placed into the resulting vector at {@code N}.
 711      *
 712      * @param s the input scalar
 713      * @param m the mask controlling lane selection
 714      * @return the result of blending the lane elements of this vector with
 715      * those of the broadcast of an input scalar
 716      */
 717     public abstract IntVector blend(int s, VectorMask<Integer> m);
 718 
 719     @Override
 720     public abstract IntVector rearrange(Vector<Integer> v,
 721                                                       VectorShuffle<Integer> s, VectorMask<Integer> m);
 722 
 723     @Override
 724     public abstract IntVector rearrange(VectorShuffle<Integer> m);
 725 
 726     @Override
 727     public abstract IntVector reshape(VectorSpecies<Integer> s);
 728 
 729     @Override
 730     public abstract IntVector rotateEL(int i);
 731 
 732     @Override
 733     public abstract IntVector rotateER(int i);
 734 
 735     @Override
 736     public abstract IntVector shiftEL(int i);
 737 
 738     @Override
 739     public abstract IntVector shiftER(int i);
 740 
 741 
 742 
 743     /**
 744      * Bitwise ANDs this vector with an input vector.
 745      * <p>
 746      * This is a vector binary operation where the primitive bitwise AND
 747      * operation ({@code &}) is applied to lane elements.


 757      * This is a vector binary operation where the primitive bitwise AND
 758      * operation ({@code &}) is applied to lane elements.
 759      *
 760      * @param s the input scalar
 761      * @return the bitwise AND of this vector with the broadcast of an input
 762      * scalar
 763      */
 764     public abstract IntVector and(int s);
 765 
 766     /**
 767      * Bitwise ANDs this vector with an input vector, selecting lane elements
 768      * controlled by a mask.
 769      * <p>
 770      * This is a vector binary operation where the primitive bitwise AND
 771      * operation ({@code &}) is applied to lane elements.
 772      *
 773      * @param v the input vector
 774      * @param m the mask controlling lane selection
 775      * @return the bitwise AND of this vector with the input vector
 776      */
 777     public abstract IntVector and(Vector<Integer> v, VectorMask<Integer> m);
 778 
 779     /**
 780      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 781      * lane elements controlled by a mask.
 782      * <p>
 783      * This is a vector binary operation where the primitive bitwise AND
 784      * operation ({@code &}) is applied to lane elements.
 785      *
 786      * @param s the input scalar
 787      * @param m the mask controlling lane selection
 788      * @return the bitwise AND of this vector with the broadcast of an input
 789      * scalar
 790      */
 791     public abstract IntVector and(int s, VectorMask<Integer> m);
 792 
 793     /**
 794      * Bitwise ORs this vector with an input vector.
 795      * <p>
 796      * This is a vector binary operation where the primitive bitwise OR
 797      * operation ({@code |}) is applied to lane elements.
 798      *
 799      * @param v the input vector
 800      * @return the bitwise OR of this vector with the input vector
 801      */
 802     public abstract IntVector or(Vector<Integer> v);
 803 
 804     /**
 805      * Bitwise ORs this vector with the broadcast of an input scalar.
 806      * <p>
 807      * This is a vector binary operation where the primitive bitwise OR
 808      * operation ({@code |}) is applied to lane elements.
 809      *
 810      * @param s the input scalar
 811      * @return the bitwise OR of this vector with the broadcast of an input
 812      * scalar
 813      */
 814     public abstract IntVector or(int s);
 815 
 816     /**
 817      * Bitwise ORs this vector with an input vector, selecting lane elements
 818      * controlled by a mask.
 819      * <p>
 820      * This is a vector binary operation where the primitive bitwise OR
 821      * operation ({@code |}) is applied to lane elements.
 822      *
 823      * @param v the input vector
 824      * @param m the mask controlling lane selection
 825      * @return the bitwise OR of this vector with the input vector
 826      */
 827     public abstract IntVector or(Vector<Integer> v, VectorMask<Integer> m);
 828 
 829     /**
 830      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
 831      * lane elements controlled by a mask.
 832      * <p>
 833      * This is a vector binary operation where the primitive bitwise OR
 834      * operation ({@code |}) is applied to lane elements.
 835      *
 836      * @param s the input scalar
 837      * @param m the mask controlling lane selection
 838      * @return the bitwise OR of this vector with the broadcast of an input
 839      * scalar
 840      */
 841     public abstract IntVector or(int s, VectorMask<Integer> m);
 842 
 843     /**
 844      * Bitwise XORs this vector with an input vector.
 845      * <p>
 846      * This is a vector binary operation where the primitive bitwise XOR
 847      * operation ({@code ^}) is applied to lane elements.
 848      *
 849      * @param v the input vector
 850      * @return the bitwise XOR of this vector with the input vector
 851      */
 852     public abstract IntVector xor(Vector<Integer> v);
 853 
 854     /**
 855      * Bitwise XORs this vector with the broadcast of an input scalar.
 856      * <p>
 857      * This is a vector binary operation where the primitive bitwise XOR
 858      * operation ({@code ^}) is applied to lane elements.
 859      *
 860      * @param s the input scalar
 861      * @return the bitwise XOR of this vector with the broadcast of an input
 862      * scalar
 863      */
 864     public abstract IntVector xor(int s);
 865 
 866     /**
 867      * Bitwise XORs this vector with an input vector, selecting lane elements
 868      * controlled by a mask.
 869      * <p>
 870      * This is a vector binary operation where the primitive bitwise XOR
 871      * operation ({@code ^}) is applied to lane elements.
 872      *
 873      * @param v the input vector
 874      * @param m the mask controlling lane selection
 875      * @return the bitwise XOR of this vector with the input vector
 876      */
 877     public abstract IntVector xor(Vector<Integer> v, VectorMask<Integer> m);
 878 
 879     /**
 880      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
 881      * lane elements controlled by a mask.
 882      * <p>
 883      * This is a vector binary operation where the primitive bitwise XOR
 884      * operation ({@code ^}) is applied to lane elements.
 885      *
 886      * @param s the input scalar
 887      * @param m the mask controlling lane selection
 888      * @return the bitwise XOR of this vector with the broadcast of an input
 889      * scalar
 890      */
 891     public abstract IntVector xor(int s, VectorMask<Integer> m);
 892 
 893     /**
 894      * Bitwise NOTs this vector.
 895      * <p>
 896      * This is a vector unary operation where the primitive bitwise NOT
 897      * operation ({@code ~}) is applied to lane elements.
 898      *
 899      * @return the bitwise NOT of this vector
 900      */
 901     public abstract IntVector not();
 902 
 903     /**
 904      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
 905      * <p>
 906      * This is a vector unary operation where the primitive bitwise NOT
 907      * operation ({@code ~}) is applied to lane elements.
 908      *
 909      * @param m the mask controlling lane selection
 910      * @return the bitwise NOT of this vector
 911      */
 912     public abstract IntVector not(VectorMask<Integer> m);
 913 
 914     /**
 915      * Logically left shifts this vector by the broadcast of an input scalar.
 916      * <p>
 917      * This is a vector binary operation where the primitive logical left shift
 918      * operation ({@code <<}) is applied to lane elements.
 919      *
 920      * @param s the input scalar; the number of the bits to left shift
 921      * @return the result of logically left shifting left this vector by the
 922      * broadcast of an input scalar
 923      */
 924     public abstract IntVector shiftL(int s);
 925 
 926     /**
 927      * Logically left shifts this vector by the broadcast of an input scalar,
 928      * selecting lane elements controlled by a mask.
 929      * <p>
 930      * This is a vector binary operation where the primitive logical left shift
 931      * operation ({@code <<}) is applied to lane elements.
 932      *
 933      * @param s the input scalar; the number of the bits to left shift
 934      * @param m the mask controlling lane selection
 935      * @return the result of logically left shifting this vector by the
 936      * broadcast of an input scalar
 937      */
 938     public abstract IntVector shiftL(int s, VectorMask<Integer> m);
 939 
 940     /**
 941      * Logically left shifts this vector by an input vector.
 942      * <p>
 943      * This is a vector binary operation where the primitive logical left shift
 944      * operation ({@code <<}) is applied to lane elements.
 945      *
 946      * @param v the input vector
 947      * @return the result of logically left shifting this vector by the input
 948      * vector
 949      */
 950     public abstract IntVector shiftL(Vector<Integer> v);
 951 
 952     /**
 953      * Logically left shifts this vector by an input vector, selecting lane
 954      * elements controlled by a mask.
 955      * <p>
 956      * This is a vector binary operation where the primitive logical left shift
 957      * operation ({@code <<}) is applied to lane elements.
 958      *
 959      * @param v the input vector
 960      * @param m the mask controlling lane selection
 961      * @return the result of logically left shifting this vector by the input
 962      * vector
 963      */
 964     public IntVector shiftL(Vector<Integer> v, VectorMask<Integer> m) {
 965         return bOp(v, m, (i, a, b) -> (int) (a << b));
 966     }
 967 
 968     // logical, or unsigned, shift right
 969 
 970     /**
 971      * Logically right shifts (or unsigned right shifts) this vector by the
 972      * broadcast of an input scalar.
 973      * <p>
 974      * This is a vector binary operation where the primitive logical right shift
 975      * operation ({@code >>>}) is applied to lane elements.
 976      *
 977      * @param s the input scalar; the number of the bits to right shift
 978      * @return the result of logically right shifting this vector by the
 979      * broadcast of an input scalar
 980      */
 981     public abstract IntVector shiftR(int s);
 982 
 983     /**
 984      * Logically right shifts (or unsigned right shifts) this vector by the
 985      * broadcast of an input scalar, selecting lane elements controlled by a
 986      * mask.
 987      * <p>
 988      * This is a vector binary operation where the primitive logical right shift
 989      * operation ({@code >>>}) is applied to lane elements.
 990      *
 991      * @param s the input scalar; the number of the bits to right shift
 992      * @param m the mask controlling lane selection
 993      * @return the result of logically right shifting this vector by the
 994      * broadcast of an input scalar
 995      */
 996     public abstract IntVector shiftR(int s, VectorMask<Integer> m);
 997 
 998     /**
 999      * Logically right shifts (or unsigned right shifts) this vector by an
1000      * input vector.
1001      * <p>
1002      * This is a vector binary operation where the primitive logical right shift
1003      * operation ({@code >>>}) is applied to lane elements.
1004      *
1005      * @param v the input vector
1006      * @return the result of logically right shifting this vector by the
1007      * input vector
1008      */
1009     public abstract IntVector shiftR(Vector<Integer> v);
1010 
1011     /**
1012      * Logically right shifts (or unsigned right shifts) this vector by an
1013      * input vector, selecting lane elements controlled by a mask.
1014      * <p>
1015      * This is a vector binary operation where the primitive logical right shift
1016      * operation ({@code >>>}) is applied to lane elements.
1017      *
1018      * @param v the input vector
1019      * @param m the mask controlling lane selection
1020      * @return the result of logically right shifting this vector by the
1021      * input vector
1022      */
1023     public IntVector shiftR(Vector<Integer> v, VectorMask<Integer> m) {
1024         return bOp(v, m, (i, a, b) -> (int) (a >>> b));
1025     }
1026 
1027     /**
1028      * Arithmetically right shifts (or signed right shifts) this vector by the
1029      * broadcast of an input scalar.
1030      * <p>
1031      * This is a vector binary operation where the primitive arithmetic right
1032      * shift operation ({@code >>}) is applied to lane elements.
1033      *
1034      * @param s the input scalar; the number of the bits to right shift
1035      * @return the result of arithmetically right shifting this vector by the
1036      * broadcast of an input scalar
1037      */
1038     public abstract IntVector aShiftR(int s);
1039 
1040     /**
1041      * Arithmetically right shifts (or signed right shifts) this vector by the
1042      * broadcast of an input scalar, selecting lane elements controlled by a
1043      * mask.
1044      * <p>
1045      * This is a vector binary operation where the primitive arithmetic right
1046      * shift operation ({@code >>}) is applied to lane elements.
1047      *
1048      * @param s the input scalar; the number of the bits to right shift
1049      * @param m the mask controlling lane selection
1050      * @return the result of arithmetically right shifting this vector by the
1051      * broadcast of an input scalar
1052      */
1053     public abstract IntVector aShiftR(int s, VectorMask<Integer> m);
1054 
1055     /**
1056      * Arithmetically right shifts (or signed right shifts) this vector by an
1057      * input vector.
1058      * <p>
1059      * This is a vector binary operation where the primitive arithmetic right
1060      * shift operation ({@code >>}) is applied to lane elements.
1061      *
1062      * @param v the input vector
1063      * @return the result of arithmetically right shifting this vector by the
1064      * input vector
1065      */
1066     public abstract IntVector aShiftR(Vector<Integer> v);
1067 
1068     /**
1069      * Arithmetically right shifts (or signed right shifts) this vector by an
1070      * input vector, selecting lane elements controlled by a mask.
1071      * <p>
1072      * This is a vector binary operation where the primitive arithmetic right
1073      * shift operation ({@code >>}) is applied to lane elements.
1074      *
1075      * @param v the input vector
1076      * @param m the mask controlling lane selection
1077      * @return the result of arithmetically right shifting this vector by the
1078      * input vector
1079      */
1080     public IntVector aShiftR(Vector<Integer> v, VectorMask<Integer> m) {
1081         return bOp(v, m, (i, a, b) -> (int) (a >> b));
1082     }
1083 
1084     /**
1085      * Rotates left this vector by the broadcast of an input scalar.
1086      * <p>
1087      * This is a vector binary operation where the operation
1088      * {@link Integer#rotateLeft} is applied to lane elements and where
1089      * lane elements of this vector apply to the first argument, and lane
1090      * elements of the broadcast vector apply to the second argument (the
1091      * rotation distance).
1092      *
1093      * @param s the input scalar; the number of the bits to rotate left
1094      * @return the result of rotating left this vector by the broadcast of an
1095      * input scalar
1096      */
1097     @ForceInline
1098     public final IntVector rotateL(int s) {
1099         return shiftL(s).or(shiftR(-s));
1100     }
1101 
1102     /**
1103      * Rotates left this vector by the broadcast of an input scalar, selecting
1104      * lane elements controlled by a mask.
1105      * <p>
1106      * This is a vector binary operation where the operation
1107      * {@link Integer#rotateLeft} is applied to lane elements and where
1108      * lane elements of this vector apply to the first argument, and lane
1109      * elements of the broadcast vector apply to the second argument (the
1110      * rotation distance).
1111      *
1112      * @param s the input scalar; the number of the bits to rotate left
1113      * @param m the mask controlling lane selection
1114      * @return the result of rotating left this vector by the broadcast of an
1115      * input scalar
1116      */
1117     @ForceInline
1118     public final IntVector rotateL(int s, VectorMask<Integer> m) {
1119         return shiftL(s, m).or(shiftR(-s, m), m);
1120     }
1121 
1122     /**
1123      * Rotates right this vector by the broadcast of an input scalar.
1124      * <p>
1125      * This is a vector binary operation where the operation
1126      * {@link Integer#rotateRight} is applied to lane elements and where
1127      * lane elements of this vector apply to the first argument, and lane
1128      * elements of the broadcast vector apply to the second argument (the
1129      * rotation distance).
1130      *
1131      * @param s the input scalar; the number of the bits to rotate right
1132      * @return the result of rotating right this vector by the broadcast of an
1133      * input scalar
1134      */
1135     @ForceInline
1136     public final IntVector rotateR(int s) {
1137         return shiftR(s).or(shiftL(-s));
1138     }
1139 
1140     /**
1141      * Rotates right this vector by the broadcast of an input scalar, selecting
1142      * lane elements controlled by a mask.
1143      * <p>
1144      * This is a vector binary operation where the operation
1145      * {@link Integer#rotateRight} is applied to lane elements and where
1146      * lane elements of this vector apply to the first argument, and lane
1147      * elements of the broadcast vector apply to the second argument (the
1148      * rotation distance).
1149      *
1150      * @param s the input scalar; the number of the bits to rotate right
1151      * @param m the mask controlling lane selection
1152      * @return the result of rotating right this vector by the broadcast of an
1153      * input scalar
1154      */
1155     @ForceInline
1156     public final IntVector rotateR(int s, VectorMask<Integer> m) {
1157         return shiftR(s, m).or(shiftL(-s, m), m);
1158     }
1159 
1160     @Override
1161     public abstract void intoByteArray(byte[] a, int ix);
1162 
1163     @Override
1164     public abstract void intoByteArray(byte[] a, int ix, VectorMask<Integer> m);
1165 
1166     @Override
1167     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1168 
1169     @Override
1170     public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Integer> m);
1171 
1172 
1173     // Type specific horizontal reductions
1174     /**
1175      * Adds all lane elements of this vector.
1176      * <p>
1177      * This is an associative vector reduction operation where the addition
1178      * operation ({@code +}) is applied to lane elements,
1179      * and the identity value is {@code 0}.
1180      *
1181      * @return the addition of all the lane elements of this vector
1182      */
1183     public abstract int addAll();
1184 
1185     /**
1186      * Adds all lane elements of this vector, selecting lane elements
1187      * controlled by a mask.
1188      * <p>
1189      * This is an associative vector reduction operation where the addition
1190      * operation ({@code +}) is applied to lane elements,
1191      * and the identity value is {@code 0}.
1192      *
1193      * @param m the mask controlling lane selection
1194      * @return the addition of the selected lane elements of this vector
1195      */
1196     public abstract int addAll(VectorMask<Integer> m);
1197 
1198     /**
1199      * Multiplies all lane elements of this vector.
1200      * <p>
1201      * This is an associative vector reduction operation where the
1202      * multiplication operation ({@code *}) is applied to lane elements,
1203      * and the identity value is {@code 1}.
1204      *
1205      * @return the multiplication of all the lane elements of this vector
1206      */
1207     public abstract int mulAll();
1208 
1209     /**
1210      * Multiplies all lane elements of this vector, selecting lane elements
1211      * controlled by a mask.
1212      * <p>
1213      * This is an associative vector reduction operation where the
1214      * multiplication operation ({@code *}) is applied to lane elements,
1215      * and the identity value is {@code 1}.
1216      *
1217      * @param m the mask controlling lane selection
1218      * @return the multiplication of all the lane elements of this vector
1219      */
1220     public abstract int mulAll(VectorMask<Integer> m);
1221 
1222     /**
1223      * Returns the minimum lane element of this vector.
1224      * <p>
1225      * This is an associative vector reduction operation where the operation
1226      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1227      * and the identity value is
1228      * {@link Integer#MAX_VALUE}.
1229      *
1230      * @return the minimum lane element of this vector
1231      */
1232     public abstract int minAll();
1233 
1234     /**
1235      * Returns the minimum lane element of this vector, selecting lane elements
1236      * controlled by a mask.
1237      * <p>
1238      * This is an associative vector reduction operation where the operation
1239      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1240      * and the identity value is
1241      * {@link Integer#MAX_VALUE}.
1242      *
1243      * @param m the mask controlling lane selection
1244      * @return the minimum lane element of this vector
1245      */
1246     public abstract int minAll(VectorMask<Integer> m);
1247 
1248     /**
1249      * Returns the maximum lane element of this vector.
1250      * <p>
1251      * This is an associative vector reduction operation where the operation
1252      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1253      * and the identity value is
1254      * {@link Integer#MIN_VALUE}.
1255      *
1256      * @return the maximum lane element of this vector
1257      */
1258     public abstract int maxAll();
1259 
1260     /**
1261      * Returns the maximum lane element of this vector, selecting lane elements
1262      * controlled by a mask.
1263      * <p>
1264      * This is an associative vector reduction operation where the operation
1265      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1266      * and the identity value is
1267      * {@link Integer#MIN_VALUE}.
1268      *
1269      * @param m the mask controlling lane selection
1270      * @return the maximum lane element of this vector
1271      */
1272     public abstract int maxAll(VectorMask<Integer> m);
1273 
1274     /**
1275      * Logically ORs all lane elements of this vector.
1276      * <p>
1277      * This is an associative vector reduction operation where the logical OR
1278      * operation ({@code |}) is applied to lane elements,
1279      * and the identity value is {@code 0}.
1280      *
1281      * @return the logical OR all the lane elements of this vector
1282      */
1283     public abstract int orAll();
1284 
1285     /**
1286      * Logically ORs all lane elements of this vector, selecting lane elements
1287      * controlled by a mask.
1288      * <p>
1289      * This is an associative vector reduction operation where the logical OR
1290      * operation ({@code |}) is applied to lane elements,
1291      * and the identity value is {@code 0}.
1292      *
1293      * @param m the mask controlling lane selection
1294      * @return the logical OR all the lane elements of this vector
1295      */
1296     public abstract int orAll(VectorMask<Integer> m);
1297 
1298     /**
1299      * Logically ANDs all lane elements of this vector.
1300      * <p>
1301      * This is an associative vector reduction operation where the logical AND
1302      * operation ({@code |}) is applied to lane elements,
1303      * and the identity value is {@code -1}.
1304      *
1305      * @return the logical AND all the lane elements of this vector
1306      */
1307     public abstract int andAll();
1308 
1309     /**
1310      * Logically ANDs all lane elements of this vector, selecting lane elements
1311      * controlled by a mask.
1312      * <p>
1313      * This is an associative vector reduction operation where the logical AND
1314      * operation ({@code |}) is applied to lane elements,
1315      * and the identity value is {@code -1}.
1316      *
1317      * @param m the mask controlling lane selection
1318      * @return the logical AND all the lane elements of this vector
1319      */
1320     public abstract int andAll(VectorMask<Integer> m);
1321 
1322     /**
1323      * Logically XORs all lane elements of this vector.
1324      * <p>
1325      * This is an associative vector reduction operation where the logical XOR
1326      * operation ({@code ^}) is applied to lane elements,
1327      * and the identity value is {@code 0}.
1328      *
1329      * @return the logical XOR all the lane elements of this vector
1330      */
1331     public abstract int xorAll();
1332 
1333     /**
1334      * Logically XORs all lane elements of this vector, selecting lane elements
1335      * controlled by a mask.
1336      * <p>
1337      * This is an associative vector reduction operation where the logical XOR
1338      * operation ({@code ^}) is applied to lane elements,
1339      * and the identity value is {@code 0}.
1340      *
1341      * @param m the mask controlling lane selection
1342      * @return the logical XOR all the lane elements of this vector
1343      */
1344     public abstract int xorAll(VectorMask<Integer> m);
1345 
1346     // Type specific accessors
1347 
1348     /**
1349      * Gets the lane element at lane index {@code i}
1350      *
1351      * @param i the lane index
1352      * @return the lane element at lane index {@code i}
1353      * @throws IllegalArgumentException if the index is is out of range
1354      * ({@code < 0 || >= length()})
1355      */
1356     public abstract int get(int i);
1357 
1358     /**
1359      * Replaces the lane element of this vector at lane index {@code i} with
1360      * value {@code e}.
1361      * <p>
1362      * This is a cross-lane operation and behaves as if it returns the result
1363      * of blending this vector with an input vector that is the result of
1364      * broadcasting {@code e} and a mask that has only one lane set at lane


1406      * @param i the offset into the array
1407      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1408      * {@code i > a.length - this.length()}
1409      */
1410     public abstract void intoArray(int[] a, int i);
1411 
1412     /**
1413      * Stores this vector into an array starting at offset and using a mask.
1414      * <p>
1415      * For each vector lane, where {@code N} is the vector lane index,
1416      * if the mask lane at index {@code N} is set then the lane element at
1417      * index {@code N} is stored into the array index {@code i + N}.
1418      *
1419      * @param a the array
1420      * @param i the offset into the array
1421      * @param m the mask
1422      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1423      * for any vector lane index {@code N} where the mask at lane {@code N}
1424      * is set {@code i >= a.length - N}
1425      */
1426     public abstract void intoArray(int[] a, int i, VectorMask<Integer> m);
1427 
1428     /**
1429      * Stores this vector into an array using indexes obtained from an index
1430      * map.
1431      * <p>
1432      * For each vector lane, where {@code N} is the vector lane index, the
1433      * lane element at index {@code N} is stored into the array at index
1434      * {@code i + indexMap[j + N]}.
1435      *
1436      * @param a the array
1437      * @param i the offset into the array, may be negative if relative
1438      * indexes in the index map compensate to produce a value within the
1439      * array bounds
1440      * @param indexMap the index map
1441      * @param j the offset into the index map
1442      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1443      * {@code j > indexMap.length - this.length()},
1444      * or for any vector lane index {@code N} the result of
1445      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1446      */


1451      * map and using a mask.
1452      * <p>
1453      * For each vector lane, where {@code N} is the vector lane index,
1454      * if the mask lane at index {@code N} is set then the lane element at
1455      * index {@code N} is stored into the array at index
1456      * {@code i + indexMap[j + N]}.
1457      *
1458      * @param a the array
1459      * @param i the offset into the array, may be negative if relative
1460      * indexes in the index map compensate to produce a value within the
1461      * array bounds
1462      * @param m the mask
1463      * @param indexMap the index map
1464      * @param j the offset into the index map
1465      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1466      * {@code j > indexMap.length - this.length()},
1467      * or for any vector lane index {@code N} where the mask at lane
1468      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1469      * {@code < 0} or {@code >= a.length}
1470      */
1471     public abstract void intoArray(int[] a, int i, VectorMask<Integer> m, int[] indexMap, int j);
1472     // Species
1473 
1474     @Override
1475     public abstract VectorSpecies<Integer> species();
1476 
1477     /**
1478      * Class representing {@link IntVector}'s of the same {@link VectorShape VectorShape}.
1479      */
1480     static final class IntSpecies extends AbstractSpecies<Integer> {
1481         final Function<int[], IntVector> vectorFactory;

1482 
1483         private IntSpecies(VectorShape shape,
1484                           Class<?> boxType,
1485                           Class<?> maskType,
1486                           Function<int[], IntVector> vectorFactory,
1487                           Function<boolean[], VectorMask<Integer>> maskFactory,
1488                           Function<IntUnaryOperator, VectorShuffle<Integer>> shuffleFromArrayFactory,
1489                           fShuffleFromArray<Integer> shuffleFromOpFactory) {
1490             super(shape, int.class, Integer.SIZE, boxType, maskType, maskFactory,
1491                   shuffleFromArrayFactory, shuffleFromOpFactory);
1492             this.vectorFactory = vectorFactory;

1493         }
1494 
1495         interface FOp {
1496             int apply(int i);
1497         }
1498 




1499         IntVector op(FOp f) {
1500             int[] res = new int[length()];
1501             for (int i = 0; i < length(); i++) {
1502                 res[i] = f.apply(i);
1503             }
1504             return vectorFactory.apply(res);
1505         }
1506 
1507         IntVector op(VectorMask<Integer> o, FOp f) {
1508             int[] res = new int[length()];
1509             boolean[] mbits = ((AbstractMask<Integer>)o).getBits();
1510             for (int i = 0; i < length(); i++) {
1511                 if (mbits[i]) {
1512                     res[i] = f.apply(i);
1513                 }
1514             }
1515             return vectorFactory.apply(res);
1516         }








1517     }
1518 
1519     /**
1520      * Finds the preferred species for an element type of {@code int}.
1521      * <p>
1522      * A preferred species is a species chosen by the platform that has a
1523      * shape of maximal bit size.  A preferred species for different element
1524      * types will have the same shape, and therefore vectors, masks, and
1525      * shuffles created from such species will be shape compatible.
1526      *
1527      * @return the preferred species for an element type of {@code int}
1528      */
1529     private static IntSpecies preferredSpecies() {
1530         return (IntSpecies) VectorSpecies.ofPreferred(int.class);
1531     }
1532 
1533     /**
1534      * Finds a species for an element type of {@code int} and shape.
1535      *
1536      * @param s the shape
1537      * @return a species for an element type of {@code int} and shape
1538      * @throws IllegalArgumentException if no such species exists for the shape
1539      */
1540     static IntSpecies species(VectorShape s) {
1541         Objects.requireNonNull(s);
1542         switch (s) {
1543             case S_64_BIT: return (IntSpecies) SPECIES_64;
1544             case S_128_BIT: return (IntSpecies) SPECIES_128;
1545             case S_256_BIT: return (IntSpecies) SPECIES_256;
1546             case S_512_BIT: return (IntSpecies) SPECIES_512;
1547             case S_Max_BIT: return (IntSpecies) SPECIES_MAX;
1548             default: throw new IllegalArgumentException("Bad shape: " + s);
1549         }
1550     }
1551 
1552     /** Species representing {@link IntVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
1553     public static final VectorSpecies<Integer> SPECIES_64 = new IntSpecies(VectorShape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class,
1554                                                                      Int64Vector::new, Int64Vector.Int64Mask::new,
1555                                                                      Int64Vector.Int64Shuffle::new, Int64Vector.Int64Shuffle::new);
1556 
1557     /** Species representing {@link IntVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
1558     public static final VectorSpecies<Integer> SPECIES_128 = new IntSpecies(VectorShape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class,
1559                                                                       Int128Vector::new, Int128Vector.Int128Mask::new,
1560                                                                       Int128Vector.Int128Shuffle::new, Int128Vector.Int128Shuffle::new);
1561 
1562     /** Species representing {@link IntVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
1563     public static final VectorSpecies<Integer> SPECIES_256 = new IntSpecies(VectorShape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class,
1564                                                                       Int256Vector::new, Int256Vector.Int256Mask::new,
1565                                                                       Int256Vector.Int256Shuffle::new, Int256Vector.Int256Shuffle::new);
1566 
1567     /** Species representing {@link IntVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
1568     public static final VectorSpecies<Integer> SPECIES_512 = new IntSpecies(VectorShape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class,
1569                                                                       Int512Vector::new, Int512Vector.Int512Mask::new,
1570                                                                       Int512Vector.Int512Shuffle::new, Int512Vector.Int512Shuffle::new);
1571 
1572     /** Species representing {@link IntVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
1573     public static final VectorSpecies<Integer> SPECIES_MAX = new IntSpecies(VectorShape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class,
1574                                                                       IntMaxVector::new, IntMaxVector.IntMaxMask::new,
1575                                                                       IntMaxVector.IntMaxShuffle::new, IntMaxVector.IntMaxShuffle::new);
1576 
1577     /**
1578      * Preferred species for {@link IntVector}s.
1579      * A preferred species is a species of maximal bit size for the platform.
1580      */
1581     public static final VectorSpecies<Integer> SPECIES_PREFERRED = (VectorSpecies<Integer>) preferredSpecies();
1582 }
< prev index next >