< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java

Print this page
rev 55589 : Species-phase2
rev 55590 : added missing javadocs, changed jtreg test
rev 55591 : XxxSpecies made package private
rev 55592 : Capitalized Species names


  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.ShortBuffer;
  29 import java.nio.ByteOrder;
  30 import java.util.Objects;
  31 import java.util.function.IntUnaryOperator;

  32 import java.util.concurrent.ThreadLocalRandom;
  33 
  34 import jdk.internal.misc.Unsafe;
  35 import jdk.internal.vm.annotation.ForceInline;
  36 import static jdk.incubator.vector.VectorIntrinsics.*;
  37 
  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code short} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class ShortVector extends Vector<Short> {
  45 
  46     ShortVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_SHORT_INDEX_SCALE);
  49 
  50     // Unary operator
  51 


  93 
  94     interface FUnCon {
  95         void apply(int i, short a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(Mask<Short> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @param species species of desired vector
 109      * @return a zero vector of given species
 110      */
 111     @ForceInline
 112     @SuppressWarnings("unchecked")
 113     public static ShortVector zero(ShortSpecies species) {
 114         return species.zero();


 115     }
 116 
 117     /**
 118      * Loads a vector from a byte array starting at an offset.
 119      * <p>
 120      * Bytes are composed into primitive lane elements according to the
 121      * native byte order of the underlying platform
 122      * <p>
 123      * This method behaves as if it returns the result of calling the
 124      * byte buffer, offset, and mask accepting
 125      * {@link #fromByteBuffer(ShortSpecies, ByteBuffer, int, Mask) method} as follows:
 126      * <pre>{@code
 127      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 128      * }</pre>
 129      *
 130      * @param species species of desired vector
 131      * @param a the byte array
 132      * @param ix the offset into the array
 133      * @return a vector loaded from a byte array
 134      * @throws IndexOutOfBoundsException if {@code i < 0} or
 135      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 136      */
 137     @ForceInline
 138     @SuppressWarnings("unchecked")
 139     public static ShortVector fromByteArray(ShortSpecies species, byte[] a, int ix) {
 140         Objects.requireNonNull(a);
 141         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 142         return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(),
 143                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 144                                      a, ix, species,
 145                                      (c, idx, s) -> {
 146                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 147                                          ShortBuffer tb = bbc.asShortBuffer();
 148                                          return ((ShortSpecies)s).op(i -> tb.get());
 149                                      });
 150     }
 151 
 152     /**
 153      * Loads a vector from a byte array starting at an offset and using a
 154      * mask.
 155      * <p>
 156      * Bytes are composed into primitive lane elements according to the
 157      * native byte order of the underlying platform.
 158      * <p>
 159      * This method behaves as if it returns the result of calling the
 160      * byte buffer, offset, and mask accepting
 161      * {@link #fromByteBuffer(ShortSpecies, ByteBuffer, int, Mask) method} as follows:
 162      * <pre>{@code
 163      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 164      * }</pre>
 165      *
 166      * @param species species of desired vector
 167      * @param a the byte array
 168      * @param ix the offset into the array
 169      * @param m the mask
 170      * @return a vector loaded from a byte array
 171      * @throws IndexOutOfBoundsException if {@code i < 0} or
 172      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 173      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 174      * or {@code > a.length},
 175      * for any vector lane index {@code N} where the mask at lane {@code N}
 176      * is set
 177      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 178      */
 179     @ForceInline
 180     public static ShortVector fromByteArray(ShortSpecies species, byte[] a, int ix, Mask<Short> m) {
 181         return zero(species).blend(fromByteArray(species, a, ix), m);
 182     }
 183 
 184     /**
 185      * Loads a vector from an array starting at offset.
 186      * <p>
 187      * For each vector lane, where {@code N} is the vector lane index, the
 188      * array element at index {@code i + N} is placed into the
 189      * resulting vector at lane index {@code N}.
 190      *
 191      * @param species species of desired vector
 192      * @param a the array
 193      * @param i the offset into the array
 194      * @return the vector loaded from an array
 195      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 196      * {@code i > a.length - this.length()}
 197      */
 198     @ForceInline
 199     @SuppressWarnings("unchecked")
 200     public static ShortVector fromArray(ShortSpecies species, short[] a, int i){
 201         Objects.requireNonNull(a);
 202         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 203         return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(),
 204                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_SHORT_BASE_OFFSET,
 205                                      a, i, species,
 206                                      (c, idx, s) -> ((ShortSpecies)s).op(n -> c[idx + n]));
 207     }
 208 
 209 
 210     /**
 211      * Loads a vector from an array starting at offset and using a mask.
 212      * <p>
 213      * For each vector lane, where {@code N} is the vector lane index,
 214      * if the mask lane at index {@code N} is set then the array element at
 215      * index {@code i + N} is placed into the resulting vector at lane index
 216      * {@code N}, otherwise the default element value is placed into the
 217      * resulting vector at lane index {@code N}.
 218      *
 219      * @param species species of desired vector
 220      * @param a the array
 221      * @param i the offset into the array
 222      * @param m the mask
 223      * @return the vector loaded from an array
 224      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 225      * for any vector lane index {@code N} where the mask at lane {@code N}
 226      * is set {@code i > a.length - N}
 227      */
 228     @ForceInline
 229     public static ShortVector fromArray(ShortSpecies species, short[] a, int i, Mask<Short> m) {
 230         return zero(species).blend(fromArray(species, a, i), m);
 231     }
 232 
 233     /**
 234      * Loads a vector from an array using indexes obtained from an index
 235      * map.
 236      * <p>
 237      * For each vector lane, where {@code N} is the vector lane index, the
 238      * array element at index {@code i + indexMap[j + N]} is placed into the
 239      * resulting vector at lane index {@code N}.
 240      *
 241      * @param species species of desired vector
 242      * @param a the array
 243      * @param i the offset into the array, may be negative if relative
 244      * indexes in the index map compensate to produce a value within the
 245      * array bounds
 246      * @param indexMap the index map
 247      * @param j the offset into the index map
 248      * @return the vector loaded from an array
 249      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 250      * {@code j > indexMap.length - this.length()},
 251      * or for any vector lane index {@code N} the result of
 252      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 253      */
 254     public static ShortVector fromArray(ShortSpecies species, short[] a, int i, int[] indexMap, int j) {
 255         return species.op(n -> a[i + indexMap[j + n]]);
 256     }
 257     /**
 258      * Loads a vector from an array using indexes obtained from an index
 259      * map and using a mask.
 260      * <p>
 261      * For each vector lane, where {@code N} is the vector lane index,
 262      * if the mask lane at index {@code N} is set then the array element at
 263      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 264      * at lane index {@code N}.
 265      *
 266      * @param species species of desired vector
 267      * @param a the array
 268      * @param i the offset into the array, may be negative if relative
 269      * indexes in the index map compensate to produce a value within the
 270      * array bounds
 271      * @param m the mask
 272      * @param indexMap the index map
 273      * @param j the offset into the index map
 274      * @return the vector loaded from an array
 275      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 276      * {@code j > indexMap.length - this.length()},
 277      * or for any vector lane index {@code N} where the mask at lane
 278      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 279      * {@code < 0} or {@code >= a.length}
 280      */
 281     public static ShortVector fromArray(ShortSpecies species, short[] a, int i, Mask<Short> m, int[] indexMap, int j) {
 282         return species.op(m, n -> a[i + indexMap[j + n]]);
 283     }
 284 
 285     /**
 286      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 287      * offset into the byte buffer.
 288      * <p>
 289      * Bytes are composed into primitive lane elements according to the
 290      * native byte order of the underlying platform.
 291      * <p>
 292      * This method behaves as if it returns the result of calling the
 293      * byte buffer, offset, and mask accepting
 294      * {@link #fromByteBuffer(ShortSpecies, ByteBuffer, int, Mask)} method} as follows:
 295      * <pre>{@code
 296      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 297      * }</pre>
 298      *
 299      * @param species species of desired vector
 300      * @param bb the byte buffer
 301      * @param ix the offset into the byte buffer
 302      * @return a vector loaded from a byte buffer
 303      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 304      * or {@code > b.limit()},
 305      * or if there are fewer than
 306      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 307      * remaining in the byte buffer from the given offset
 308      */
 309     @ForceInline
 310     @SuppressWarnings("unchecked")
 311     public static ShortVector fromByteBuffer(ShortSpecies species, ByteBuffer bb, int ix) {
 312         if (bb.order() != ByteOrder.nativeOrder()) {
 313             throw new IllegalArgumentException();
 314         }
 315         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 316         return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(),
 317                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 318                                      bb, ix, species,
 319                                      (c, idx, s) -> {
 320                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 321                                          ShortBuffer tb = bbc.asShortBuffer();
 322                                          return ((ShortSpecies)s).op(i -> tb.get());
 323                                      });
 324     }
 325 
 326     /**
 327      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 328      * offset into the byte buffer and using a mask.
 329      * <p>
 330      * This method behaves as if the byte buffer is viewed as a primitive
 331      * {@link java.nio.Buffer buffer} for the primitive element type,


 343      * e[] es = new e[this.length()];
 344      * for (int n = 0; n < t.length; n++) {
 345      *     if (m.isSet(n))
 346      *         es[n] = eb.get(n);
 347      * }
 348      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 349      * }</pre>
 350      *
 351      * @param species species of desired vector
 352      * @param bb the byte buffer
 353      * @param ix the offset into the byte buffer
 354      * @param m the mask
 355      * @return a vector loaded from a byte buffer
 356      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 357      * or {@code > b.limit()},
 358      * for any vector lane index {@code N} where the mask at lane {@code N}
 359      * is set
 360      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 361      */
 362     @ForceInline
 363     public static ShortVector fromByteBuffer(ShortSpecies species, ByteBuffer bb, int ix, Mask<Short> m) {
 364         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 365     }
 366 
 367     /**










































































 368      * Returns a mask where each lane is set or unset according to given
 369      * {@code boolean} values
 370      * <p>
 371      * For each mask lane, where {@code N} is the mask lane index,
 372      * if the given {@code boolean} value at index {@code N} is {@code true}
 373      * then the mask lane at index {@code N} is set, otherwise it is unset.
 374      *
 375      * @param species mask species
 376      * @param bits the given {@code boolean} values
 377      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 378      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 379      */
 380     @ForceInline
 381     public static Mask<Short> maskFromValues(ShortSpecies species, boolean... bits) {
 382         if (species.boxType() == ShortMaxVector.class)
 383             return new ShortMaxVector.ShortMaxMask(bits);
 384         switch (species.bitSize()) {
 385             case 64: return new Short64Vector.Short64Mask(bits);
 386             case 128: return new Short128Vector.Short128Mask(bits);
 387             case 256: return new Short256Vector.Short256Mask(bits);
 388             case 512: return new Short512Vector.Short512Mask(bits);
 389             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 390         }
 391     }
 392 
 393     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 394     static Mask<Short> trueMask(ShortSpecies species) {
 395         if (species.boxType() == ShortMaxVector.class)
 396             return ShortMaxVector.ShortMaxMask.TRUE_MASK;
 397         switch (species.bitSize()) {
 398             case 64: return Short64Vector.Short64Mask.TRUE_MASK;
 399             case 128: return Short128Vector.Short128Mask.TRUE_MASK;
 400             case 256: return Short256Vector.Short256Mask.TRUE_MASK;
 401             case 512: return Short512Vector.Short512Mask.TRUE_MASK;
 402             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 403         }
 404     }
 405 
 406     static Mask<Short> falseMask(ShortSpecies species) {
 407         if (species.boxType() == ShortMaxVector.class)
 408             return ShortMaxVector.ShortMaxMask.FALSE_MASK;
 409         switch (species.bitSize()) {
 410             case 64: return Short64Vector.Short64Mask.FALSE_MASK;
 411             case 128: return Short128Vector.Short128Mask.FALSE_MASK;
 412             case 256: return Short256Vector.Short256Mask.FALSE_MASK;
 413             case 512: return Short512Vector.Short512Mask.FALSE_MASK;
 414             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 415         }
 416     }
 417 
 418     /**
 419      * Loads a mask from a {@code boolean} array starting at an offset.
 420      * <p>
 421      * For each mask lane, where {@code N} is the mask lane index,
 422      * if the array element at index {@code ix + N} is {@code true} then the
 423      * mask lane at index {@code N} is set, otherwise it is unset.
 424      *
 425      * @param species mask species
 426      * @param bits the {@code boolean} array
 427      * @param ix the offset into the array
 428      * @return the mask loaded from a {@code boolean} array
 429      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 430      * {@code ix > bits.length - species.length()}
 431      */
 432     @ForceInline
 433     @SuppressWarnings("unchecked")
 434     public static Mask<Short> maskFromArray(ShortSpecies species, boolean[] bits, int ix) {
 435         Objects.requireNonNull(bits);
 436         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 437         return VectorIntrinsics.load((Class<Mask<Short>>) species.maskType(), short.class, species.length(),
 438                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 439                                      bits, ix, species,
 440                                      (c, idx, s) -> (Mask<Short>) ((ShortSpecies)s).opm(n -> c[idx + n]));
 441     }
 442 
 443     /**
 444      * Returns a mask where all lanes are set.
 445      *
 446      * @param species mask species
 447      * @return a mask where all lanes are set
 448      */
 449     @ForceInline
 450     @SuppressWarnings("unchecked")
 451     public static Mask<Short> maskAllTrue(ShortSpecies species) {
 452         return VectorIntrinsics.broadcastCoerced((Class<Mask<Short>>) species.maskType(), short.class, species.length(),
 453                                                  (short)-1,  species,
 454                                                  ((z, s) -> trueMask((ShortSpecies)s)));
 455     }
 456 
 457     /**
 458      * Returns a mask where all lanes are unset.
 459      *
 460      * @param species mask species
 461      * @return a mask where all lanes are unset
 462      */
 463     @ForceInline
 464     @SuppressWarnings("unchecked")
 465     public static Mask<Short> maskAllFalse(ShortSpecies species) {
 466         return VectorIntrinsics.broadcastCoerced((Class<Mask<Short>>) species.maskType(), short.class, species.length(),
 467                                                  0, species, 
 468                                                  ((z, s) -> falseMask((ShortSpecies)s)));
 469     }
 470 
 471     /**
 472      * Returns a shuffle of mapped indexes where each lane element is
 473      * the result of applying a mapping function to the corresponding lane
 474      * index.
 475      * <p>
 476      * Care should be taken to ensure Shuffle values produced from this
 477      * method are consumed as constants to ensure optimal generation of
 478      * code.  For example, values held in static final fields or values
 479      * held in loop constant local variables.
 480      * <p>
 481      * This method behaves as if a shuffle is created from an array of
 482      * mapped indexes as follows:
 483      * <pre>{@code
 484      *   int[] a = new int[species.length()];
 485      *   for (int i = 0; i < a.length; i++) {
 486      *       a[i] = f.applyAsInt(i);
 487      *   }
 488      *   return this.shuffleFromValues(a);
 489      * }</pre>
 490      *
 491      * @param species shuffle species
 492      * @param f the lane index mapping function
 493      * @return a shuffle of mapped indexes
 494      */
 495     @ForceInline
 496     public static Shuffle<Short> shuffle(ShortSpecies species, IntUnaryOperator f) {
 497         if (species.boxType() == ShortMaxVector.class)
 498             return new ShortMaxVector.ShortMaxShuffle(f);
 499         switch (species.bitSize()) {
 500             case 64: return new Short64Vector.Short64Shuffle(f);
 501             case 128: return new Short128Vector.Short128Shuffle(f);
 502             case 256: return new Short256Vector.Short256Shuffle(f);
 503             case 512: return new Short512Vector.Short512Shuffle(f);
 504             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 505         }
 506     }
 507 
 508     /**
 509      * Returns a shuffle where each lane element is the value of its
 510      * corresponding lane index.
 511      * <p>
 512      * This method behaves as if a shuffle is created from an identity
 513      * index mapping function as follows:
 514      * <pre>{@code
 515      *   return this.shuffle(i -> i);
 516      * }</pre>
 517      *
 518      * @param species shuffle species
 519      * @return a shuffle of lane indexes
 520      */
 521     @ForceInline
 522     public static Shuffle<Short> shuffleIota(ShortSpecies species) {
 523         if (species.boxType() == ShortMaxVector.class)
 524             return new ShortMaxVector.ShortMaxShuffle(AbstractShuffle.IDENTITY);
 525         switch (species.bitSize()) {
 526             case 64: return new Short64Vector.Short64Shuffle(AbstractShuffle.IDENTITY);
 527             case 128: return new Short128Vector.Short128Shuffle(AbstractShuffle.IDENTITY);
 528             case 256: return new Short256Vector.Short256Shuffle(AbstractShuffle.IDENTITY);
 529             case 512: return new Short512Vector.Short512Shuffle(AbstractShuffle.IDENTITY);
 530             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 531         }
 532     }
 533 
 534     /**
 535      * Returns a shuffle where each lane element is set to a given
 536      * {@code int} value logically AND'ed by the species length minus one.
 537      * <p>
 538      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 539      * the {@code int} value at index {@code N} logically AND'ed by
 540      * {@code species.length() - 1} is placed into the resulting shuffle at
 541      * lane index {@code N}.
 542      *
 543      * @param species shuffle species
 544      * @param ixs the given {@code int} values
 545      * @return a shuffle where each lane element is set to a given
 546      * {@code int} value
 547      * @throws IndexOutOfBoundsException if the number of int values is
 548      * {@code < species.length()}
 549      */
 550     @ForceInline
 551     public static Shuffle<Short> shuffleFromValues(ShortSpecies species, int... ixs) {
 552         if (species.boxType() == ShortMaxVector.class)
 553             return new ShortMaxVector.ShortMaxShuffle(ixs);
 554         switch (species.bitSize()) {
 555             case 64: return new Short64Vector.Short64Shuffle(ixs);
 556             case 128: return new Short128Vector.Short128Shuffle(ixs);
 557             case 256: return new Short256Vector.Short256Shuffle(ixs);
 558             case 512: return new Short512Vector.Short512Shuffle(ixs);
 559             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 560         }
 561     }
 562 
 563     /**
 564      * Loads a shuffle from an {@code int} array starting at an offset.
 565      * <p>
 566      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 567      * array element at index {@code i + N} logically AND'ed by
 568      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 569      * index {@code N}.
 570      *
 571      * @param species shuffle species
 572      * @param ixs the {@code int} array
 573      * @param i the offset into the array
 574      * @return a shuffle loaded from the {@code int} array
 575      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 576      * {@code i > a.length - species.length()}
 577      */
 578     @ForceInline
 579     public static Shuffle<Short> shuffleFromArray(ShortSpecies species, int[] ixs, int i) {
 580         if (species.boxType() == ShortMaxVector.class)
 581             return new ShortMaxVector.ShortMaxShuffle(ixs, i);
 582         switch (species.bitSize()) {
 583             case 64: return new Short64Vector.Short64Shuffle(ixs, i);
 584             case 128: return new Short128Vector.Short128Shuffle(ixs, i);
 585             case 256: return new Short256Vector.Short256Shuffle(ixs, i);
 586             case 512: return new Short512Vector.Short512Shuffle(ixs, i);
 587             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 588         }
 589     }
 590 
 591 
 592     // Ops
 593 
 594     @Override
 595     public abstract ShortVector add(Vector<Short> v);
 596 
 597     /**
 598      * Adds this vector to the broadcast of an input scalar.
 599      * <p>
 600      * This is a vector binary operation where the primitive addition operation
 601      * ({@code +}) is applied to lane elements.
 602      *
 603      * @param s the input scalar
 604      * @return the result of adding this vector to the broadcast of an input
 605      * scalar
 606      */
 607     public abstract ShortVector add(short s);
 608 
 609     @Override
 610     public abstract ShortVector add(Vector<Short> v, Mask<Short> m);
 611 


