< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/ShortVector.java

Print this page

  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 any
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.ByteOrder;
  29 import java.nio.ReadOnlyBufferException;
  30 import java.util.Arrays;
  31 import java.util.Objects;
  32 import java.util.function.BinaryOperator;
  33 import java.util.function.Function;
  34 import java.util.function.UnaryOperator;
  35 
  36 import jdk.internal.misc.ScopedMemoryAccess;
  37 import jdk.internal.misc.Unsafe;
  38 import jdk.internal.vm.annotation.ForceInline;
  39 import jdk.internal.vm.vector.VectorSupport;
  40 
  41 import static jdk.internal.vm.vector.VectorSupport.*;
  42 import static jdk.incubator.vector.VectorIntrinsics.*;
  43 
  44 import static jdk.incubator.vector.VectorOperators.*;
  45 
  46 // -- This file was mechanically generated: Do not edit! -- //
  47 
  48 /**
  49  * A specialized {@link Vector} representing an ordered immutable sequence of
  50  * {@code short} values.
  51  */
  52 @SuppressWarnings("cast")  // warning: redundant cast

 156     ShortVector uOp(FUnOp f);
 157     @ForceInline
 158     final
 159     ShortVector uOpTemplate(FUnOp f) {
 160         short[] vec = vec();
 161         short[] res = new short[length()];
 162         for (int i = 0; i < res.length; i++) {
 163             res[i] = f.apply(i, vec[i]);
 164         }
 165         return vectorFactory(res);
 166     }
 167 
 168     /*package-private*/
 169     abstract
 170     ShortVector uOp(VectorMask<Short> m,
 171                              FUnOp f);
 172     @ForceInline
 173     final
 174     ShortVector uOpTemplate(VectorMask<Short> m,
 175                                      FUnOp f) {



 176         short[] vec = vec();
 177         short[] res = new short[length()];
 178         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 179         for (int i = 0; i < res.length; i++) {
 180             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
 181         }
 182         return vectorFactory(res);
 183     }
 184 
 185     // Binary operator
 186 
 187     /*package-private*/
 188     interface FBinOp {
 189         short apply(int i, short a, short b);
 190     }
 191 
 192     /*package-private*/
 193     abstract
 194     ShortVector bOp(Vector<Short> o,
 195                              FBinOp f);

 199                                      FBinOp f) {
 200         short[] res = new short[length()];
 201         short[] vec1 = this.vec();
 202         short[] vec2 = ((ShortVector)o).vec();
 203         for (int i = 0; i < res.length; i++) {
 204             res[i] = f.apply(i, vec1[i], vec2[i]);
 205         }
 206         return vectorFactory(res);
 207     }
 208 
 209     /*package-private*/
 210     abstract
 211     ShortVector bOp(Vector<Short> o,
 212                              VectorMask<Short> m,
 213                              FBinOp f);
 214     @ForceInline
 215     final
 216     ShortVector bOpTemplate(Vector<Short> o,
 217                                      VectorMask<Short> m,
 218                                      FBinOp f) {



 219         short[] res = new short[length()];
 220         short[] vec1 = this.vec();
 221         short[] vec2 = ((ShortVector)o).vec();
 222         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 223         for (int i = 0; i < res.length; i++) {
 224             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 225         }
 226         return vectorFactory(res);
 227     }
 228 
 229     // Ternary operator
 230 
 231     /*package-private*/
 232     interface FTriOp {
 233         short apply(int i, short a, short b, short c);
 234     }
 235 
 236     /*package-private*/
 237     abstract
 238     ShortVector tOp(Vector<Short> o1,

 248         short[] vec2 = ((ShortVector)o1).vec();
 249         short[] vec3 = ((ShortVector)o2).vec();
 250         for (int i = 0; i < res.length; i++) {
 251             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 252         }
 253         return vectorFactory(res);
 254     }
 255 
 256     /*package-private*/
 257     abstract
 258     ShortVector tOp(Vector<Short> o1,
 259                              Vector<Short> o2,
 260                              VectorMask<Short> m,
 261                              FTriOp f);
 262     @ForceInline
 263     final
 264     ShortVector tOpTemplate(Vector<Short> o1,
 265                                      Vector<Short> o2,
 266                                      VectorMask<Short> m,
 267                                      FTriOp f) {



 268         short[] res = new short[length()];
 269         short[] vec1 = this.vec();
 270         short[] vec2 = ((ShortVector)o1).vec();
 271         short[] vec3 = ((ShortVector)o2).vec();
 272         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 273         for (int i = 0; i < res.length; i++) {
 274             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 275         }
 276         return vectorFactory(res);
 277     }
 278 
 279     // Reduction operator
 280 
 281     /*package-private*/
 282     abstract
 283     short rOp(short v, FBinOp f);















 284     @ForceInline
 285     final
 286     short rOpTemplate(short v, FBinOp f) {
 287         short[] vec = vec();
 288         for (int i = 0; i < vec.length; i++) {
 289             v = f.apply(i, v, vec[i]);
 290         }
 291         return v;
 292     }
 293 
 294     // Memory reference
 295 
 296     /*package-private*/
 297     interface FLdOp<M> {
 298         short apply(M memory, int offset, int i);
 299     }
 300 
 301     /*package-private*/
 302     @ForceInline
 303     final

 532     final ShortVector broadcastTemplate(long e) {
 533         return vspecies().broadcast(e);
 534     }
 535 
 536     // Unary lanewise support
 537 
 538     /**
 539      * {@inheritDoc} <!--workaround-->
 540      */
 541     public abstract
 542     ShortVector lanewise(VectorOperators.Unary op);
 543 
 544     @ForceInline
 545     final
 546     ShortVector lanewiseTemplate(VectorOperators.Unary op) {
 547         if (opKind(op, VO_SPECIAL)) {
 548             if (op == ZOMO) {
 549                 return blend(broadcast(-1), compare(NE, 0));
 550             }
 551             if (op == NOT) {
 552                 return broadcast(-1).lanewiseTemplate(XOR, this);
 553             } else if (op == NEG) {
 554                 // FIXME: Support this in the JIT.
 555                 return broadcast(0).lanewiseTemplate(SUB, this);
 556             }
 557         }
 558         int opc = opCode(op);
 559         return VectorSupport.unaryOp(
 560             opc, getClass(), short.class, length(),
 561             this,
 562             UN_IMPL.find(op, opc, (opc_) -> {
 563               switch (opc_) {
 564                 case VECTOR_OP_NEG: return v0 ->
 565                         v0.uOp((i, a) -> (short) -a);
 566                 case VECTOR_OP_ABS: return v0 ->
 567                         v0.uOp((i, a) -> (short) Math.abs(a));
 568                 default: return null;
 569               }}));
 570     }
 571     private static final
 572     ImplCache<Unary,UnaryOperator<ShortVector>> UN_IMPL
 573         = new ImplCache<>(Unary.class, ShortVector.class);
 574 
 575     /**
 576      * {@inheritDoc} <!--workaround-->
 577      */
 578     @ForceInline
 579     public final
 580     ShortVector lanewise(VectorOperators.Unary op,
 581                                   VectorMask<Short> m) {
 582         return blend(lanewise(op), m);


































 583     }
 584 
 585     // Binary lanewise support
 586 
 587     /**
 588      * {@inheritDoc} <!--workaround-->
 589      * @see #lanewise(VectorOperators.Binary,short)
 590      * @see #lanewise(VectorOperators.Binary,short,VectorMask)
 591      */
 592     @Override
 593     public abstract
 594     ShortVector lanewise(VectorOperators.Binary op,
 595                                   Vector<Short> v);
 596     @ForceInline
 597     final
 598     ShortVector lanewiseTemplate(VectorOperators.Binary op,
 599                                           Vector<Short> v) {
 600         ShortVector that = (ShortVector) v;
 601         that.check(this);

 602         if (opKind(op, VO_SPECIAL  | VO_SHIFT)) {
 603             if (op == FIRST_NONZERO) {
 604                 // FIXME: Support this in the JIT.
 605                 VectorMask<Short> thisNZ
 606                     = this.viewAsIntegralLanes().compare(NE, (short) 0);
 607                 that = that.blend((short) 0, thisNZ.cast(vspecies()));
 608                 op = OR_UNCHECKED;
 609             }
 610             if (opKind(op, VO_SHIFT)) {
 611                 // As per shift specification for Java, mask the shift count.
 612                 // This allows the JIT to ignore some ISA details.
 613                 that = that.lanewise(AND, SHIFT_MASK);
 614             }
 615             if (op == AND_NOT) {
 616                 // FIXME: Support this in the JIT.
 617                 that = that.lanewise(NOT);
 618                 op = AND;
 619             } else if (op == DIV) {
 620                 VectorMask<Short> eqz = that.eq((short)0);
 621                 if (eqz.anyTrue()) {
 622                     throw that.divZeroException();
 623                 }
 624             }
 625         }

 626         int opc = opCode(op);
 627         return VectorSupport.binaryOp(
 628             opc, getClass(), short.class, length(),
 629             this, that,
 630             BIN_IMPL.find(op, opc, (opc_) -> {
 631               switch (opc_) {
 632                 case VECTOR_OP_ADD: return (v0, v1) ->
 633                         v0.bOp(v1, (i, a, b) -> (short)(a + b));
 634                 case VECTOR_OP_SUB: return (v0, v1) ->
 635                         v0.bOp(v1, (i, a, b) -> (short)(a - b));
 636                 case VECTOR_OP_MUL: return (v0, v1) ->
 637                         v0.bOp(v1, (i, a, b) -> (short)(a * b));
 638                 case VECTOR_OP_DIV: return (v0, v1) ->
 639                         v0.bOp(v1, (i, a, b) -> (short)(a / b));
 640                 case VECTOR_OP_MAX: return (v0, v1) ->
 641                         v0.bOp(v1, (i, a, b) -> (short)Math.max(a, b));
 642                 case VECTOR_OP_MIN: return (v0, v1) ->
 643                         v0.bOp(v1, (i, a, b) -> (short)Math.min(a, b));
 644                 case VECTOR_OP_AND: return (v0, v1) ->
 645                         v0.bOp(v1, (i, a, b) -> (short)(a & b));
 646                 case VECTOR_OP_OR: return (v0, v1) ->
 647                         v0.bOp(v1, (i, a, b) -> (short)(a | b));
 648                 case VECTOR_OP_XOR: return (v0, v1) ->
 649                         v0.bOp(v1, (i, a, b) -> (short)(a ^ b));
 650                 case VECTOR_OP_LSHIFT: return (v0, v1) ->
 651                         v0.bOp(v1, (i, a, n) -> (short)(a << n));
 652                 case VECTOR_OP_RSHIFT: return (v0, v1) ->
 653                         v0.bOp(v1, (i, a, n) -> (short)(a >> n));
 654                 case VECTOR_OP_URSHIFT: return (v0, v1) ->
 655                         v0.bOp(v1, (i, a, n) -> (short)((a & LSHR_SETUP_MASK) >>> n));
 656                 case VECTOR_OP_LROTATE: return (v0, v1) ->
 657                         v0.bOp(v1, (i, a, n) -> rotateLeft(a, (int)n));
 658                 case VECTOR_OP_RROTATE: return (v0, v1) ->
 659                         v0.bOp(v1, (i, a, n) -> rotateRight(a, (int)n));
 660                 default: return null;
 661                 }}));
 662     }
 663     private static final
 664     ImplCache<Binary,BinaryOperator<ShortVector>> BIN_IMPL
 665         = new ImplCache<>(Binary.class, ShortVector.class);
 666 
 667     /**
 668      * {@inheritDoc} <!--workaround-->
 669      * @see #lanewise(VectorOperators.Binary,short,VectorMask)
 670      */
 671     @ForceInline
 672     public final
 673     ShortVector lanewise(VectorOperators.Binary op,
 674                                   Vector<Short> v,
 675                                   VectorMask<Short> m) {





 676         ShortVector that = (ShortVector) v;
 677         if (op == DIV) {
 678             VectorMask<Short> eqz = that.eq((short)0);
 679             if (eqz.and(m).anyTrue()) {
 680                 throw that.divZeroException();























 681             }
 682             // suppress div/0 exceptions in unset lanes
 683             that = that.lanewise(NOT, eqz);
 684             return blend(lanewise(DIV, that), m);
 685         }
 686         return blend(lanewise(op, v), m);











































 687     }

 688     // FIXME: Maybe all of the public final methods in this file (the
 689     // simple ones that just call lanewise) should be pushed down to
 690     // the X-VectorBits template.  They can't optimize properly at
 691     // this level, and must rely on inlining.  Does it work?
 692     // (If it works, of course keep the code here.)
 693 
 694     /**
 695      * Combines the lane values of this vector
 696      * with the value of a broadcast scalar.
 697      *
 698      * This is a lane-wise binary operation which applies
 699      * the selected operation to each lane.
 700      * The return value will be equal to this expression:
 701      * {@code this.lanewise(op, this.broadcast(e))}.
 702      *
 703      * @param op the operation used to process lane values
 704      * @param e the input scalar
 705      * @return the result of applying the operation lane-wise
 706      *         to the two input vectors
 707      * @throws UnsupportedOperationException if this vector does

 730      * This is a masked lane-wise binary operation which applies
 731      * the selected operation to each lane.
 732      * The return value will be equal to this expression:
 733      * {@code this.lanewise(op, this.broadcast(e), m)}.
 734      *
 735      * @param op the operation used to process lane values
 736      * @param e the input scalar
 737      * @param m the mask controlling lane selection
 738      * @return the result of applying the operation lane-wise
 739      *         to the input vector and the scalar
 740      * @throws UnsupportedOperationException if this vector does
 741      *         not support the requested operation
 742      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
 743      * @see #lanewise(VectorOperators.Binary,short)
 744      */
 745     @ForceInline
 746     public final
 747     ShortVector lanewise(VectorOperators.Binary op,
 748                                   short e,
 749                                   VectorMask<Short> m) {
 750         return blend(lanewise(op, e), m);






 751     }
 752 
 753     /**
 754      * {@inheritDoc} <!--workaround-->
 755      * @apiNote
 756      * When working with vector subtypes like {@code ShortVector},
 757      * {@linkplain #lanewise(VectorOperators.Binary,short)
 758      * the more strongly typed method}
 759      * is typically selected.  It can be explicitly selected
 760      * using a cast: {@code v.lanewise(op,(short)e)}.
 761      * The two expressions will produce numerically identical results.
 762      */
 763     @ForceInline
 764     public final
 765     ShortVector lanewise(VectorOperators.Binary op,
 766                                   long e) {
 767         short e1 = (short) e;
 768         if ((long)e1 != e
 769             // allow shift ops to clip down their int parameters
 770             && !(opKind(op, VO_SHIFT) && (int)e1 == e)
 771             ) {
 772             vspecies().checkValue(e);  // for exception
 773         }
 774         return lanewise(op, e1);
 775     }
 776 
 777     /**
 778      * {@inheritDoc} <!--workaround-->
 779      * @apiNote
 780      * When working with vector subtypes like {@code ShortVector},
 781      * {@linkplain #lanewise(VectorOperators.Binary,short,VectorMask)
 782      * the more strongly typed method}
 783      * is typically selected.  It can be explicitly selected
 784      * using a cast: {@code v.lanewise(op,(short)e,m)}.
 785      * The two expressions will produce numerically identical results.
 786      */
 787     @ForceInline
 788     public final
 789     ShortVector lanewise(VectorOperators.Binary op,
 790                                   long e, VectorMask<Short> m) {
 791         return blend(lanewise(op, e), m);






 792     }
 793 
 794     /*package-private*/
 795     abstract ShortVector
 796     lanewiseShift(VectorOperators.Binary op, int e);
 797 
 798     /*package-private*/
 799     @ForceInline
 800     final ShortVector
 801     lanewiseShiftTemplate(VectorOperators.Binary op, int e) {
 802         // Special handling for these.  FIXME: Refactor?
 803         assert(opKind(op, VO_SHIFT));
 804         // As per shift specification for Java, mask the shift count.
 805         e &= SHIFT_MASK;
 806         int opc = opCode(op);
 807         return VectorSupport.broadcastInt(
 808             opc, getClass(), short.class, length(),
 809             this, e,
 810             BIN_INT_IMPL.find(op, opc, (opc_) -> {
 811               switch (opc_) {
 812                 case VECTOR_OP_LSHIFT: return (v, n) ->
 813                         v.uOp((i, a) -> (short)(a << n));
 814                 case VECTOR_OP_RSHIFT: return (v, n) ->
 815                         v.uOp((i, a) -> (short)(a >> n));
 816                 case VECTOR_OP_URSHIFT: return (v, n) ->
 817                         v.uOp((i, a) -> (short)((a & LSHR_SETUP_MASK) >>> n));
 818                 case VECTOR_OP_LROTATE: return (v, n) ->
 819                         v.uOp((i, a) -> rotateLeft(a, (int)n));
 820                 case VECTOR_OP_RROTATE: return (v, n) ->
 821                         v.uOp((i, a) -> rotateRight(a, (int)n));
 822                 default: return null;
 823                 }}));








 824     }

 825     private static final
 826     ImplCache<Binary,VectorBroadcastIntOp<ShortVector>> BIN_INT_IMPL
 827         = new ImplCache<>(Binary.class, ShortVector.class);
 828 
















 829     // As per shift specification for Java, mask the shift count.
 830     // We mask 0X3F (long), 0X1F (int), 0x0F (short), 0x7 (byte).
 831     // The latter two maskings go beyond the JLS, but seem reasonable
 832     // since our lane types are first-class types, not just dressed
 833     // up ints.
 834     private static final int SHIFT_MASK = (Short.SIZE - 1);
 835     // Also simulate >>> on sub-word variables with a mask.
 836     private static final int LSHR_SETUP_MASK = ((1 << Short.SIZE) - 1);
 837 
 838     // Ternary lanewise support
 839 
 840     // Ternary operators come in eight variations:
 841     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2])
 842     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask)
 843 
 844     // It is annoying to support all of these variations of masking
 845     // and broadcast, but it would be more surprising not to continue
 846     // the obvious pattern started by unary and binary.
 847 
 848    /**

 861                                                   Vector<Short> v2);
 862     @ForceInline
 863     final
 864     ShortVector lanewiseTemplate(VectorOperators.Ternary op,
 865                                           Vector<Short> v1,
 866                                           Vector<Short> v2) {
 867         ShortVector that = (ShortVector) v1;
 868         ShortVector tother = (ShortVector) v2;
 869         // It's a word: https://www.dictionary.com/browse/tother
 870         // See also Chapter 11 of Dickens, Our Mutual Friend:
 871         // "Totherest Governor," replied Mr Riderhood...
 872         that.check(this);
 873         tother.check(this);
 874         if (op == BITWISE_BLEND) {
 875             // FIXME: Support this in the JIT.
 876             that = this.lanewise(XOR, that).lanewise(AND, tother);
 877             return this.lanewise(XOR, that);
 878         }
 879         int opc = opCode(op);
 880         return VectorSupport.ternaryOp(
 881             opc, getClass(), short.class, length(),
 882             this, that, tother,
 883             TERN_IMPL.find(op, opc, (opc_) -> {
 884               switch (opc_) {
 885                 default: return null;
 886                 }}));
 887     }
 888     private static final
 889     ImplCache<Ternary,TernaryOperation<ShortVector>> TERN_IMPL
 890         = new ImplCache<>(Ternary.class, ShortVector.class);
 891 
 892     /**
 893      * {@inheritDoc} <!--workaround-->
 894      * @see #lanewise(VectorOperators.Ternary,short,short,VectorMask)
 895      * @see #lanewise(VectorOperators.Ternary,Vector,short,VectorMask)
 896      * @see #lanewise(VectorOperators.Ternary,short,Vector,VectorMask)
 897      */
 898     @ForceInline
 899     public final
 900     ShortVector lanewise(VectorOperators.Ternary op,
 901                                   Vector<Short> v1,
 902                                   Vector<Short> v2,
 903                                   VectorMask<Short> m) {
 904         return blend(lanewise(op, v1, v2), m);



































 905     }
 906 
 907     /**
 908      * Combines the lane values of this vector
 909      * with the values of two broadcast scalars.
 910      *
 911      * This is a lane-wise ternary operation which applies
 912      * the selected operation to each lane.
 913      * The return value will be equal to this expression:
 914      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}.
 915      *
 916      * @param op the operation used to combine lane values
 917      * @param e1 the first input scalar
 918      * @param e2 the second input scalar
 919      * @return the result of applying the operation lane-wise
 920      *         to the input vector and the scalars
 921      * @throws UnsupportedOperationException if this vector does
 922      *         not support the requested operation
 923      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 924      * @see #lanewise(VectorOperators.Ternary,short,short,VectorMask)

 941      * The return value will be equal to this expression:
 942      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}.
 943      *
 944      * @param op the operation used to combine lane values
 945      * @param e1 the first input scalar
 946      * @param e2 the second input scalar
 947      * @param m the mask controlling lane selection
 948      * @return the result of applying the operation lane-wise
 949      *         to the input vector and the scalars
 950      * @throws UnsupportedOperationException if this vector does
 951      *         not support the requested operation
 952      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
 953      * @see #lanewise(VectorOperators.Ternary,short,short)
 954      */
 955     @ForceInline
 956     public final
 957     ShortVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m)
 958                                   short e1,
 959                                   short e2,
 960                                   VectorMask<Short> m) {
 961         return blend(lanewise(op, e1, e2), m);
 962     }
 963 
 964     /**
 965      * Combines the lane values of this vector
 966      * with the values of another vector and a broadcast scalar.
 967      *
 968      * This is a lane-wise ternary operation which applies
 969      * the selected operation to each lane.
 970      * The return value will be equal to this expression:
 971      * {@code this.lanewise(op, v1, this.broadcast(e2))}.
 972      *
 973      * @param op the operation used to combine lane values
 974      * @param v1 the other input vector
 975      * @param e2 the input scalar
 976      * @return the result of applying the operation lane-wise
 977      *         to the input vectors and the scalar
 978      * @throws UnsupportedOperationException if this vector does
 979      *         not support the requested operation
 980      * @see #lanewise(VectorOperators.Ternary,short,short)
 981      * @see #lanewise(VectorOperators.Ternary,Vector,short,VectorMask)

 999      * {@code this.lanewise(op, v1, this.broadcast(e2), m)}.
1000      *
1001      * @param op the operation used to combine lane values
1002      * @param v1 the other input vector
1003      * @param e2 the input scalar
1004      * @param m the mask controlling lane selection
1005      * @return the result of applying the operation lane-wise
1006      *         to the input vectors and the scalar
1007      * @throws UnsupportedOperationException if this vector does
1008      *         not support the requested operation
1009      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1010      * @see #lanewise(VectorOperators.Ternary,short,short,VectorMask)
1011      * @see #lanewise(VectorOperators.Ternary,Vector,short)
1012      */
1013     @ForceInline
1014     public final
1015     ShortVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m)
1016                                   Vector<Short> v1,
1017                                   short e2,
1018                                   VectorMask<Short> m) {
1019         return blend(lanewise(op, v1, e2), m);
1020     }
1021 
1022     /**
1023      * Combines the lane values of this vector
1024      * with the values of another vector and a broadcast scalar.
1025      *
1026      * This is a lane-wise ternary operation which applies
1027      * the selected operation to each lane.
1028      * The return value will be equal to this expression:
1029      * {@code this.lanewise(op, this.broadcast(e1), v2)}.
1030      *
1031      * @param op the operation used to combine lane values
1032      * @param e1 the input scalar
1033      * @param v2 the other input vector
1034      * @return the result of applying the operation lane-wise
1035      *         to the input vectors and the scalar
1036      * @throws UnsupportedOperationException if this vector does
1037      *         not support the requested operation
1038      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1039      * @see #lanewise(VectorOperators.Ternary,short,Vector,VectorMask)

1056      * The return value will be equal to this expression:
1057      * {@code this.lanewise(op, this.broadcast(e1), v2, m)}.
1058      *
1059      * @param op the operation used to combine lane values
1060      * @param e1 the input scalar
1061      * @param v2 the other input vector
1062      * @param m the mask controlling lane selection
1063      * @return the result of applying the operation lane-wise
1064      *         to the input vectors and the scalar
1065      * @throws UnsupportedOperationException if this vector does
1066      *         not support the requested operation
1067      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
1068      * @see #lanewise(VectorOperators.Ternary,short,Vector)
1069      */
1070     @ForceInline
1071     public final
1072     ShortVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m)
1073                                   short e1,
1074                                   Vector<Short> v2,
1075                                   VectorMask<Short> m) {
1076         return blend(lanewise(op, e1, v2), m);
1077     }
1078 
1079     // (Thus endeth the Great and Mighty Ternary Ogdoad.)
1080     // https://en.wikipedia.org/wiki/Ogdoad
1081 
1082     /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV
1083     //
1084     // These include masked and non-masked versions.
1085     // This subclass adds broadcast (masked or not).
1086 
1087     /**
1088      * {@inheritDoc} <!--workaround-->
1089      * @see #add(short)
1090      */
1091     @Override
1092     @ForceInline
1093     public final ShortVector add(Vector<Short> v) {
1094         return lanewise(ADD, v);
1095     }
1096 

