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.boxType(), short.class, species.length(),
 116                                                  0, species,
 117                                                  ((bits, s) -> ((ShortSpecies)s).op(i -> (short)bits)));
 118     }
 119 
 120     /**
 121      * Loads a vector from a byte array starting at an offset.
 122      * <p>
 123      * Bytes are composed into primitive lane elements according to the
 124      * native byte order of the underlying platform
 125      * <p>
 126      * This method behaves as if it returns the result of calling the
 127      * byte buffer, offset, and mask accepting
 128      * {@link #fromByteBuffer(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.boxType(), 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.boxType(), 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.boxType(), 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
 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.boxType(), 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.boxType(), 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 rotateEL(int i);
 783 
 784     /**
 785      * {@inheritDoc}
 786      */
 787     @Override
 788     public abstract ShortVector rotateER(int i);
 789 
 790     /**
 791      * {@inheritDoc}
 792      */
 793     @Override
 794     public abstract ShortVector shiftEL(int i);
 795 
 796     /**
 797      * {@inheritDoc}
 798      */
 799     @Override
 800     public abstract ShortVector shiftER(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. Only the 4
 981      * 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 left this vector by the
 987      * broadcast of an input scalar
 988      */
 989     public abstract ShortVector shiftL(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. Only the 4
 998      * 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 left this vector by the
1005      * broadcast of an input scalar
1006      */
1007     public abstract ShortVector shiftL(int s, VectorMask<Short> m);
1008 
1009 
1010     // logical, or unsigned, shift right
1011 
1012      /**
1013      * Logically right shifts (or unsigned right shifts) this vector by the
1014      * broadcast of an input scalar.
1015      * <p>
1016      * This is a lane-wise binary operation which applies the primitive logical right shift
1017      * operation ({@code >>>}) to each lane to logically right shift the
1018      * element by shift value as specified by the input scalar. Only the 4
1019      * lowest-order bits of shift value are used. It is as if the shift value
1020      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1021      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1022      *
1023      * @param s the input scalar; the number of the bits to right shift
1024      * @return the result of logically right shifting this vector by the
1025      * broadcast of an input scalar
1026      */
1027     public abstract ShortVector shiftR(int s);
1028 
1029      /**
1030      * Logically right shifts (or unsigned right shifts) this vector by the
1031      * broadcast of an input scalar, selecting lane elements controlled by a
1032      * mask.
1033      * <p>
1034      * This is a lane-wise binary operation which applies the primitive logical right shift
1035      * operation ({@code >>>}) to each lane to logically right shift the
1036      * element by shift value as specified by the input scalar. Only the 4
1037      * lowest-order bits of shift value are used. It is as if the shift value
1038      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1039      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1040      *
1041      * @param s the input scalar; the number of the bits to right shift
1042      * @param m the mask controlling lane selection
1043      * @return the result of logically right shifting this vector by the
1044      * broadcast of an input scalar
1045      */
1046     public abstract ShortVector shiftR(int s, VectorMask<Short> m);
1047 
1048 
1049     /**
1050      * Arithmetically right shifts (or signed right shifts) this vector by the
1051      * broadcast of an input scalar.
1052      * <p>
1053      * This is a lane-wise binary operation which applies the primitive arithmetic right
1054      * shift operation ({@code >>}) to each lane to arithmetically
1055      * right shift the element by shift value as specified by the input scalar.
1056      * Only the 4 lowest-order bits of shift value are used. It is as if the shift
1057      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1058      * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1059      *
1060      * @param s the input scalar; the number of the bits to right shift
1061      * @return the result of arithmetically right shifting this vector by the
1062      * broadcast of an input scalar
1063      */
1064     public abstract ShortVector aShiftR(int s);
1065 
1066     /**
1067      * Arithmetically right shifts (or signed right shifts) this vector by the
1068      * broadcast of an input scalar, selecting lane elements controlled by a
1069      * mask.
1070      * <p>
1071      * This is a lane-wise binary operation which applies the primitive arithmetic right
1072      * shift operation ({@code >>}) to each lane to arithmetically
1073      * right shift the 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
1075      * value 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      * @param m the mask controlling lane selection
1080      * @return the result of arithmetically right shifting this vector by the
1081      * broadcast of an input scalar
1082      */
1083     public abstract ShortVector aShiftR(int s, VectorMask<Short> m);
1084 
1085 
1086     /**
1087      * {@inheritDoc}
1088      */
1089     @Override
1090     public abstract void intoByteArray(byte[] a, int ix);
1091 
1092     /**
1093      * {@inheritDoc}
1094      */
1095     @Override
1096     public abstract void intoByteArray(byte[] a, int ix, VectorMask<Short> m);
1097 
1098     /**
1099      * {@inheritDoc}
1100      */
1101     @Override
1102     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1103 
1104     /**
1105      * {@inheritDoc}
1106      */
1107     @Override
1108     public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Short> m);
1109 
1110 
1111     // Type specific horizontal reductions
1112     /**
1113      * Adds all lane elements of this vector.
1114      * <p>
1115      * This is an associative cross-lane reduction operation which applies the addition
1116      * operation ({@code +}) to lane elements,
1117      * and the identity value is {@code 0}.
1118      *
1119      * @return the addition of all the lane elements of this vector
1120      */
1121     public abstract short addAll();
1122 
1123     /**
1124      * Adds all lane elements of this vector, selecting lane elements
1125      * controlled by a mask.
1126      * <p>
1127      * This is an associative cross-lane reduction operation which applies the addition
1128      * operation ({@code +}) to lane elements,
1129      * and the identity value is {@code 0}.
1130      *
1131      * @param m the mask controlling lane selection
1132      * @return the addition of the selected lane elements of this vector
1133      */
1134     public abstract short addAll(VectorMask<Short> m);
1135 
1136     /**
1137      * Multiplies all lane elements of this vector.
1138      * <p>
1139      * This is an associative cross-lane reduction operation which applies the
1140      * multiplication operation ({@code *}) to lane elements,
1141      * and the identity value is {@code 1}.
1142      *
1143      * @return the multiplication of all the lane elements of this vector
1144      */
1145     public abstract short mulAll();
1146 
1147     /**
1148      * Multiplies all lane elements of this vector, selecting lane elements
1149      * controlled by a mask.
1150      * <p>
1151      * This is an associative cross-lane reduction operation which applies the
1152      * multiplication operation ({@code *}) to lane elements,
1153      * and the identity value is {@code 1}.
1154      *
1155      * @param m the mask controlling lane selection
1156      * @return the multiplication of all the lane elements of this vector
1157      */
1158     public abstract short mulAll(VectorMask<Short> m);
1159 
1160     /**
1161      * Returns the minimum lane element of this vector.
1162      * <p>
1163      * This is an associative cross-lane reduction operation which applies the operation
1164      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1165      * and the identity value is
1166      * {@link Short#MAX_VALUE}.
1167      *
1168      * @return the minimum lane element of this vector
1169      */
1170     public abstract short minAll();
1171 
1172     /**
1173      * Returns the minimum lane element of this vector, selecting lane elements
1174      * controlled by a mask.
1175      * <p>
1176      * This is an associative cross-lane reduction operation which applies the operation
1177      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1178      * and the identity value is
1179      * {@link Short#MAX_VALUE}.
1180      *
1181      * @param m the mask controlling lane selection
1182      * @return the minimum lane element of this vector
1183      */
1184     public abstract short minAll(VectorMask<Short> m);
1185 
1186     /**
1187      * Returns the maximum lane element of this vector.
1188      * <p>
1189      * This is an associative cross-lane reduction operation which applies the operation
1190      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1191      * and the identity value is
1192      * {@link Short#MIN_VALUE}.
1193      *
1194      * @return the maximum lane element of this vector
1195      */
1196     public abstract short maxAll();
1197 
1198     /**
1199      * Returns the maximum lane element of this vector, selecting lane elements
1200      * controlled by a mask.
1201      * <p>
1202      * This is an associative cross-lane reduction operation which applies the operation
1203      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1204      * and the identity value is
1205      * {@link Short#MIN_VALUE}.
1206      *
1207      * @param m the mask controlling lane selection
1208      * @return the maximum lane element of this vector
1209      */
1210     public abstract short maxAll(VectorMask<Short> m);
1211 
1212     /**
1213      * Logically ORs all lane elements of this vector.
1214      * <p>
1215      * This is an associative cross-lane reduction operation which applies the logical OR
1216      * operation ({@code |}) to lane elements,
1217      * and the identity value is {@code 0}.
1218      *
1219      * @return the logical OR all the lane elements of this vector
1220      */
1221     public abstract short orAll();
1222 
1223     /**
1224      * Logically ORs all lane elements of this vector, selecting lane elements
1225      * controlled by a mask.
1226      * <p>
1227      * This is an associative cross-lane reduction operation which applies the logical OR
1228      * operation ({@code |}) to lane elements,
1229      * and the identity value is {@code 0}.
1230      *
1231      * @param m the mask controlling lane selection
1232      * @return the logical OR all the lane elements of this vector
1233      */
1234     public abstract short orAll(VectorMask<Short> m);
1235 
1236     /**
1237      * Logically ANDs all lane elements of this vector.
1238      * <p>
1239      * This is an associative cross-lane reduction operation which applies the logical AND
1240      * operation ({@code |}) to lane elements,
1241      * and the identity value is {@code -1}.
1242      *
1243      * @return the logical AND all the lane elements of this vector
1244      */
1245     public abstract short andAll();
1246 
1247     /**
1248      * Logically ANDs all lane elements of this vector, selecting lane elements
1249      * controlled by a mask.
1250      * <p>
1251      * This is an associative cross-lane reduction operation which applies the logical AND
1252      * operation ({@code |}) to lane elements,
1253      * and the identity value is {@code -1}.
1254      *
1255      * @param m the mask controlling lane selection
1256      * @return the logical AND all the lane elements of this vector
1257      */
1258     public abstract short andAll(VectorMask<Short> m);
1259 
1260     /**
1261      * Logically XORs all lane elements of this vector.
1262      * <p>
1263      * This is an associative cross-lane reduction operation which applies the logical XOR
1264      * operation ({@code ^}) to lane elements,
1265      * and the identity value is {@code 0}.
1266      *
1267      * @return the logical XOR all the lane elements of this vector
1268      */
1269     public abstract short xorAll();
1270 
1271     /**
1272      * Logically XORs all lane elements of this vector, selecting lane elements
1273      * controlled by a mask.
1274      * <p>
1275      * This is an associative cross-lane reduction operation which applies the logical XOR
1276      * operation ({@code ^}) to lane elements,
1277      * and the identity value is {@code 0}.
1278      *
1279      * @param m the mask controlling lane selection
1280      * @return the logical XOR all the lane elements of this vector
1281      */
1282     public abstract short xorAll(VectorMask<Short> m);
1283 
1284     // Type specific accessors
1285 
1286     /**
1287      * Gets the lane element at lane index {@code i}
1288      *
1289      * @param i the lane index
1290      * @return the lane element at lane index {@code i}
1291      * @throws IllegalArgumentException if the index is is out of range
1292      * ({@code < 0 || >= length()})
1293      */
1294     public abstract short lane(int i);
1295 
1296     /**
1297      * Replaces the lane element of this vector at lane index {@code i} with
1298      * value {@code e}.
1299      * <p>
1300      * This is a cross-lane operation and behaves as if it returns the result
1301      * of blending this vector with an input vector that is the result of
1302      * broadcasting {@code e} and a mask that has only one lane set at lane
1303      * index {@code i}.
1304      *
1305      * @param i the lane index of the lane element to be replaced
1306      * @param e the value to be placed
1307      * @return the result of replacing the lane element of this vector at lane
1308      * index {@code i} with value {@code e}.
1309      * @throws IllegalArgumentException if the index is is out of range
1310      * ({@code < 0 || >= length()})
1311      */
1312     public abstract ShortVector with(int i, short e);
1313 
1314     // Type specific extractors
1315 
1316     /**
1317      * Returns an array containing the lane elements of this vector.
1318      * <p>
1319      * This method behaves as if it {@link #intoArray(short[], int)} stores}
1320      * this vector into an allocated array and returns the array as follows:
1321      * <pre>{@code
1322      *   short[] a = new short[this.length()];
1323      *   this.intoArray(a, 0);
1324      *   return a;
1325      * }</pre>
1326      *
1327      * @return an array containing the the lane elements of this vector
1328      */
1329     @ForceInline
1330     public final short[] toArray() {
1331         short[] a = new short[species().length()];
1332         intoArray(a, 0);
1333         return a;
1334     }
1335 
1336     /**
1337      * Stores this vector into an array starting at offset.
1338      * <p>
1339      * For each vector lane, where {@code N} is the vector lane index,
1340      * the lane element at index {@code N} is stored into the array at index
1341      * {@code offset + N}.
1342      *
1343      * @param a the array
1344      * @param offset the offset into the array
1345      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1346      * {@code offset > a.length - this.length()}
1347      */
1348     public abstract void intoArray(short[] a, int offset);
1349 
1350     /**
1351      * Stores this vector into an array starting at offset and using a mask.
1352      * <p>
1353      * For each vector lane, where {@code N} is the vector lane index,
1354      * if the mask lane at index {@code N} is set then the lane element at
1355      * index {@code N} is stored into the array index {@code offset + N}.
1356      *
1357      * @param a the array
1358      * @param offset the offset into the array
1359      * @param m the mask
1360      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1361      * for any vector lane index {@code N} where the mask at lane {@code N}
1362      * is set {@code offset >= a.length - N}
1363      */
1364     public abstract void intoArray(short[] a, int offset, VectorMask<Short> m);
1365 
1366     /**
1367      * Stores this vector into an array using indexes obtained from an index
1368      * map.
1369      * <p>
1370      * For each vector lane, where {@code N} is the vector lane index, the
1371      * lane element at index {@code N} is stored into the array at index
1372      * {@code a_offset + indexMap[i_offset + N]}.
1373      *
1374      * @param a the array
1375      * @param a_offset the offset into the array, may be negative if relative
1376      * indexes in the index map compensate to produce a value within the
1377      * array bounds
1378      * @param indexMap the index map
1379      * @param i_offset the offset into the index map
1380      * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
1381      * {@code i_offset > indexMap.length - this.length()},
1382      * or for any vector lane index {@code N} the result of
1383      * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length}
1384      */
1385     public void intoArray(short[] a, int a_offset, int[] indexMap, int i_offset) {
1386         forEach((n, e) -> a[a_offset + indexMap[i_offset + n]] = e);
1387     }
1388 
1389     /**
1390      * Stores this vector into an array using indexes obtained from an index
1391      * map and using a mask.
1392      * <p>
1393      * For each vector lane, where {@code N} is the vector lane index,
1394      * if the mask lane at index {@code N} is set then the lane element at
1395      * index {@code N} is stored into the array at index
1396      * {@code a_offset + indexMap[i_offset + N]}.
1397      *
1398      * @param a the array
1399      * @param a_offset the offset into the array, may be negative if relative
1400      * indexes in the index map compensate to produce a value within the
1401      * array bounds
1402      * @param m the mask
1403      * @param indexMap the index map
1404      * @param i_offset the offset into the index map
1405      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1406      * {@code i_offset > indexMap.length - this.length()},
1407      * or for any vector lane index {@code N} where the mask at lane
1408      * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is
1409      * {@code < 0} or {@code >= a.length}
1410      */
1411     public void intoArray(short[] a, int a_offset, VectorMask<Short> m, int[] indexMap, int i_offset) {
1412         forEach(m, (n, e) -> a[a_offset + indexMap[i_offset + n]] = e);
1413     }
1414     // Species
1415 
1416     /**
1417      * {@inheritDoc}
1418      */
1419     @Override
1420     public abstract VectorSpecies<Short> species();
1421 
1422     /**
1423      * Class representing {@link ShortVector}'s of the same {@link VectorShape VectorShape}.
1424      */
1425     static final class ShortSpecies extends AbstractSpecies<Short> {
1426         final Function<short[], ShortVector> vectorFactory;
1427 
1428         private ShortSpecies(VectorShape shape,
1429                           Class<?> boxType,
1430                           Class<?> maskType,
1431                           Function<short[], ShortVector> vectorFactory,
1432                           Function<boolean[], VectorMask<Short>> maskFactory,
1433                           Function<IntUnaryOperator, VectorShuffle<Short>> shuffleFromArrayFactory,
1434                           fShuffleFromArray<Short> shuffleFromOpFactory) {
1435             super(shape, short.class, Short.SIZE, boxType, maskType, maskFactory,
1436                   shuffleFromArrayFactory, shuffleFromOpFactory);
1437             this.vectorFactory = vectorFactory;
1438         }
1439 
1440         interface FOp {
1441             short apply(int i);
1442         }
1443 
1444         ShortVector op(FOp f) {
1445             short[] res = new short[length()];
1446             for (int i = 0; i < length(); i++) {
1447                 res[i] = f.apply(i);
1448             }
1449             return vectorFactory.apply(res);
1450         }
1451 
1452         ShortVector op(VectorMask<Short> o, FOp f) {
1453             short[] res = new short[length()];
1454             boolean[] mbits = ((AbstractMask<Short>)o).getBits();
1455             for (int i = 0; i < length(); i++) {
1456                 if (mbits[i]) {
1457                     res[i] = f.apply(i);
1458                 }
1459             }
1460             return vectorFactory.apply(res);
1461         }
1462     }
1463 
1464     /**
1465      * Finds the preferred species for an element type of {@code short}.
1466      * <p>
1467      * A preferred species is a species chosen by the platform that has a
1468      * shape of maximal bit size.  A preferred species for different element
1469      * types will have the same shape, and therefore vectors, masks, and
1470      * shuffles created from such species will be shape compatible.
1471      *
1472      * @return the preferred species for an element type of {@code short}
1473      */
1474     private static ShortSpecies preferredSpecies() {
1475         return (ShortSpecies) VectorSpecies.ofPreferred(short.class);
1476     }
1477 
1478     /**
1479      * Finds a species for an element type of {@code short} and shape.
1480      *
1481      * @param s the shape
1482      * @return a species for an element type of {@code short} and shape
1483      * @throws IllegalArgumentException if no such species exists for the shape
1484      */
1485     static ShortSpecies species(VectorShape s) {
1486         Objects.requireNonNull(s);
1487         switch (s) {
1488             case S_64_BIT: return (ShortSpecies) SPECIES_64;
1489             case S_128_BIT: return (ShortSpecies) SPECIES_128;
1490             case S_256_BIT: return (ShortSpecies) SPECIES_256;
1491             case S_512_BIT: return (ShortSpecies) SPECIES_512;
1492             case S_Max_BIT: return (ShortSpecies) SPECIES_MAX;
1493             default: throw new IllegalArgumentException("Bad shape: " + s);
1494         }
1495     }
1496 
1497     /** Species representing {@link ShortVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
1498     public static final VectorSpecies<Short> SPECIES_64 = new ShortSpecies(VectorShape.S_64_BIT, Short64Vector.class, Short64Vector.Short64Mask.class,
1499                                                                      Short64Vector::new, Short64Vector.Short64Mask::new,
1500                                                                      Short64Vector.Short64Shuffle::new, Short64Vector.Short64Shuffle::new);
1501 
1502     /** Species representing {@link ShortVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
1503     public static final VectorSpecies<Short> SPECIES_128 = new ShortSpecies(VectorShape.S_128_BIT, Short128Vector.class, Short128Vector.Short128Mask.class,
1504                                                                       Short128Vector::new, Short128Vector.Short128Mask::new,
1505                                                                       Short128Vector.Short128Shuffle::new, Short128Vector.Short128Shuffle::new);
1506 
1507     /** Species representing {@link ShortVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
1508     public static final VectorSpecies<Short> SPECIES_256 = new ShortSpecies(VectorShape.S_256_BIT, Short256Vector.class, Short256Vector.Short256Mask.class,
1509                                                                       Short256Vector::new, Short256Vector.Short256Mask::new,
1510                                                                       Short256Vector.Short256Shuffle::new, Short256Vector.Short256Shuffle::new);
1511 
1512     /** Species representing {@link ShortVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
1513     public static final VectorSpecies<Short> SPECIES_512 = new ShortSpecies(VectorShape.S_512_BIT, Short512Vector.class, Short512Vector.Short512Mask.class,
1514                                                                       Short512Vector::new, Short512Vector.Short512Mask::new,
1515                                                                       Short512Vector.Short512Shuffle::new, Short512Vector.Short512Shuffle::new);
1516 
1517     /** Species representing {@link ShortVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
1518     public static final VectorSpecies<Short> SPECIES_MAX = new ShortSpecies(VectorShape.S_Max_BIT, ShortMaxVector.class, ShortMaxVector.ShortMaxMask.class,
1519                                                                       ShortMaxVector::new, ShortMaxVector.ShortMaxMask::new,
1520                                                                       ShortMaxVector.ShortMaxShuffle::new, ShortMaxVector.ShortMaxShuffle::new);
1521 
1522     /**
1523      * Preferred species for {@link ShortVector}s.
1524      * A preferred species is a species of maximal bit size for the platform.
1525      */
1526     public static final VectorSpecies<Short> SPECIES_PREFERRED = (VectorSpecies<Short>) preferredSpecies();
1527 }