1452      *
1453      * @param a the array
1454      * @param i the offset into the array, may be negative if relative
1455      * indexes in the index map compensate to produce a value within the
1456      * array bounds
1457      * @param m the mask
1458      * @param indexMap the index map
1459      * @param j the offset into the index map
1460      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1461      * {@code j > indexMap.length - this.length()},
1462      * or for any vector lane index {@code N} where the mask at lane
1463      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1464      * {@code < 0} or {@code >= a.length}
1465      */
1466     public void intoArray(short[] a, int i, Mask<Short> m, int[] indexMap, int j) {
1467         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
1468     }
1469     // Species
1470 
1471     @Override
1472     public abstract ShortSpecies species();
1473 
1474     /**
1475      * Class representing {@link ShortVector}'s of the same {@link Vector.Shape Shape}.
1476      */
1477     public static abstract class ShortSpecies extends Vector.Species<Short> {













1478         interface FOp {
1479             short apply(int i);
1480         }
1481 
1482         abstract ShortVector op(FOp f);
1483 
1484         abstract ShortVector op(Mask<Short> m, FOp f);
1485 
1486         interface FOpm {
1487             boolean apply(int i);
1488         }
1489 
1490         abstract Mask<Short> opm(FOpm f);
1491 
1492 
1493 
1494         // Factories
1495 
1496         @Override
1497         public abstract ShortVector zero();
1498 
1499         /**
1500          * Returns a vector where all lane elements are set to the primitive
1501          * value {@code e}.
1502          *
1503          * @param e the value
1504          * @return a vector of vector where all lane elements are set to
1505          * the primitive value {@code e}
1506          */
1507         public abstract ShortVector broadcast(short e);
1508 
1509         /**
1510          * Returns a vector where the first lane element is set to the primtive
1511          * value {@code e}, all other lane elements are set to the default
1512          * value.
1513          *
1514          * @param e the value
1515          * @return a vector where the first lane element is set to the primitive
1516          * value {@code e}
1517          */
1518         @ForceInline
1519         public final ShortVector single(short e) {
1520             return zero().with(0, e);
1521         }
1522 
1523         /**
1524          * Returns a vector where each lane element is set to a randomly
1525          * generated primitive value.
1526          *
1527          * The semantics are equivalent to calling
1528          * {@code (short)ThreadLocalRandom#nextInt()}.
1529          *
1530          * @return a vector where each lane elements is set to a randomly
1531          * generated primitive value
1532          */
1533         public ShortVector random() {
1534             ThreadLocalRandom r = ThreadLocalRandom.current();
1535             return op(i -> (short) r.nextInt());
1536         }
1537 
1538         /**
1539          * Returns a vector where each lane element is set to a given
1540          * primitive value.
1541          * <p>
1542          * For each vector lane, where {@code N} is the vector lane index, the
1543          * the primitive value at index {@code N} is placed into the resulting
1544          * vector at lane index {@code N}.
1545          *
1546          * @param es the given primitive values
1547          * @return a vector where each lane element is set to a given primitive
1548          * value
1549          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
1550          */
1551         public abstract ShortVector scalars(short... es);
1552     }
1553 
1554     /**
1555      * Finds the preferred species for an element type of {@code short}.
1556      * <p>
1557      * A preferred species is a species chosen by the platform that has a
1558      * shape of maximal bit size.  A preferred species for different element
1559      * types will have the same shape, and therefore vectors, masks, and
1560      * shuffles created from such species will be shape compatible.
1561      *
1562      * @return the preferred species for an element type of {@code short}
1563      */
1564     @SuppressWarnings("unchecked")
1565     public static ShortSpecies preferredSpecies() {
1566         return (ShortSpecies) Species.ofPreferred(short.class);
1567     }
1568 
1569     /**
1570      * Finds a species for an element type of {@code short} and shape.
1571      *
1572      * @param s the shape
1573      * @return a species for an element type of {@code short} and shape
1574      * @throws IllegalArgumentException if no such species exists for the shape
1575      */
1576     @SuppressWarnings("unchecked")
1577     public static ShortSpecies species(Vector.Shape s) {
1578         Objects.requireNonNull(s);
1579         switch (s) {
1580             case S_64_BIT: return Short64Vector.SPECIES;
1581             case S_128_BIT: return Short128Vector.SPECIES;
1582             case S_256_BIT: return Short256Vector.SPECIES;
1583             case S_512_BIT: return Short512Vector.SPECIES;
1584             case S_Max_BIT: return ShortMaxVector.SPECIES;
1585             default: throw new IllegalArgumentException("Bad shape: " + s);
1586         }
1587     }


