1728     @Override
1729     @ForceInline
1730     public final
1731     VectorMask<Short> test(VectorOperators.Test op,
1732                                   VectorMask<Short> m) {
1733         return test(op).and(m);
1734     }
1735 
1736     /**
1737      * {@inheritDoc} <!--workaround-->
1738      */
1739     @Override
1740     public abstract
1741     VectorMask<Short> compare(VectorOperators.Comparison op, Vector<Short> v);
1742 
1743     /*package-private*/
1744     @ForceInline
1745     final
1746     <M extends VectorMask<Short>>
1747     M compareTemplate(Class<M> maskType, Comparison op, Vector<Short> v) {
1748         Objects.requireNonNull(v);
1749         ShortSpecies vsp = vspecies();
1750         ShortVector that = (ShortVector) v;
1751         that.check(this);
1752         int opc = opCode(op);
1753         return VectorSupport.compare(
1754             opc, getClass(), maskType, short.class, length(),
1755             this, that,
1756             (cond, v0, v1) -> {
1757                 AbstractMask<Short> m
1758                     = v0.bTest(cond, v1, (cond_, i, a, b)
1759                                -> compareWithOp(cond, a, b));
1760                 @SuppressWarnings("unchecked")
1761                 M m2 = (M) m;
1762                 return m2;
1763             });
1764     }
1765 






















1766     @ForceInline
1767     private static boolean compareWithOp(int cond, short a, short b) {
1768         return switch (cond) {
1769             case BT_eq -> a == b;
1770             case BT_ne -> a != b;
1771             case BT_lt -> a < b;
1772             case BT_le -> a <= b;
1773             case BT_gt -> a > b;
1774             case BT_ge -> a >= b;
1775             case BT_ult -> Short.compareUnsigned(a, b) < 0;
1776             case BT_ule -> Short.compareUnsigned(a, b) <= 0;
1777             case BT_ugt -> Short.compareUnsigned(a, b) > 0;
1778             case BT_uge -> Short.compareUnsigned(a, b) >= 0;
1779             default -> throw new AssertionError();
1780         };
1781     }
1782 
1783     /**
1784      * {@inheritDoc} <!--workaround-->
1785      */
1786     @Override
1787     @ForceInline
1788     public final
1789     VectorMask<Short> compare(VectorOperators.Comparison op,
1790                                   Vector<Short> v,
1791                                   VectorMask<Short> m) {
1792         return compare(op, v).and(m);
1793     }
1794 
1795     /**
1796      * Tests this vector by comparing it with an input scalar,
1797      * according to the given comparison operation.
1798      *
1799      * This is a lane-wise binary test operation which applies
1800      * the comparison operation to each lane.
1801      * <p>
1802      * The result is the same as
1803      * {@code compare(op, broadcast(species(), e))}.
1804      * That is, the scalar may be regarded as broadcast to
1805      * a vector of the same species, and then compared
1806      * against the original vector, using the selected
1807      * comparison operation.
1808      *
1809      * @param op the operation used to compare lane values
1810      * @param e the input scalar
1811      * @return the mask result of testing lane-wise if this vector
1812      *         compares to the input, according to the selected
1813      *         comparison operator
1814      * @see ShortVector#compare(VectorOperators.Comparison,Vector)

1833      *
1834      * This is a masked lane-wise binary test operation which applies
1835      * to each pair of corresponding lane values.
1836      *
1837      * The returned result is equal to the expression
1838      * {@code compare(op,s).and(m)}.
1839      *
1840      * @param op the operation used to compare lane values
1841      * @param e the input scalar
1842      * @param m the mask controlling lane selection
1843      * @return the mask result of testing lane-wise if this vector
1844      *         compares to the input, according to the selected
1845      *         comparison operator,
1846      *         and only in the lanes selected by the mask
1847      * @see ShortVector#compare(VectorOperators.Comparison,Vector,VectorMask)
1848      */
1849     @ForceInline
1850     public final VectorMask<Short> compare(VectorOperators.Comparison op,
1851                                                short e,
1852                                                VectorMask<Short> m) {
1853         return compare(op, e).and(m);
1854     }
1855 
1856     /**
1857      * {@inheritDoc} <!--workaround-->
1858      */
1859     @Override
1860     public abstract
1861     VectorMask<Short> compare(Comparison op, long e);
1862 
1863     /*package-private*/
1864     @ForceInline
1865     final
1866     <M extends VectorMask<Short>>
1867     M compareTemplate(Class<M> maskType, Comparison op, long e) {
1868         return compareTemplate(maskType, op, broadcast(e));
1869     }
1870 
1871     /**
1872      * {@inheritDoc} <!--workaround-->
1873      */

