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