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