2084     wrongPartForSlice(int part) {
2085         String msg = String.format("bad part number %d for slice operation",
2086                                    part);
2087         return new ArrayIndexOutOfBoundsException(msg);
2088     }
2089 
2090     /**
2091      * {@inheritDoc} <!--workaround-->
2092      */
2093     @Override
2094     public abstract
2095     ShortVector rearrange(VectorShuffle<Short> m);
2096 
2097     /*package-private*/
2098     @ForceInline
2099     final
2100     <S extends VectorShuffle<Short>>
2101     ShortVector rearrangeTemplate(Class<S> shuffletype, S shuffle) {
2102         shuffle.checkIndexes();
2103         return VectorSupport.rearrangeOp(
2104             getClass(), shuffletype, short.class, length(),
2105             this, shuffle,
2106             (v1, s_) -> v1.uOp((i, a) -> {
2107                 int ei = s_.laneSource(i);
2108                 return v1.lane(ei);
2109             }));
2110     }
2111 
2112     /**
2113      * {@inheritDoc} <!--workaround-->
2114      */
2115     @Override
2116     public abstract
2117     ShortVector rearrange(VectorShuffle<Short> s,
2118                                    VectorMask<Short> m);
2119 
2120     /*package-private*/
2121     @ForceInline
2122     final
2123     <S extends VectorShuffle<Short>>
2124     ShortVector rearrangeTemplate(Class<S> shuffletype,

2125                                            S shuffle,
2126                                            VectorMask<Short> m) {
2127         ShortVector unmasked =
2128             VectorSupport.rearrangeOp(
2129                 getClass(), shuffletype, short.class, length(),
2130                 this, shuffle,
2131                 (v1, s_) -> v1.uOp((i, a) -> {
2132                     int ei = s_.laneSource(i);
2133                     return ei < 0 ? 0 : v1.lane(ei);
2134                 }));
2135         VectorMask<Short> valid = shuffle.laneIsValid();
2136         if (m.andNot(valid).anyTrue()) {
2137             shuffle.checkIndexes();
2138             throw new AssertionError();
2139         }
2140         return broadcast((short)0).blend(unmasked, m);






2141     }
2142 
2143     /**
2144      * {@inheritDoc} <!--workaround-->
2145      */
2146     @Override
2147     public abstract
2148     ShortVector rearrange(VectorShuffle<Short> s,
2149                                    Vector<Short> v);
2150 
2151     /*package-private*/
2152     @ForceInline
2153     final
2154     <S extends VectorShuffle<Short>>
2155     ShortVector rearrangeTemplate(Class<S> shuffletype,
2156                                            S shuffle,
2157                                            ShortVector v) {
2158         VectorMask<Short> valid = shuffle.laneIsValid();
2159         @SuppressWarnings("unchecked")
2160         S ws = (S) shuffle.wrapIndexes();
2161         ShortVector r0 =
2162             VectorSupport.rearrangeOp(
2163                 getClass(), shuffletype, short.class, length(),
2164                 this, ws,
2165                 (v0, s_) -> v0.uOp((i, a) -> {
2166                     int ei = s_.laneSource(i);
2167                     return v0.lane(ei);
2168                 }));
2169         ShortVector r1 =
2170             VectorSupport.rearrangeOp(
2171                 getClass(), shuffletype, short.class, length(),
2172                 v, ws,
2173                 (v1, s_) -> v1.uOp((i, a) -> {
2174                     int ei = s_.laneSource(i);
2175                     return v1.lane(ei);
2176                 }));
2177         return r1.blend(r0, valid);
2178     }
2179 
2180     @ForceInline
2181     private final
2182     VectorShuffle<Short> toShuffle0(ShortSpecies dsp) {
2183         short[] a = toArray();
2184         int[] sa = new int[a.length];
2185         for (int i = 0; i < a.length; i++) {
2186             sa[i] = (int) a[i];
2187         }
2188         return VectorShuffle.fromArray(dsp, sa, 0);
2189     }
2190 
2191     /*package-private*/
2192     @ForceInline
2193     final

2416      * <li>
2417      * All other reduction operations are fully commutative and
2418      * associative.  The implementation can choose any order of
2419      * processing, yet it will always produce the same result.
2420      * </ul>
2421      *
2422      * @param op the operation used to combine lane values
2423      * @param m the mask controlling lane selection
2424      * @return the reduced result accumulated from the selected lane values
2425      * @throws UnsupportedOperationException if this vector does
2426      *         not support the requested operation
2427      * @see #reduceLanes(VectorOperators.Associative)
2428      */
2429     public abstract short reduceLanes(VectorOperators.Associative op,
2430                                        VectorMask<Short> m);
2431 
2432     /*package-private*/
2433     @ForceInline
2434     final
2435     short reduceLanesTemplate(VectorOperators.Associative op,

2436                                VectorMask<Short> m) {
2437         ShortVector v = reduceIdentityVector(op).blend(this, m);
2438         return v.reduceLanesTemplate(op);








2439     }
2440 
2441     /*package-private*/
2442     @ForceInline
2443     final
2444     short reduceLanesTemplate(VectorOperators.Associative op) {
2445         if (op == FIRST_NONZERO) {
2446             // FIXME:  The JIT should handle this, and other scan ops alos.
2447             VectorMask<Short> thisNZ
2448                 = this.viewAsIntegralLanes().compare(NE, (short) 0);
2449             return this.lane(thisNZ.firstTrue());
2450         }
2451         int opc = opCode(op);
2452         return fromBits(VectorSupport.reductionCoerced(
2453             opc, getClass(), short.class, length(),
2454             this,
2455             REDUCE_IMPL.find(op, opc, (opc_) -> {
2456               switch (opc_) {
2457               case VECTOR_OP_ADD: return v ->
2458                       toBits(v.rOp((short)0, (i, a, b) -> (short)(a + b)));
2459               case VECTOR_OP_MUL: return v ->
2460                       toBits(v.rOp((short)1, (i, a, b) -> (short)(a * b)));
2461               case VECTOR_OP_MIN: return v ->
2462                       toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (short) Math.min(a, b)));
2463               case VECTOR_OP_MAX: return v ->
2464                       toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (short) Math.max(a, b)));
2465               case VECTOR_OP_AND: return v ->
2466                       toBits(v.rOp((short)-1, (i, a, b) -> (short)(a & b)));
2467               case VECTOR_OP_OR: return v ->
2468                       toBits(v.rOp((short)0, (i, a, b) -> (short)(a | b)));
2469               case VECTOR_OP_XOR: return v ->
2470                       toBits(v.rOp((short)0, (i, a, b) -> (short)(a ^ b)));
2471               default: return null;
2472               }})));
2473     }

2474     private static final
2475     ImplCache<Associative,Function<ShortVector,Long>> REDUCE_IMPL
2476         = new ImplCache<>(Associative.class, ShortVector.class);




















2477 
2478     private
2479     @ForceInline
2480     ShortVector reduceIdentityVector(VectorOperators.Associative op) {
2481         int opc = opCode(op);
2482         UnaryOperator<ShortVector> fn
2483             = REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
2484                 switch (opc_) {
2485                 case VECTOR_OP_ADD:
2486                 case VECTOR_OP_OR:
2487                 case VECTOR_OP_XOR:
2488                     return v -> v.broadcast(0);
2489                 case VECTOR_OP_MUL:
2490                     return v -> v.broadcast(1);
2491                 case VECTOR_OP_AND:
2492                     return v -> v.broadcast(-1);
2493                 case VECTOR_OP_MIN:
2494                     return v -> v.broadcast(MAX_OR_INF);
2495                 case VECTOR_OP_MAX:
2496                     return v -> v.broadcast(MIN_OR_INF);

2682      * @param species species of desired vector
2683      * @param a the byte array
2684      * @param offset the offset into the array
2685      * @param bo the intended byte order
2686      * @param m the mask controlling lane selection
2687      * @return a vector loaded from a byte array
2688      * @throws IndexOutOfBoundsException
2689      *         if {@code offset+N*ESIZE < 0}
2690      *         or {@code offset+(N+1)*ESIZE > a.length}
2691      *         for any lane {@code N} in the vector
2692      *         where the mask is set
2693      */
2694     @ForceInline
2695     public static
2696     ShortVector fromByteArray(VectorSpecies<Short> species,
2697                                        byte[] a, int offset,
2698                                        ByteOrder bo,
2699                                        VectorMask<Short> m) {
2700         ShortSpecies vsp = (ShortSpecies) species;
2701         if (offset >= 0 && offset <= (a.length - species.vectorByteSize())) {
2702             ShortVector zero = vsp.zero();
2703             ShortVector v = zero.fromByteArray0(a, offset);
2704             return zero.blend(v.maybeSwap(bo), m);
2705         }
2706 
2707         // FIXME: optimize
2708         checkMaskFromIndexSize(offset, vsp, m, 2, a.length);
2709         ByteBuffer wb = wrapper(a, bo);
2710         return vsp.ldOp(wb, offset, (AbstractMask<Short>)m,
2711                    (wb_, o, i)  -> wb_.getShort(o + i * 2));
2712     }
2713 
2714     /**
2715      * Loads a vector from an array of type {@code short[]}
2716      * starting at an offset.
2717      * For each vector lane, where {@code N} is the vector lane index, the
2718      * array element at index {@code offset + N} is placed into the
2719      * resulting vector at lane index {@code N}.
2720      *
2721      * @param species species of desired vector
2722      * @param a the array
2723      * @param offset the offset into the array
2724      * @return the vector loaded from an array

2746      * {@code N}, otherwise the default element value is placed into the
2747      * resulting vector at lane index {@code N}.
2748      *
2749      * @param species species of desired vector
2750      * @param a the array
2751      * @param offset the offset into the array
2752      * @param m the mask controlling lane selection
2753      * @return the vector loaded from an array
2754      * @throws IndexOutOfBoundsException
2755      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2756      *         for any lane {@code N} in the vector
2757      *         where the mask is set
2758      */
2759     @ForceInline
2760     public static
2761     ShortVector fromArray(VectorSpecies<Short> species,
2762                                    short[] a, int offset,
2763                                    VectorMask<Short> m) {
2764         ShortSpecies vsp = (ShortSpecies) species;
2765         if (offset >= 0 && offset <= (a.length - species.length())) {
2766             ShortVector zero = vsp.zero();
2767             return zero.blend(zero.fromArray0(a, offset), m);
2768         }
2769 
2770         // FIXME: optimize
2771         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2772         return vsp.vOp(m, i -> a[offset + i]);
2773     }
2774 
2775     /**
2776      * Gathers a new vector composed of elements from an array of type
2777      * {@code short[]},
2778      * using indexes obtained by adding a fixed {@code offset} to a
2779      * series of secondary offsets from an <em>index map</em>.
2780      * The index map is a contiguous sequence of {@code VLENGTH}
2781      * elements in a second array of {@code int}s, starting at a given
2782      * {@code mapOffset}.
2783      * <p>
2784      * For each vector lane, where {@code N} is the vector lane index,
2785      * the lane is loaded from the array
2786      * element {@code a[f(N)]}, where {@code f(N)} is the
2787      * index mapping expression

2896      * {@code N}, otherwise the default element value is placed into the
2897      * resulting vector at lane index {@code N}.
2898      *
2899      * @param species species of desired vector
2900      * @param a the array
2901      * @param offset the offset into the array
2902      * @param m the mask controlling lane selection
2903      * @return the vector loaded from an array
2904      * @throws IndexOutOfBoundsException
2905      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2906      *         for any lane {@code N} in the vector
2907      *         where the mask is set
2908      */
2909     @ForceInline
2910     public static
2911     ShortVector fromCharArray(VectorSpecies<Short> species,
2912                                        char[] a, int offset,
2913                                        VectorMask<Short> m) {
2914         ShortSpecies vsp = (ShortSpecies) species;
2915         if (offset >= 0 && offset <= (a.length - species.length())) {
2916             ShortVector zero = vsp.zero();
2917             return zero.blend(zero.fromCharArray0(a, offset), m);
2918         }
2919 
2920         // FIXME: optimize
2921         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2922         return vsp.vOp(m, i -> (short) a[offset + i]);
2923     }
2924 
2925     /**
2926      * Gathers a new vector composed of elements from an array of type
2927      * {@code char[]},
2928      * using indexes obtained by adding a fixed {@code offset} to a
2929      * series of secondary offsets from an <em>index map</em>.
2930      * The index map is a contiguous sequence of {@code VLENGTH}
2931      * elements in a second array of {@code int}s, starting at a given
2932      * {@code mapOffset}.
2933      * <p>
2934      * For each vector lane, where {@code N} is the vector lane index,
2935      * the lane is loaded from the expression
2936      * {@code (short) a[f(N)]}, where {@code f(N)} is the
2937      * index mapping expression

3082      * @param species species of desired vector
3083      * @param bb the byte buffer
3084      * @param offset the offset into the byte buffer
3085      * @param bo the intended byte order
3086      * @param m the mask controlling lane selection
3087      * @return a vector loaded from a byte buffer
3088      * @throws IndexOutOfBoundsException
3089      *         if {@code offset+N*2 < 0}
3090      *         or {@code offset+N*2 >= bb.limit()}
3091      *         for any lane {@code N} in the vector
3092      *         where the mask is set
3093      */
3094     @ForceInline
3095     public static
3096     ShortVector fromByteBuffer(VectorSpecies<Short> species,
3097                                         ByteBuffer bb, int offset,
3098                                         ByteOrder bo,
3099                                         VectorMask<Short> m) {
3100         ShortSpecies vsp = (ShortSpecies) species;
3101         if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) {
3102             ShortVector zero = vsp.zero();
3103             ShortVector v = zero.fromByteBuffer0(bb, offset);
3104             return zero.blend(v.maybeSwap(bo), m);
3105         }
3106 
3107         // FIXME: optimize
3108         checkMaskFromIndexSize(offset, vsp, m, 2, bb.limit());
3109         ByteBuffer wb = wrapper(bb, bo);
3110         return vsp.ldOp(wb, offset, (AbstractMask<Short>)m,
3111                    (wb_, o, i)  -> wb_.getShort(o + i * 2));
3112     }
3113 
3114     // Memory store operations
3115 
3116     /**
3117      * Stores this vector into an array of type {@code short[]}
3118      * starting at an offset.
3119      * <p>
3120      * For each vector lane, where {@code N} is the vector lane index,
3121      * the lane element at index {@code N} is stored into the array
3122      * element {@code a[offset+N]}.
3123      *
3124      * @param a the array, of type {@code short[]}

3156      * Lanes where the mask is unset are not stored and do not need
3157      * to correspond to legitimate elements of {@code a}.
3158      * That is, unset lanes may correspond to array indexes less than
3159      * zero or beyond the end of the array.
3160      *
3161      * @param a the array, of type {@code short[]}
3162      * @param offset the offset into the array
3163      * @param m the mask controlling lane storage
3164      * @throws IndexOutOfBoundsException
3165      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3166      *         for any lane {@code N} in the vector
3167      *         where the mask is set
3168      */
3169     @ForceInline
3170     public final
3171     void intoArray(short[] a, int offset,
3172                    VectorMask<Short> m) {
3173         if (m.allTrue()) {
3174             intoArray(a, offset);
3175         } else {
3176             // FIXME: optimize
3177             ShortSpecies vsp = vspecies();
3178             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3179             stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v);
3180         }
3181     }
3182 
3183     /**
3184      * Scatters this vector into an array of type {@code short[]}
3185      * using indexes obtained by adding a fixed {@code offset} to a
3186      * series of secondary offsets from an <em>index map</em>.
3187      * The index map is a contiguous sequence of {@code VLENGTH}
3188      * elements in a second array of {@code int}s, starting at a given
3189      * {@code mapOffset}.
3190      * <p>
3191      * For each vector lane, where {@code N} is the vector lane index,
3192      * the lane element at index {@code N} is stored into the array
3193      * element {@code a[f(N)]}, where {@code f(N)} is the
3194      * index mapping expression
3195      * {@code offset + indexMap[mapOffset + N]]}.
3196      *
3197      * @param a the array
3198      * @param offset an offset to combine with the index map offsets
3199      * @param indexMap the index map

3304      * Lanes where the mask is unset are not stored and do not need
3305      * to correspond to legitimate elements of {@code a}.
3306      * That is, unset lanes may correspond to array indexes less than
3307      * zero or beyond the end of the array.
3308      *
3309      * @param a the array, of type {@code char[]}
3310      * @param offset the offset into the array
3311      * @param m the mask controlling lane storage
3312      * @throws IndexOutOfBoundsException
3313      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3314      *         for any lane {@code N} in the vector
3315      *         where the mask is set
3316      */
3317     @ForceInline
3318     public final
3319     void intoCharArray(char[] a, int offset,
3320                        VectorMask<Short> m) {
3321         if (m.allTrue()) {
3322             intoCharArray(a, offset);
3323         } else {
3324             // FIXME: optimize
3325             ShortSpecies vsp = vspecies();
3326             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3327             stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = (char) v);
3328         }
3329     }
3330 
3331     /**
3332      * Scatters this vector into an array of type {@code char[]}
3333      * using indexes obtained by adding a fixed {@code offset} to a
3334      * series of secondary offsets from an <em>index map</em>.
3335      * The index map is a contiguous sequence of {@code VLENGTH}
3336      * elements in a second array of {@code int}s, starting at a given
3337      * {@code mapOffset}.
3338      * <p>
3339      * For each vector lane, where {@code N} is the vector lane index,
3340      * the lane element at index {@code N}
3341      * is first cast to a {@code char} value and then
3342      * stored into the array
3343      * element {@code a[f(N)]}, where {@code f(N)} is the
3344      * index mapping expression
3345      * {@code offset + indexMap[mapOffset + N]]}.
3346      *
3347      * @param a the array

3421     @ForceInline
3422     public final
3423     void intoByteArray(byte[] a, int offset,
3424                        ByteOrder bo) {
3425         offset = checkFromIndexSize(offset, byteSize(), a.length);
3426         maybeSwap(bo).intoByteArray0(a, offset);
3427     }
3428 
3429     /**
3430      * {@inheritDoc} <!--workaround-->
3431      */
3432     @Override
3433     @ForceInline
3434     public final
3435     void intoByteArray(byte[] a, int offset,
3436                        ByteOrder bo,
3437                        VectorMask<Short> m) {
3438         if (m.allTrue()) {
3439             intoByteArray(a, offset, bo);
3440         } else {
3441             // FIXME: optimize
3442             ShortSpecies vsp = vspecies();
3443             checkMaskFromIndexSize(offset, vsp, m, 2, a.length);
3444             ByteBuffer wb = wrapper(a, bo);
3445             this.stOp(wb, offset, m,
3446                     (wb_, o, i, e) -> wb_.putShort(o + i * 2, e));
3447         }
3448     }
3449 
3450     /**
3451      * {@inheritDoc} <!--workaround-->
3452      */
3453     @Override
3454     @ForceInline
3455     public final
3456     void intoByteBuffer(ByteBuffer bb, int offset,
3457                         ByteOrder bo) {
3458         if (bb.isReadOnly()) {
3459             throw new ReadOnlyBufferException();
3460         }
3461         offset = checkFromIndexSize(offset, byteSize(), bb.limit());
3462         maybeSwap(bo).intoByteBuffer0(bb, offset);
3463     }
3464 
3465     /**
3466      * {@inheritDoc} <!--workaround-->
3467      */
3468     @Override
3469     @ForceInline
3470     public final
3471     void intoByteBuffer(ByteBuffer bb, int offset,
3472                         ByteOrder bo,
3473                         VectorMask<Short> m) {
3474         if (m.allTrue()) {
3475             intoByteBuffer(bb, offset, bo);
3476         } else {
3477             // FIXME: optimize
3478             if (bb.isReadOnly()) {
3479                 throw new ReadOnlyBufferException();
3480             }
3481             ShortSpecies vsp = vspecies();
3482             checkMaskFromIndexSize(offset, vsp, m, 2, bb.limit());
3483             ByteBuffer wb = wrapper(bb, bo);
3484             this.stOp(wb, offset, m,
3485                     (wb_, o, i, e) -> wb_.putShort(o + i * 2, e));
3486         }
3487     }
3488 
3489     // ================================================
3490 
3491     // Low-level memory operations.
3492     //
3493     // Note that all of these operations *must* inline into a context
3494     // where the exact species of the involved vector is a
3495     // compile-time constant.  Otherwise, the intrinsic generation
3496     // will fail and performance will suffer.
3497     //
3498     // In many cases this is achieved by re-deriving a version of the
3499     // method in each concrete subclass (per species).  The re-derived
3500     // method simply calls one of these generic methods, with exact
3501     // parameters for the controlling metadata, which is either a
3502     // typed vector or constant species instance.
3503 
3504     // Unchecked loading operations in native byte order.
3505     // Caller is responsible for applying index checks, masking, and
3506     // byte swapping.
3507 
3508     /*package-private*/
3509     abstract
3510     ShortVector fromArray0(short[] a, int offset);
3511     @ForceInline
3512     final
3513     ShortVector fromArray0Template(short[] a, int offset) {
3514         ShortSpecies vsp = vspecies();
3515         return VectorSupport.load(
3516             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3517             a, arrayAddress(a, offset),
3518             a, offset, vsp,
3519             (arr, off, s) -> s.ldOp(arr, off,
3520                                     (arr_, off_, i) -> arr_[off_ + i]));
3521     }
3522 


















