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