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