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