3523     /*package-private*/
3524     abstract
3525     ShortVector fromCharArray0(char[] a, int offset);
3526     @ForceInline
3527     final
3528     ShortVector fromCharArray0Template(char[] a, int offset) {
3529         ShortSpecies vsp = vspecies();
3530         return VectorSupport.load(
3531             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3532             a, charArrayAddress(a, offset),
3533             a, offset, vsp,
3534             (arr, off, s) -> s.ldOp(arr, off,
3535                                     (arr_, off_, i) -> (short) arr_[off_ + i]));
3536     }
3537 

















3538 
3539     @Override
3540     abstract
3541     ShortVector fromByteArray0(byte[] a, int offset);
3542     @ForceInline
3543     final
3544     ShortVector fromByteArray0Template(byte[] a, int offset) {
3545         ShortSpecies vsp = vspecies();
3546         return VectorSupport.load(
3547             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3548             a, byteArrayAddress(a, offset),
3549             a, offset, vsp,
3550             (arr, off, s) -> {
3551                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3552                 return s.ldOp(wb, off,
3553                         (wb_, o, i) -> wb_.getShort(o + i * 2));
3554             });
3555     }
3556 



















3557     abstract
3558     ShortVector fromByteBuffer0(ByteBuffer bb, int offset);
3559     @ForceInline
3560     final
3561     ShortVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
3562         ShortSpecies vsp = vspecies();
3563         return ScopedMemoryAccess.loadFromByteBuffer(
3564                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3565                 bb, offset, vsp,
3566                 (buf, off, s) -> {
3567                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3568                     return s.ldOp(wb, off,
3569                             (wb_, o, i) -> wb_.getShort(o + i * 2));
3570                 });
3571     }
3572 


