1588 }


  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.ShortBuffer;
  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 short} values.
  43  */
  44 @SuppressWarnings("cast")
  45 public abstract class ShortVector extends Vector<Short> {
  46 
  47     ShortVector() {}
  48 
  49     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_SHORT_INDEX_SCALE);
  50 
  51     // Unary operator
  52 


  94 
  95     interface FUnCon {
  96         void apply(int i, short a);
  97     }
  98 
  99     abstract void forEach(FUnCon f);
 100 
 101     abstract void forEach(Mask<Short> 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 ShortVector zero(Species<Short> species) {
 115         return VectorIntrinsics.broadcastCoerced((Class<ShortVector>) species.boxType(), short.class, species.length(),
 116                                                  0, species,
 117                                                  ((bits, s) -> ((ShortSpecies)s).op(i -> (short)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(Species<Short>, ByteBuffer, int, Mask) method} as follows:
 129      * <pre>{@code
 130      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 131      * }</pre>
 132      *
 133      * @param species species of desired vector
 134      * @param a the byte array
 135      * @param ix the offset into the array
 136      * @return a vector loaded from a byte array
 137      * @throws IndexOutOfBoundsException if {@code i < 0} or
 138      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 139      */
 140     @ForceInline
 141     @SuppressWarnings("unchecked")
 142     public static ShortVector fromByteArray(Species<Short> species, byte[] a, int ix) {
 143         Objects.requireNonNull(a);
 144         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 145         return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(),
 146                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 147                                      a, ix, species,
 148                                      (c, idx, s) -> {
 149                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 150                                          ShortBuffer tb = bbc.asShortBuffer();
 151                                          return ((ShortSpecies)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(Species<Short>, ByteBuffer, int, Mask) method} as follows:
 165      * <pre>{@code
 166      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 167      * }</pre>
 168      *
 169      * @param species species of desired vector
 170      * @param a the byte array
 171      * @param ix the offset into the array
 172      * @param m the mask
 173      * @return a vector loaded from a byte array
 174      * @throws IndexOutOfBoundsException if {@code i < 0} or
 175      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 176      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 177      * or {@code > a.length},
 178      * for any vector lane index {@code N} where the mask at lane {@code N}
 179      * is set
 180      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 181      */
 182     @ForceInline
 183     public static ShortVector fromByteArray(Species<Short> species, byte[] a, int ix, Mask<Short> m) {
 184         return zero(species).blend(fromByteArray(species, a, ix), m);
 185     }
 186 
 187     /**
 188      * Loads a vector from an array starting at offset.
 189      * <p>
 190      * For each vector lane, where {@code N} is the vector lane index, the
 191      * array element at index {@code i + N} is placed into the
 192      * resulting vector at lane index {@code N}.
 193      *
 194      * @param species species of desired vector
 195      * @param a the array
 196      * @param i the offset into the array
 197      * @return the vector loaded from an array
 198      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 199      * {@code i > a.length - this.length()}
 200      */
 201     @ForceInline
 202     @SuppressWarnings("unchecked")
 203     public static ShortVector fromArray(Species<Short> species, short[] a, int i){
 204         Objects.requireNonNull(a);
 205         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 206         return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(),
 207                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_SHORT_BASE_OFFSET,
 208                                      a, i, species,
 209                                      (c, idx, s) -> ((ShortSpecies)s).op(n -> c[idx + n]));
 210     }
 211 
 212 
 213     /**
 214      * Loads a vector from an array starting at offset and using a mask.
 215      * <p>
 216      * For each vector lane, where {@code N} is the vector lane index,
 217      * if the mask lane at index {@code N} is set then the array element at
 218      * index {@code i + N} is placed into the resulting vector at lane index
 219      * {@code N}, otherwise the default element value is placed into the
 220      * resulting vector at lane index {@code N}.
 221      *
 222      * @param species species of desired vector
 223      * @param a the array
 224      * @param i the offset into the array
 225      * @param m the mask
 226      * @return the vector loaded from an array
 227      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 228      * for any vector lane index {@code N} where the mask at lane {@code N}
 229      * is set {@code i > a.length - N}
 230      */
 231     @ForceInline
 232     public static ShortVector fromArray(Species<Short> species, short[] a, int i, Mask<Short> m) {
 233         return zero(species).blend(fromArray(species, a, i), m);
 234     }
 235 
 236     /**
 237      * Loads a vector from an array using indexes obtained from an index
 238      * map.
 239      * <p>
 240      * For each vector lane, where {@code N} is the vector lane index, the
 241      * array element at index {@code i + indexMap[j + N]} is placed into the
 242      * resulting vector at lane index {@code N}.
 243      *
 244      * @param species species of desired vector
 245      * @param a the array
 246      * @param i the offset into the array, may be negative if relative
 247      * indexes in the index map compensate to produce a value within the
 248      * array bounds
 249      * @param indexMap the index map
 250      * @param j the offset into the index map
 251      * @return the vector loaded from an array
 252      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 253      * {@code j > indexMap.length - this.length()},
 254      * or for any vector lane index {@code N} the result of
 255      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 256      */
 257     public static ShortVector fromArray(Species<Short> species, short[] a, int i, int[] indexMap, int j) {
 258         return ((ShortSpecies)species).op(n -> a[i + indexMap[j + n]]);
 259     }
 260     /**
 261      * Loads a vector from an array using indexes obtained from an index
 262      * map and using a mask.
 263      * <p>
 264      * For each vector lane, where {@code N} is the vector lane index,
 265      * if the mask lane at index {@code N} is set then the array element at
 266      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 267      * at lane index {@code N}.
 268      *
 269      * @param species species of desired vector
 270      * @param a the array
 271      * @param i the offset into the array, may be negative if relative
 272      * indexes in the index map compensate to produce a value within the
 273      * array bounds
 274      * @param m the mask
 275      * @param indexMap the index map
 276      * @param j the offset into the index map
 277      * @return the vector loaded from an array
 278      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 279      * {@code j > indexMap.length - this.length()},
 280      * or for any vector lane index {@code N} where the mask at lane
 281      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 282      * {@code < 0} or {@code >= a.length}
 283      */
 284     public static ShortVector fromArray(Species<Short> species, short[] a, int i, Mask<Short> m, int[] indexMap, int j) {
 285         return ((ShortSpecies)species).op(m, n -> a[i + indexMap[j + n]]);
 286     }
 287 
 288     /**
 289      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 290      * offset into the byte buffer.
 291      * <p>
 292      * Bytes are composed into primitive lane elements according to the
 293      * native byte order of the underlying platform.
 294      * <p>
 295      * This method behaves as if it returns the result of calling the
 296      * byte buffer, offset, and mask accepting
 297      * {@link #fromByteBuffer(Species<Short>, ByteBuffer, int, Mask)} method} as follows:
 298      * <pre>{@code
 299      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 300      * }</pre>
 301      *
 302      * @param species species of desired vector
 303      * @param bb the byte buffer
 304      * @param ix the offset into the byte buffer
 305      * @return a vector loaded from a byte buffer
 306      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 307      * or {@code > b.limit()},
 308      * or if there are fewer than
 309      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 310      * remaining in the byte buffer from the given offset
 311      */
 312     @ForceInline
 313     @SuppressWarnings("unchecked")
 314     public static ShortVector fromByteBuffer(Species<Short> species, ByteBuffer bb, int ix) {
 315         if (bb.order() != ByteOrder.nativeOrder()) {
 316             throw new IllegalArgumentException();
 317         }
 318         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 319         return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(),
 320                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 321                                      bb, ix, species,
 322                                      (c, idx, s) -> {
 323                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 324                                          ShortBuffer tb = bbc.asShortBuffer();
 325                                          return ((ShortSpecies)s).op(i -> tb.get());
 326                                      });
 327     }
 328 
 329     /**
 330      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 331      * offset into the byte buffer and using a mask.
 332      * <p>
 333      * This method behaves as if the byte buffer is viewed as a primitive
 334      * {@link java.nio.Buffer buffer} for the primitive element type,


 346      * e[] es = new e[this.length()];
 347      * for (int n = 0; n < t.length; n++) {
 348      *     if (m.isSet(n))
 349      *         es[n] = eb.get(n);
 350      * }
 351      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 352      * }</pre>
 353      *
 354      * @param species species of desired vector
 355      * @param bb the byte buffer
 356      * @param ix the offset into the byte buffer
 357      * @param m the mask
 358      * @return a vector loaded from a byte buffer
 359      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 360      * or {@code > b.limit()},
 361      * for any vector lane index {@code N} where the mask at lane {@code N}
 362      * is set
 363      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 364      */
 365     @ForceInline
 366     public static ShortVector fromByteBuffer(Species<Short> species, ByteBuffer bb, int ix, Mask<Short> m) {
 367         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 368     }
 369 
 370     /**
 371      * Returns a vector where all lane elements are set to the primitive
 372      * value {@code e}.
 373      *
 374      * @param s species of the desired vector
 375      * @param e the value
 376      * @return a vector of vector where all lane elements are set to
 377      * the primitive value {@code e}
 378      */
 379     @ForceInline
 380     @SuppressWarnings("unchecked")
 381     public static ShortVector broadcast(Species<Short> s, short e) {
 382         return VectorIntrinsics.broadcastCoerced(
 383             (Class<ShortVector>) s.boxType(), short.class, s.length(),
 384             e, s,
 385             ((bits, sp) -> ((ShortSpecies)sp).op(i -> (short)bits)));
 386     }
 387 
 388     /**
 389      * Returns a vector where each lane element is set to a given
 390      * primitive value.
 391      * <p>
 392      * For each vector lane, where {@code N} is the vector lane index, the
 393      * the primitive value at index {@code N} is placed into the resulting
 394      * vector at lane index {@code N}.
 395      *
 396      * @param s species of the desired vector
 397      * @param es the given primitive values
 398      * @return a vector where each lane element is set to a given primitive
 399      * value
 400      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 401      */
 402     @ForceInline
 403     @SuppressWarnings("unchecked")
 404     public static ShortVector scalars(Species<Short> s, short... es) {
 405         Objects.requireNonNull(es);
 406         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 407         return VectorIntrinsics.load((Class<ShortVector>) s.boxType(), short.class, s.length(),
 408                                      es, Unsafe.ARRAY_SHORT_BASE_OFFSET,
 409                                      es, ix, s,
 410                                      (c, idx, sp) -> ((ShortSpecies)sp).op(n -> c[idx + n]));
 411     }
 412 
 413     /**
 414      * Returns a vector where the first lane element is set to the primtive
 415      * value {@code e}, all other lane elements are set to the default
 416      * value.
 417      *
 418      * @param s species of the desired vector
 419      * @param e the value
 420      * @return a vector where the first lane element is set to the primitive
 421      * value {@code e}
 422      */
 423     @ForceInline
 424     public static final ShortVector single(Species<Short> s, short e) {
 425         return zero(s).with(0, e);
 426     }
 427 
 428     /**
 429      * Returns a vector where each lane element is set to a randomly
 430      * generated primitive value.
 431      *
 432      * The semantics are equivalent to calling
 433      * (short){@link ThreadLocalRandom#nextInt()}
 434      *
 435      * @param s species of the desired vector
 436      * @return a vector where each lane elements is set to a randomly
 437      * generated primitive value
 438      */
 439     public static ShortVector random(Species<Short> s) {
 440         ThreadLocalRandom r = ThreadLocalRandom.current();
 441         return ((ShortSpecies)s).op(i -> (short) r.nextInt());
 442     }
 443 
 444     /**
 445      * Returns a mask where each lane is set or unset according to given
 446      * {@code boolean} values
 447      * <p>
 448      * For each mask lane, where {@code N} is the mask lane index,
 449      * if the given {@code boolean} value at index {@code N} is {@code true}
 450      * then the mask lane at index {@code N} is set, otherwise it is unset.
 451      *
 452      * @param species mask species
 453      * @param bits the given {@code boolean} values
 454      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 455      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 456      */
 457     @ForceInline
 458     public static Mask<Short> maskFromValues(Species<Short> species, boolean... bits) {
 459         if (species.boxType() == ShortMaxVector.class)
 460             return new ShortMaxVector.ShortMaxMask(bits);
 461         switch (species.bitSize()) {
 462             case 64: return new Short64Vector.Short64Mask(bits);
 463             case 128: return new Short128Vector.Short128Mask(bits);
 464             case 256: return new Short256Vector.Short256Mask(bits);
 465             case 512: return new Short512Vector.Short512Mask(bits);
 466             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 467         }
 468     }
 469 
 470     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 471     static Mask<Short> trueMask(Species<Short> species) {
 472         if (species.boxType() == ShortMaxVector.class)
 473             return ShortMaxVector.ShortMaxMask.TRUE_MASK;
 474         switch (species.bitSize()) {
 475             case 64: return Short64Vector.Short64Mask.TRUE_MASK;
 476             case 128: return Short128Vector.Short128Mask.TRUE_MASK;
 477             case 256: return Short256Vector.Short256Mask.TRUE_MASK;
 478             case 512: return Short512Vector.Short512Mask.TRUE_MASK;
 479             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 480         }
 481     }
 482 
 483     static Mask<Short> falseMask(Species<Short> species) {
 484         if (species.boxType() == ShortMaxVector.class)
 485             return ShortMaxVector.ShortMaxMask.FALSE_MASK;
 486         switch (species.bitSize()) {
 487             case 64: return Short64Vector.Short64Mask.FALSE_MASK;
 488             case 128: return Short128Vector.Short128Mask.FALSE_MASK;
 489             case 256: return Short256Vector.Short256Mask.FALSE_MASK;
 490             case 512: return Short512Vector.Short512Mask.FALSE_MASK;
 491             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 492         }
 493     }
 494 
 495     /**
 496      * Loads a mask from a {@code boolean} array starting at an offset.
 497      * <p>
 498      * For each mask lane, where {@code N} is the mask lane index,
 499      * if the array element at index {@code ix + N} is {@code true} then the
 500      * mask lane at index {@code N} is set, otherwise it is unset.
 501      *
 502      * @param species mask species
 503      * @param bits the {@code boolean} array
 504      * @param ix the offset into the array
 505      * @return the mask loaded from a {@code boolean} array
 506      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 507      * {@code ix > bits.length - species.length()}
 508      */
 509     @ForceInline
 510     @SuppressWarnings("unchecked")
 511     public static Mask<Short> maskFromArray(Species<Short> species, boolean[] bits, int ix) {
 512         Objects.requireNonNull(bits);
 513         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 514         return VectorIntrinsics.load((Class<Mask<Short>>) species.maskType(), short.class, species.length(),
 515                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 516                                      bits, ix, species,
 517                                      (c, idx, s) -> (Mask<Short>) ((ShortSpecies)s).opm(n -> c[idx + n]));
 518     }
 519 
 520     /**
 521      * Returns a mask where all lanes are set.
 522      *
 523      * @param species mask species
 524      * @return a mask where all lanes are set
 525      */
 526     @ForceInline
 527     @SuppressWarnings("unchecked")
 528     public static Mask<Short> maskAllTrue(Species<Short> species) {
 529         return VectorIntrinsics.broadcastCoerced((Class<Mask<Short>>) species.maskType(), short.class, species.length(),
 530                                                  (short)-1,  species,
 531                                                  ((z, s) -> trueMask(s)));
 532     }
 533 
 534     /**
 535      * Returns a mask where all lanes are unset.
 536      *
 537      * @param species mask species
 538      * @return a mask where all lanes are unset
 539      */
 540     @ForceInline
 541     @SuppressWarnings("unchecked")
 542     public static Mask<Short> maskAllFalse(Species<Short> species) {
 543         return VectorIntrinsics.broadcastCoerced((Class<Mask<Short>>) species.maskType(), short.class, species.length(),
 544                                                  0, species, 
 545                                                  ((z, s) -> falseMask(s)));
 546     }
 547 
 548     /**
 549      * Returns a shuffle of mapped indexes where each lane element is
 550      * the result of applying a mapping function to the corresponding lane
 551      * index.
 552      * <p>
 553      * Care should be taken to ensure Shuffle values produced from this
 554      * method are consumed as constants to ensure optimal generation of
 555      * code.  For example, values held in static final fields or values
 556      * held in loop constant local variables.
 557      * <p>
 558      * This method behaves as if a shuffle is created from an array of
 559      * mapped indexes as follows:
 560      * <pre>{@code
 561      *   int[] a = new int[species.length()];
 562      *   for (int i = 0; i < a.length; i++) {
 563      *       a[i] = f.applyAsInt(i);
 564      *   }
 565      *   return this.shuffleFromValues(a);
 566      * }</pre>
 567      *
 568      * @param species shuffle species
 569      * @param f the lane index mapping function
 570      * @return a shuffle of mapped indexes
 571      */
 572     @ForceInline
 573     public static Shuffle<Short> shuffle(Species<Short> species, IntUnaryOperator f) {
 574         if (species.boxType() == ShortMaxVector.class)
 575             return new ShortMaxVector.ShortMaxShuffle(f);
 576         switch (species.bitSize()) {
 577             case 64: return new Short64Vector.Short64Shuffle(f);
 578             case 128: return new Short128Vector.Short128Shuffle(f);
 579             case 256: return new Short256Vector.Short256Shuffle(f);
 580             case 512: return new Short512Vector.Short512Shuffle(f);
 581             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 582         }
 583     }
 584 
 585     /**
 586      * Returns a shuffle where each lane element is the value of its
 587      * corresponding lane index.
 588      * <p>
 589      * This method behaves as if a shuffle is created from an identity
 590      * index mapping function as follows:
 591      * <pre>{@code
 592      *   return this.shuffle(i -> i);
 593      * }</pre>
 594      *
 595      * @param species shuffle species
 596      * @return a shuffle of lane indexes
 597      */
 598     @ForceInline
 599     public static Shuffle<Short> shuffleIota(Species<Short> species) {
 600         if (species.boxType() == ShortMaxVector.class)
 601             return new ShortMaxVector.ShortMaxShuffle(AbstractShuffle.IDENTITY);
 602         switch (species.bitSize()) {
 603             case 64: return new Short64Vector.Short64Shuffle(AbstractShuffle.IDENTITY);
 604             case 128: return new Short128Vector.Short128Shuffle(AbstractShuffle.IDENTITY);
 605             case 256: return new Short256Vector.Short256Shuffle(AbstractShuffle.IDENTITY);
 606             case 512: return new Short512Vector.Short512Shuffle(AbstractShuffle.IDENTITY);
 607             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 608         }
 609     }
 610 
 611     /**
 612      * Returns a shuffle where each lane element is set to a given
 613      * {@code int} value logically AND'ed by the species length minus one.
 614      * <p>
 615      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 616      * the {@code int} value at index {@code N} logically AND'ed by
 617      * {@code species.length() - 1} is placed into the resulting shuffle at
 618      * lane index {@code N}.
 619      *
 620      * @param species shuffle species
 621      * @param ixs the given {@code int} values
 622      * @return a shuffle where each lane element is set to a given
 623      * {@code int} value
 624      * @throws IndexOutOfBoundsException if the number of int values is
 625      * {@code < species.length()}
 626      */
 627     @ForceInline
 628     public static Shuffle<Short> shuffleFromValues(Species<Short> species, int... ixs) {
 629         if (species.boxType() == ShortMaxVector.class)
 630             return new ShortMaxVector.ShortMaxShuffle(ixs);
 631         switch (species.bitSize()) {
 632             case 64: return new Short64Vector.Short64Shuffle(ixs);
 633             case 128: return new Short128Vector.Short128Shuffle(ixs);
 634             case 256: return new Short256Vector.Short256Shuffle(ixs);
 635             case 512: return new Short512Vector.Short512Shuffle(ixs);
 636             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 637         }
 638     }
 639 
 640     /**
 641      * Loads a shuffle from an {@code int} array starting at an offset.
 642      * <p>
 643      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 644      * array element at index {@code i + N} logically AND'ed by
 645      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 646      * index {@code N}.
 647      *
 648      * @param species shuffle species
 649      * @param ixs the {@code int} array
 650      * @param i the offset into the array
 651      * @return a shuffle loaded from the {@code int} array
 652      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 653      * {@code i > a.length - species.length()}
 654      */
 655     @ForceInline
 656     public static Shuffle<Short> shuffleFromArray(Species<Short> species, int[] ixs, int i) {
 657         if (species.boxType() == ShortMaxVector.class)
 658             return new ShortMaxVector.ShortMaxShuffle(ixs, i);
 659         switch (species.bitSize()) {
 660             case 64: return new Short64Vector.Short64Shuffle(ixs, i);
 661             case 128: return new Short128Vector.Short128Shuffle(ixs, i);
 662             case 256: return new Short256Vector.Short256Shuffle(ixs, i);
 663             case 512: return new Short512Vector.Short512Shuffle(ixs, i);
 664             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 665         }
 666     }
 667 

 668     // Ops
 669 
 670     @Override
 671     public abstract ShortVector add(Vector<Short> v);
 672 
 673     /**
 674      * Adds this vector to the broadcast of an input scalar.
 675      * <p>
 676      * This is a vector binary operation where the primitive addition operation
 677      * ({@code +}) is applied to lane elements.
 678      *
 679      * @param s the input scalar
 680      * @return the result of adding this vector to the broadcast of an input
 681      * scalar
 682      */
 683     public abstract ShortVector add(short s);
 684 
 685     @Override
 686     public abstract ShortVector add(Vector<Short> v, Mask<Short> m);
 687 


1528      *
1529      * @param a the array
1530      * @param i the offset into the array, may be negative if relative
1531      * indexes in the index map compensate to produce a value within the
1532      * array bounds
1533      * @param m the mask
1534      * @param indexMap the index map
1535      * @param j the offset into the index map
1536      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1537      * {@code j > indexMap.length - this.length()},
1538      * or for any vector lane index {@code N} where the mask at lane
1539      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1540      * {@code < 0} or {@code >= a.length}
1541      */
1542     public void intoArray(short[] a, int i, Mask<Short> m, int[] indexMap, int j) {
1543         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
1544     }
1545     // Species
1546 
1547     @Override
1548     public abstract Species<Short> species();
1549 
1550     /**
1551      * Class representing {@link ShortVector}'s of the same {@link Vector.Shape Shape}.
1552      */
1553     static final class ShortSpecies extends Vector.AbstractSpecies<Short> {
1554         final Function<short[], ShortVector> vectorFactory;
1555         final Function<boolean[], Vector.Mask<Short>> maskFactory;
1556 
1557         private ShortSpecies(Vector.Shape shape,
1558                           Class<?> boxType,
1559                           Class<?> maskType,
1560                           Function<short[], ShortVector> vectorFactory,
1561                           Function<boolean[], Vector.Mask<Short>> maskFactory) {
1562             super(shape, short.class, Short.SIZE, boxType, maskType);
1563             this.vectorFactory = vectorFactory;
1564             this.maskFactory = maskFactory;
1565         }
1566 
1567         interface FOp {
1568             short apply(int i);
1569         }
1570 




1571         interface FOpm {
1572             boolean apply(int i);
1573         }
1574 
1575         ShortVector op(FOp f) {
1576             short[] res = new short[length()];
1577             for (int i = 0; i < length(); i++) {
1578                 res[i] = f.apply(i);
1579             }
1580             return vectorFactory.apply(res);

























1581         }
1582 
1583         ShortVector op(Vector.Mask<Short> o, FOp f) {
1584             short[] res = new short[length()];
1585             boolean[] mbits = ((AbstractMask<Short>)o).getBits();
1586             for (int i = 0; i < length(); i++) {
1587                 if (mbits[i]) {
1588                     res[i] = f.apply(i);
1589                 }
1590             }
1591             return vectorFactory.apply(res);




1592         }
1593 
1594         Vector.Mask<Short> opm(IntVector.IntSpecies.FOpm f) {
1595             boolean[] res = new boolean[length()];
1596             for (int i = 0; i < length(); i++) {
1597                 res[i] = (boolean)f.apply(i);
1598             }
1599             return maskFactory.apply(res);
1600         }







1601     }
1602 
1603     /**
1604      * Finds the preferred species for an element type of {@code short}.
1605      * <p>
1606      * A preferred species is a species chosen by the platform that has a
1607      * shape of maximal bit size.  A preferred species for different element
1608      * types will have the same shape, and therefore vectors, masks, and
1609      * shuffles created from such species will be shape compatible.
1610      *
1611      * @return the preferred species for an element type of {@code short}
1612      */
1613     private static ShortSpecies preferredSpecies() {

1614         return (ShortSpecies) Species.ofPreferred(short.class);
1615     }
1616 
1617     /**
1618      * Finds a species for an element type of {@code short} and shape.
1619      *
1620      * @param s the shape
1621      * @return a species for an element type of {@code short} and shape
1622      * @throws IllegalArgumentException if no such species exists for the shape
1623      */
1624     static ShortSpecies species(Vector.Shape s) {

1625         Objects.requireNonNull(s);
1626         switch (s) {
1627             case S_64_BIT: return (ShortSpecies) SPECIES_64;
1628             case S_128_BIT: return (ShortSpecies) SPECIES_128;
1629             case S_256_BIT: return (ShortSpecies) SPECIES_256;
1630             case S_512_BIT: return (ShortSpecies) SPECIES_512;
1631             case S_Max_BIT: return (ShortSpecies) SPECIES_MAX;
1632             default: throw new IllegalArgumentException("Bad shape: " + s);
1633         }
1634     }
1635 
1636     /** Species representing {@link ShortVector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */
1637     public static final Species<Short> SPECIES_64 = new ShortSpecies(Shape.S_64_BIT, Short64Vector.class, Short64Vector.Short64Mask.class,
1638                                                                      Short64Vector::new, Short64Vector.Short64Mask::new);
1639 
1640     /** Species representing {@link ShortVector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */
1641     public static final Species<Short> SPECIES_128 = new ShortSpecies(Shape.S_128_BIT, Short128Vector.class, Short128Vector.Short128Mask.class,
1642                                                                       Short128Vector::new, Short128Vector.Short128Mask::new);
1643 
1644     /** Species representing {@link ShortVector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */
1645     public static final Species<Short> SPECIES_256 = new ShortSpecies(Shape.S_256_BIT, Short256Vector.class, Short256Vector.Short256Mask.class,
1646                                                                       Short256Vector::new, Short256Vector.Short256Mask::new);
1647 
1648     /** Species representing {@link ShortVector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */
1649     public static final Species<Short> SPECIES_512 = new ShortSpecies(Shape.S_512_BIT, Short512Vector.class, Short512Vector.Short512Mask.class,
1650                                                                       Short512Vector::new, Short512Vector.Short512Mask::new);
1651 
1652     /** Species representing {@link ShortVector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */
1653     public static final Species<Short> SPECIES_MAX = new ShortSpecies(Shape.S_Max_BIT, ShortMaxVector.class, ShortMaxVector.ShortMaxMask.class,
1654                                                                       ShortMaxVector::new, ShortMaxVector.ShortMaxMask::new);
1655 
1656     /**
1657      * Preferred species for {@link ShortVector}s.
1658      * A preferred species is a species of maximal bit size for the platform.
1659      */
1660     public static final Species<Short> SPECIES_PREFERRED = (Species<Short>) preferredSpecies();
1661 }
< prev index next >