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