3573     // Unchecked storing operations in native byte order.
3574     // Caller is responsible for applying index checks, masking, and
3575     // byte swapping.
3576 
3577     abstract
3578     void intoArray0(short[] a, int offset);
3579     @ForceInline
3580     final
3581     void intoArray0Template(short[] a, int offset) {
3582         ShortSpecies vsp = vspecies();
3583         VectorSupport.store(
3584             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3585             a, arrayAddress(a, offset),
3586             this, a, offset,
3587             (arr, off, v)
3588             -> v.stOp(arr, off,
3589                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3590     }
3591 



















3592     abstract
3593     void intoByteArray0(byte[] a, int offset);
3594     @ForceInline
3595     final
3596     void intoByteArray0Template(byte[] a, int offset) {
3597         ShortSpecies vsp = vspecies();
3598         VectorSupport.store(
3599             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3600             a, byteArrayAddress(a, offset),
3601             this, a, offset,
3602             (arr, off, v) -> {
3603                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3604                 v.stOp(wb, off,
3605                         (tb_, o, i, e) -> tb_.putShort(o + i * 2, e));
3606             });
3607     }
3608 



















3609     @ForceInline
3610     final
3611     void intoByteBuffer0(ByteBuffer bb, int offset) {
3612         ShortSpecies vsp = vspecies();
3613         ScopedMemoryAccess.storeIntoByteBuffer(
3614                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3615                 this, bb, offset,
3616                 (buf, off, v) -> {
3617                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3618                     v.stOp(wb, off,
3619                             (wb_, o, i, e) -> wb_.putShort(o + i * 2, e));
3620                 });
3621     }
3622 




































3623     // End of low-level memory operations.
3624 
3625     private static
3626     void checkMaskFromIndexSize(int offset,
3627                                 ShortSpecies vsp,
3628                                 VectorMask<Short> m,
3629                                 int scale,
3630                                 int limit) {
3631         ((AbstractMask<Short>)m)
3632             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3633     }
3634 
3635     @ForceInline
3636     private void conditionalStoreNYI(int offset,
3637                                      ShortSpecies vsp,
3638                                      VectorMask<Short> m,
3639                                      int scale,
3640                                      int limit) {
3641         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3642             String msg =

3937             short[] res = new short[laneCount()];
3938             boolean[] mbits = ((AbstractMask<Short>)m).getBits();
3939             for (int i = 0; i < res.length; i++) {
3940                 if (mbits[i]) {
3941                     res[i] = f.apply(i);
3942                 }
3943             }
3944             return dummyVector().vectorFactory(res);
3945         }
3946 
3947         /*package-private*/
3948         @ForceInline
3949         <M> ShortVector ldOp(M memory, int offset,
3950                                       FLdOp<M> f) {
3951             return dummyVector().ldOp(memory, offset, f);
3952         }
3953 
3954         /*package-private*/
3955         @ForceInline
3956         <M> ShortVector ldOp(M memory, int offset,
3957                                       AbstractMask<Short> m,
3958                                       FLdOp<M> f) {
3959             return dummyVector().ldOp(memory, offset, m, f);
3960         }
3961 
3962         /*package-private*/
3963         @ForceInline
3964         <M> void stOp(M memory, int offset, FStOp<M> f) {
3965             dummyVector().stOp(memory, offset, f);
3966         }
3967 
3968         /*package-private*/
3969         @ForceInline
3970         <M> void stOp(M memory, int offset,
3971                       AbstractMask<Short> m,
3972                       FStOp<M> f) {
3973             dummyVector().stOp(memory, offset, m, f);
3974         }
3975 
3976         // N.B. Make sure these constant vectors and
3977         // masks load up correctly into registers.

  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 any
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.ByteOrder;
  29 import java.nio.ReadOnlyBufferException;
  30 import java.util.Arrays;
  31 import java.util.Objects;

  32 import java.util.function.Function;
  33 import java.util.function.UnaryOperator;
  34 
  35 import jdk.internal.misc.ScopedMemoryAccess;
  36 import jdk.internal.misc.Unsafe;
  37 import jdk.internal.vm.annotation.ForceInline;
  38 import jdk.internal.vm.vector.VectorSupport;
  39 
  40 import static jdk.internal.vm.vector.VectorSupport.*;
  41 import static jdk.incubator.vector.VectorIntrinsics.*;
  42 
  43 import static jdk.incubator.vector.VectorOperators.*;
  44 
  45 // -- This file was mechanically generated: Do not edit! -- //
  46 
  47 /**
  48  * A specialized {@link Vector} representing an ordered immutable sequence of
  49  * {@code short} values.
  50  */
  51 @SuppressWarnings("cast")  // warning: redundant cast

 155     ShortVector uOp(FUnOp f);
 156     @ForceInline
 157     final
 158     ShortVector uOpTemplate(FUnOp f) {
 159         short[] vec = vec();
 160         short[] res = new short[length()];
 161         for (int i = 0; i < res.length; i++) {
 162             res[i] = f.apply(i, vec[i]);
 163         }
 164         return vectorFactory(res);
 165     }
 166 
 167     /*package-private*/
 168     abstract
 169     ShortVector uOp(VectorMask<Short> m,
 170                              FUnOp f);
 171     @ForceInline
 172     final
 173     ShortVector uOpTemplate(VectorMask<Short> m,
 174                                      FUnOp f) {
 175         if (m == null) {
 176             return uOpTemplate(f);
 177         }
 178         short[] vec = vec();
 179         short[] res = new short[length()];
 180         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 181         for (int i = 0; i < res.length; i++) {
 182             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
 183         }
 184         return vectorFactory(res);
 185     }
 186 
 187     // Binary operator
 188 
 189     /*package-private*/
 190     interface FBinOp {
 191         short apply(int i, short a, short b);
 192     }
 193 
 194     /*package-private*/
 195     abstract
 196     ShortVector bOp(Vector<Short> o,
 197                              FBinOp f);

 201                                      FBinOp f) {
 202         short[] res = new short[length()];
 203         short[] vec1 = this.vec();
 204         short[] vec2 = ((ShortVector)o).vec();
 205         for (int i = 0; i < res.length; i++) {
 206             res[i] = f.apply(i, vec1[i], vec2[i]);
 207         }
 208         return vectorFactory(res);
 209     }
 210 
 211     /*package-private*/
 212     abstract
 213     ShortVector bOp(Vector<Short> o,
 214                              VectorMask<Short> m,
 215                              FBinOp f);
 216     @ForceInline
 217     final
 218     ShortVector bOpTemplate(Vector<Short> o,
 219                                      VectorMask<Short> m,
 220                                      FBinOp f) {
 221         if (m == null) {
 222             return bOpTemplate(o, f);
 223         }
 224         short[] res = new short[length()];
 225         short[] vec1 = this.vec();
 226         short[] vec2 = ((ShortVector)o).vec();
 227         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 228         for (int i = 0; i < res.length; i++) {
 229             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 230         }
 231         return vectorFactory(res);
 232     }
 233 
 234     // Ternary operator
 235 
 236     /*package-private*/
 237     interface FTriOp {
 238         short apply(int i, short a, short b, short c);
 239     }
 240 
 241     /*package-private*/
 242     abstract
 243     ShortVector tOp(Vector<Short> o1,

 253         short[] vec2 = ((ShortVector)o1).vec();
 254         short[] vec3 = ((ShortVector)o2).vec();
 255         for (int i = 0; i < res.length; i++) {
 256             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 257         }
 258         return vectorFactory(res);
 259     }
 260 
 261     /*package-private*/
 262     abstract
 263     ShortVector tOp(Vector<Short> o1,
 264                              Vector<Short> o2,
 265                              VectorMask<Short> m,
 266                              FTriOp f);
 267     @ForceInline
 268     final
 269     ShortVector tOpTemplate(Vector<Short> o1,
 270                                      Vector<Short> o2,
 271                                      VectorMask<Short> m,
 272                                      FTriOp f) {
 273         if (m == null) {
 274             return tOpTemplate(o1, o2, f);
 275         }
 276         short[] res = new short[length()];
 277         short[] vec1 = this.vec();
 278         short[] vec2 = ((ShortVector)o1).vec();
 279         short[] vec3 = ((ShortVector)o2).vec();
 280         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 281         for (int i = 0; i < res.length; i++) {
 282             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 283         }
 284         return vectorFactory(res);
 285     }
 286 
 287     // Reduction operator
 288 
 289     /*package-private*/
 290     abstract
 291     short rOp(short v, VectorMask<Short> m, FBinOp f);
 292 
 293     @ForceInline
 294     final
 295     short rOpTemplate(short v, VectorMask<Short> m, FBinOp f) {
 296         if (m == null) {
 297             return rOpTemplate(v, f);
 298         }
 299         short[] vec = vec();
 300         boolean[] mbits = ((AbstractMask<Short>)m).getBits();
 301         for (int i = 0; i < vec.length; i++) {
 302             v = mbits[i] ? f.apply(i, v, vec[i]) : v;
 303         }
 304         return v;
 305     }
 306 
 307     @ForceInline
 308     final
 309     short rOpTemplate(short v, FBinOp f) {
 310         short[] vec = vec();
 311         for (int i = 0; i < vec.length; i++) {
 312             v = f.apply(i, v, vec[i]);
 313         }
 314         return v;
 315     }
 316 
 317     // Memory reference
 318 
 319     /*package-private*/
 320     interface FLdOp<M> {
 321         short apply(M memory, int offset, int i);
 322     }
 323 
 324     /*package-private*/
 325     @ForceInline
 326     final

 555     final ShortVector broadcastTemplate(long e) {
 556         return vspecies().broadcast(e);
 557     }
 558 
 559     // Unary lanewise support
 560 
 561     /**
 562      * {@inheritDoc} <!--workaround-->
 563      */
 564     public abstract
 565     ShortVector lanewise(VectorOperators.Unary op);
 566 
 567     @ForceInline
 568     final
 569     ShortVector lanewiseTemplate(VectorOperators.Unary op) {
 570         if (opKind(op, VO_SPECIAL)) {
 571             if (op == ZOMO) {
 572                 return blend(broadcast(-1), compare(NE, 0));
 573             }
 574             if (op == NOT) {
 575                 return broadcast(-1).lanewise(XOR, this);
 576             } else if (op == NEG) {
 577                 // FIXME: Support this in the JIT.
 578                 return broadcast(0).lanewise(SUB, this);
 579             }
 580         }
 581         int opc = opCode(op);
 582         return VectorSupport.unaryOp(
 583             opc, getClass(), null, short.class, length(),
 584             this, null,
 585             UN_IMPL.find(op, opc, ShortVector::unaryOperations));







 586     }



 587 
 588     /**
 589      * {@inheritDoc} <!--workaround-->
 590      */
 591     @Override
 592     public abstract
 593     ShortVector lanewise(VectorOperators.Unary op,
 594                                   VectorMask<Short> m);
 595     @ForceInline
 596     final
 597     ShortVector lanewiseTemplate(VectorOperators.Unary op,
 598                                           Class<? extends VectorMask<Short>> maskClass,
 599                                           VectorMask<Short> m) {
 600         m.check(maskClass, this);
 601         if (opKind(op, VO_SPECIAL)) {
 602             if (op == ZOMO) {
 603                 return blend(broadcast(-1), compare(NE, 0, m));
 604             }
 605             if (op == NOT) {
 606                 return lanewise(XOR, broadcast(-1), m);
 607             } else if (op == NEG) {
 608                 return lanewise(NOT, m).lanewise(ADD, broadcast(1), m);
 609             }
 610         }
 611         int opc = opCode(op);
 612         return VectorSupport.unaryOp(
 613             opc, getClass(), maskClass, short.class, length(),
 614             this, m,
 615             UN_IMPL.find(op, opc, ShortVector::unaryOperations));
 616     }
 617 
 618     private static final
 619     ImplCache<Unary, UnaryOperation<ShortVector, VectorMask<Short>>>
 620         UN_IMPL = new ImplCache<>(Unary.class, ShortVector.class);
 621 
 622     private static UnaryOperation<ShortVector, VectorMask<Short>> unaryOperations(int opc_) {
 623         switch (opc_) {
 624             case VECTOR_OP_NEG: return (v0, m) ->
 625                     v0.uOp(m, (i, a) -> (short) -a);
 626             case VECTOR_OP_ABS: return (v0, m) ->
 627                     v0.uOp(m, (i, a) -> (short) Math.abs(a));
 628             default: return null;
 629         }
 630     }
 631 
 632     // Binary lanewise support
 633 
 634     /**
 635      * {@inheritDoc} <!--workaround-->
 636      * @see #lanewise(VectorOperators.Binary,short)
 637      * @see #lanewise(VectorOperators.Binary,short,VectorMask)
 638      */
 639     @Override
 640     public abstract
 641     ShortVector lanewise(VectorOperators.Binary op,
 642                                   Vector<Short> v);
 643     @ForceInline
 644     final
 645     ShortVector lanewiseTemplate(VectorOperators.Binary op,
 646                                           Vector<Short> v) {
 647         ShortVector that = (ShortVector) v;
 648         that.check(this);
 649 
 650         if (opKind(op, VO_SPECIAL  | VO_SHIFT)) {
 651             if (op == FIRST_NONZERO) {
 652                 // FIXME: Support this in the JIT.
 653                 VectorMask<Short> thisNZ
 654                     = this.viewAsIntegralLanes().compare(NE, (short) 0);
 655                 that = that.blend((short) 0, thisNZ.cast(vspecies()));
 656                 op = OR_UNCHECKED;
 657             }
 658             if (opKind(op, VO_SHIFT)) {
 659                 // As per shift specification for Java, mask the shift count.
 660                 // This allows the JIT to ignore some ISA details.
 661                 that = that.lanewise(AND, SHIFT_MASK);
 662             }
 663             if (op == AND_NOT) {
 664                 // FIXME: Support this in the JIT.
 665                 that = that.lanewise(NOT);
 666                 op = AND;
 667             } else if (op == DIV) {
 668                 VectorMask<Short> eqz = that.eq((short) 0);
 669                 if (eqz.anyTrue()) {
 670                     throw that.divZeroException();
 671                 }
 672             }
 673         }
 674 
 675         int opc = opCode(op);
 676         return VectorSupport.binaryOp(
 677             opc, getClass(), null, short.class, length(),
 678             this, that, null,
 679             BIN_IMPL.find(op, opc, ShortVector::binaryOperations));































 680     }



 681 
 682     /**
 683      * {@inheritDoc} <!--workaround-->
 684      * @see #lanewise(VectorOperators.Binary,short,VectorMask)
 685      */
 686     @Override
 687     public abstract
 688     ShortVector lanewise(VectorOperators.Binary op,
 689                                   Vector<Short> v,
 690                                   VectorMask<Short> m);
 691     @ForceInline
 692     final
 693     ShortVector lanewiseTemplate(VectorOperators.Binary op,
 694                                           Class<? extends VectorMask<Short>> maskClass,
 695                                           Vector<Short> v, VectorMask<Short> m) {
 696         ShortVector that = (ShortVector) v;
 697         that.check(this);
 698         m.check(maskClass, this);
 699 
 700         if (opKind(op, VO_SPECIAL  | VO_SHIFT)) {
 701             if (op == FIRST_NONZERO) {
 702                 // FIXME: Support this in the JIT.
 703                 VectorMask<Short> thisNZ
 704                     = this.viewAsIntegralLanes().compare(NE, (short) 0);
 705                 that = that.blend((short) 0, thisNZ.cast(vspecies()));
 706                 op = OR_UNCHECKED;
 707             }
 708             if (opKind(op, VO_SHIFT)) {
 709                 // As per shift specification for Java, mask the shift count.
 710                 // This allows the JIT to ignore some ISA details.
 711                 that = that.lanewise(AND, SHIFT_MASK);
 712             }
 713             if (op == AND_NOT) {
 714                 // FIXME: Support this in the JIT.
 715                 that = that.lanewise(NOT);
 716                 op = AND;
 717             } else if (op == DIV) {
 718                 VectorMask<Short> eqz = that.eq((short)0);
 719                 if (eqz.and(m).anyTrue()) {
 720                     throw that.divZeroException();
 721                 }
 722                 // suppress div/0 exceptions in unset lanes
 723                 that = that.lanewise(NOT, eqz);
 724             }



 725         }
 726 
 727         int opc = opCode(op);
 728         return VectorSupport.binaryOp(
 729             opc, getClass(), maskClass, short.class, length(),
 730             this, that, m,
 731             BIN_IMPL.find(op, opc, ShortVector::binaryOperations));
 732     }
 733 
 734     private static final
 735     ImplCache<Binary, BinaryOperation<ShortVector, VectorMask<Short>>>
 736         BIN_IMPL = new ImplCache<>(Binary.class, ShortVector.class);
 737 
 738     private static BinaryOperation<ShortVector, VectorMask<Short>> binaryOperations(int opc_) {
 739         switch (opc_) {
 740             case VECTOR_OP_ADD: return (v0, v1, vm) ->
 741                     v0.bOp(v1, vm, (i, a, b) -> (short)(a + b));
 742             case VECTOR_OP_SUB: return (v0, v1, vm) ->
 743                     v0.bOp(v1, vm, (i, a, b) -> (short)(a - b));
 744             case VECTOR_OP_MUL: return (v0, v1, vm) ->
 745                     v0.bOp(v1, vm, (i, a, b) -> (short)(a * b));
 746             case VECTOR_OP_DIV: return (v0, v1, vm) ->
 747                     v0.bOp(v1, vm, (i, a, b) -> (short)(a / b));
 748             case VECTOR_OP_MAX: return (v0, v1, vm) ->
 749                     v0.bOp(v1, vm, (i, a, b) -> (short)Math.max(a, b));
 750             case VECTOR_OP_MIN: return (v0, v1, vm) ->
 751                     v0.bOp(v1, vm, (i, a, b) -> (short)Math.min(a, b));
 752             case VECTOR_OP_AND: return (v0, v1, vm) ->
 753                     v0.bOp(v1, vm, (i, a, b) -> (short)(a & b));
 754             case VECTOR_OP_OR: return (v0, v1, vm) ->
 755                     v0.bOp(v1, vm, (i, a, b) -> (short)(a | b));
 756             case VECTOR_OP_XOR: return (v0, v1, vm) ->
 757                     v0.bOp(v1, vm, (i, a, b) -> (short)(a ^ b));
 758             case VECTOR_OP_LSHIFT: return (v0, v1, vm) ->
 759                     v0.bOp(v1, vm, (i, a, n) -> (short)(a << n));
 760             case VECTOR_OP_RSHIFT: return (v0, v1, vm) ->
 761                     v0.bOp(v1, vm, (i, a, n) -> (short)(a >> n));
 762             case VECTOR_OP_URSHIFT: return (v0, v1, vm) ->
 763                     v0.bOp(v1, vm, (i, a, n) -> (short)((a & LSHR_SETUP_MASK) >>> n));
 764             case VECTOR_OP_LROTATE: return (v0, v1, vm) ->
 765                     v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n));
 766             case VECTOR_OP_RROTATE: return (v0, v1, vm) ->
 767                     v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n));
 768             default: return null;
 769         }
 770     }
 771 
 772     // FIXME: Maybe all of the public final methods in this file (the
 773     // simple ones that just call lanewise) should be pushed down to
 774     // the X-VectorBits template.  They can't optimize properly at
 775     // this level, and must rely on inlining.  Does it work?
 776     // (If it works, of course keep the code here.)
 777 
 778     /**
 779      * Combines the lane values of this vector
 780      * with the value of a broadcast scalar.
 781      *
 782      * This is a lane-wise binary operation which applies
 783      * the selected operation to each lane.
 784      * The return value will be equal to this expression:
 785      * {@code this.lanewise(op, this.broadcast(e))}.
 786      *
 787      * @param op the operation used to process lane values
 788      * @param e the input scalar
 789      * @return the result of applying the operation lane-wise
 790      *         to the two input vectors
 791      * @throws UnsupportedOperationException if this vector does

 814      * This is a masked lane-wise binary operation which applies
 815      * the selected operation to each lane.
 816      * The return value will be equal to this expression:
 817      * {@code this.lanewise(op, this.broadcast(e), m)}.
 818      *
 819      * @param op the operation used to process lane values
 820      * @param e the input scalar
 821      * @param m the mask controlling lane selection
 822      * @return the result of applying the operation lane-wise
 823      *         to the input vector and the scalar
 824      * @throws UnsupportedOperationException if this vector does
 825      *         not support the requested operation
 826      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
 827      * @see #lanewise(VectorOperators.Binary,short)
 828      */
 829     @ForceInline
 830     public final
 831     ShortVector lanewise(VectorOperators.Binary op,
 832                                   short e,
 833                                   VectorMask<Short> m) {
 834         if (opKind(op, VO_SHIFT) && (short)(int)e == e) {
 835             return lanewiseShift(op, (int) e, m);
 836         }
 837         if (op == AND_NOT) {
 838             op = AND; e = (short) ~e;
 839         }
 840         return lanewise(op, broadcast(e), m);
 841     }
 842 
 843     /**
 844      * {@inheritDoc} <!--workaround-->
 845      * @apiNote
 846      * When working with vector subtypes like {@code ShortVector},
 847      * {@linkplain #lanewise(VectorOperators.Binary,short)
 848      * the more strongly typed method}
 849      * is typically selected.  It can be explicitly selected
 850      * using a cast: {@code v.lanewise(op,(short)e)}.
 851      * The two expressions will produce numerically identical results.
 852      */
 853     @ForceInline
 854     public final
 855     ShortVector lanewise(VectorOperators.Binary op,
 856                                   long e) {
 857         short e1 = (short) e;
 858         if ((long)e1 != e
 859             // allow shift ops to clip down their int parameters
 860             && !(opKind(op, VO_SHIFT) && (int)e1 == e)) {

 861             vspecies().checkValue(e);  // for exception
 862         }
 863         return lanewise(op, e1);
 864     }
 865 
 866     /**
 867      * {@inheritDoc} <!--workaround-->
 868      * @apiNote
 869      * When working with vector subtypes like {@code ShortVector},
 870      * {@linkplain #lanewise(VectorOperators.Binary,short,VectorMask)
 871      * the more strongly typed method}
 872      * is typically selected.  It can be explicitly selected
 873      * using a cast: {@code v.lanewise(op,(short)e,m)}.
 874      * The two expressions will produce numerically identical results.
 875      */
 876     @ForceInline
 877     public final
 878     ShortVector lanewise(VectorOperators.Binary op,
 879                                   long e, VectorMask<Short> m) {
 880         short e1 = (short) e;
 881         if ((long)e1 != e
 882             // allow shift ops to clip down their int parameters
 883             && !(opKind(op, VO_SHIFT) && (int)e1 == e)) {
 884             vspecies().checkValue(e);  // for exception
 885         }
 886         return lanewise(op, e1, m);
 887     }
 888 
 889     /*package-private*/
 890     abstract ShortVector
 891     lanewiseShift(VectorOperators.Binary op, int e);
 892 
 893     /*package-private*/
 894     @ForceInline
 895     final ShortVector
 896     lanewiseShiftTemplate(VectorOperators.Binary op, int e) {
 897         // Special handling for these.  FIXME: Refactor?
 898         assert(opKind(op, VO_SHIFT));
 899         // As per shift specification for Java, mask the shift count.
 900         e &= SHIFT_MASK;
 901         int opc = opCode(op);
 902         return VectorSupport.broadcastInt(
 903             opc, getClass(), null, short.class, length(),
 904             this, e, null,
 905             BIN_INT_IMPL.find(op, opc, ShortVector::broadcastIntOperations));
 906     }
 907 
 908     /*package-private*/
 909     abstract ShortVector
 910     lanewiseShift(VectorOperators.Binary op, int e, VectorMask<Short> m);
 911 
 912     /*package-private*/
 913     @ForceInline
 914     final ShortVector
 915     lanewiseShiftTemplate(VectorOperators.Binary op,
 916                           Class<? extends VectorMask<Short>> maskClass,
 917                           int e, VectorMask<Short> m) {
 918         m.check(maskClass, this);
 919         assert(opKind(op, VO_SHIFT));
 920         // As per shift specification for Java, mask the shift count.
 921         e &= SHIFT_MASK;
 922         int opc = opCode(op);
 923         return VectorSupport.broadcastInt(
 924             opc, getClass(), maskClass, short.class, length(),
 925             this, e, m,
 926             BIN_INT_IMPL.find(op, opc, ShortVector::broadcastIntOperations));
 927     }
 928 
 929     private static final
 930     ImplCache<Binary,VectorBroadcastIntOp<ShortVector, VectorMask<Short>>> BIN_INT_IMPL
 931         = new ImplCache<>(Binary.class, ShortVector.class);
 932 
 933     private static VectorBroadcastIntOp<ShortVector, VectorMask<Short>> broadcastIntOperations(int opc_) {
 934         switch (opc_) {
 935             case VECTOR_OP_LSHIFT: return (v, n, m) ->
 936                     v.uOp(m, (i, a) -> (short)(a << n));
 937             case VECTOR_OP_RSHIFT: return (v, n, m) ->
 938                     v.uOp(m, (i, a) -> (short)(a >> n));
 939             case VECTOR_OP_URSHIFT: return (v, n, m) ->
 940                     v.uOp(m, (i, a) -> (short)((a & LSHR_SETUP_MASK) >>> n));
 941             case VECTOR_OP_LROTATE: return (v, n, m) ->
 942                     v.uOp(m, (i, a) -> rotateLeft(a, (int)n));
 943             case VECTOR_OP_RROTATE: return (v, n, m) ->
 944                     v.uOp(m, (i, a) -> rotateRight(a, (int)n));
 945             default: return null;
 946         }
 947     }
 948 
 949     // As per shift specification for Java, mask the shift count.
 950     // We mask 0X3F (long), 0X1F (int), 0x0F (short), 0x7 (byte).
 951     // The latter two maskings go beyond the JLS, but seem reasonable
 952     // since our lane types are first-class types, not just dressed
 953     // up ints.
 954     private static final int SHIFT_MASK = (Short.SIZE - 1);
 955     // Also simulate >>> on sub-word variables with a mask.
 956     private static final int LSHR_SETUP_MASK = ((1 << Short.SIZE) - 1);
 957 
 958     // Ternary lanewise support
 959 
 960     // Ternary operators come in eight variations:
 961     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2])
 962     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask)
 963 
 964     // It is annoying to support all of these variations of masking
 965     // and broadcast, but it would be more surprising not to continue
 966     // the obvious pattern started by unary and binary.
 967 
 968    /**

 981                                                   Vector<Short> v2);
 982     @ForceInline
 983     final
 984     ShortVector lanewiseTemplate(VectorOperators.Ternary op,
 985                                           Vector<Short> v1,
 986                                           Vector<Short> v2) {
 987         ShortVector that = (ShortVector) v1;
 988         ShortVector tother = (ShortVector) v2;
 989         // It's a word: https://www.dictionary.com/browse/tother
 990         // See also Chapter 11 of Dickens, Our Mutual Friend:
 991         // "Totherest Governor," replied Mr Riderhood...
 992         that.check(this);
 993         tother.check(this);
 994         if (op == BITWISE_BLEND) {
 995             // FIXME: Support this in the JIT.
 996             that = this.lanewise(XOR, that).lanewise(AND, tother);
 997             return this.lanewise(XOR, that);
 998         }
 999         int opc = opCode(op);
1000         return VectorSupport.ternaryOp(
1001             opc, getClass(), null, short.class, length(),
1002             this, that, tother, null,
1003             TERN_IMPL.find(op, opc, ShortVector::ternaryOperations));



1004     }



1005 
1006     /**
1007      * {@inheritDoc} <!--workaround-->
1008      * @see #lanewise(VectorOperators.Ternary,short,short,VectorMask)
1009      * @see #lanewise(VectorOperators.Ternary,Vector,short,VectorMask)
1010      * @see #lanewise(VectorOperators.Ternary,short,Vector,VectorMask)
1011      */
1012     @Override
1013     public abstract
1014     ShortVector lanewise(VectorOperators.Ternary op,
1015                                   Vector<Short> v1,
1016                                   Vector<Short> v2,
1017                                   VectorMask<Short> m);
1018     @ForceInline
1019     final
1020     ShortVector lanewiseTemplate(VectorOperators.Ternary op,
1021                                           Class<? extends VectorMask<Short>> maskClass,
1022                                           Vector<Short> v1,
1023                                           Vector<Short> v2,
1024                                           VectorMask<Short> m) {
1025         ShortVector that = (ShortVector) v1;
1026         ShortVector tother = (ShortVector) v2;
1027         // It's a word: https://www.dictionary.com/browse/tother
1028         // See also Chapter 11 of Dickens, Our Mutual Friend:
1029         // "Totherest Governor," replied Mr Riderhood...
1030         that.check(this);
1031         tother.check(this);
1032         m.check(maskClass, this);
1033 
1034         if (op == BITWISE_BLEND) {
1035             // FIXME: Support this in the JIT.
1036             that = this.lanewise(XOR, that).lanewise(AND, tother);
1037             return this.lanewise(XOR, that, m);
1038         }
1039         int opc = opCode(op);
1040         return VectorSupport.ternaryOp(
1041             opc, getClass(), maskClass, short.class, length(),
1042             this, that, tother, m,
1043             TERN_IMPL.find(op, opc, ShortVector::ternaryOperations));
1044     }
1045 
1046     private static final
1047     ImplCache<Ternary, TernaryOperation<ShortVector, VectorMask<Short>>>
1048         TERN_IMPL = new ImplCache<>(Ternary.class, ShortVector.class);
1049 
1050     private static TernaryOperation<ShortVector, VectorMask<Short>> ternaryOperations(int opc_) {
1051         switch (opc_) {
1052             default: return null;
1053         }
1054     }
1055 
1056     /**
1057      * Combines the lane values of this vector
1058      * with the values of two broadcast scalars.
1059      *
1060      * This is a lane-wise ternary operation which applies
1061      * the selected operation to each lane.
1062      * The return value will be equal to this expression:
1063      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}.
1064      *
1065      * @param op the operation used to combine lane values
1066      * @param e1 the first input scalar
1067      * @param e2 the second input scalar
1068      * @return the result of applying the operation lane-wise
1069      *         to the input vector and the scalars
1070      * @throws UnsupportedOperationException if this vector does
1071      *         not support the requested operation
1072      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1073      * @see #lanewise(VectorOperators.Ternary,short,short,VectorMask)

1090      * The return value will be equal to this expression:
1091      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}.
1092      *
1093      * @param op the operation used to combine lane values
1094      * @param e1 the first input scalar
1095      * @param e2 the second input scalar
1096      * @param m the mask controlling lane selection
1097      * @return the result of applying the operation lane-wise
1098      *         to the input vector and the scalars
1099      * @throws UnsupportedOperationException if this vector does
1100      *         not support the requested operation
1101      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
1102      * @see #lanewise(VectorOperators.Ternary,short,short)
1103      */
1104     @ForceInline
1105     public final
1106     ShortVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m)
1107                                   short e1,
1108                                   short e2,
1109                                   VectorMask<Short> m) {
1110         return lanewise(op, broadcast(e1), broadcast(e2), m);
1111     }
1112 
1113     /**
1114      * Combines the lane values of this vector
1115      * with the values of another vector and a broadcast scalar.
1116      *
1117      * This is a lane-wise ternary operation which applies
1118      * the selected operation to each lane.
1119      * The return value will be equal to this expression:
1120      * {@code this.lanewise(op, v1, this.broadcast(e2))}.
1121      *
1122      * @param op the operation used to combine lane values
1123      * @param v1 the other input vector
1124      * @param e2 the input scalar
1125      * @return the result of applying the operation lane-wise
1126      *         to the input vectors and the scalar
1127      * @throws UnsupportedOperationException if this vector does
1128      *         not support the requested operation
1129      * @see #lanewise(VectorOperators.Ternary,short,short)
1130      * @see #lanewise(VectorOperators.Ternary,Vector,short,VectorMask)

1148      * {@code this.lanewise(op, v1, this.broadcast(e2), m)}.
1149      *
1150      * @param op the operation used to combine lane values
1151      * @param v1 the other input vector
1152      * @param e2 the input scalar
1153      * @param m the mask controlling lane selection
1154      * @return the result of applying the operation lane-wise
1155      *         to the input vectors and the scalar
1156      * @throws UnsupportedOperationException if this vector does
1157      *         not support the requested operation
1158      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1159      * @see #lanewise(VectorOperators.Ternary,short,short,VectorMask)
1160      * @see #lanewise(VectorOperators.Ternary,Vector,short)
1161      */
1162     @ForceInline
1163     public final
1164     ShortVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m)
1165                                   Vector<Short> v1,
1166                                   short e2,
1167                                   VectorMask<Short> m) {
1168         return lanewise(op, v1, broadcast(e2), m);
1169     }
1170 
1171     /**
1172      * Combines the lane values of this vector
1173      * with the values of another vector and a broadcast scalar.
1174      *
1175      * This is a lane-wise ternary operation which applies
1176      * the selected operation to each lane.
1177      * The return value will be equal to this expression:
1178      * {@code this.lanewise(op, this.broadcast(e1), v2)}.
1179      *
1180      * @param op the operation used to combine lane values
1181      * @param e1 the input scalar
1182      * @param v2 the other input vector
1183      * @return the result of applying the operation lane-wise
1184      *         to the input vectors and the scalar
1185      * @throws UnsupportedOperationException if this vector does
1186      *         not support the requested operation
1187      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1188      * @see #lanewise(VectorOperators.Ternary,short,Vector,VectorMask)

1205      * The return value will be equal to this expression:
1206      * {@code this.lanewise(op, this.broadcast(e1), v2, m)}.
1207      *
1208      * @param op the operation used to combine lane values
1209      * @param e1 the input scalar
1210      * @param v2 the other input vector
1211      * @param m the mask controlling lane selection
1212      * @return the result of applying the operation lane-wise
1213      *         to the input vectors and the scalar
1214      * @throws UnsupportedOperationException if this vector does
1215      *         not support the requested operation
1216      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
1217      * @see #lanewise(VectorOperators.Ternary,short,Vector)
1218      */
1219     @ForceInline
1220     public final
1221     ShortVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m)
1222                                   short e1,
1223                                   Vector<Short> v2,
1224                                   VectorMask<Short> m) {
1225         return lanewise(op, broadcast(e1), v2, m);
1226     }
1227 
1228     // (Thus endeth the Great and Mighty Ternary Ogdoad.)
1229     // https://en.wikipedia.org/wiki/Ogdoad
1230 
1231     /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV
1232     //
1233     // These include masked and non-masked versions.
1234     // This subclass adds broadcast (masked or not).
1235 
1236     /**
1237      * {@inheritDoc} <!--workaround-->
1238      * @see #add(short)
1239      */
1240     @Override
1241     @ForceInline
1242     public final ShortVector add(Vector<Short> v) {
1243         return lanewise(ADD, v);
1244     }
1245 

