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