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.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 
  52     interface FUnOp {
  53         short apply(int i, short a);
  54     }
  55 
  56     abstract ShortVector uOp(FUnOp f);
  57 
  58     abstract ShortVector uOp(Mask<Short> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         short apply(int i, short a, short b);
  64     }
  65 
  66     abstract ShortVector bOp(Vector<Short> v, FBinOp f);
  67 
  68     abstract ShortVector bOp(Vector<Short> v, Mask<Short> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         short apply(int i, short a, short b, short c);
  74     }
  75 
  76     abstract ShortVector tOp(Vector<Short> v1, Vector<Short> v2, FTriOp f);
  77 
  78     abstract ShortVector tOp(Vector<Short> v1, Vector<Short> v2, Mask<Short> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract short rOp(short v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, short a, short b);
  88     }
  89 
  90     abstract Mask<Short> bTest(Vector<Short> v, FBinTest f);
  91 
  92     // Foreach
  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,
 332      * according to the native byte order of the underlying platform, and
 333      * the returned vector is loaded with a mask from a primitive array
 334      * obtained from the primitive buffer.
 335      * The following pseudocode expresses the behaviour, where
 336      * {@coce EBuffer} is the primitive buffer type, {@code e} is the
 337      * primitive element type, and {@code ESpecies<S>} is the primitive
 338      * species for {@code e}:
 339      * <pre>{@code
 340      * EBuffer eb = b.duplicate().
 341      *     order(ByteOrder.nativeOrder()).position(i).
 342      *     asEBuffer();
 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 i + 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 a set.
 445      *
 446      * @param species mask species
 447      * @return a mask where all lanes are a 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 a unset.
 459      *
 460      * @param species mask species
 461      * @return a mask where all lanes are a 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 
 612     /**
 613      * Adds this vector to broadcast of an input scalar,
 614      * selecting lane elements controlled by a mask.
 615      * <p>
 616      * This is a vector binary operation where the primitive addition operation
 617      * ({@code +}) is applied to lane elements.
 618      *
 619      * @param s the input scalar
 620      * @param m the mask controlling lane selection
 621      * @return the result of adding this vector to the broadcast of an input
 622      * scalar
 623      */
 624     public abstract ShortVector add(short s, Mask<Short> m);
 625 
 626     @Override
 627     public abstract ShortVector sub(Vector<Short> v);
 628 
 629     /**
 630      * Subtracts the broadcast of an input scalar from this vector.
 631      * <p>
 632      * This is a vector binary operation where the primitive subtraction
 633      * operation ({@code -}) is applied to lane elements.
 634      *
 635      * @param s the input scalar
 636      * @return the result of subtracting the broadcast of an input
 637      * scalar from this vector
 638      */
 639     public abstract ShortVector sub(short s);
 640 
 641     @Override
 642     public abstract ShortVector sub(Vector<Short> v, Mask<Short> m);
 643 
 644     /**
 645      * Subtracts the broadcast of an input scalar from this vector, selecting
 646      * lane elements controlled by a mask.
 647      * <p>
 648      * This is a vector binary operation where the primitive subtraction
 649      * operation ({@code -}) is applied to lane elements.
 650      *
 651      * @param s the input scalar
 652      * @param m the mask controlling lane selection
 653      * @return the result of subtracting the broadcast of an input
 654      * scalar from this vector
 655      */
 656     public abstract ShortVector sub(short s, Mask<Short> m);
 657 
 658     @Override
 659     public abstract ShortVector mul(Vector<Short> v);
 660 
 661     /**
 662      * Multiplies this vector with the broadcast of an input scalar.
 663      * <p>
 664      * This is a vector binary operation where the primitive multiplication
 665      * operation ({@code *}) is applied to lane elements.
 666      *
 667      * @param s the input scalar
 668      * @return the result of multiplying this vector with the broadcast of an
 669      * input scalar
 670      */
 671     public abstract ShortVector mul(short s);
 672 
 673     @Override
 674     public abstract ShortVector mul(Vector<Short> v, Mask<Short> m);
 675 
 676     /**
 677      * Multiplies this vector with the broadcast of an input scalar, selecting
 678      * lane elements controlled by a mask.
 679      * <p>
 680      * This is a vector binary operation where the primitive multiplication
 681      * operation ({@code *}) is applied to lane elements.
 682      *
 683      * @param s the input scalar
 684      * @param m the mask controlling lane selection
 685      * @return the result of multiplying this vector with the broadcast of an
 686      * input scalar
 687      */
 688     public abstract ShortVector mul(short s, Mask<Short> m);
 689 
 690     @Override
 691     public abstract ShortVector neg();
 692 
 693     @Override
 694     public abstract ShortVector neg(Mask<Short> m);
 695 
 696     @Override
 697     public abstract ShortVector abs();
 698 
 699     @Override
 700     public abstract ShortVector abs(Mask<Short> m);
 701 
 702     @Override
 703     public abstract ShortVector min(Vector<Short> v);
 704 
 705     @Override
 706     public abstract ShortVector min(Vector<Short> v, Mask<Short> m);
 707 
 708     /**
 709      * Returns the minimum of this vector and the broadcast of an input scalar.
 710      * <p>
 711      * This is a vector binary operation where the operation
 712      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 713      *
 714      * @param s the input scalar
 715      * @return the minimum of this vector and the broadcast of an input scalar
 716      */
 717     public abstract ShortVector min(short s);
 718 
 719     @Override
 720     public abstract ShortVector max(Vector<Short> v);
 721 
 722     @Override
 723     public abstract ShortVector max(Vector<Short> v, Mask<Short> m);
 724 
 725     /**
 726      * Returns the maximum of this vector and the broadcast of an input scalar.
 727      * <p>
 728      * This is a vector binary operation where the operation
 729      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 730      *
 731      * @param s the input scalar
 732      * @return the maximum of this vector and the broadcast of an input scalar
 733      */
 734     public abstract ShortVector max(short s);
 735 
 736     @Override
 737     public abstract Mask<Short> equal(Vector<Short> v);
 738 
 739     /**
 740      * Tests if this vector is equal to the broadcast of an input scalar.
 741      * <p>
 742      * This is a vector binary test operation where the primitive equals
 743      * operation ({@code ==}) is applied to lane elements.
 744      *
 745      * @param s the input scalar
 746      * @return the result mask of testing if this vector is equal to the
 747      * broadcast of an input scalar
 748      */
 749     public abstract Mask<Short> equal(short s);
 750 
 751     @Override
 752     public abstract Mask<Short> notEqual(Vector<Short> v);
 753 
 754     /**
 755      * Tests if this vector is not equal to the broadcast of an input scalar.
 756      * <p>
 757      * This is a vector binary test operation where the primitive not equals
 758      * operation ({@code !=}) is applied to lane elements.
 759      *
 760      * @param s the input scalar
 761      * @return the result mask of testing if this vector is not equal to the
 762      * broadcast of an input scalar
 763      */
 764     public abstract Mask<Short> notEqual(short s);
 765 
 766     @Override
 767     public abstract Mask<Short> lessThan(Vector<Short> v);
 768 
 769     /**
 770      * Tests if this vector is less than the broadcast of an input scalar.
 771      * <p>
 772      * This is a vector binary test operation where the primitive less than
 773      * operation ({@code <}) is applied to lane elements.
 774      *
 775      * @param s the input scalar
 776      * @return the mask result of testing if this vector is less than the
 777      * broadcast of an input scalar
 778      */
 779     public abstract Mask<Short> lessThan(short s);
 780 
 781     @Override
 782     public abstract Mask<Short> lessThanEq(Vector<Short> v);
 783 
 784     /**
 785      * Tests if this vector is less or equal to the broadcast of an input scalar.
 786      * <p>
 787      * This is a vector binary test operation where the primitive less than
 788      * or equal to operation ({@code <=}) is applied to lane elements.
 789      *
 790      * @param s the input scalar
 791      * @return the mask result of testing if this vector is less than or equal
 792      * to the broadcast of an input scalar
 793      */
 794     public abstract Mask<Short> lessThanEq(short s);
 795 
 796     @Override
 797     public abstract Mask<Short> greaterThan(Vector<Short> v);
 798 
 799     /**
 800      * Tests if this vector is greater than the broadcast of an input scalar.
 801      * <p>
 802      * This is a vector binary test operation where the primitive greater than
 803      * operation ({@code >}) is applied to lane elements.
 804      *
 805      * @param s the input scalar
 806      * @return the mask result of testing if this vector is greater than the
 807      * broadcast of an input scalar
 808      */
 809     public abstract Mask<Short> greaterThan(short s);
 810 
 811     @Override
 812     public abstract Mask<Short> greaterThanEq(Vector<Short> v);
 813 
 814     /**
 815      * Tests if this vector is greater than or equal to the broadcast of an
 816      * input scalar.
 817      * <p>
 818      * This is a vector binary test operation where the primitive greater than
 819      * or equal to operation ({@code >=}) is applied to lane elements.
 820      *
 821      * @param s the input scalar
 822      * @return the mask result of testing if this vector is greater than or
 823      * equal to the broadcast of an input scalar
 824      */
 825     public abstract Mask<Short> greaterThanEq(short s);
 826 
 827     @Override
 828     public abstract ShortVector blend(Vector<Short> v, Mask<Short> m);
 829 
 830     /**
 831      * Blends the lane elements of this vector with those of the broadcast of an
 832      * input scalar, selecting lanes controlled by a mask.
 833      * <p>
 834      * For each lane of the mask, at lane index {@code N}, if the mask lane
 835      * is set then the lane element at {@code N} from the input vector is
 836      * selected and placed into the resulting vector at {@code N},
 837      * otherwise the the lane element at {@code N} from this input vector is
 838      * selected and placed into the resulting vector at {@code N}.
 839      *
 840      * @param s the input scalar
 841      * @param m the mask controlling lane selection
 842      * @return the result of blending the lane elements of this vector with
 843      * those of the broadcast of an input scalar
 844      */
 845     public abstract ShortVector blend(short s, Mask<Short> m);
 846 
 847     @Override
 848     public abstract ShortVector rearrange(Vector<Short> v,
 849                                                       Shuffle<Short> s, Mask<Short> m);
 850 
 851     @Override
 852     public abstract ShortVector rearrange(Shuffle<Short> m);
 853 
 854     @Override
 855     public abstract ShortVector reshape(Species<Short> s);
 856 
 857     @Override
 858     public abstract ShortVector rotateEL(int i);
 859 
 860     @Override
 861     public abstract ShortVector rotateER(int i);
 862 
 863     @Override
 864     public abstract ShortVector shiftEL(int i);
 865 
 866     @Override
 867     public abstract ShortVector shiftER(int i);
 868 
 869 
 870 
 871     /**
 872      * Bitwise ANDs this vector with an input vector.
 873      * <p>
 874      * This is a vector binary operation where the primitive bitwise AND
 875      * operation ({@code &}) is applied to lane elements.
 876      *
 877      * @param v the input vector
 878      * @return the bitwise AND of this vector with the input vector
 879      */
 880     public abstract ShortVector and(Vector<Short> v);
 881 
 882     /**
 883      * Bitwise ANDs this vector with the broadcast of an input scalar.
 884      * <p>
 885      * This is a vector binary operation where the primitive bitwise AND
 886      * operation ({@code &}) is applied to lane elements.
 887      *
 888      * @param s the input scalar
 889      * @return the bitwise AND of this vector with the broadcast of an input
 890      * scalar
 891      */
 892     public abstract ShortVector and(short s);
 893 
 894     /**
 895      * Bitwise ANDs this vector with an input vector, selecting lane elements
 896      * controlled by a mask.
 897      * <p>
 898      * This is a vector binary operation where the primitive bitwise AND
 899      * operation ({@code &}) is applied to lane elements.
 900      *
 901      * @param v the input vector
 902      * @param m the mask controlling lane selection
 903      * @return the bitwise AND of this vector with the input vector
 904      */
 905     public abstract ShortVector and(Vector<Short> v, Mask<Short> m);
 906 
 907     /**
 908      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 909      * lane elements controlled by a mask.
 910      * <p>
 911      * This is a vector binary operation where the primitive bitwise AND
 912      * operation ({@code &}) is applied to lane elements.
 913      *
 914      * @param s the input scalar
 915      * @param m the mask controlling lane selection
 916      * @return the bitwise AND of this vector with the broadcast of an input
 917      * scalar
 918      */
 919     public abstract ShortVector and(short s, Mask<Short> m);
 920 
 921     /**
 922      * Bitwise ORs this vector with an input vector.
 923      * <p>
 924      * This is a vector binary operation where the primitive bitwise OR
 925      * operation ({@code |}) is applied to lane elements.
 926      *
 927      * @param v the input vector
 928      * @return the bitwise OR of this vector with the input vector
 929      */
 930     public abstract ShortVector or(Vector<Short> v);
 931 
 932     /**
 933      * Bitwise ORs this vector with the broadcast of an input scalar.
 934      * <p>
 935      * This is a vector binary operation where the primitive bitwise OR
 936      * operation ({@code |}) is applied to lane elements.
 937      *
 938      * @param s the input scalar
 939      * @return the bitwise OR of this vector with the broadcast of an input
 940      * scalar
 941      */
 942     public abstract ShortVector or(short s);
 943 
 944     /**
 945      * Bitwise ORs this vector with an input vector, selecting lane elements
 946      * controlled by a mask.
 947      * <p>
 948      * This is a vector binary operation where the primitive bitwise OR
 949      * operation ({@code |}) is applied to lane elements.
 950      *
 951      * @param v the input vector
 952      * @param m the mask controlling lane selection
 953      * @return the bitwise OR of this vector with the input vector
 954      */
 955     public abstract ShortVector or(Vector<Short> v, Mask<Short> m);
 956 
 957     /**
 958      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
 959      * lane elements controlled by a mask.
 960      * <p>
 961      * This is a vector binary operation where the primitive bitwise OR
 962      * operation ({@code |}) is applied to lane elements.
 963      *
 964      * @param s the input scalar
 965      * @param m the mask controlling lane selection
 966      * @return the bitwise OR of this vector with the broadcast of an input
 967      * scalar
 968      */
 969     public abstract ShortVector or(short s, Mask<Short> m);
 970 
 971     /**
 972      * Bitwise XORs this vector with an input vector.
 973      * <p>
 974      * This is a vector binary operation where the primitive bitwise XOR
 975      * operation ({@code ^}) is applied to lane elements.
 976      *
 977      * @param v the input vector
 978      * @return the bitwise XOR of this vector with the input vector
 979      */
 980     public abstract ShortVector xor(Vector<Short> v);
 981 
 982     /**
 983      * Bitwise XORs this vector with the broadcast of an input scalar.
 984      * <p>
 985      * This is a vector binary operation where the primitive bitwise XOR
 986      * operation ({@code ^}) is applied to lane elements.
 987      *
 988      * @param s the input scalar
 989      * @return the bitwise XOR of this vector with the broadcast of an input
 990      * scalar
 991      */
 992     public abstract ShortVector xor(short s);
 993 
 994     /**
 995      * Bitwise XORs this vector with an input vector, selecting lane elements
 996      * controlled by a mask.
 997      * <p>
 998      * This is a vector binary operation where the primitive bitwise XOR
 999      * operation ({@code ^}) is applied to lane elements.
1000      *
1001      * @param v the input vector
1002      * @param m the mask controlling lane selection
1003      * @return the bitwise XOR of this vector with the input vector
1004      */
1005     public abstract ShortVector xor(Vector<Short> v, Mask<Short> m);
1006 
1007     /**
1008      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1009      * lane elements controlled by a mask.
1010      * <p>
1011      * This is a vector binary operation where the primitive bitwise XOR
1012      * operation ({@code ^}) is applied to lane elements.
1013      *
1014      * @param s the input scalar
1015      * @param m the mask controlling lane selection
1016      * @return the bitwise XOR of this vector with the broadcast of an input
1017      * scalar
1018      */
1019     public abstract ShortVector xor(short s, Mask<Short> m);
1020 
1021     /**
1022      * Bitwise NOTs this vector.
1023      * <p>
1024      * This is a vector unary operation where the primitive bitwise NOT
1025      * operation ({@code ~}) is applied to lane elements.
1026      *
1027      * @return the bitwise NOT of this vector
1028      */
1029     public abstract ShortVector not();
1030 
1031     /**
1032      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1033      * <p>
1034      * This is a vector unary operation where the primitive bitwise NOT
1035      * operation ({@code ~}) is applied to lane elements.
1036      *
1037      * @param m the mask controlling lane selection
1038      * @return the bitwise NOT of this vector
1039      */
1040     public abstract ShortVector not(Mask<Short> m);
1041 
1042     /**
1043      * Logically left shifts this vector by the broadcast of an input scalar.
1044      * <p>
1045      * This is a vector binary operation where the primitive logical left shift
1046      * operation ({@code <<}) is applied to lane elements to left shift the
1047      * element by shift value as specified by the input scalar. Only the 4
1048      * lowest-order bits of shift value are used. It is as if the shift value
1049      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1050      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1051      *
1052      * @param s the input scalar; the number of the bits to left shift
1053      * @return the result of logically left shifting left this vector by the
1054      * broadcast of an input scalar
1055      */
1056     public abstract ShortVector shiftL(int s);
1057 
1058     /**
1059      * Logically left shifts this vector by the broadcast of an input scalar,
1060      * selecting lane elements controlled by a mask.
1061      * <p>
1062      * This is a vector binary operation where the primitive logical left shift
1063      * operation ({@code <<}) is applied to lane elements to left shift the
1064      * element by shift value as specified by the input scalar. Only the 4
1065      * lowest-order bits of shift value are used. It is as if the shift value
1066      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1067      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1068      *
1069      * @param s the input scalar; the number of the bits to left shift
1070      * @param m the mask controlling lane selection
1071      * @return the result of logically left shifting left this vector by the
1072      * broadcast of an input scalar
1073      */
1074     public abstract ShortVector shiftL(int s, Mask<Short> m);
1075 
1076 
1077     // logical, or unsigned, shift right
1078 
1079      /**
1080      * Logically right shifts (or unsigned right shifts) this vector by the
1081      * broadcast of an input scalar.
1082      * <p>
1083      * This is a vector binary operation where the primitive logical right shift
1084      * operation ({@code >>>}) is applied to lane elements to logically right shift the
1085      * element by shift value as specified by the input scalar. Only the 4
1086      * lowest-order bits of shift value are used. It is as if the shift value
1087      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1088      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1089      *
1090      * @param s the input scalar; the number of the bits to right shift
1091      * @return the result of logically right shifting this vector by the
1092      * broadcast of an input scalar
1093      */
1094     public abstract ShortVector shiftR(int s);
1095 
1096      /**
1097      * Logically right shifts (or unsigned right shifts) this vector by the
1098      * broadcast of an input scalar, selecting lane elements controlled by a
1099      * mask.
1100      * <p>
1101      * This is a vector binary operation where the primitive logical right shift
1102      * operation ({@code >>>}) is applied to lane elements to logically right shift the
1103      * element by shift value as specified by the input scalar. Only the 4
1104      * lowest-order bits of shift value are used. It is as if the shift value
1105      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1106      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1107      *
1108      * @param s the input scalar; the number of the bits to right shift
1109      * @param m the mask controlling lane selection
1110      * @return the result of logically right shifting this vector by the
1111      * broadcast of an input scalar
1112      */
1113     public abstract ShortVector shiftR(int s, Mask<Short> 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 vector binary operation where the primitive arithmetic right
1121      * shift operation ({@code >>}) is applied to lane elements  to arithmetically
1122      * right shift the element by shift value as specified by the input scalar.
1123      * Only the 4 lowest-order bits of shift value are used. It is as if the shift
1124      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1125      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1126      *
1127      * @param s the input scalar; the number of the bits to right shift
1128      * @return the result of arithmetically right shifting this vector by the
1129      * broadcast of an input scalar
1130      */
1131     public abstract ShortVector aShiftR(int s);
1132 
1133     /**
1134      * Arithmetically right shifts (or signed right shifts) this vector by the
1135      * broadcast of an input scalar, selecting lane elements controlled by a
1136      * mask.
1137      * <p>
1138      * This is a vector binary operation where the primitive arithmetic right
1139      * shift operation ({@code >>}) is applied to lane elements  to arithmetically
1140      * right shift the element by shift value as specified by the input scalar.
1141      * Only the 4 lowest-order bits of shift value are used. It is as if the shift
1142      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1143      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1144      *
1145      * @param s the input scalar; the number of the bits to right shift
1146      * @param m the mask controlling lane selection
1147      * @return the result of arithmetically right shifting this vector by the
1148      * broadcast of an input scalar
1149      */
1150     public abstract ShortVector aShiftR(int s, Mask<Short> m);
1151 
1152 
1153     @Override
1154     public abstract void intoByteArray(byte[] a, int ix);
1155 
1156     @Override
1157     public abstract void intoByteArray(byte[] a, int ix, Mask<Short> m);
1158 
1159     @Override
1160     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1161 
1162     @Override
1163     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Short> m);
1164 
1165 
1166     // Type specific horizontal reductions
1167     /**
1168      * Adds all lane elements of this vector.
1169      * <p>
1170      * This is an associative vector reduction operation where the addition
1171      * operation ({@code +}) is applied to lane elements,
1172      * and the identity value is {@code 0}.
1173      *
1174      * @return the addition of all the lane elements of this vector
1175      */
1176     public abstract short addAll();
1177 
1178     /**
1179      * Adds all lane elements of this vector, selecting lane elements
1180      * controlled by a mask.
1181      * <p>
1182      * This is an associative vector reduction operation where the addition
1183      * operation ({@code +}) is applied to lane elements,
1184      * and the identity value is {@code 0}.
1185      *
1186      * @param m the mask controlling lane selection
1187      * @return the addition of the selected lane elements of this vector
1188      */
1189     public abstract short addAll(Mask<Short> m);
1190 
1191     /**
1192      * Multiplies all lane elements of this vector.
1193      * <p>
1194      * This is an associative vector reduction operation where the
1195      * multiplication operation ({@code *}) is applied to lane elements,
1196      * and the identity value is {@code 1}.
1197      *
1198      * @return the multiplication of all the lane elements of this vector
1199      */
1200     public abstract short mulAll();
1201 
1202     /**
1203      * Multiplies all lane elements of this vector, selecting lane elements
1204      * controlled by a mask.
1205      * <p>
1206      * This is an associative vector reduction operation where the
1207      * multiplication operation ({@code *}) is applied to lane elements,
1208      * and the identity value is {@code 1}.
1209      *
1210      * @param m the mask controlling lane selection
1211      * @return the multiplication of all the lane elements of this vector
1212      */
1213     public abstract short mulAll(Mask<Short> m);
1214 
1215     /**
1216      * Returns the minimum lane element of this vector.
1217      * <p>
1218      * This is an associative vector reduction operation where the operation
1219      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1220      * and the identity value is
1221      * {@link Short#MAX_VALUE}.
1222      *
1223      * @return the minimum lane element of this vector
1224      */
1225     public abstract short minAll();
1226 
1227     /**
1228      * Returns the minimum lane element of this vector, selecting lane elements
1229      * controlled by a mask.
1230      * <p>
1231      * This is an associative vector reduction operation where the operation
1232      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1233      * and the identity value is
1234      * {@link Short#MAX_VALUE}.
1235      *
1236      * @param m the mask controlling lane selection
1237      * @return the minimum lane element of this vector
1238      */
1239     public abstract short minAll(Mask<Short> m);
1240 
1241     /**
1242      * Returns the maximum lane element of this vector.
1243      * <p>
1244      * This is an associative vector reduction operation where the operation
1245      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1246      * and the identity value is
1247      * {@link Short#MIN_VALUE}.
1248      *
1249      * @return the maximum lane element of this vector
1250      */
1251     public abstract short maxAll();
1252 
1253     /**
1254      * Returns the maximum lane element of this vector, selecting lane elements
1255      * controlled by a mask.
1256      * <p>
1257      * This is an associative vector reduction operation where the operation
1258      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1259      * and the identity value is
1260      * {@link Short#MIN_VALUE}.
1261      *
1262      * @param m the mask controlling lane selection
1263      * @return the maximum lane element of this vector
1264      */
1265     public abstract short maxAll(Mask<Short> m);
1266 
1267     /**
1268      * Logically ORs all lane elements of this vector.
1269      * <p>
1270      * This is an associative vector reduction operation where the logical OR
1271      * operation ({@code |}) is applied to lane elements,
1272      * and the identity value is {@code 0}.
1273      *
1274      * @return the logical OR all the lane elements of this vector
1275      */
1276     public abstract short orAll();
1277 
1278     /**
1279      * Logically ORs all lane elements of this vector, selecting lane elements
1280      * controlled by a mask.
1281      * <p>
1282      * This is an associative vector reduction operation where the logical OR
1283      * operation ({@code |}) is applied to lane elements,
1284      * and the identity value is {@code 0}.
1285      *
1286      * @param m the mask controlling lane selection
1287      * @return the logical OR all the lane elements of this vector
1288      */
1289     public abstract short orAll(Mask<Short> m);
1290 
1291     /**
1292      * Logically ANDs all lane elements of this vector.
1293      * <p>
1294      * This is an associative vector reduction operation where the logical AND
1295      * operation ({@code |}) is applied to lane elements,
1296      * and the identity value is {@code -1}.
1297      *
1298      * @return the logical AND all the lane elements of this vector
1299      */
1300     public abstract short andAll();
1301 
1302     /**
1303      * Logically ANDs all lane elements of this vector, selecting lane elements
1304      * controlled by a mask.
1305      * <p>
1306      * This is an associative vector reduction operation where the logical AND
1307      * operation ({@code |}) is applied to lane elements,
1308      * and the identity value is {@code -1}.
1309      *
1310      * @param m the mask controlling lane selection
1311      * @return the logical AND all the lane elements of this vector
1312      */
1313     public abstract short andAll(Mask<Short> m);
1314 
1315     /**
1316      * Logically XORs all lane elements of this vector.
1317      * <p>
1318      * This is an associative vector reduction operation where the logical XOR
1319      * operation ({@code ^}) is applied to lane elements,
1320      * and the identity value is {@code 0}.
1321      *
1322      * @return the logical XOR all the lane elements of this vector
1323      */
1324     public abstract short xorAll();
1325 
1326     /**
1327      * Logically XORs all lane elements of this vector, selecting lane elements
1328      * controlled by a mask.
1329      * <p>
1330      * This is an associative vector reduction operation where the logical XOR
1331      * operation ({@code ^}) is applied to lane elements,
1332      * and the identity value is {@code 0}.
1333      *
1334      * @param m the mask controlling lane selection
1335      * @return the logical XOR all the lane elements of this vector
1336      */
1337     public abstract short xorAll(Mask<Short> m);
1338 
1339     // Type specific accessors
1340 
1341     /**
1342      * Gets the lane element at lane index {@code i}
1343      *
1344      * @param i the lane index
1345      * @return the lane element at lane index {@code i}
1346      * @throws IllegalArgumentException if the index is is out of range
1347      * ({@code < 0 || >= length()})
1348      */
1349     public abstract short get(int i);
1350 
1351     /**
1352      * Replaces the lane element of this vector at lane index {@code i} with
1353      * value {@code e}.
1354      * <p>
1355      * This is a cross-lane operation and behaves as if it returns the result
1356      * of blending this vector with an input vector that is the result of
1357      * broadcasting {@code e} and a mask that has only one lane set at lane
1358      * index {@code i}.
1359      *
1360      * @param i the lane index of the lane element to be replaced
1361      * @param e the value to be placed
1362      * @return the result of replacing the lane element of this vector at lane
1363      * index {@code i} with value {@code e}.
1364      * @throws IllegalArgumentException if the index is is out of range
1365      * ({@code < 0 || >= length()})
1366      */
1367     public abstract ShortVector with(int i, short e);
1368 
1369     // Type specific extractors
1370 
1371     /**
1372      * Returns an array containing the lane elements of this vector.
1373      * <p>
1374      * This method behaves as if it {@link #intoArray(short[], int)} stores}
1375      * this vector into an allocated array and returns the array as follows:
1376      * <pre>{@code
1377      *   short[] a = new short[this.length()];
1378      *   this.intoArray(a, 0);
1379      *   return a;
1380      * }</pre>
1381      *
1382      * @return an array containing the the lane elements of this vector
1383      */
1384     @ForceInline
1385     public final short[] toArray() {
1386         short[] a = new short[species().length()];
1387         intoArray(a, 0);
1388         return a;
1389     }
1390 
1391     /**
1392      * Stores this vector into an array starting at offset.
1393      * <p>
1394      * For each vector lane, where {@code N} is the vector lane index,
1395      * the lane element at index {@code N} is stored into the array at index
1396      * {@code i + N}.
1397      *
1398      * @param a the array
1399      * @param i the offset into the array
1400      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1401      * {@code i > a.length - this.length()}
1402      */
1403     public abstract void intoArray(short[] a, int i);
1404 
1405     /**
1406      * Stores this vector into an array starting at offset and using a mask.
1407      * <p>
1408      * For each vector lane, where {@code N} is the vector lane index,
1409      * if the mask lane at index {@code N} is set then the lane element at
1410      * index {@code N} is stored into the array index {@code i + N}.
1411      *
1412      * @param a the array
1413      * @param i the offset into the array
1414      * @param m the mask
1415      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1416      * for any vector lane index {@code N} where the mask at lane {@code N}
1417      * is set {@code i >= a.length - N}
1418      */
1419     public abstract void intoArray(short[] a, int i, Mask<Short> m);
1420 
1421     /**
1422      * Stores this vector into an array using indexes obtained from an index
1423      * map.
1424      * <p>
1425      * For each vector lane, where {@code N} is the vector lane index, the
1426      * lane element at index {@code N} is stored into the array at index
1427      * {@code i + indexMap[j + N]}.
1428      *
1429      * @param a the array
1430      * @param i the offset into the array, may be negative if relative
1431      * indexes in the index map compensate to produce a value within the
1432      * array bounds
1433      * @param indexMap the index map
1434      * @param j the offset into the index map
1435      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1436      * {@code j > indexMap.length - this.length()},
1437      * or for any vector lane index {@code N} the result of
1438      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1439      */
1440     public void intoArray(short[] a, int i, int[] indexMap, int j) {
1441         forEach((n, e) -> a[i + indexMap[j + n]] = e);
1442     }
1443 
1444     /**
1445      * Stores this vector into an array using indexes obtained from an index
1446      * map and using a mask.
1447      * <p>
1448      * For each vector lane, where {@code N} is the vector lane index,
1449      * if the mask lane at index {@code N} is set then the lane element at
1450      * index {@code N} is stored into the array at index
1451      * {@code i + indexMap[j + N]}.
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      * A specialized factory for creating {@link ShortVector} value of the same
1476      * shape, and a {@link Mask} and {@link Shuffle} values of the same shape
1477      * and {@code int} element type.
1478      */
1479     public static abstract class ShortSpecies extends Vector.Species<Short> {
1480         interface FOp {
1481             short apply(int i);
1482         }
1483 
1484         abstract ShortVector op(FOp f);
1485 
1486         abstract ShortVector op(Mask<Short> m, FOp f);
1487 
1488         interface FOpm {
1489             boolean apply(int i);
1490         }
1491 
1492         abstract Mask<Short> opm(FOpm f);
1493 
1494 
1495 
1496         // Factories
1497 
1498         @Override
1499         public abstract ShortVector zero();
1500 
1501         /**
1502          * Returns a vector where all lane elements are set to the primitive
1503          * value {@code e}.
1504          *
1505          * @param e the value
1506          * @return a vector of vector where all lane elements are set to
1507          * the primitive value {@code e}
1508          */
1509         public abstract ShortVector broadcast(short e);
1510 
1511         /**
1512          * Returns a vector where the first lane element is set to the primtive
1513          * value {@code e}, all other lane elements are set to the default
1514          * value.
1515          *
1516          * @param e the value
1517          * @return a vector where the first lane element is set to the primitive
1518          * value {@code e}
1519          */
1520         @ForceInline
1521         public final ShortVector single(short e) {
1522             return zero().with(0, e);
1523         }
1524 
1525         /**
1526          * Returns a vector where each lane element is set to a randomly
1527          * generated primitive value.
1528          *
1529          * The semantics are equivalent to calling
1530          * {@code (short)ThreadLocalRandom#nextInt()}.
1531          *
1532          * @return a vector where each lane elements is set to a randomly
1533          * generated primitive value
1534          */
1535         public ShortVector random() {
1536             ThreadLocalRandom r = ThreadLocalRandom.current();
1537             return op(i -> (short) r.nextInt());
1538         }
1539 
1540         /**
1541          * Returns a vector where each lane element is set to a given
1542          * primitive value.
1543          * <p>
1544          * For each vector lane, where {@code N} is the vector lane index, the
1545          * the primitive value at index {@code N} is placed into the resulting
1546          * vector at lane index {@code N}.
1547          *
1548          * @param es the given primitive values
1549          * @return a vector where each lane element is set to a given primitive
1550          * value
1551          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
1552          */
1553         public abstract ShortVector scalars(short... es);
1554     }
1555 
1556     /**
1557      * Finds the preferred species for an element type of {@code short}.
1558      * <p>
1559      * A preferred species is a species chosen by the platform that has a
1560      * shape of maximal bit size.  A preferred species for different element
1561      * types will have the same shape, and therefore vectors, masks, and
1562      * shuffles created from such species will be shape compatible.
1563      *
1564      * @return the preferred species for an element type of {@code short}
1565      */
1566     @SuppressWarnings("unchecked")
1567     public static ShortSpecies preferredSpecies() {
1568         return (ShortSpecies) Species.ofPreferred(short.class);
1569     }
1570 
1571     /**
1572      * Finds a species for an element type of {@code short} and shape.
1573      *
1574      * @param s the shape
1575      * @return a species for an element type of {@code short} and shape
1576      * @throws IllegalArgumentException if no such species exists for the shape
1577      */
1578     @SuppressWarnings("unchecked")
1579     public static ShortSpecies species(Vector.Shape s) {
1580         Objects.requireNonNull(s);
1581         switch (s) {
1582             case S_64_BIT: return Short64Vector.SPECIES;
1583             case S_128_BIT: return Short128Vector.SPECIES;
1584             case S_256_BIT: return Short256Vector.SPECIES;
1585             case S_512_BIT: return Short512Vector.SPECIES;
1586             case S_Max_BIT: return ShortMaxVector.SPECIES;
1587             default: throw new IllegalArgumentException("Bad shape: " + s);
1588         }
1589     }
1590 }