1877     @Override
1878     @ForceInline
1879     public final
1880     VectorMask<Short> test(VectorOperators.Test op,
1881                                   VectorMask<Short> m) {
1882         return test(op).and(m);
1883     }
1884 
1885     /**
1886      * {@inheritDoc} <!--workaround-->
1887      */
1888     @Override
1889     public abstract
1890     VectorMask<Short> compare(VectorOperators.Comparison op, Vector<Short> v);
1891 
1892     /*package-private*/
1893     @ForceInline
1894     final
1895     <M extends VectorMask<Short>>
1896     M compareTemplate(Class<M> maskType, Comparison op, Vector<Short> v) {


1897         ShortVector that = (ShortVector) v;
1898         that.check(this);
1899         int opc = opCode(op);
1900         return VectorSupport.compare(
1901             opc, getClass(), maskType, short.class, length(),
1902             this, that, null,
1903             (cond, v0, v1, m1) -> {
1904                 AbstractMask<Short> m
1905                     = v0.bTest(cond, v1, (cond_, i, a, b)
1906                                -> compareWithOp(cond, a, b));
1907                 @SuppressWarnings("unchecked")
1908                 M m2 = (M) m;
1909                 return m2;
1910             });
1911     }
1912 
1913     /*package-private*/
1914     @ForceInline
1915     final
1916     <M extends VectorMask<Short>>
1917     M compareTemplate(Class<M> maskType, Comparison op, Vector<Short> v, M m) {
1918         ShortVector that = (ShortVector) v;
1919         that.check(this);
1920         m.check(maskType, this);
1921         int opc = opCode(op);
1922         return VectorSupport.compare(
1923             opc, getClass(), maskType, short.class, length(),
1924             this, that, m,
1925             (cond, v0, v1, m1) -> {
1926                 AbstractMask<Short> cmpM
1927                     = v0.bTest(cond, v1, (cond_, i, a, b)
1928                                -> compareWithOp(cond, a, b));
1929                 @SuppressWarnings("unchecked")
1930                 M m2 = (M) cmpM.and(m1);
1931                 return m2;
1932             });
1933     }
1934 
1935     @ForceInline
1936     private static boolean compareWithOp(int cond, short a, short b) {
1937         return switch (cond) {
1938             case BT_eq -> a == b;
1939             case BT_ne -> a != b;
1940             case BT_lt -> a < b;
1941             case BT_le -> a <= b;
1942             case BT_gt -> a > b;
1943             case BT_ge -> a >= b;
1944             case BT_ult -> Short.compareUnsigned(a, b) < 0;
1945             case BT_ule -> Short.compareUnsigned(a, b) <= 0;
1946             case BT_ugt -> Short.compareUnsigned(a, b) > 0;
1947             case BT_uge -> Short.compareUnsigned(a, b) >= 0;
1948             default -> throw new AssertionError();
1949         };
1950     }
1951 












1952     /**
1953      * Tests this vector by comparing it with an input scalar,
1954      * according to the given comparison operation.
1955      *
1956      * This is a lane-wise binary test operation which applies
1957      * the comparison operation to each lane.
1958      * <p>
1959      * The result is the same as
1960      * {@code compare(op, broadcast(species(), e))}.
1961      * That is, the scalar may be regarded as broadcast to
1962      * a vector of the same species, and then compared
1963      * against the original vector, using the selected
1964      * comparison operation.
1965      *
1966      * @param op the operation used to compare lane values
1967      * @param e the input scalar
1968      * @return the mask result of testing lane-wise if this vector
1969      *         compares to the input, according to the selected
1970      *         comparison operator
1971      * @see ShortVector#compare(VectorOperators.Comparison,Vector)

1990      *
1991      * This is a masked lane-wise binary test operation which applies
1992      * to each pair of corresponding lane values.
1993      *
1994      * The returned result is equal to the expression
1995      * {@code compare(op,s).and(m)}.
1996      *
1997      * @param op the operation used to compare lane values
1998      * @param e the input scalar
1999      * @param m the mask controlling lane selection
2000      * @return the mask result of testing lane-wise if this vector
2001      *         compares to the input, according to the selected
2002      *         comparison operator,
2003      *         and only in the lanes selected by the mask
2004      * @see ShortVector#compare(VectorOperators.Comparison,Vector,VectorMask)
2005      */
2006     @ForceInline
2007     public final VectorMask<Short> compare(VectorOperators.Comparison op,
2008                                                short e,
2009                                                VectorMask<Short> m) {
2010         return compare(op, broadcast(e), m);
2011     }
2012 
2013     /**
2014      * {@inheritDoc} <!--workaround-->
2015      */
2016     @Override
2017     public abstract
2018     VectorMask<Short> compare(Comparison op, long e);
2019 
2020     /*package-private*/
2021     @ForceInline
2022     final
2023     <M extends VectorMask<Short>>
2024     M compareTemplate(Class<M> maskType, Comparison op, long e) {
2025         return compareTemplate(maskType, op, broadcast(e));
2026     }
2027 
2028     /**
2029      * {@inheritDoc} <!--workaround-->
2030      */

