1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.IntBuffer;
  29 import java.nio.ByteOrder;
  30 import java.util.Objects;
  31 import java.util.function.IntUnaryOperator;
  32 import java.util.concurrent.ThreadLocalRandom;
  33 
  34 import jdk.internal.misc.Unsafe;
  35 import jdk.internal.vm.annotation.ForceInline;
  36 import static jdk.incubator.vector.VectorIntrinsics.*;
  37 
  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code int} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class IntVector extends Vector<Integer> {
  45 
  46     IntVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
  49 
  50     // Unary operator
  51 
  52     interface FUnOp {
  53         int apply(int i, int a);
  54     }
  55 
  56     abstract IntVector uOp(FUnOp f);
  57 
  58     abstract IntVector uOp(Mask<Integer> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         int apply(int i, int a, int b);
  64     }
  65 
  66     abstract IntVector bOp(Vector<Integer> v, FBinOp f);
  67 
  68     abstract IntVector bOp(Vector<Integer> v, Mask<Integer> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         int apply(int i, int a, int b, int c);
  74     }
  75 
  76     abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, FTriOp f);
  77 
  78     abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, Mask<Integer> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract int rOp(int v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, int a, int b);
  88     }
  89 
  90     abstract Mask<Integer> bTest(Vector<Integer> v, FBinTest f);
  91 
  92     // Foreach
  93 
  94     interface FUnCon {
  95         void apply(int i, int a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(Mask<Integer> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @param species species of desired vector
 109      * @return a zero vector of given species
 110      */
 111     @ForceInline
 112     @SuppressWarnings("unchecked")
 113     public static IntVector zero(IntSpecies species) {
 114         return species.zero();
 115     }
 116 
 117     /**
 118      * Loads a vector from a byte array starting at an offset.
 119      * <p>
 120      * Bytes are composed into primitive lane elements according to the
 121      * native byte order of the underlying platform
 122      * <p>
 123      * This method behaves as if it returns the result of calling the
 124      * byte buffer, offset, and mask accepting
 125      * {@link #fromByteBuffer(IntSpecies, ByteBuffer, int, Mask) method} as follows:
 126      * <pre>{@code
 127      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 128      * }</pre>
 129      *
 130      * @param species species of desired vector
 131      * @param a the byte array
 132      * @param ix the offset into the array
 133      * @return a vector loaded from a byte array
 134      * @throws IndexOutOfBoundsException if {@code i < 0} or
 135      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 136      */
 137     @ForceInline
 138     @SuppressWarnings("unchecked")
 139     public static IntVector fromByteArray(IntSpecies species, byte[] a, int ix) {
 140         Objects.requireNonNull(a);
 141         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 142         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 143                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 144                                      a, ix, species,
 145                                      (c, idx, s) -> {
 146                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 147                                          IntBuffer tb = bbc.asIntBuffer();
 148                                          return ((IntSpecies)s).op(i -> tb.get());
 149                                      });
 150     }
 151 
 152     /**
 153      * Loads a vector from a byte array starting at an offset and using a
 154      * mask.
 155      * <p>
 156      * Bytes are composed into primitive lane elements according to the
 157      * native byte order of the underlying platform.
 158      * <p>
 159      * This method behaves as if it returns the result of calling the
 160      * byte buffer, offset, and mask accepting
 161      * {@link #fromByteBuffer(IntSpecies, ByteBuffer, int, Mask) method} as follows:
 162      * <pre>{@code
 163      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 164      * }</pre>
 165      *
 166      * @param species species of desired vector
 167      * @param a the byte array
 168      * @param ix the offset into the array
 169      * @param m the mask
 170      * @return a vector loaded from a byte array
 171      * @throws IndexOutOfBoundsException if {@code i < 0} or
 172      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 173      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 174      * or {@code > a.length},
 175      * for any vector lane index {@code N} where the mask at lane {@code N}
 176      * is set
 177      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 178      */
 179     @ForceInline
 180     public static IntVector fromByteArray(IntSpecies species, byte[] a, int ix, Mask<Integer> m) {
 181         return zero(species).blend(fromByteArray(species, a, ix), m);
 182     }
 183 
 184     /**
 185      * Loads a vector from an array starting at offset.
 186      * <p>
 187      * For each vector lane, where {@code N} is the vector lane index, the
 188      * array element at index {@code i + N} is placed into the
 189      * resulting vector at lane index {@code N}.
 190      *
 191      * @param species species of desired vector
 192      * @param a the array
 193      * @param i the offset into the array
 194      * @return the vector loaded from an array
 195      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 196      * {@code i > a.length - this.length()}
 197      */
 198     @ForceInline
 199     @SuppressWarnings("unchecked")
 200     public static IntVector fromArray(IntSpecies species, int[] a, int i){
 201         Objects.requireNonNull(a);
 202         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 203         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 204                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_INT_BASE_OFFSET,
 205                                      a, i, species,
 206                                      (c, idx, s) -> ((IntSpecies)s).op(n -> c[idx + n]));
 207     }
 208 
 209 
 210     /**
 211      * Loads a vector from an array starting at offset and using a mask.
 212      * <p>
 213      * For each vector lane, where {@code N} is the vector lane index,
 214      * if the mask lane at index {@code N} is set then the array element at
 215      * index {@code i + N} is placed into the resulting vector at lane index
 216      * {@code N}, otherwise the default element value is placed into the
 217      * resulting vector at lane index {@code N}.
 218      *
 219      * @param species species of desired vector
 220      * @param a the array
 221      * @param i the offset into the array
 222      * @param m the mask
 223      * @return the vector loaded from an array
 224      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 225      * for any vector lane index {@code N} where the mask at lane {@code N}
 226      * is set {@code i > a.length - N}
 227      */
 228     @ForceInline
 229     public static IntVector fromArray(IntSpecies species, int[] a, int i, Mask<Integer> m) {
 230         return zero(species).blend(fromArray(species, a, i), m);
 231     }
 232 
 233     /**
 234      * Loads a vector from an array using indexes obtained from an index
 235      * map.
 236      * <p>
 237      * For each vector lane, where {@code N} is the vector lane index, the
 238      * array element at index {@code i + indexMap[j + N]} is placed into the
 239      * resulting vector at lane index {@code N}.
 240      *
 241      * @param species species of desired vector
 242      * @param a the array
 243      * @param i the offset into the array, may be negative if relative
 244      * indexes in the index map compensate to produce a value within the
 245      * array bounds
 246      * @param indexMap the index map
 247      * @param j the offset into the index map
 248      * @return the vector loaded from an array
 249      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 250      * {@code j > indexMap.length - this.length()},
 251      * or for any vector lane index {@code N} the result of
 252      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 253      */
 254     @ForceInline
 255     @SuppressWarnings("unchecked")
 256     public static IntVector fromArray(IntSpecies species, int[] a, int i, int[] indexMap, int j) {
 257         Objects.requireNonNull(a);
 258         Objects.requireNonNull(indexMap);
 259 
 260         // Index vector: vix[0:n] = k -> i + indexMap[j + i]
 261         IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
 262 
 263         vix = VectorIntrinsics.checkIndex(vix, a.length);
 264 
 265         return VectorIntrinsics.loadWithMap((Class<IntVector>) species.boxType(), int.class, species.length(),
 266                                             species.indexSpecies().vectorType(), a, Unsafe.ARRAY_INT_BASE_OFFSET, vix,
 267                                             a, i, indexMap, j, species,
 268                                            (c, idx, iMap, idy, s) -> ((IntSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 269         }
 270 
 271     /**
 272      * Loads a vector from an array using indexes obtained from an index
 273      * map and using a mask.
 274      * <p>
 275      * For each vector lane, where {@code N} is the vector lane index,
 276      * if the mask lane at index {@code N} is set then the array element at
 277      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 278      * at lane index {@code N}.
 279      *
 280      * @param species species of desired vector
 281      * @param a the array
 282      * @param i the offset into the array, may be negative if relative
 283      * indexes in the index map compensate to produce a value within the
 284      * array bounds
 285      * @param m the mask
 286      * @param indexMap the index map
 287      * @param j the offset into the index map
 288      * @return the vector loaded from an array
 289      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 290      * {@code j > indexMap.length - this.length()},
 291      * or for any vector lane index {@code N} where the mask at lane
 292      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 293      * {@code < 0} or {@code >= a.length}
 294      */
 295     @ForceInline
 296     @SuppressWarnings("unchecked")
 297     public static IntVector fromArray(IntSpecies species, int[] a, int i, Mask<Integer> m, int[] indexMap, int j) {
 298         // @@@ This can result in out of bounds errors for unset mask lanes
 299         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 300     }
 301 
 302 
 303     /**
 304      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 305      * offset into the byte buffer.
 306      * <p>
 307      * Bytes are composed into primitive lane elements according to the
 308      * native byte order of the underlying platform.
 309      * <p>
 310      * This method behaves as if it returns the result of calling the
 311      * byte buffer, offset, and mask accepting
 312      * {@link #fromByteBuffer(IntSpecies, ByteBuffer, int, Mask)} method} as follows:
 313      * <pre>{@code
 314      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 315      * }</pre>
 316      *
 317      * @param species species of desired vector
 318      * @param bb the byte buffer
 319      * @param ix the offset into the byte buffer
 320      * @return a vector loaded from a byte buffer
 321      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 322      * or {@code > b.limit()},
 323      * or if there are fewer than
 324      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 325      * remaining in the byte buffer from the given offset
 326      */
 327     @ForceInline
 328     @SuppressWarnings("unchecked")
 329     public static IntVector fromByteBuffer(IntSpecies species, ByteBuffer bb, int ix) {
 330         if (bb.order() != ByteOrder.nativeOrder()) {
 331             throw new IllegalArgumentException();
 332         }
 333         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 334         return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
 335                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 336                                      bb, ix, species,
 337                                      (c, idx, s) -> {
 338                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 339                                          IntBuffer tb = bbc.asIntBuffer();
 340                                          return ((IntSpecies)s).op(i -> tb.get());
 341                                      });
 342     }
 343 
 344     /**
 345      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 346      * offset into the byte buffer and using a mask.
 347      * <p>
 348      * This method behaves as if the byte buffer is viewed as a primitive
 349      * {@link java.nio.Buffer buffer} for the primitive element type,
 350      * according to the native byte order of the underlying platform, and
 351      * the returned vector is loaded with a mask from a primitive array
 352      * obtained from the primitive buffer.
 353      * The following pseudocode expresses the behaviour, where
 354      * {@coce EBuffer} is the primitive buffer type, {@code e} is the
 355      * primitive element type, and {@code ESpecies<S>} is the primitive
 356      * species for {@code e}:
 357      * <pre>{@code
 358      * EBuffer eb = b.duplicate().
 359      *     order(ByteOrder.nativeOrder()).position(i).
 360      *     asEBuffer();
 361      * e[] es = new e[this.length()];
 362      * for (int n = 0; n < t.length; n++) {
 363      *     if (m.isSet(n))
 364      *         es[n] = eb.get(n);
 365      * }
 366      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 367      * }</pre>
 368      *
 369      * @param species species of desired vector
 370      * @param bb the byte buffer
 371      * @param ix the offset into the byte buffer
 372      * @param m the mask
 373      * @return a vector loaded from a byte buffer
 374      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 375      * or {@code > b.limit()},
 376      * for any vector lane index {@code N} where the mask at lane {@code N}
 377      * is set
 378      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 379      */
 380     @ForceInline
 381     public static IntVector fromByteBuffer(IntSpecies species, ByteBuffer bb, int ix, Mask<Integer> m) {
 382         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 383     }
 384 
 385     /**
 386      * Returns a mask where each lane is set or unset according to given
 387      * {@code boolean} values
 388      * <p>
 389      * For each mask lane, where {@code N} is the mask lane index,
 390      * if the given {@code boolean} value at index {@code N} is {@code true}
 391      * then the mask lane at index {@code N} is set, otherwise it is unset.
 392      *
 393      * @param species mask species
 394      * @param bits the given {@code boolean} values
 395      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 396      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 397      */
 398     @ForceInline
 399     public static Mask<Integer> maskFromValues(IntSpecies species, boolean... bits) {
 400         if (species.boxType() == IntMaxVector.class)
 401             return new IntMaxVector.IntMaxMask(bits);
 402         switch (species.bitSize()) {
 403             case 64: return new Int64Vector.Int64Mask(bits);
 404             case 128: return new Int128Vector.Int128Mask(bits);
 405             case 256: return new Int256Vector.Int256Mask(bits);
 406             case 512: return new Int512Vector.Int512Mask(bits);
 407             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 408         }
 409     }
 410 
 411     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 412     static Mask<Integer> trueMask(IntSpecies species) {
 413         if (species.boxType() == IntMaxVector.class)
 414             return IntMaxVector.IntMaxMask.TRUE_MASK;
 415         switch (species.bitSize()) {
 416             case 64: return Int64Vector.Int64Mask.TRUE_MASK;
 417             case 128: return Int128Vector.Int128Mask.TRUE_MASK;
 418             case 256: return Int256Vector.Int256Mask.TRUE_MASK;
 419             case 512: return Int512Vector.Int512Mask.TRUE_MASK;
 420             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 421         }
 422     }
 423 
 424     static Mask<Integer> falseMask(IntSpecies species) {
 425         if (species.boxType() == IntMaxVector.class)
 426             return IntMaxVector.IntMaxMask.FALSE_MASK;
 427         switch (species.bitSize()) {
 428             case 64: return Int64Vector.Int64Mask.FALSE_MASK;
 429             case 128: return Int128Vector.Int128Mask.FALSE_MASK;
 430             case 256: return Int256Vector.Int256Mask.FALSE_MASK;
 431             case 512: return Int512Vector.Int512Mask.FALSE_MASK;
 432             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 433         }
 434     }
 435 
 436     /**
 437      * Loads a mask from a {@code boolean} array starting at an offset.
 438      * <p>
 439      * For each mask lane, where {@code N} is the mask lane index,
 440      * if the array element at index {@code ix + N} is {@code true} then the
 441      * mask lane at index {@code N} is set, otherwise it is unset.
 442      *
 443      * @param species mask species
 444      * @param bits the {@code boolean} array
 445      * @param ix the offset into the array
 446      * @return the mask loaded from a {@code boolean} array
 447      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 448      * {@code ix > bits.length - species.length()}
 449      */
 450     @ForceInline
 451     @SuppressWarnings("unchecked")
 452     public static Mask<Integer> maskFromArray(IntSpecies species, boolean[] bits, int ix) {
 453         Objects.requireNonNull(bits);
 454         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 455         return VectorIntrinsics.load((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
 456                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 457                                      bits, ix, species,
 458                                      (c, idx, s) -> (Mask<Integer>) ((IntSpecies)s).opm(n -> c[idx + n]));
 459     }
 460 
 461     /**
 462      * Returns a mask where all lanes are set.
 463      *
 464      * @param species mask species
 465      * @return a mask where all lanes are set
 466      */
 467     @ForceInline
 468     @SuppressWarnings("unchecked")
 469     public static Mask<Integer> maskAllTrue(IntSpecies species) {
 470         return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
 471                                                  (int)-1,  species,
 472                                                  ((z, s) -> trueMask((IntSpecies)s)));
 473     }
 474 
 475     /**
 476      * Returns a mask where all lanes are unset.
 477      *
 478      * @param species mask species
 479      * @return a mask where all lanes are unset
 480      */
 481     @ForceInline
 482     @SuppressWarnings("unchecked")
 483     public static Mask<Integer> maskAllFalse(IntSpecies species) {
 484         return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
 485                                                  0, species, 
 486                                                  ((z, s) -> falseMask((IntSpecies)s)));
 487     }
 488 
 489     /**
 490      * Returns a shuffle of mapped indexes where each lane element is
 491      * the result of applying a mapping function to the corresponding lane
 492      * index.
 493      * <p>
 494      * Care should be taken to ensure Shuffle values produced from this
 495      * method are consumed as constants to ensure optimal generation of
 496      * code.  For example, values held in static final fields or values
 497      * held in loop constant local variables.
 498      * <p>
 499      * This method behaves as if a shuffle is created from an array of
 500      * mapped indexes as follows:
 501      * <pre>{@code
 502      *   int[] a = new int[species.length()];
 503      *   for (int i = 0; i < a.length; i++) {
 504      *       a[i] = f.applyAsInt(i);
 505      *   }
 506      *   return this.shuffleFromValues(a);
 507      * }</pre>
 508      *
 509      * @param species shuffle species
 510      * @param f the lane index mapping function
 511      * @return a shuffle of mapped indexes
 512      */
 513     @ForceInline
 514     public static Shuffle<Integer> shuffle(IntSpecies species, IntUnaryOperator f) {
 515         if (species.boxType() == IntMaxVector.class)
 516             return new IntMaxVector.IntMaxShuffle(f);
 517         switch (species.bitSize()) {
 518             case 64: return new Int64Vector.Int64Shuffle(f);
 519             case 128: return new Int128Vector.Int128Shuffle(f);
 520             case 256: return new Int256Vector.Int256Shuffle(f);
 521             case 512: return new Int512Vector.Int512Shuffle(f);
 522             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 523         }
 524     }
 525 
 526     /**
 527      * Returns a shuffle where each lane element is the value of its
 528      * corresponding lane index.
 529      * <p>
 530      * This method behaves as if a shuffle is created from an identity
 531      * index mapping function as follows:
 532      * <pre>{@code
 533      *   return this.shuffle(i -> i);
 534      * }</pre>
 535      *
 536      * @param species shuffle species
 537      * @return a shuffle of lane indexes
 538      */
 539     @ForceInline
 540     public static Shuffle<Integer> shuffleIota(IntSpecies species) {
 541         if (species.boxType() == IntMaxVector.class)
 542             return new IntMaxVector.IntMaxShuffle(AbstractShuffle.IDENTITY);
 543         switch (species.bitSize()) {
 544             case 64: return new Int64Vector.Int64Shuffle(AbstractShuffle.IDENTITY);
 545             case 128: return new Int128Vector.Int128Shuffle(AbstractShuffle.IDENTITY);
 546             case 256: return new Int256Vector.Int256Shuffle(AbstractShuffle.IDENTITY);
 547             case 512: return new Int512Vector.Int512Shuffle(AbstractShuffle.IDENTITY);
 548             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 549         }
 550     }
 551 
 552     /**
 553      * Returns a shuffle where each lane element is set to a given
 554      * {@code int} value logically AND'ed by the species length minus one.
 555      * <p>
 556      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 557      * the {@code int} value at index {@code N} logically AND'ed by
 558      * {@code species.length() - 1} is placed into the resulting shuffle at
 559      * lane index {@code N}.
 560      *
 561      * @param species shuffle species
 562      * @param ixs the given {@code int} values
 563      * @return a shuffle where each lane element is set to a given
 564      * {@code int} value
 565      * @throws IndexOutOfBoundsException if the number of int values is
 566      * {@code < species.length()}
 567      */
 568     @ForceInline
 569     public static Shuffle<Integer> shuffleFromValues(IntSpecies species, int... ixs) {
 570         if (species.boxType() == IntMaxVector.class)
 571             return new IntMaxVector.IntMaxShuffle(ixs);
 572         switch (species.bitSize()) {
 573             case 64: return new Int64Vector.Int64Shuffle(ixs);
 574             case 128: return new Int128Vector.Int128Shuffle(ixs);
 575             case 256: return new Int256Vector.Int256Shuffle(ixs);
 576             case 512: return new Int512Vector.Int512Shuffle(ixs);
 577             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 578         }
 579     }
 580 
 581     /**
 582      * Loads a shuffle from an {@code int} array starting at an offset.
 583      * <p>
 584      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 585      * array element at index {@code i + N} logically AND'ed by
 586      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 587      * index {@code N}.
 588      *
 589      * @param species shuffle species
 590      * @param ixs the {@code int} array
 591      * @param i the offset into the array
 592      * @return a shuffle loaded from the {@code int} array
 593      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 594      * {@code i > a.length - species.length()}
 595      */
 596     @ForceInline
 597     public static Shuffle<Integer> shuffleFromArray(IntSpecies species, int[] ixs, int i) {
 598         if (species.boxType() == IntMaxVector.class)
 599             return new IntMaxVector.IntMaxShuffle(ixs, i);
 600         switch (species.bitSize()) {
 601             case 64: return new Int64Vector.Int64Shuffle(ixs, i);
 602             case 128: return new Int128Vector.Int128Shuffle(ixs, i);
 603             case 256: return new Int256Vector.Int256Shuffle(ixs, i);
 604             case 512: return new Int512Vector.Int512Shuffle(ixs, i);
 605             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 606         }
 607     }
 608 
 609 
 610     // Ops
 611 
 612     @Override
 613     public abstract IntVector add(Vector<Integer> v);
 614 
 615     /**
 616      * Adds this vector to the broadcast of an input scalar.
 617      * <p>
 618      * This is a vector binary operation where the primitive addition operation
 619      * ({@code +}) is applied to lane elements.
 620      *
 621      * @param s the input scalar
 622      * @return the result of adding this vector to the broadcast of an input
 623      * scalar
 624      */
 625     public abstract IntVector add(int s);
 626 
 627     @Override
 628     public abstract IntVector add(Vector<Integer> v, Mask<Integer> m);
 629 
 630     /**
 631      * Adds this vector to broadcast of an input scalar,
 632      * selecting lane elements controlled by a mask.
 633      * <p>
 634      * This is a vector binary operation where the primitive addition operation
 635      * ({@code +}) is applied to lane elements.
 636      *
 637      * @param s the input scalar
 638      * @param m the mask controlling lane selection
 639      * @return the result of adding this vector to the broadcast of an input
 640      * scalar
 641      */
 642     public abstract IntVector add(int s, Mask<Integer> m);
 643 
 644     @Override
 645     public abstract IntVector sub(Vector<Integer> v);
 646 
 647     /**
 648      * Subtracts the broadcast of an input scalar from this vector.
 649      * <p>
 650      * This is a vector binary operation where the primitive subtraction
 651      * operation ({@code -}) is applied to lane elements.
 652      *
 653      * @param s the input scalar
 654      * @return the result of subtracting the broadcast of an input
 655      * scalar from this vector
 656      */
 657     public abstract IntVector sub(int s);
 658 
 659     @Override
 660     public abstract IntVector sub(Vector<Integer> v, Mask<Integer> m);
 661 
 662     /**
 663      * Subtracts the broadcast of an input scalar from this vector, selecting
 664      * lane elements controlled by a mask.
 665      * <p>
 666      * This is a vector binary operation where the primitive subtraction
 667      * operation ({@code -}) is applied to lane elements.
 668      *
 669      * @param s the input scalar
 670      * @param m the mask controlling lane selection
 671      * @return the result of subtracting the broadcast of an input
 672      * scalar from this vector
 673      */
 674     public abstract IntVector sub(int s, Mask<Integer> m);
 675 
 676     @Override
 677     public abstract IntVector mul(Vector<Integer> v);
 678 
 679     /**
 680      * Multiplies this vector with the broadcast of an input scalar.
 681      * <p>
 682      * This is a vector binary operation where the primitive multiplication
 683      * operation ({@code *}) is applied to lane elements.
 684      *
 685      * @param s the input scalar
 686      * @return the result of multiplying this vector with the broadcast of an
 687      * input scalar
 688      */
 689     public abstract IntVector mul(int s);
 690 
 691     @Override
 692     public abstract IntVector mul(Vector<Integer> v, Mask<Integer> m);
 693 
 694     /**
 695      * Multiplies this vector with the broadcast of an input scalar, selecting
 696      * lane elements controlled by a mask.
 697      * <p>
 698      * This is a vector binary operation where the primitive multiplication
 699      * operation ({@code *}) is applied to lane elements.
 700      *
 701      * @param s the input scalar
 702      * @param m the mask controlling lane selection
 703      * @return the result of multiplying this vector with the broadcast of an
 704      * input scalar
 705      */
 706     public abstract IntVector mul(int s, Mask<Integer> m);
 707 
 708     @Override
 709     public abstract IntVector neg();
 710 
 711     @Override
 712     public abstract IntVector neg(Mask<Integer> m);
 713 
 714     @Override
 715     public abstract IntVector abs();
 716 
 717     @Override
 718     public abstract IntVector abs(Mask<Integer> m);
 719 
 720     @Override
 721     public abstract IntVector min(Vector<Integer> v);
 722 
 723     @Override
 724     public abstract IntVector min(Vector<Integer> v, Mask<Integer> m);
 725 
 726     /**
 727      * Returns the minimum of this vector and the broadcast of an input scalar.
 728      * <p>
 729      * This is a vector binary operation where the operation
 730      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 731      *
 732      * @param s the input scalar
 733      * @return the minimum of this vector and the broadcast of an input scalar
 734      */
 735     public abstract IntVector min(int s);
 736 
 737     @Override
 738     public abstract IntVector max(Vector<Integer> v);
 739 
 740     @Override
 741     public abstract IntVector max(Vector<Integer> v, Mask<Integer> m);
 742 
 743     /**
 744      * Returns the maximum of this vector and the broadcast of an input scalar.
 745      * <p>
 746      * This is a vector binary operation where the operation
 747      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 748      *
 749      * @param s the input scalar
 750      * @return the maximum of this vector and the broadcast of an input scalar
 751      */
 752     public abstract IntVector max(int s);
 753 
 754     @Override
 755     public abstract Mask<Integer> equal(Vector<Integer> v);
 756 
 757     /**
 758      * Tests if this vector is equal to the broadcast of an input scalar.
 759      * <p>
 760      * This is a vector binary test operation where the primitive equals
 761      * operation ({@code ==}) is applied to lane elements.
 762      *
 763      * @param s the input scalar
 764      * @return the result mask of testing if this vector is equal to the
 765      * broadcast of an input scalar
 766      */
 767     public abstract Mask<Integer> equal(int s);
 768 
 769     @Override
 770     public abstract Mask<Integer> notEqual(Vector<Integer> v);
 771 
 772     /**
 773      * Tests if this vector is not equal to the broadcast of an input scalar.
 774      * <p>
 775      * This is a vector binary test operation where the primitive not equals
 776      * operation ({@code !=}) is applied to lane elements.
 777      *
 778      * @param s the input scalar
 779      * @return the result mask of testing if this vector is not equal to the
 780      * broadcast of an input scalar
 781      */
 782     public abstract Mask<Integer> notEqual(int s);
 783 
 784     @Override
 785     public abstract Mask<Integer> lessThan(Vector<Integer> v);
 786 
 787     /**
 788      * Tests if this vector is less than the broadcast of an input scalar.
 789      * <p>
 790      * This is a vector binary test operation where the primitive less than
 791      * operation ({@code <}) is applied to lane elements.
 792      *
 793      * @param s the input scalar
 794      * @return the mask result of testing if this vector is less than the
 795      * broadcast of an input scalar
 796      */
 797     public abstract Mask<Integer> lessThan(int s);
 798 
 799     @Override
 800     public abstract Mask<Integer> lessThanEq(Vector<Integer> v);
 801 
 802     /**
 803      * Tests if this vector is less or equal to the broadcast of an input scalar.
 804      * <p>
 805      * This is a vector binary test operation where the primitive less than
 806      * or equal to operation ({@code <=}) is applied to lane elements.
 807      *
 808      * @param s the input scalar
 809      * @return the mask result of testing if this vector is less than or equal
 810      * to the broadcast of an input scalar
 811      */
 812     public abstract Mask<Integer> lessThanEq(int s);
 813 
 814     @Override
 815     public abstract Mask<Integer> greaterThan(Vector<Integer> v);
 816 
 817     /**
 818      * Tests if this vector is greater than the broadcast of an input scalar.
 819      * <p>
 820      * This is a vector binary test operation where the primitive greater than
 821      * operation ({@code >}) is applied to lane elements.
 822      *
 823      * @param s the input scalar
 824      * @return the mask result of testing if this vector is greater than the
 825      * broadcast of an input scalar
 826      */
 827     public abstract Mask<Integer> greaterThan(int s);
 828 
 829     @Override
 830     public abstract Mask<Integer> greaterThanEq(Vector<Integer> v);
 831 
 832     /**
 833      * Tests if this vector is greater than or equal to the broadcast of an
 834      * input scalar.
 835      * <p>
 836      * This is a vector binary test operation where the primitive greater than
 837      * or equal to operation ({@code >=}) is applied to lane elements.
 838      *
 839      * @param s the input scalar
 840      * @return the mask result of testing if this vector is greater than or
 841      * equal to the broadcast of an input scalar
 842      */
 843     public abstract Mask<Integer> greaterThanEq(int s);
 844 
 845     @Override
 846     public abstract IntVector blend(Vector<Integer> v, Mask<Integer> m);
 847 
 848     /**
 849      * Blends the lane elements of this vector with those of the broadcast of an
 850      * input scalar, selecting lanes controlled by a mask.
 851      * <p>
 852      * For each lane of the mask, at lane index {@code N}, if the mask lane
 853      * is set then the lane element at {@code N} from the input vector is
 854      * selected and placed into the resulting vector at {@code N},
 855      * otherwise the the lane element at {@code N} from this input vector is
 856      * selected and placed into the resulting vector at {@code N}.
 857      *
 858      * @param s the input scalar
 859      * @param m the mask controlling lane selection
 860      * @return the result of blending the lane elements of this vector with
 861      * those of the broadcast of an input scalar
 862      */
 863     public abstract IntVector blend(int s, Mask<Integer> m);
 864 
 865     @Override
 866     public abstract IntVector rearrange(Vector<Integer> v,
 867                                                       Shuffle<Integer> s, Mask<Integer> m);
 868 
 869     @Override
 870     public abstract IntVector rearrange(Shuffle<Integer> m);
 871 
 872     @Override
 873     public abstract IntVector reshape(Species<Integer> s);
 874 
 875     @Override
 876     public abstract IntVector rotateEL(int i);
 877 
 878     @Override
 879     public abstract IntVector rotateER(int i);
 880 
 881     @Override
 882     public abstract IntVector shiftEL(int i);
 883 
 884     @Override
 885     public abstract IntVector shiftER(int i);
 886 
 887 
 888 
 889     /**
 890      * Bitwise ANDs this vector with an input vector.
 891      * <p>
 892      * This is a vector binary operation where the primitive bitwise AND
 893      * operation ({@code &}) is applied to lane elements.
 894      *
 895      * @param v the input vector
 896      * @return the bitwise AND of this vector with the input vector
 897      */
 898     public abstract IntVector and(Vector<Integer> v);
 899 
 900     /**
 901      * Bitwise ANDs this vector with the broadcast of an input scalar.
 902      * <p>
 903      * This is a vector binary operation where the primitive bitwise AND
 904      * operation ({@code &}) is applied to lane elements.
 905      *
 906      * @param s the input scalar
 907      * @return the bitwise AND of this vector with the broadcast of an input
 908      * scalar
 909      */
 910     public abstract IntVector and(int s);
 911 
 912     /**
 913      * Bitwise ANDs this vector with an input vector, selecting lane elements
 914      * controlled by a mask.
 915      * <p>
 916      * This is a vector binary operation where the primitive bitwise AND
 917      * operation ({@code &}) is applied to lane elements.
 918      *
 919      * @param v the input vector
 920      * @param m the mask controlling lane selection
 921      * @return the bitwise AND of this vector with the input vector
 922      */
 923     public abstract IntVector and(Vector<Integer> v, Mask<Integer> m);
 924 
 925     /**
 926      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 927      * lane elements controlled by a mask.
 928      * <p>
 929      * This is a vector binary operation where the primitive bitwise AND
 930      * operation ({@code &}) is applied to lane elements.
 931      *
 932      * @param s the input scalar
 933      * @param m the mask controlling lane selection
 934      * @return the bitwise AND of this vector with the broadcast of an input
 935      * scalar
 936      */
 937     public abstract IntVector and(int s, Mask<Integer> m);
 938 
 939     /**
 940      * Bitwise ORs this vector with an input vector.
 941      * <p>
 942      * This is a vector binary operation where the primitive bitwise OR
 943      * operation ({@code |}) is applied to lane elements.
 944      *
 945      * @param v the input vector
 946      * @return the bitwise OR of this vector with the input vector
 947      */
 948     public abstract IntVector or(Vector<Integer> v);
 949 
 950     /**
 951      * Bitwise ORs this vector with the broadcast of an input scalar.
 952      * <p>
 953      * This is a vector binary operation where the primitive bitwise OR
 954      * operation ({@code |}) is applied to lane elements.
 955      *
 956      * @param s the input scalar
 957      * @return the bitwise OR of this vector with the broadcast of an input
 958      * scalar
 959      */
 960     public abstract IntVector or(int s);
 961 
 962     /**
 963      * Bitwise ORs this vector with an input vector, selecting lane elements
 964      * controlled by a mask.
 965      * <p>
 966      * This is a vector binary operation where the primitive bitwise OR
 967      * operation ({@code |}) is applied to lane elements.
 968      *
 969      * @param v the input vector
 970      * @param m the mask controlling lane selection
 971      * @return the bitwise OR of this vector with the input vector
 972      */
 973     public abstract IntVector or(Vector<Integer> v, Mask<Integer> m);
 974 
 975     /**
 976      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
 977      * lane elements controlled by a mask.
 978      * <p>
 979      * This is a vector binary operation where the primitive bitwise OR
 980      * operation ({@code |}) is applied to lane elements.
 981      *
 982      * @param s the input scalar
 983      * @param m the mask controlling lane selection
 984      * @return the bitwise OR of this vector with the broadcast of an input
 985      * scalar
 986      */
 987     public abstract IntVector or(int s, Mask<Integer> m);
 988 
 989     /**
 990      * Bitwise XORs this vector with an input vector.
 991      * <p>
 992      * This is a vector binary operation where the primitive bitwise XOR
 993      * operation ({@code ^}) is applied to lane elements.
 994      *
 995      * @param v the input vector
 996      * @return the bitwise XOR of this vector with the input vector
 997      */
 998     public abstract IntVector xor(Vector<Integer> v);
 999 
1000     /**
1001      * Bitwise XORs this vector with the broadcast of an input scalar.
1002      * <p>
1003      * This is a vector binary operation where the primitive bitwise XOR
1004      * operation ({@code ^}) is applied to lane elements.
1005      *
1006      * @param s the input scalar
1007      * @return the bitwise XOR of this vector with the broadcast of an input
1008      * scalar
1009      */
1010     public abstract IntVector xor(int s);
1011 
1012     /**
1013      * Bitwise XORs this vector with an input vector, selecting lane elements
1014      * controlled by a mask.
1015      * <p>
1016      * This is a vector binary operation where the primitive bitwise XOR
1017      * operation ({@code ^}) is applied to lane elements.
1018      *
1019      * @param v the input vector
1020      * @param m the mask controlling lane selection
1021      * @return the bitwise XOR of this vector with the input vector
1022      */
1023     public abstract IntVector xor(Vector<Integer> v, Mask<Integer> m);
1024 
1025     /**
1026      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1027      * lane elements controlled by a mask.
1028      * <p>
1029      * This is a vector binary operation where the primitive bitwise XOR
1030      * operation ({@code ^}) is applied to lane elements.
1031      *
1032      * @param s the input scalar
1033      * @param m the mask controlling lane selection
1034      * @return the bitwise XOR of this vector with the broadcast of an input
1035      * scalar
1036      */
1037     public abstract IntVector xor(int s, Mask<Integer> m);
1038 
1039     /**
1040      * Bitwise NOTs this vector.
1041      * <p>
1042      * This is a vector unary operation where the primitive bitwise NOT
1043      * operation ({@code ~}) is applied to lane elements.
1044      *
1045      * @return the bitwise NOT of this vector
1046      */
1047     public abstract IntVector not();
1048 
1049     /**
1050      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1051      * <p>
1052      * This is a vector unary operation where the primitive bitwise NOT
1053      * operation ({@code ~}) is applied to lane elements.
1054      *
1055      * @param m the mask controlling lane selection
1056      * @return the bitwise NOT of this vector
1057      */
1058     public abstract IntVector not(Mask<Integer> m);
1059 
1060     /**
1061      * Logically left shifts this vector by the broadcast of an input scalar.
1062      * <p>
1063      * This is a vector binary operation where the primitive logical left shift
1064      * operation ({@code <<}) is applied to lane elements.
1065      *
1066      * @param s the input scalar; the number of the bits to left shift
1067      * @return the result of logically left shifting left this vector by the
1068      * broadcast of an input scalar
1069      */
1070     public abstract IntVector shiftL(int s);
1071 
1072     /**
1073      * Logically left shifts this vector by the broadcast of an input scalar,
1074      * selecting lane elements controlled by a mask.
1075      * <p>
1076      * This is a vector binary operation where the primitive logical left shift
1077      * operation ({@code <<}) is applied to lane elements.
1078      *
1079      * @param s the input scalar; the number of the bits to left shift
1080      * @param m the mask controlling lane selection
1081      * @return the result of logically left shifting this vector by the
1082      * broadcast of an input scalar
1083      */
1084     public abstract IntVector shiftL(int s, Mask<Integer> m);
1085 
1086     /**
1087      * Logically left shifts this vector by an input vector.
1088      * <p>
1089      * This is a vector binary operation where the primitive logical left shift
1090      * operation ({@code <<}) is applied to lane elements.
1091      *
1092      * @param v the input vector
1093      * @return the result of logically left shifting this vector by the input
1094      * vector
1095      */
1096     public abstract IntVector shiftL(Vector<Integer> v);
1097 
1098     /**
1099      * Logically left shifts this vector by an input vector, selecting lane
1100      * elements controlled by a mask.
1101      * <p>
1102      * This is a vector binary operation where the primitive logical left shift
1103      * operation ({@code <<}) is applied to lane elements.
1104      *
1105      * @param v the input vector
1106      * @param m the mask controlling lane selection
1107      * @return the result of logically left shifting this vector by the input
1108      * vector
1109      */
1110     public IntVector shiftL(Vector<Integer> v, Mask<Integer> m) {
1111         return bOp(v, m, (i, a, b) -> (int) (a << b));
1112     }
1113 
1114     // logical, or unsigned, shift right
1115 
1116     /**
1117      * Logically right shifts (or unsigned right shifts) this vector by the
1118      * broadcast of an input scalar.
1119      * <p>
1120      * This is a vector binary operation where the primitive logical right shift
1121      * operation ({@code >>>}) is applied to lane elements.
1122      *
1123      * @param s the input scalar; the number of the bits to right shift
1124      * @return the result of logically right shifting this vector by the
1125      * broadcast of an input scalar
1126      */
1127     public abstract IntVector shiftR(int s);
1128 
1129     /**
1130      * Logically right shifts (or unsigned right shifts) this vector by the
1131      * broadcast of an input scalar, selecting lane elements controlled by a
1132      * mask.
1133      * <p>
1134      * This is a vector binary operation where the primitive logical right shift
1135      * operation ({@code >>>}) is applied to lane elements.
1136      *
1137      * @param s the input scalar; the number of the bits to right shift
1138      * @param m the mask controlling lane selection
1139      * @return the result of logically right shifting this vector by the
1140      * broadcast of an input scalar
1141      */
1142     public abstract IntVector shiftR(int s, Mask<Integer> m);
1143 
1144     /**
1145      * Logically right shifts (or unsigned right shifts) this vector by an
1146      * input vector.
1147      * <p>
1148      * This is a vector binary operation where the primitive logical right shift
1149      * operation ({@code >>>}) is applied to lane elements.
1150      *
1151      * @param v the input vector
1152      * @return the result of logically right shifting this vector by the
1153      * input vector
1154      */
1155     public abstract IntVector shiftR(Vector<Integer> v);
1156 
1157     /**
1158      * Logically right shifts (or unsigned right shifts) this vector by an
1159      * input vector, selecting lane elements controlled by a mask.
1160      * <p>
1161      * This is a vector binary operation where the primitive logical right shift
1162      * operation ({@code >>>}) is applied to lane elements.
1163      *
1164      * @param v the input vector
1165      * @param m the mask controlling lane selection
1166      * @return the result of logically right shifting this vector by the
1167      * input vector
1168      */
1169     public IntVector shiftR(Vector<Integer> v, Mask<Integer> m) {
1170         return bOp(v, m, (i, a, b) -> (int) (a >>> b));
1171     }
1172 
1173     /**
1174      * Arithmetically right shifts (or signed right shifts) this vector by the
1175      * broadcast of an input scalar.
1176      * <p>
1177      * This is a vector binary operation where the primitive arithmetic right
1178      * shift operation ({@code >>}) is applied to lane elements.
1179      *
1180      * @param s the input scalar; the number of the bits to right shift
1181      * @return the result of arithmetically right shifting this vector by the
1182      * broadcast of an input scalar
1183      */
1184     public abstract IntVector aShiftR(int s);
1185 
1186     /**
1187      * Arithmetically right shifts (or signed right shifts) this vector by the
1188      * broadcast of an input scalar, selecting lane elements controlled by a
1189      * mask.
1190      * <p>
1191      * This is a vector binary operation where the primitive arithmetic right
1192      * shift operation ({@code >>}) is applied to lane elements.
1193      *
1194      * @param s the input scalar; the number of the bits to right shift
1195      * @param m the mask controlling lane selection
1196      * @return the result of arithmetically right shifting this vector by the
1197      * broadcast of an input scalar
1198      */
1199     public abstract IntVector aShiftR(int s, Mask<Integer> m);
1200 
1201     /**
1202      * Arithmetically right shifts (or signed right shifts) this vector by an
1203      * input vector.
1204      * <p>
1205      * This is a vector binary operation where the primitive arithmetic right
1206      * shift operation ({@code >>}) is applied to lane elements.
1207      *
1208      * @param v the input vector
1209      * @return the result of arithmetically right shifting this vector by the
1210      * input vector
1211      */
1212     public abstract IntVector aShiftR(Vector<Integer> v);
1213 
1214     /**
1215      * Arithmetically right shifts (or signed right shifts) this vector by an
1216      * input vector, selecting lane elements controlled by a mask.
1217      * <p>
1218      * This is a vector binary operation where the primitive arithmetic right
1219      * shift operation ({@code >>}) is applied to lane elements.
1220      *
1221      * @param v the input vector
1222      * @param m the mask controlling lane selection
1223      * @return the result of arithmetically right shifting this vector by the
1224      * input vector
1225      */
1226     public IntVector aShiftR(Vector<Integer> v, Mask<Integer> m) {
1227         return bOp(v, m, (i, a, b) -> (int) (a >> b));
1228     }
1229 
1230     /**
1231      * Rotates left this vector by the broadcast of an input scalar.
1232      * <p>
1233      * This is a vector binary operation where the operation
1234      * {@link Integer#rotateLeft} is applied to lane elements and where
1235      * lane elements of this vector apply to the first argument, and lane
1236      * elements of the broadcast vector apply to the second argument (the
1237      * rotation distance).
1238      *
1239      * @param s the input scalar; the number of the bits to rotate left
1240      * @return the result of rotating left this vector by the broadcast of an
1241      * input scalar
1242      */
1243     @ForceInline
1244     public final IntVector rotateL(int s) {
1245         return shiftL(s).or(shiftR(-s));
1246     }
1247 
1248     /**
1249      * Rotates left this vector by the broadcast of an input scalar, selecting
1250      * lane elements controlled by a mask.
1251      * <p>
1252      * This is a vector binary operation where the operation
1253      * {@link Integer#rotateLeft} is applied to lane elements and where
1254      * lane elements of this vector apply to the first argument, and lane
1255      * elements of the broadcast vector apply to the second argument (the
1256      * rotation distance).
1257      *
1258      * @param s the input scalar; the number of the bits to rotate left
1259      * @param m the mask controlling lane selection
1260      * @return the result of rotating left this vector by the broadcast of an
1261      * input scalar
1262      */
1263     @ForceInline
1264     public final IntVector rotateL(int s, Mask<Integer> m) {
1265         return shiftL(s, m).or(shiftR(-s, m), m);
1266     }
1267 
1268     /**
1269      * Rotates right this vector by the broadcast of an input scalar.
1270      * <p>
1271      * This is a vector binary operation where the operation
1272      * {@link Integer#rotateRight} is applied to lane elements and where
1273      * lane elements of this vector apply to the first argument, and lane
1274      * elements of the broadcast vector apply to the second argument (the
1275      * rotation distance).
1276      *
1277      * @param s the input scalar; the number of the bits to rotate right
1278      * @return the result of rotating right this vector by the broadcast of an
1279      * input scalar
1280      */
1281     @ForceInline
1282     public final IntVector rotateR(int s) {
1283         return shiftR(s).or(shiftL(-s));
1284     }
1285 
1286     /**
1287      * Rotates right this vector by the broadcast of an input scalar, selecting
1288      * lane elements controlled by a mask.
1289      * <p>
1290      * This is a vector binary operation where the operation
1291      * {@link Integer#rotateRight} is applied to lane elements and where
1292      * lane elements of this vector apply to the first argument, and lane
1293      * elements of the broadcast vector apply to the second argument (the
1294      * rotation distance).
1295      *
1296      * @param s the input scalar; the number of the bits to rotate right
1297      * @param m the mask controlling lane selection
1298      * @return the result of rotating right this vector by the broadcast of an
1299      * input scalar
1300      */
1301     @ForceInline
1302     public final IntVector rotateR(int s, Mask<Integer> m) {
1303         return shiftR(s, m).or(shiftL(-s, m), m);
1304     }
1305 
1306     @Override
1307     public abstract void intoByteArray(byte[] a, int ix);
1308 
1309     @Override
1310     public abstract void intoByteArray(byte[] a, int ix, Mask<Integer> m);
1311 
1312     @Override
1313     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1314 
1315     @Override
1316     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Integer> m);
1317 
1318 
1319     // Type specific horizontal reductions
1320     /**
1321      * Adds all lane elements of this vector.
1322      * <p>
1323      * This is an associative vector reduction operation where the addition
1324      * operation ({@code +}) is applied to lane elements,
1325      * and the identity value is {@code 0}.
1326      *
1327      * @return the addition of all the lane elements of this vector
1328      */
1329     public abstract int addAll();
1330 
1331     /**
1332      * Adds all lane elements of this vector, selecting lane elements
1333      * controlled by a mask.
1334      * <p>
1335      * This is an associative vector reduction operation where the addition
1336      * operation ({@code +}) is applied to lane elements,
1337      * and the identity value is {@code 0}.
1338      *
1339      * @param m the mask controlling lane selection
1340      * @return the addition of the selected lane elements of this vector
1341      */
1342     public abstract int addAll(Mask<Integer> m);
1343 
1344     /**
1345      * Multiplies all lane elements of this vector.
1346      * <p>
1347      * This is an associative vector reduction operation where the
1348      * multiplication operation ({@code *}) is applied to lane elements,
1349      * and the identity value is {@code 1}.
1350      *
1351      * @return the multiplication of all the lane elements of this vector
1352      */
1353     public abstract int mulAll();
1354 
1355     /**
1356      * Multiplies all lane elements of this vector, selecting lane elements
1357      * controlled by a mask.
1358      * <p>
1359      * This is an associative vector reduction operation where the
1360      * multiplication operation ({@code *}) is applied to lane elements,
1361      * and the identity value is {@code 1}.
1362      *
1363      * @param m the mask controlling lane selection
1364      * @return the multiplication of all the lane elements of this vector
1365      */
1366     public abstract int mulAll(Mask<Integer> m);
1367 
1368     /**
1369      * Returns the minimum lane element of this vector.
1370      * <p>
1371      * This is an associative vector reduction operation where the operation
1372      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1373      * and the identity value is
1374      * {@link Integer#MAX_VALUE}.
1375      *
1376      * @return the minimum lane element of this vector
1377      */
1378     public abstract int minAll();
1379 
1380     /**
1381      * Returns the minimum lane element of this vector, selecting lane elements
1382      * controlled by a mask.
1383      * <p>
1384      * This is an associative vector reduction operation where the operation
1385      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1386      * and the identity value is
1387      * {@link Integer#MAX_VALUE}.
1388      *
1389      * @param m the mask controlling lane selection
1390      * @return the minimum lane element of this vector
1391      */
1392     public abstract int minAll(Mask<Integer> m);
1393 
1394     /**
1395      * Returns the maximum lane element of this vector.
1396      * <p>
1397      * This is an associative vector reduction operation where the operation
1398      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1399      * and the identity value is
1400      * {@link Integer#MIN_VALUE}.
1401      *
1402      * @return the maximum lane element of this vector
1403      */
1404     public abstract int maxAll();
1405 
1406     /**
1407      * Returns the maximum lane element of this vector, selecting lane elements
1408      * controlled by a mask.
1409      * <p>
1410      * This is an associative vector reduction operation where the operation
1411      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1412      * and the identity value is
1413      * {@link Integer#MIN_VALUE}.
1414      *
1415      * @param m the mask controlling lane selection
1416      * @return the maximum lane element of this vector
1417      */
1418     public abstract int maxAll(Mask<Integer> m);
1419 
1420     /**
1421      * Logically ORs all lane elements of this vector.
1422      * <p>
1423      * This is an associative vector reduction operation where the logical OR
1424      * operation ({@code |}) is applied to lane elements,
1425      * and the identity value is {@code 0}.
1426      *
1427      * @return the logical OR all the lane elements of this vector
1428      */
1429     public abstract int orAll();
1430 
1431     /**
1432      * Logically ORs all lane elements of this vector, selecting lane elements
1433      * controlled by a mask.
1434      * <p>
1435      * This is an associative vector reduction operation where the logical OR
1436      * operation ({@code |}) is applied to lane elements,
1437      * and the identity value is {@code 0}.
1438      *
1439      * @param m the mask controlling lane selection
1440      * @return the logical OR all the lane elements of this vector
1441      */
1442     public abstract int orAll(Mask<Integer> m);
1443 
1444     /**
1445      * Logically ANDs all lane elements of this vector.
1446      * <p>
1447      * This is an associative vector reduction operation where the logical AND
1448      * operation ({@code |}) is applied to lane elements,
1449      * and the identity value is {@code -1}.
1450      *
1451      * @return the logical AND all the lane elements of this vector
1452      */
1453     public abstract int andAll();
1454 
1455     /**
1456      * Logically ANDs all lane elements of this vector, selecting lane elements
1457      * controlled by a mask.
1458      * <p>
1459      * This is an associative vector reduction operation where the logical AND
1460      * operation ({@code |}) is applied to lane elements,
1461      * and the identity value is {@code -1}.
1462      *
1463      * @param m the mask controlling lane selection
1464      * @return the logical AND all the lane elements of this vector
1465      */
1466     public abstract int andAll(Mask<Integer> m);
1467 
1468     /**
1469      * Logically XORs all lane elements of this vector.
1470      * <p>
1471      * This is an associative vector reduction operation where the logical XOR
1472      * operation ({@code ^}) is applied to lane elements,
1473      * and the identity value is {@code 0}.
1474      *
1475      * @return the logical XOR all the lane elements of this vector
1476      */
1477     public abstract int xorAll();
1478 
1479     /**
1480      * Logically XORs all lane elements of this vector, selecting lane elements
1481      * controlled by a mask.
1482      * <p>
1483      * This is an associative vector reduction operation where the logical XOR
1484      * operation ({@code ^}) is applied to lane elements,
1485      * and the identity value is {@code 0}.
1486      *
1487      * @param m the mask controlling lane selection
1488      * @return the logical XOR all the lane elements of this vector
1489      */
1490     public abstract int xorAll(Mask<Integer> m);
1491 
1492     // Type specific accessors
1493 
1494     /**
1495      * Gets the lane element at lane index {@code i}
1496      *
1497      * @param i the lane index
1498      * @return the lane element at lane index {@code i}
1499      * @throws IllegalArgumentException if the index is is out of range
1500      * ({@code < 0 || >= length()})
1501      */
1502     public abstract int get(int i);
1503 
1504     /**
1505      * Replaces the lane element of this vector at lane index {@code i} with
1506      * value {@code e}.
1507      * <p>
1508      * This is a cross-lane operation and behaves as if it returns the result
1509      * of blending this vector with an input vector that is the result of
1510      * broadcasting {@code e} and a mask that has only one lane set at lane
1511      * index {@code i}.
1512      *
1513      * @param i the lane index of the lane element to be replaced
1514      * @param e the value to be placed
1515      * @return the result of replacing the lane element of this vector at lane
1516      * index {@code i} with value {@code e}.
1517      * @throws IllegalArgumentException if the index is is out of range
1518      * ({@code < 0 || >= length()})
1519      */
1520     public abstract IntVector with(int i, int e);
1521 
1522     // Type specific extractors
1523 
1524     /**
1525      * Returns an array containing the lane elements of this vector.
1526      * <p>
1527      * This method behaves as if it {@link #intoArray(int[], int)} stores}
1528      * this vector into an allocated array and returns the array as follows:
1529      * <pre>{@code
1530      *   int[] a = new int[this.length()];
1531      *   this.intoArray(a, 0);
1532      *   return a;
1533      * }</pre>
1534      *
1535      * @return an array containing the the lane elements of this vector
1536      */
1537     @ForceInline
1538     public final int[] toArray() {
1539         int[] a = new int[species().length()];
1540         intoArray(a, 0);
1541         return a;
1542     }
1543 
1544     /**
1545      * Stores this vector into an array starting at offset.
1546      * <p>
1547      * For each vector lane, where {@code N} is the vector lane index,
1548      * the lane element at index {@code N} is stored into the array at index
1549      * {@code i + N}.
1550      *
1551      * @param a the array
1552      * @param i the offset into the array
1553      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1554      * {@code i > a.length - this.length()}
1555      */
1556     public abstract void intoArray(int[] a, int i);
1557 
1558     /**
1559      * Stores this vector into an array starting at offset and using a mask.
1560      * <p>
1561      * For each vector lane, where {@code N} is the vector lane index,
1562      * if the mask lane at index {@code N} is set then the lane element at
1563      * index {@code N} is stored into the array index {@code i + N}.
1564      *
1565      * @param a the array
1566      * @param i the offset into the array
1567      * @param m the mask
1568      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1569      * for any vector lane index {@code N} where the mask at lane {@code N}
1570      * is set {@code i >= a.length - N}
1571      */
1572     public abstract void intoArray(int[] a, int i, Mask<Integer> m);
1573 
1574     /**
1575      * Stores this vector into an array using indexes obtained from an index
1576      * map.
1577      * <p>
1578      * For each vector lane, where {@code N} is the vector lane index, the
1579      * lane element at index {@code N} is stored into the array at index
1580      * {@code i + indexMap[j + N]}.
1581      *
1582      * @param a the array
1583      * @param i the offset into the array, may be negative if relative
1584      * indexes in the index map compensate to produce a value within the
1585      * array bounds
1586      * @param indexMap the index map
1587      * @param j the offset into the index map
1588      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1589      * {@code j > indexMap.length - this.length()},
1590      * or for any vector lane index {@code N} the result of
1591      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1592      */
1593     public abstract void intoArray(int[] a, int i, int[] indexMap, int j);
1594 
1595     /**
1596      * Stores this vector into an array using indexes obtained from an index
1597      * map and using a mask.
1598      * <p>
1599      * For each vector lane, where {@code N} is the vector lane index,
1600      * if the mask lane at index {@code N} is set then the lane element at
1601      * index {@code N} is stored into the array at index
1602      * {@code i + indexMap[j + N]}.
1603      *
1604      * @param a the array
1605      * @param i the offset into the array, may be negative if relative
1606      * indexes in the index map compensate to produce a value within the
1607      * array bounds
1608      * @param m the mask
1609      * @param indexMap the index map
1610      * @param j the offset into the index map
1611      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1612      * {@code j > indexMap.length - this.length()},
1613      * or for any vector lane index {@code N} where the mask at lane
1614      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1615      * {@code < 0} or {@code >= a.length}
1616      */
1617     public abstract void intoArray(int[] a, int i, Mask<Integer> m, int[] indexMap, int j);
1618     // Species
1619 
1620     @Override
1621     public abstract IntSpecies species();
1622 
1623     /**
1624      * Class representing {@link IntVector}'s of the same {@link Vector.Shape Shape}.
1625      */
1626     public static abstract class IntSpecies extends Vector.Species<Integer> {
1627         interface FOp {
1628             int apply(int i);
1629         }
1630 
1631         abstract IntVector op(FOp f);
1632 
1633         abstract IntVector op(Mask<Integer> m, FOp f);
1634 
1635         interface FOpm {
1636             boolean apply(int i);
1637         }
1638 
1639         abstract Mask<Integer> opm(FOpm f);
1640 
1641         abstract IntVector.IntSpecies indexSpecies();
1642 
1643         // Factories
1644 
1645         @Override
1646         public abstract IntVector zero();
1647 
1648         /**
1649          * Returns a vector where all lane elements are set to the primitive
1650          * value {@code e}.
1651          *
1652          * @param e the value
1653          * @return a vector of vector where all lane elements are set to
1654          * the primitive value {@code e}
1655          */
1656         public abstract IntVector broadcast(int e);
1657 
1658         /**
1659          * Returns a vector where the first lane element is set to the primtive
1660          * value {@code e}, all other lane elements are set to the default
1661          * value.
1662          *
1663          * @param e the value
1664          * @return a vector where the first lane element is set to the primitive
1665          * value {@code e}
1666          */
1667         @ForceInline
1668         public final IntVector single(int e) {
1669             return zero().with(0, e);
1670         }
1671 
1672         /**
1673          * Returns a vector where each lane element is set to a randomly
1674          * generated primitive value.
1675          *
1676          * The semantics are equivalent to calling
1677          * {@code (int)ThreadLocalRandom#nextInt()}.
1678          *
1679          * @return a vector where each lane elements is set to a randomly
1680          * generated primitive value
1681          */
1682         public IntVector random() {
1683             ThreadLocalRandom r = ThreadLocalRandom.current();
1684             return op(i -> r.nextInt());
1685         }
1686 
1687         /**
1688          * Returns a vector where each lane element is set to a given
1689          * primitive value.
1690          * <p>
1691          * For each vector lane, where {@code N} is the vector lane index, the
1692          * the primitive value at index {@code N} is placed into the resulting
1693          * vector at lane index {@code N}.
1694          *
1695          * @param es the given primitive values
1696          * @return a vector where each lane element is set to a given primitive
1697          * value
1698          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
1699          */
1700         public abstract IntVector scalars(int... es);
1701     }
1702 
1703     /**
1704      * Finds the preferred species for an element type of {@code int}.
1705      * <p>
1706      * A preferred species is a species chosen by the platform that has a
1707      * shape of maximal bit size.  A preferred species for different element
1708      * types will have the same shape, and therefore vectors, masks, and
1709      * shuffles created from such species will be shape compatible.
1710      *
1711      * @return the preferred species for an element type of {@code int}
1712      */
1713     @SuppressWarnings("unchecked")
1714     public static IntSpecies preferredSpecies() {
1715         return (IntSpecies) Species.ofPreferred(int.class);
1716     }
1717 
1718     /**
1719      * Finds a species for an element type of {@code int} and shape.
1720      *
1721      * @param s the shape
1722      * @return a species for an element type of {@code int} and shape
1723      * @throws IllegalArgumentException if no such species exists for the shape
1724      */
1725     @SuppressWarnings("unchecked")
1726     public static IntSpecies species(Vector.Shape s) {
1727         Objects.requireNonNull(s);
1728         switch (s) {
1729             case S_64_BIT: return Int64Vector.SPECIES;
1730             case S_128_BIT: return Int128Vector.SPECIES;
1731             case S_256_BIT: return Int256Vector.SPECIES;
1732             case S_512_BIT: return Int512Vector.SPECIES;
1733             case S_Max_BIT: return IntMaxVector.SPECIES;
1734             default: throw new IllegalArgumentException("Bad shape: " + s);
1735         }
1736     }
1737 }