2241     wrongPartForSlice(int part) {
2242         String msg = String.format("bad part number %d for slice operation",
2243                                    part);
2244         return new ArrayIndexOutOfBoundsException(msg);
2245     }
2246 
2247     /**
2248      * {@inheritDoc} <!--workaround-->
2249      */
2250     @Override
2251     public abstract
2252     ShortVector rearrange(VectorShuffle<Short> m);
2253 
2254     /*package-private*/
2255     @ForceInline
2256     final
2257     <S extends VectorShuffle<Short>>
2258     ShortVector rearrangeTemplate(Class<S> shuffletype, S shuffle) {
2259         shuffle.checkIndexes();
2260         return VectorSupport.rearrangeOp(
2261             getClass(), shuffletype, null, short.class, length(),
2262             this, shuffle, null,
2263             (v1, s_, m_) -> v1.uOp((i, a) -> {
2264                 int ei = s_.laneSource(i);
2265                 return v1.lane(ei);
2266             }));
2267     }
2268 
2269     /**
2270      * {@inheritDoc} <!--workaround-->
2271      */
2272     @Override
2273     public abstract
2274     ShortVector rearrange(VectorShuffle<Short> s,
2275                                    VectorMask<Short> m);
2276 
2277     /*package-private*/
2278     @ForceInline
2279     final
2280     <S extends VectorShuffle<Short>, M extends VectorMask<Short>>
2281     ShortVector rearrangeTemplate(Class<S> shuffletype,
2282                                            Class<M> masktype,
2283                                            S shuffle,
2284                                            M m) {
2285 
2286         m.check(masktype, this);






2287         VectorMask<Short> valid = shuffle.laneIsValid();
2288         if (m.andNot(valid).anyTrue()) {
2289             shuffle.checkIndexes();
2290             throw new AssertionError();
2291         }
2292         return VectorSupport.rearrangeOp(
2293                    getClass(), shuffletype, masktype, short.class, length(),
2294                    this, shuffle, m,
2295                    (v1, s_, m_) -> v1.uOp((i, a) -> {
2296                         int ei = s_.laneSource(i);
2297                         return ei < 0  || !m_.laneIsSet(i) ? 0 : v1.lane(ei);
2298                    }));
2299     }
2300 
2301     /**
2302      * {@inheritDoc} <!--workaround-->
2303      */
2304     @Override
2305     public abstract
2306     ShortVector rearrange(VectorShuffle<Short> s,
2307                                    Vector<Short> v);
2308 
2309     /*package-private*/
2310     @ForceInline
2311     final
2312     <S extends VectorShuffle<Short>>
2313     ShortVector rearrangeTemplate(Class<S> shuffletype,
2314                                            S shuffle,
2315                                            ShortVector v) {
2316         VectorMask<Short> valid = shuffle.laneIsValid();
2317         @SuppressWarnings("unchecked")
2318         S ws = (S) shuffle.wrapIndexes();
2319         ShortVector r0 =
2320             VectorSupport.rearrangeOp(
2321                 getClass(), shuffletype, null, short.class, length(),
2322                 this, ws, null,
2323                 (v0, s_, m_) -> v0.uOp((i, a) -> {
2324                     int ei = s_.laneSource(i);
2325                     return v0.lane(ei);
2326                 }));
2327         ShortVector r1 =
2328             VectorSupport.rearrangeOp(
2329                 getClass(), shuffletype, null, short.class, length(),
2330                 v, ws, null,
2331                 (v1, s_, m_) -> v1.uOp((i, a) -> {
2332                     int ei = s_.laneSource(i);
2333                     return v1.lane(ei);
2334                 }));
2335         return r1.blend(r0, valid);
2336     }
2337 
2338     @ForceInline
2339     private final
2340     VectorShuffle<Short> toShuffle0(ShortSpecies dsp) {
2341         short[] a = toArray();
2342         int[] sa = new int[a.length];
2343         for (int i = 0; i < a.length; i++) {
2344             sa[i] = (int) a[i];
2345         }
2346         return VectorShuffle.fromArray(dsp, sa, 0);
2347     }
2348 
2349     /*package-private*/
2350     @ForceInline
2351     final

2574      * <li>
2575      * All other reduction operations are fully commutative and
2576      * associative.  The implementation can choose any order of
2577      * processing, yet it will always produce the same result.
2578      * </ul>
2579      *
2580      * @param op the operation used to combine lane values
2581      * @param m the mask controlling lane selection
2582      * @return the reduced result accumulated from the selected lane values
2583      * @throws UnsupportedOperationException if this vector does
2584      *         not support the requested operation
2585      * @see #reduceLanes(VectorOperators.Associative)
2586      */
2587     public abstract short reduceLanes(VectorOperators.Associative op,
2588                                        VectorMask<Short> m);
2589 
2590     /*package-private*/
2591     @ForceInline
2592     final
2593     short reduceLanesTemplate(VectorOperators.Associative op,
2594                                Class<? extends VectorMask<Short>> maskClass,
2595                                VectorMask<Short> m) {
2596         m.check(maskClass, this);
2597         if (op == FIRST_NONZERO) {
2598             ShortVector v = reduceIdentityVector(op).blend(this, m);
2599             return v.reduceLanesTemplate(op);
2600         }
2601         int opc = opCode(op);
2602         return fromBits(VectorSupport.reductionCoerced(
2603             opc, getClass(), maskClass, short.class, length(),
2604             this, m,
2605             REDUCE_IMPL.find(op, opc, ShortVector::reductionOperations)));
2606     }
2607 
2608     /*package-private*/
2609     @ForceInline
2610     final
2611     short reduceLanesTemplate(VectorOperators.Associative op) {
2612         if (op == FIRST_NONZERO) {
2613             // FIXME:  The JIT should handle this, and other scan ops alos.
2614             VectorMask<Short> thisNZ
2615                 = this.viewAsIntegralLanes().compare(NE, (short) 0);
2616             return this.lane(thisNZ.firstTrue());
2617         }
2618         int opc = opCode(op);
2619         return fromBits(VectorSupport.reductionCoerced(
2620             opc, getClass(), null, short.class, length(),
2621             this, null,
2622             REDUCE_IMPL.find(op, opc, ShortVector::reductionOperations)));

















2623     }
2624 
2625     private static final
2626     ImplCache<Associative, ReductionOperation<ShortVector, VectorMask<Short>>>
2627         REDUCE_IMPL = new ImplCache<>(Associative.class, ShortVector.class);
2628 
2629     private static ReductionOperation<ShortVector, VectorMask<Short>> reductionOperations(int opc_) {
2630         switch (opc_) {
2631             case VECTOR_OP_ADD: return (v, m) ->
2632                     toBits(v.rOp((short)0, m, (i, a, b) -> (short)(a + b)));
2633             case VECTOR_OP_MUL: return (v, m) ->
2634                     toBits(v.rOp((short)1, m, (i, a, b) -> (short)(a * b)));
2635             case VECTOR_OP_MIN: return (v, m) ->
2636                     toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (short) Math.min(a, b)));
2637             case VECTOR_OP_MAX: return (v, m) ->
2638                     toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (short) Math.max(a, b)));
2639             case VECTOR_OP_AND: return (v, m) ->
2640                     toBits(v.rOp((short)-1, m, (i, a, b) -> (short)(a & b)));
2641             case VECTOR_OP_OR: return (v, m) ->
2642                     toBits(v.rOp((short)0, m, (i, a, b) -> (short)(a | b)));
2643             case VECTOR_OP_XOR: return (v, m) ->
2644                     toBits(v.rOp((short)0, m, (i, a, b) -> (short)(a ^ b)));
2645             default: return null;
2646         }
2647     }
2648 
2649     private
2650     @ForceInline
2651     ShortVector reduceIdentityVector(VectorOperators.Associative op) {
2652         int opc = opCode(op);
2653         UnaryOperator<ShortVector> fn
2654             = REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
2655                 switch (opc_) {
2656                 case VECTOR_OP_ADD:
2657                 case VECTOR_OP_OR:
2658                 case VECTOR_OP_XOR:
2659                     return v -> v.broadcast(0);
2660                 case VECTOR_OP_MUL:
2661                     return v -> v.broadcast(1);
2662                 case VECTOR_OP_AND:
2663                     return v -> v.broadcast(-1);
2664                 case VECTOR_OP_MIN:
2665                     return v -> v.broadcast(MAX_OR_INF);
2666                 case VECTOR_OP_MAX:
2667                     return v -> v.broadcast(MIN_OR_INF);

2853      * @param species species of desired vector
2854      * @param a the byte array
2855      * @param offset the offset into the array
2856      * @param bo the intended byte order
2857      * @param m the mask controlling lane selection
2858      * @return a vector loaded from a byte array
2859      * @throws IndexOutOfBoundsException
2860      *         if {@code offset+N*ESIZE < 0}
2861      *         or {@code offset+(N+1)*ESIZE > a.length}
2862      *         for any lane {@code N} in the vector
2863      *         where the mask is set
2864      */
2865     @ForceInline
2866     public static
2867     ShortVector fromByteArray(VectorSpecies<Short> species,
2868                                        byte[] a, int offset,
2869                                        ByteOrder bo,
2870                                        VectorMask<Short> m) {
2871         ShortSpecies vsp = (ShortSpecies) species;
2872         if (offset >= 0 && offset <= (a.length - species.vectorByteSize())) {
2873             return vsp.dummyVector().fromByteArray0(a, offset, m).maybeSwap(bo);


2874         }
2875 
2876         // FIXME: optimize
2877         checkMaskFromIndexSize(offset, vsp, m, 2, a.length);
2878         ByteBuffer wb = wrapper(a, bo);
2879         return vsp.ldOp(wb, offset, (AbstractMask<Short>)m,
2880                    (wb_, o, i)  -> wb_.getShort(o + i * 2));
2881     }
2882 
2883     /**
2884      * Loads a vector from an array of type {@code short[]}
2885      * starting at an offset.
2886      * For each vector lane, where {@code N} is the vector lane index, the
2887      * array element at index {@code offset + N} is placed into the
2888      * resulting vector at lane index {@code N}.
2889      *
2890      * @param species species of desired vector
2891      * @param a the array
2892      * @param offset the offset into the array
2893      * @return the vector loaded from an array

2915      * {@code N}, otherwise the default element value is placed into the
2916      * resulting vector at lane index {@code N}.
2917      *
2918      * @param species species of desired vector
2919      * @param a the array
2920      * @param offset the offset into the array
2921      * @param m the mask controlling lane selection
2922      * @return the vector loaded from an array
2923      * @throws IndexOutOfBoundsException
2924      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2925      *         for any lane {@code N} in the vector
2926      *         where the mask is set
2927      */
2928     @ForceInline
2929     public static
2930     ShortVector fromArray(VectorSpecies<Short> species,
2931                                    short[] a, int offset,
2932                                    VectorMask<Short> m) {
2933         ShortSpecies vsp = (ShortSpecies) species;
2934         if (offset >= 0 && offset <= (a.length - species.length())) {
2935             return vsp.dummyVector().fromArray0(a, offset, m);

2936         }
2937 
2938         // FIXME: optimize
2939         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2940         return vsp.vOp(m, i -> a[offset + i]);
2941     }
2942 
2943     /**
2944      * Gathers a new vector composed of elements from an array of type
2945      * {@code short[]},
2946      * using indexes obtained by adding a fixed {@code offset} to a
2947      * series of secondary offsets from an <em>index map</em>.
2948      * The index map is a contiguous sequence of {@code VLENGTH}
2949      * elements in a second array of {@code int}s, starting at a given
2950      * {@code mapOffset}.
2951      * <p>
2952      * For each vector lane, where {@code N} is the vector lane index,
2953      * the lane is loaded from the array
2954      * element {@code a[f(N)]}, where {@code f(N)} is the
2955      * index mapping expression

3064      * {@code N}, otherwise the default element value is placed into the
3065      * resulting vector at lane index {@code N}.
3066      *
3067      * @param species species of desired vector
3068      * @param a the array
3069      * @param offset the offset into the array
3070      * @param m the mask controlling lane selection
3071      * @return the vector loaded from an array
3072      * @throws IndexOutOfBoundsException
3073      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3074      *         for any lane {@code N} in the vector
3075      *         where the mask is set
3076      */
3077     @ForceInline
3078     public static
3079     ShortVector fromCharArray(VectorSpecies<Short> species,
3080                                        char[] a, int offset,
3081                                        VectorMask<Short> m) {
3082         ShortSpecies vsp = (ShortSpecies) species;
3083         if (offset >= 0 && offset <= (a.length - species.length())) {
3084             return vsp.dummyVector().fromCharArray0(a, offset, m);

3085         }
3086 
3087         // FIXME: optimize
3088         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3089         return vsp.vOp(m, i -> (short) a[offset + i]);
3090     }
3091 
3092     /**
3093      * Gathers a new vector composed of elements from an array of type
3094      * {@code char[]},
3095      * using indexes obtained by adding a fixed {@code offset} to a
3096      * series of secondary offsets from an <em>index map</em>.
3097      * The index map is a contiguous sequence of {@code VLENGTH}
3098      * elements in a second array of {@code int}s, starting at a given
3099      * {@code mapOffset}.
3100      * <p>
3101      * For each vector lane, where {@code N} is the vector lane index,
3102      * the lane is loaded from the expression
3103      * {@code (short) a[f(N)]}, where {@code f(N)} is the
3104      * index mapping expression

3249      * @param species species of desired vector
3250      * @param bb the byte buffer
3251      * @param offset the offset into the byte buffer
3252      * @param bo the intended byte order
3253      * @param m the mask controlling lane selection
3254      * @return a vector loaded from a byte buffer
3255      * @throws IndexOutOfBoundsException
3256      *         if {@code offset+N*2 < 0}
3257      *         or {@code offset+N*2 >= bb.limit()}
3258      *         for any lane {@code N} in the vector
3259      *         where the mask is set
3260      */
3261     @ForceInline
3262     public static
3263     ShortVector fromByteBuffer(VectorSpecies<Short> species,
3264                                         ByteBuffer bb, int offset,
3265                                         ByteOrder bo,
3266                                         VectorMask<Short> m) {
3267         ShortSpecies vsp = (ShortSpecies) species;
3268         if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) {
3269             return vsp.dummyVector().fromByteBuffer0(bb, offset, m).maybeSwap(bo);


3270         }
3271 
3272         // FIXME: optimize
3273         checkMaskFromIndexSize(offset, vsp, m, 2, bb.limit());
3274         ByteBuffer wb = wrapper(bb, bo);
3275         return vsp.ldOp(wb, offset, (AbstractMask<Short>)m,
3276                    (wb_, o, i)  -> wb_.getShort(o + i * 2));
3277     }
3278 
3279     // Memory store operations
3280 
3281     /**
3282      * Stores this vector into an array of type {@code short[]}
3283      * starting at an offset.
3284      * <p>
3285      * For each vector lane, where {@code N} is the vector lane index,
3286      * the lane element at index {@code N} is stored into the array
3287      * element {@code a[offset+N]}.
3288      *
3289      * @param a the array, of type {@code short[]}

3321      * Lanes where the mask is unset are not stored and do not need
3322      * to correspond to legitimate elements of {@code a}.
3323      * That is, unset lanes may correspond to array indexes less than
3324      * zero or beyond the end of the array.
3325      *
3326      * @param a the array, of type {@code short[]}
3327      * @param offset the offset into the array
3328      * @param m the mask controlling lane storage
3329      * @throws IndexOutOfBoundsException
3330      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3331      *         for any lane {@code N} in the vector
3332      *         where the mask is set
3333      */
3334     @ForceInline
3335     public final
3336     void intoArray(short[] a, int offset,
3337                    VectorMask<Short> m) {
3338         if (m.allTrue()) {
3339             intoArray(a, offset);
3340         } else {

3341             ShortSpecies vsp = vspecies();
3342             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3343             intoArray0(a, offset, m);
3344         }
3345     }
3346 
3347     /**
3348      * Scatters this vector into an array of type {@code short[]}
3349      * using indexes obtained by adding a fixed {@code offset} to a
3350      * series of secondary offsets from an <em>index map</em>.
3351      * The index map is a contiguous sequence of {@code VLENGTH}
3352      * elements in a second array of {@code int}s, starting at a given
3353      * {@code mapOffset}.
3354      * <p>
3355      * For each vector lane, where {@code N} is the vector lane index,
3356      * the lane element at index {@code N} is stored into the array
3357      * element {@code a[f(N)]}, where {@code f(N)} is the
3358      * index mapping expression
3359      * {@code offset + indexMap[mapOffset + N]]}.
3360      *
3361      * @param a the array
3362      * @param offset an offset to combine with the index map offsets
3363      * @param indexMap the index map

3468      * Lanes where the mask is unset are not stored and do not need
3469      * to correspond to legitimate elements of {@code a}.
3470      * That is, unset lanes may correspond to array indexes less than
3471      * zero or beyond the end of the array.
3472      *
3473      * @param a the array, of type {@code char[]}
3474      * @param offset the offset into the array
3475      * @param m the mask controlling lane storage
3476      * @throws IndexOutOfBoundsException
3477      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3478      *         for any lane {@code N} in the vector
3479      *         where the mask is set
3480      */
3481     @ForceInline
3482     public final
3483     void intoCharArray(char[] a, int offset,
3484                        VectorMask<Short> m) {
3485         if (m.allTrue()) {
3486             intoCharArray(a, offset);
3487         } else {

3488             ShortSpecies vsp = vspecies();
3489             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3490             intoCharArray0(a, offset, m);
3491         }
3492     }
3493 
3494     /**
3495      * Scatters this vector into an array of type {@code char[]}
3496      * using indexes obtained by adding a fixed {@code offset} to a
3497      * series of secondary offsets from an <em>index map</em>.
3498      * The index map is a contiguous sequence of {@code VLENGTH}
3499      * elements in a second array of {@code int}s, starting at a given
3500      * {@code mapOffset}.
3501      * <p>
3502      * For each vector lane, where {@code N} is the vector lane index,
3503      * the lane element at index {@code N}
3504      * is first cast to a {@code char} value and then
3505      * stored into the array
3506      * element {@code a[f(N)]}, where {@code f(N)} is the
3507      * index mapping expression
3508      * {@code offset + indexMap[mapOffset + N]]}.
3509      *
3510      * @param a the array

3584     @ForceInline
3585     public final
3586     void intoByteArray(byte[] a, int offset,
3587                        ByteOrder bo) {
3588         offset = checkFromIndexSize(offset, byteSize(), a.length);
3589         maybeSwap(bo).intoByteArray0(a, offset);
3590     }
3591 
3592     /**
3593      * {@inheritDoc} <!--workaround-->
3594      */
3595     @Override
3596     @ForceInline
3597     public final
3598     void intoByteArray(byte[] a, int offset,
3599                        ByteOrder bo,
3600                        VectorMask<Short> m) {
3601         if (m.allTrue()) {
3602             intoByteArray(a, offset, bo);
3603         } else {

3604             ShortSpecies vsp = vspecies();
3605             checkMaskFromIndexSize(offset, vsp, m, 2, a.length);
3606             maybeSwap(bo).intoByteArray0(a, offset, m);


3607         }
3608     }
3609 
3610     /**
3611      * {@inheritDoc} <!--workaround-->
3612      */
3613     @Override
3614     @ForceInline
3615     public final
3616     void intoByteBuffer(ByteBuffer bb, int offset,
3617                         ByteOrder bo) {
3618         if (ScopedMemoryAccess.isReadOnly(bb)) {
3619             throw new ReadOnlyBufferException();
3620         }
3621         offset = checkFromIndexSize(offset, byteSize(), bb.limit());
3622         maybeSwap(bo).intoByteBuffer0(bb, offset);
3623     }
3624 
3625     /**
3626      * {@inheritDoc} <!--workaround-->
3627      */
3628     @Override
3629     @ForceInline
3630     public final
3631     void intoByteBuffer(ByteBuffer bb, int offset,
3632                         ByteOrder bo,
3633                         VectorMask<Short> m) {
3634         if (m.allTrue()) {
3635             intoByteBuffer(bb, offset, bo);
3636         } else {

3637             if (bb.isReadOnly()) {
3638                 throw new ReadOnlyBufferException();
3639             }
3640             ShortSpecies vsp = vspecies();
3641             checkMaskFromIndexSize(offset, vsp, m, 2, bb.limit());
3642             maybeSwap(bo).intoByteBuffer0(bb, offset, m);


3643         }
3644     }
3645 
3646     // ================================================
3647 
3648     // Low-level memory operations.
3649     //
3650     // Note that all of these operations *must* inline into a context
3651     // where the exact species of the involved vector is a
3652     // compile-time constant.  Otherwise, the intrinsic generation
3653     // will fail and performance will suffer.
3654     //
3655     // In many cases this is achieved by re-deriving a version of the
3656     // method in each concrete subclass (per species).  The re-derived
3657     // method simply calls one of these generic methods, with exact
3658     // parameters for the controlling metadata, which is either a
3659     // typed vector or constant species instance.
3660 
3661     // Unchecked loading operations in native byte order.
3662     // Caller is responsible for applying index checks, masking, and
3663     // byte swapping.
3664 
3665     /*package-private*/
3666     abstract
3667     ShortVector fromArray0(short[] a, int offset);
3668     @ForceInline
3669     final
3670     ShortVector fromArray0Template(short[] a, int offset) {
3671         ShortSpecies vsp = vspecies();
3672         return VectorSupport.load(
3673             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3674             a, arrayAddress(a, offset),
3675             a, offset, vsp,
3676             (arr, off, s) -> s.ldOp(arr, off,
3677                                     (arr_, off_, i) -> arr_[off_ + i]));
3678     }
3679 
3680     /*package-private*/
3681     abstract
3682     ShortVector fromArray0(short[] a, int offset, VectorMask<Short> m);
3683     @ForceInline
3684     final
3685     <M extends VectorMask<Short>>
3686     ShortVector fromArray0Template(Class<M> maskClass, short[] a, int offset, M m) {
3687         m.check(species());
3688         ShortSpecies vsp = vspecies();
3689         return VectorSupport.loadMasked(
3690             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3691             a, arrayAddress(a, offset), m,
3692             a, offset, vsp,
3693             (arr, off, s, vm) -> s.ldOp(arr, off, vm,
3694                                         (arr_, off_, i) -> arr_[off_ + i]));
3695     }
3696 
3697 
3698     /*package-private*/
3699     abstract
3700     ShortVector fromCharArray0(char[] a, int offset);
3701     @ForceInline
3702     final
3703     ShortVector fromCharArray0Template(char[] a, int offset) {
3704         ShortSpecies vsp = vspecies();
3705         return VectorSupport.load(
3706             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3707             a, charArrayAddress(a, offset),
3708             a, offset, vsp,
3709             (arr, off, s) -> s.ldOp(arr, off,
3710                                     (arr_, off_, i) -> (short) arr_[off_ + i]));
3711     }
3712 
3713     /*package-private*/
3714     abstract
3715     ShortVector fromCharArray0(char[] a, int offset, VectorMask<Short> m);
3716     @ForceInline
3717     final
3718     <M extends VectorMask<Short>>
3719     ShortVector fromCharArray0Template(Class<M> maskClass, char[] a, int offset, M m) {
3720         m.check(species());
3721         ShortSpecies vsp = vspecies();
3722         return VectorSupport.loadMasked(
3723                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3724                 a, charArrayAddress(a, offset), m,
3725                 a, offset, vsp,
3726                 (arr, off, s, vm) -> s.ldOp(arr, off, vm,
3727                                             (arr_, off_, i) -> (short) arr_[off_ + i]));
3728     }
3729 
3730 
3731     @Override
3732     abstract
3733     ShortVector fromByteArray0(byte[] a, int offset);
3734     @ForceInline
3735     final
3736     ShortVector fromByteArray0Template(byte[] a, int offset) {
3737         ShortSpecies vsp = vspecies();
3738         return VectorSupport.load(
3739             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3740             a, byteArrayAddress(a, offset),
3741             a, offset, vsp,
3742             (arr, off, s) -> {
3743                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3744                 return s.ldOp(wb, off,
3745                         (wb_, o, i) -> wb_.getShort(o + i * 2));
3746             });
3747     }
3748 
3749     abstract
3750     ShortVector fromByteArray0(byte[] a, int offset, VectorMask<Short> m);
3751     @ForceInline
3752     final
3753     <M extends VectorMask<Short>>
3754     ShortVector fromByteArray0Template(Class<M> maskClass, byte[] a, int offset, M m) {
3755         ShortSpecies vsp = vspecies();
3756         m.check(vsp);
3757         return VectorSupport.loadMasked(
3758             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3759             a, byteArrayAddress(a, offset), m,
3760             a, offset, vsp,
3761             (arr, off, s, vm) -> {
3762                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3763                 return s.ldOp(wb, off, vm,
3764                         (wb_, o, i) -> wb_.getShort(o + i * 2));
3765             });
3766     }
3767 
3768     abstract
3769     ShortVector fromByteBuffer0(ByteBuffer bb, int offset);
3770     @ForceInline
3771     final
3772     ShortVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
3773         ShortSpecies vsp = vspecies();
3774         return ScopedMemoryAccess.loadFromByteBuffer(
3775                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3776                 bb, offset, vsp,
3777                 (buf, off, s) -> {
3778                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3779                     return s.ldOp(wb, off,
3780                             (wb_, o, i) -> wb_.getShort(o + i * 2));
3781                 });
3782     }
3783 
3784     abstract
3785     ShortVector fromByteBuffer0(ByteBuffer bb, int offset, VectorMask<Short> m);
3786     @ForceInline
3787     final
3788     <M extends VectorMask<Short>>
3789     ShortVector fromByteBuffer0Template(Class<M> maskClass, ByteBuffer bb, int offset, M m) {
3790         ShortSpecies vsp = vspecies();
3791         m.check(vsp);
3792         return ScopedMemoryAccess.loadFromByteBufferMasked(
3793                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3794                 bb, offset, m, vsp,
3795                 (buf, off, s, vm) -> {
3796                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3797                     return s.ldOp(wb, off, vm,
3798                             (wb_, o, i) -> wb_.getShort(o + i * 2));
3799                 });
3800     }
3801 
3802     // Unchecked storing operations in native byte order.
3803     // Caller is responsible for applying index checks, masking, and
3804     // byte swapping.
3805 
3806     abstract
3807     void intoArray0(short[] a, int offset);
3808     @ForceInline
3809     final
3810     void intoArray0Template(short[] a, int offset) {
3811         ShortSpecies vsp = vspecies();
3812         VectorSupport.store(
3813             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3814             a, arrayAddress(a, offset),
3815             this, a, offset,
3816             (arr, off, v)
3817             -> v.stOp(arr, off,
3818                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3819     }
3820 
3821     abstract
3822     void intoArray0(short[] a, int offset, VectorMask<Short> m);
3823     @ForceInline
3824     final
3825     <M extends VectorMask<Short>>
3826     void intoArray0Template(Class<M> maskClass, short[] a, int offset, M m) {
3827         m.check(species());
3828         ShortSpecies vsp = vspecies();
3829         VectorSupport.storeMasked(
3830             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3831             a, arrayAddress(a, offset),
3832             this, m, a, offset,
3833             (arr, off, v, vm)
3834             -> v.stOp(arr, off, vm,
3835                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
3836     }
3837 
3838 
3839 
3840     abstract
3841     void intoByteArray0(byte[] a, int offset);
3842     @ForceInline
3843     final
3844     void intoByteArray0Template(byte[] a, int offset) {
3845         ShortSpecies vsp = vspecies();
3846         VectorSupport.store(
3847             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3848             a, byteArrayAddress(a, offset),
3849             this, a, offset,
3850             (arr, off, v) -> {
3851                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3852                 v.stOp(wb, off,
3853                         (tb_, o, i, e) -> tb_.putShort(o + i * 2, e));
3854             });
3855     }
3856 
3857     abstract
3858     void intoByteArray0(byte[] a, int offset, VectorMask<Short> m);
3859     @ForceInline
3860     final
3861     <M extends VectorMask<Short>>
3862     void intoByteArray0Template(Class<M> maskClass, byte[] a, int offset, M m) {
3863         ShortSpecies vsp = vspecies();
3864         m.check(vsp);
3865         VectorSupport.storeMasked(
3866             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3867             a, byteArrayAddress(a, offset),
3868             this, m, a, offset,
3869             (arr, off, v, vm) -> {
3870                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3871                 v.stOp(wb, off, vm,
3872                         (tb_, o, i, e) -> tb_.putShort(o + i * 2, e));
3873             });
3874     }
3875 
3876     @ForceInline
3877     final
3878     void intoByteBuffer0(ByteBuffer bb, int offset) {
3879         ShortSpecies vsp = vspecies();
3880         ScopedMemoryAccess.storeIntoByteBuffer(
3881                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3882                 this, bb, offset,
3883                 (buf, off, v) -> {
3884                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3885                     v.stOp(wb, off,
3886                             (wb_, o, i, e) -> wb_.putShort(o + i * 2, e));
3887                 });
3888     }
3889 
3890     abstract
3891     void intoByteBuffer0(ByteBuffer bb, int offset, VectorMask<Short> m);
3892     @ForceInline
3893     final
3894     <M extends VectorMask<Short>>
3895     void intoByteBuffer0Template(Class<M> maskClass, ByteBuffer bb, int offset, M m) {
3896         ShortSpecies vsp = vspecies();
3897         m.check(vsp);
3898         ScopedMemoryAccess.storeIntoByteBufferMasked(
3899                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3900                 this, m, bb, offset,
3901                 (buf, off, v, vm) -> {
3902                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3903                     v.stOp(wb, off, vm,
3904                             (wb_, o, i, e) -> wb_.putShort(o + i * 2, e));
3905                 });
3906     }
3907 
3908     /*package-private*/
3909     abstract
3910     void intoCharArray0(char[] a, int offset, VectorMask<Short> m);
3911     @ForceInline
3912     final
3913     <M extends VectorMask<Short>>
3914     void intoCharArray0Template(Class<M> maskClass, char[] a, int offset, M m) {
3915         m.check(species());
3916         ShortSpecies vsp = vspecies();
3917         VectorSupport.storeMasked(
3918             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3919             a, charArrayAddress(a, offset),
3920             this, m, a, offset,
3921             (arr, off, v, vm)
3922             -> v.stOp(arr, off, vm,
3923                       (arr_, off_, i, e) -> arr_[off_ + i] = (char) e));
3924     }
3925 
3926     // End of low-level memory operations.
3927 
3928     private static
3929     void checkMaskFromIndexSize(int offset,
3930                                 ShortSpecies vsp,
3931                                 VectorMask<Short> m,
3932                                 int scale,
3933                                 int limit) {
3934         ((AbstractMask<Short>)m)
3935             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3936     }
3937 
3938     @ForceInline
3939     private void conditionalStoreNYI(int offset,
3940                                      ShortSpecies vsp,
3941                                      VectorMask<Short> m,
3942                                      int scale,
3943                                      int limit) {
3944         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3945             String msg =

4240             short[] res = new short[laneCount()];
4241             boolean[] mbits = ((AbstractMask<Short>)m).getBits();
4242             for (int i = 0; i < res.length; i++) {
4243                 if (mbits[i]) {
4244                     res[i] = f.apply(i);
4245                 }
4246             }
4247             return dummyVector().vectorFactory(res);
4248         }
4249 
4250         /*package-private*/
4251         @ForceInline
4252         <M> ShortVector ldOp(M memory, int offset,
4253                                       FLdOp<M> f) {
4254             return dummyVector().ldOp(memory, offset, f);
4255         }
4256 
4257         /*package-private*/
4258         @ForceInline
4259         <M> ShortVector ldOp(M memory, int offset,
4260                                       VectorMask<Short> m,
4261                                       FLdOp<M> f) {
4262             return dummyVector().ldOp(memory, offset, m, f);
4263         }
4264 
4265         /*package-private*/
4266         @ForceInline
4267         <M> void stOp(M memory, int offset, FStOp<M> f) {
4268             dummyVector().stOp(memory, offset, f);
4269         }
4270 
4271         /*package-private*/
4272         @ForceInline
4273         <M> void stOp(M memory, int offset,
4274                       AbstractMask<Short> m,
4275                       FStOp<M> f) {
4276             dummyVector().stOp(memory, offset, m, f);
4277         }
4278 
4279         // N.B. Make sure these constant vectors and
4280         // masks load up correctly into registers.
< prev index next >