< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/FloatVector.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 float} values.
  51  */
  52 @SuppressWarnings("cast")  // warning: redundant cast

 156     FloatVector uOp(FUnOp f);
 157     @ForceInline
 158     final
 159     FloatVector uOpTemplate(FUnOp f) {
 160         float[] vec = vec();
 161         float[] res = new float[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     FloatVector uOp(VectorMask<Float> m,
 171                              FUnOp f);
 172     @ForceInline
 173     final
 174     FloatVector uOpTemplate(VectorMask<Float> m,
 175                                      FUnOp f) {



 176         float[] vec = vec();
 177         float[] res = new float[length()];
 178         boolean[] mbits = ((AbstractMask<Float>)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         float apply(int i, float a, float b);
 190     }
 191 
 192     /*package-private*/
 193     abstract
 194     FloatVector bOp(Vector<Float> o,
 195                              FBinOp f);

 199                                      FBinOp f) {
 200         float[] res = new float[length()];
 201         float[] vec1 = this.vec();
 202         float[] vec2 = ((FloatVector)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     FloatVector bOp(Vector<Float> o,
 212                              VectorMask<Float> m,
 213                              FBinOp f);
 214     @ForceInline
 215     final
 216     FloatVector bOpTemplate(Vector<Float> o,
 217                                      VectorMask<Float> m,
 218                                      FBinOp f) {



 219         float[] res = new float[length()];
 220         float[] vec1 = this.vec();
 221         float[] vec2 = ((FloatVector)o).vec();
 222         boolean[] mbits = ((AbstractMask<Float>)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         float apply(int i, float a, float b, float c);
 234     }
 235 
 236     /*package-private*/
 237     abstract
 238     FloatVector tOp(Vector<Float> o1,

 248         float[] vec2 = ((FloatVector)o1).vec();
 249         float[] vec3 = ((FloatVector)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     FloatVector tOp(Vector<Float> o1,
 259                              Vector<Float> o2,
 260                              VectorMask<Float> m,
 261                              FTriOp f);
 262     @ForceInline
 263     final
 264     FloatVector tOpTemplate(Vector<Float> o1,
 265                                      Vector<Float> o2,
 266                                      VectorMask<Float> m,
 267                                      FTriOp f) {



 268         float[] res = new float[length()];
 269         float[] vec1 = this.vec();
 270         float[] vec2 = ((FloatVector)o1).vec();
 271         float[] vec3 = ((FloatVector)o2).vec();
 272         boolean[] mbits = ((AbstractMask<Float>)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     float rOp(float v, FBinOp f);















 284     @ForceInline
 285     final
 286     float rOpTemplate(float v, FBinOp f) {
 287         float[] 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         float apply(M memory, int offset, int i);
 299     }
 300 
 301     /*package-private*/
 302     @ForceInline
 303     final

 523     }
 524 
 525     // Unary lanewise support
 526 
 527     /**
 528      * {@inheritDoc} <!--workaround-->
 529      */
 530     public abstract
 531     FloatVector lanewise(VectorOperators.Unary op);
 532 
 533     @ForceInline
 534     final
 535     FloatVector lanewiseTemplate(VectorOperators.Unary op) {
 536         if (opKind(op, VO_SPECIAL)) {
 537             if (op == ZOMO) {
 538                 return blend(broadcast(-1), compare(NE, 0));
 539             }
 540         }
 541         int opc = opCode(op);
 542         return VectorSupport.unaryOp(
 543             opc, getClass(), float.class, length(),
 544             this,
 545             UN_IMPL.find(op, opc, (opc_) -> {
 546               switch (opc_) {
 547                 case VECTOR_OP_NEG: return v0 ->
 548                         v0.uOp((i, a) -> (float) -a);
 549                 case VECTOR_OP_ABS: return v0 ->
 550                         v0.uOp((i, a) -> (float) Math.abs(a));
 551                 case VECTOR_OP_SIN: return v0 ->
 552                         v0.uOp((i, a) -> (float) Math.sin(a));
 553                 case VECTOR_OP_COS: return v0 ->
 554                         v0.uOp((i, a) -> (float) Math.cos(a));
 555                 case VECTOR_OP_TAN: return v0 ->
 556                         v0.uOp((i, a) -> (float) Math.tan(a));
 557                 case VECTOR_OP_ASIN: return v0 ->
 558                         v0.uOp((i, a) -> (float) Math.asin(a));
 559                 case VECTOR_OP_ACOS: return v0 ->
 560                         v0.uOp((i, a) -> (float) Math.acos(a));
 561                 case VECTOR_OP_ATAN: return v0 ->
 562                         v0.uOp((i, a) -> (float) Math.atan(a));
 563                 case VECTOR_OP_EXP: return v0 ->
 564                         v0.uOp((i, a) -> (float) Math.exp(a));
 565                 case VECTOR_OP_LOG: return v0 ->
 566                         v0.uOp((i, a) -> (float) Math.log(a));
 567                 case VECTOR_OP_LOG10: return v0 ->
 568                         v0.uOp((i, a) -> (float) Math.log10(a));
 569                 case VECTOR_OP_SQRT: return v0 ->
 570                         v0.uOp((i, a) -> (float) Math.sqrt(a));
 571                 case VECTOR_OP_CBRT: return v0 ->
 572                         v0.uOp((i, a) -> (float) Math.cbrt(a));
 573                 case VECTOR_OP_SINH: return v0 ->
 574                         v0.uOp((i, a) -> (float) Math.sinh(a));
 575                 case VECTOR_OP_COSH: return v0 ->
 576                         v0.uOp((i, a) -> (float) Math.cosh(a));
 577                 case VECTOR_OP_TANH: return v0 ->
 578                         v0.uOp((i, a) -> (float) Math.tanh(a));
 579                 case VECTOR_OP_EXPM1: return v0 ->
 580                         v0.uOp((i, a) -> (float) Math.expm1(a));
 581                 case VECTOR_OP_LOG1P: return v0 ->
 582                         v0.uOp((i, a) -> (float) Math.log1p(a));
 583                 default: return null;
 584               }}));
 585     }
 586     private static final
 587     ImplCache<Unary,UnaryOperator<FloatVector>> UN_IMPL
 588         = new ImplCache<>(Unary.class, FloatVector.class);
 589 
 590     /**
 591      * {@inheritDoc} <!--workaround-->
 592      */
 593     @ForceInline
 594     public final
 595     FloatVector lanewise(VectorOperators.Unary op,
 596                                   VectorMask<Float> m) {
 597         return blend(lanewise(op), m);





























































 598     }
 599 
 600     // Binary lanewise support
 601 
 602     /**
 603      * {@inheritDoc} <!--workaround-->
 604      * @see #lanewise(VectorOperators.Binary,float)
 605      * @see #lanewise(VectorOperators.Binary,float,VectorMask)
 606      */
 607     @Override
 608     public abstract
 609     FloatVector lanewise(VectorOperators.Binary op,
 610                                   Vector<Float> v);
 611     @ForceInline
 612     final
 613     FloatVector lanewiseTemplate(VectorOperators.Binary op,
 614                                           Vector<Float> v) {
 615         FloatVector that = (FloatVector) v;
 616         that.check(this);

 617         if (opKind(op, VO_SPECIAL )) {
 618             if (op == FIRST_NONZERO) {
 619                 // FIXME: Support this in the JIT.
 620                 VectorMask<Integer> thisNZ
 621                     = this.viewAsIntegralLanes().compare(NE, (int) 0);
 622                 that = that.blend((float) 0, thisNZ.cast(vspecies()));
 623                 op = OR_UNCHECKED;
 624                 // FIXME: Support OR_UNCHECKED on float/double also!
 625                 return this.viewAsIntegralLanes()
 626                     .lanewise(op, that.viewAsIntegralLanes())
 627                     .viewAsFloatingLanes();
 628             }
 629         }

 630         int opc = opCode(op);
 631         return VectorSupport.binaryOp(
 632             opc, getClass(), float.class, length(),
 633             this, that,
 634             BIN_IMPL.find(op, opc, (opc_) -> {
 635               switch (opc_) {
 636                 case VECTOR_OP_ADD: return (v0, v1) ->
 637                         v0.bOp(v1, (i, a, b) -> (float)(a + b));
 638                 case VECTOR_OP_SUB: return (v0, v1) ->
 639                         v0.bOp(v1, (i, a, b) -> (float)(a - b));
 640                 case VECTOR_OP_MUL: return (v0, v1) ->
 641                         v0.bOp(v1, (i, a, b) -> (float)(a * b));
 642                 case VECTOR_OP_DIV: return (v0, v1) ->
 643                         v0.bOp(v1, (i, a, b) -> (float)(a / b));
 644                 case VECTOR_OP_MAX: return (v0, v1) ->
 645                         v0.bOp(v1, (i, a, b) -> (float)Math.max(a, b));
 646                 case VECTOR_OP_MIN: return (v0, v1) ->
 647                         v0.bOp(v1, (i, a, b) -> (float)Math.min(a, b));
 648                 case VECTOR_OP_ATAN2: return (v0, v1) ->
 649                         v0.bOp(v1, (i, a, b) -> (float) Math.atan2(a, b));
 650                 case VECTOR_OP_POW: return (v0, v1) ->
 651                         v0.bOp(v1, (i, a, b) -> (float) Math.pow(a, b));
 652                 case VECTOR_OP_HYPOT: return (v0, v1) ->
 653                         v0.bOp(v1, (i, a, b) -> (float) Math.hypot(a, b));
 654                 default: return null;
 655                 }}));
 656     }
 657     private static final
 658     ImplCache<Binary,BinaryOperator<FloatVector>> BIN_IMPL
 659         = new ImplCache<>(Binary.class, FloatVector.class);
 660 
 661     /**
 662      * {@inheritDoc} <!--workaround-->
 663      * @see #lanewise(VectorOperators.Binary,float,VectorMask)
 664      */
 665     @ForceInline
 666     public final
 667     FloatVector lanewise(VectorOperators.Binary op,
 668                                   Vector<Float> v,
 669                                   VectorMask<Float> m) {
 670         return blend(lanewise(op, v), m);



















 671     }































 672     // FIXME: Maybe all of the public final methods in this file (the
 673     // simple ones that just call lanewise) should be pushed down to
 674     // the X-VectorBits template.  They can't optimize properly at
 675     // this level, and must rely on inlining.  Does it work?
 676     // (If it works, of course keep the code here.)
 677 
 678     /**
 679      * Combines the lane values of this vector
 680      * with the value of a broadcast scalar.
 681      *
 682      * This is a lane-wise binary operation which applies
 683      * the selected operation to each lane.
 684      * The return value will be equal to this expression:
 685      * {@code this.lanewise(op, this.broadcast(e))}.
 686      *
 687      * @param op the operation used to process lane values
 688      * @param e the input scalar
 689      * @return the result of applying the operation lane-wise
 690      *         to the two input vectors
 691      * @throws UnsupportedOperationException if this vector does

 708      * This is a masked lane-wise binary operation which applies
 709      * the selected operation to each lane.
 710      * The return value will be equal to this expression:
 711      * {@code this.lanewise(op, this.broadcast(e), m)}.
 712      *
 713      * @param op the operation used to process lane values
 714      * @param e the input scalar
 715      * @param m the mask controlling lane selection
 716      * @return the result of applying the operation lane-wise
 717      *         to the input vector and the scalar
 718      * @throws UnsupportedOperationException if this vector does
 719      *         not support the requested operation
 720      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
 721      * @see #lanewise(VectorOperators.Binary,float)
 722      */
 723     @ForceInline
 724     public final
 725     FloatVector lanewise(VectorOperators.Binary op,
 726                                   float e,
 727                                   VectorMask<Float> m) {
 728         return blend(lanewise(op, e), m);
 729     }
 730 
 731     /**
 732      * {@inheritDoc} <!--workaround-->
 733      * @apiNote
 734      * When working with vector subtypes like {@code FloatVector},
 735      * {@linkplain #lanewise(VectorOperators.Binary,float)
 736      * the more strongly typed method}
 737      * is typically selected.  It can be explicitly selected
 738      * using a cast: {@code v.lanewise(op,(float)e)}.
 739      * The two expressions will produce numerically identical results.
 740      */
 741     @ForceInline
 742     public final
 743     FloatVector lanewise(VectorOperators.Binary op,
 744                                   long e) {
 745         float e1 = (float) e;
 746         if ((long)e1 != e
 747             ) {
 748             vspecies().checkValue(e);  // for exception
 749         }
 750         return lanewise(op, e1);
 751     }
 752 
 753     /**
 754      * {@inheritDoc} <!--workaround-->
 755      * @apiNote
 756      * When working with vector subtypes like {@code FloatVector},
 757      * {@linkplain #lanewise(VectorOperators.Binary,float,VectorMask)
 758      * the more strongly typed method}
 759      * is typically selected.  It can be explicitly selected
 760      * using a cast: {@code v.lanewise(op,(float)e,m)}.
 761      * The two expressions will produce numerically identical results.
 762      */
 763     @ForceInline
 764     public final
 765     FloatVector lanewise(VectorOperators.Binary op,
 766                                   long e, VectorMask<Float> m) {
 767         return blend(lanewise(op, e), m);




 768     }
 769 
 770 
 771     // Ternary lanewise support
 772 
 773     // Ternary operators come in eight variations:
 774     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2])
 775     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask)
 776 
 777     // It is annoying to support all of these variations of masking
 778     // and broadcast, but it would be more surprising not to continue
 779     // the obvious pattern started by unary and binary.
 780 
 781    /**
 782      * {@inheritDoc} <!--workaround-->
 783      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)
 784      * @see #lanewise(VectorOperators.Ternary,Vector,float,VectorMask)
 785      * @see #lanewise(VectorOperators.Ternary,float,Vector,VectorMask)
 786      * @see #lanewise(VectorOperators.Ternary,float,float)
 787      * @see #lanewise(VectorOperators.Ternary,Vector,float)

 789      */
 790     @Override
 791     public abstract
 792     FloatVector lanewise(VectorOperators.Ternary op,
 793                                                   Vector<Float> v1,
 794                                                   Vector<Float> v2);
 795     @ForceInline
 796     final
 797     FloatVector lanewiseTemplate(VectorOperators.Ternary op,
 798                                           Vector<Float> v1,
 799                                           Vector<Float> v2) {
 800         FloatVector that = (FloatVector) v1;
 801         FloatVector tother = (FloatVector) v2;
 802         // It's a word: https://www.dictionary.com/browse/tother
 803         // See also Chapter 11 of Dickens, Our Mutual Friend:
 804         // "Totherest Governor," replied Mr Riderhood...
 805         that.check(this);
 806         tother.check(this);
 807         int opc = opCode(op);
 808         return VectorSupport.ternaryOp(
 809             opc, getClass(), float.class, length(),
 810             this, that, tother,
 811             TERN_IMPL.find(op, opc, (opc_) -> {
 812               switch (opc_) {
 813                 case VECTOR_OP_FMA: return (v0, v1_, v2_) ->
 814                         v0.tOp(v1_, v2_, (i, a, b, c) -> Math.fma(a, b, c));
 815                 default: return null;
 816                 }}));
 817     }
 818     private static final
 819     ImplCache<Ternary,TernaryOperation<FloatVector>> TERN_IMPL
 820         = new ImplCache<>(Ternary.class, FloatVector.class);
 821 
 822     /**
 823      * {@inheritDoc} <!--workaround-->
 824      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)
 825      * @see #lanewise(VectorOperators.Ternary,Vector,float,VectorMask)
 826      * @see #lanewise(VectorOperators.Ternary,float,Vector,VectorMask)
 827      */
 828     @ForceInline
 829     public final
 830     FloatVector lanewise(VectorOperators.Ternary op,
 831                                   Vector<Float> v1,
 832                                   Vector<Float> v2,
 833                                   VectorMask<Float> m) {
 834         return blend(lanewise(op, v1, v2), m);
































 835     }
 836 
 837     /**
 838      * Combines the lane values of this vector
 839      * with the values of two broadcast scalars.
 840      *
 841      * This is a lane-wise ternary operation which applies
 842      * the selected operation to each lane.
 843      * The return value will be equal to this expression:
 844      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}.
 845      *
 846      * @param op the operation used to combine lane values
 847      * @param e1 the first input scalar
 848      * @param e2 the second input scalar
 849      * @return the result of applying the operation lane-wise
 850      *         to the input vector and the scalars
 851      * @throws UnsupportedOperationException if this vector does
 852      *         not support the requested operation
 853      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 854      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)

 871      * The return value will be equal to this expression:
 872      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}.
 873      *
 874      * @param op the operation used to combine lane values
 875      * @param e1 the first input scalar
 876      * @param e2 the second input scalar
 877      * @param m the mask controlling lane selection
 878      * @return the result of applying the operation lane-wise
 879      *         to the input vector and the scalars
 880      * @throws UnsupportedOperationException if this vector does
 881      *         not support the requested operation
 882      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
 883      * @see #lanewise(VectorOperators.Ternary,float,float)
 884      */
 885     @ForceInline
 886     public final
 887     FloatVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m)
 888                                   float e1,
 889                                   float e2,
 890                                   VectorMask<Float> m) {
 891         return blend(lanewise(op, e1, e2), m);
 892     }
 893 
 894     /**
 895      * Combines the lane values of this vector
 896      * with the values of another vector and a broadcast scalar.
 897      *
 898      * This is a lane-wise ternary operation which applies
 899      * the selected operation to each lane.
 900      * The return value will be equal to this expression:
 901      * {@code this.lanewise(op, v1, this.broadcast(e2))}.
 902      *
 903      * @param op the operation used to combine lane values
 904      * @param v1 the other input vector
 905      * @param e2 the input scalar
 906      * @return the result of applying the operation lane-wise
 907      *         to the input vectors and the scalar
 908      * @throws UnsupportedOperationException if this vector does
 909      *         not support the requested operation
 910      * @see #lanewise(VectorOperators.Ternary,float,float)
 911      * @see #lanewise(VectorOperators.Ternary,Vector,float,VectorMask)

 929      * {@code this.lanewise(op, v1, this.broadcast(e2), m)}.
 930      *
 931      * @param op the operation used to combine lane values
 932      * @param v1 the other input vector
 933      * @param e2 the input scalar
 934      * @param m the mask controlling lane selection
 935      * @return the result of applying the operation lane-wise
 936      *         to the input vectors and the scalar
 937      * @throws UnsupportedOperationException if this vector does
 938      *         not support the requested operation
 939      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 940      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)
 941      * @see #lanewise(VectorOperators.Ternary,Vector,float)
 942      */
 943     @ForceInline
 944     public final
 945     FloatVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m)
 946                                   Vector<Float> v1,
 947                                   float e2,
 948                                   VectorMask<Float> m) {
 949         return blend(lanewise(op, v1, e2), m);
 950     }
 951 
 952     /**
 953      * Combines the lane values of this vector
 954      * with the values of another vector and a broadcast scalar.
 955      *
 956      * This is a lane-wise ternary operation which applies
 957      * the selected operation to each lane.
 958      * The return value will be equal to this expression:
 959      * {@code this.lanewise(op, this.broadcast(e1), v2)}.
 960      *
 961      * @param op the operation used to combine lane values
 962      * @param e1 the input scalar
 963      * @param v2 the other input vector
 964      * @return the result of applying the operation lane-wise
 965      *         to the input vectors and the scalar
 966      * @throws UnsupportedOperationException if this vector does
 967      *         not support the requested operation
 968      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 969      * @see #lanewise(VectorOperators.Ternary,float,Vector,VectorMask)

 986      * The return value will be equal to this expression:
 987      * {@code this.lanewise(op, this.broadcast(e1), v2, m)}.
 988      *
 989      * @param op the operation used to combine lane values
 990      * @param e1 the input scalar
 991      * @param v2 the other input vector
 992      * @param m the mask controlling lane selection
 993      * @return the result of applying the operation lane-wise
 994      *         to the input vectors and the scalar
 995      * @throws UnsupportedOperationException if this vector does
 996      *         not support the requested operation
 997      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
 998      * @see #lanewise(VectorOperators.Ternary,float,Vector)
 999      */
1000     @ForceInline
1001     public final
1002     FloatVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m)
1003                                   float e1,
1004                                   Vector<Float> v2,
1005                                   VectorMask<Float> m) {
1006         return blend(lanewise(op, e1, v2), m);
1007     }
1008 
1009     // (Thus endeth the Great and Mighty Ternary Ogdoad.)
1010     // https://en.wikipedia.org/wiki/Ogdoad
1011 
1012     /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV
1013     //
1014     // These include masked and non-masked versions.
1015     // This subclass adds broadcast (masked or not).
1016 
1017     /**
1018      * {@inheritDoc} <!--workaround-->
1019      * @see #add(float)
1020      */
1021     @Override
1022     @ForceInline
1023     public final FloatVector add(Vector<Float> v) {
1024         return lanewise(ADD, v);
1025     }
1026 

1642     @Override
1643     @ForceInline
1644     public final
1645     VectorMask<Float> test(VectorOperators.Test op,
1646                                   VectorMask<Float> m) {
1647         return test(op).and(m);
1648     }
1649 
1650     /**
1651      * {@inheritDoc} <!--workaround-->
1652      */
1653     @Override
1654     public abstract
1655     VectorMask<Float> compare(VectorOperators.Comparison op, Vector<Float> v);
1656 
1657     /*package-private*/
1658     @ForceInline
1659     final
1660     <M extends VectorMask<Float>>
1661     M compareTemplate(Class<M> maskType, Comparison op, Vector<Float> v) {
1662         Objects.requireNonNull(v);
1663         FloatSpecies vsp = vspecies();
1664         FloatVector that = (FloatVector) v;
1665         that.check(this);
1666         int opc = opCode(op);
1667         return VectorSupport.compare(
1668             opc, getClass(), maskType, float.class, length(),
1669             this, that,
1670             (cond, v0, v1) -> {
1671                 AbstractMask<Float> m
1672                     = v0.bTest(cond, v1, (cond_, i, a, b)
1673                                -> compareWithOp(cond, a, b));
1674                 @SuppressWarnings("unchecked")
1675                 M m2 = (M) m;
1676                 return m2;
1677             });
1678     }
1679 






















1680     @ForceInline
1681     private static boolean compareWithOp(int cond, float a, float b) {
1682         return switch (cond) {
1683             case BT_eq -> a == b;
1684             case BT_ne -> a != b;
1685             case BT_lt -> a < b;
1686             case BT_le -> a <= b;
1687             case BT_gt -> a > b;
1688             case BT_ge -> a >= b;
1689             default -> throw new AssertionError();
1690         };
1691     }
1692 
1693     /**
1694      * {@inheritDoc} <!--workaround-->
1695      */
1696     @Override
1697     @ForceInline
1698     public final
1699     VectorMask<Float> compare(VectorOperators.Comparison op,
1700                                   Vector<Float> v,
1701                                   VectorMask<Float> m) {
1702         return compare(op, v).and(m);
1703     }
1704 
1705     /**
1706      * Tests this vector by comparing it with an input scalar,
1707      * according to the given comparison operation.
1708      *
1709      * This is a lane-wise binary test operation which applies
1710      * the comparison operation to each lane.
1711      * <p>
1712      * The result is the same as
1713      * {@code compare(op, broadcast(species(), e))}.
1714      * That is, the scalar may be regarded as broadcast to
1715      * a vector of the same species, and then compared
1716      * against the original vector, using the selected
1717      * comparison operation.
1718      *
1719      * @param op the operation used to compare lane values
1720      * @param e the input scalar
1721      * @return the mask result of testing lane-wise if this vector
1722      *         compares to the input, according to the selected
1723      *         comparison operator
1724      * @see FloatVector#compare(VectorOperators.Comparison,Vector)

1743      *
1744      * This is a masked lane-wise binary test operation which applies
1745      * to each pair of corresponding lane values.
1746      *
1747      * The returned result is equal to the expression
1748      * {@code compare(op,s).and(m)}.
1749      *
1750      * @param op the operation used to compare lane values
1751      * @param e the input scalar
1752      * @param m the mask controlling lane selection
1753      * @return the mask result of testing lane-wise if this vector
1754      *         compares to the input, according to the selected
1755      *         comparison operator,
1756      *         and only in the lanes selected by the mask
1757      * @see FloatVector#compare(VectorOperators.Comparison,Vector,VectorMask)
1758      */
1759     @ForceInline
1760     public final VectorMask<Float> compare(VectorOperators.Comparison op,
1761                                                float e,
1762                                                VectorMask<Float> m) {
1763         return compare(op, e).and(m);
1764     }
1765 
1766     /**
1767      * {@inheritDoc} <!--workaround-->
1768      */
1769     @Override
1770     public abstract
1771     VectorMask<Float> compare(Comparison op, long e);
1772 
1773     /*package-private*/
1774     @ForceInline
1775     final
1776     <M extends VectorMask<Float>>
1777     M compareTemplate(Class<M> maskType, Comparison op, long e) {
1778         return compareTemplate(maskType, op, broadcast(e));
1779     }
1780 
1781     /**
1782      * {@inheritDoc} <!--workaround-->
1783      */

1994     wrongPartForSlice(int part) {
1995         String msg = String.format("bad part number %d for slice operation",
1996                                    part);
1997         return new ArrayIndexOutOfBoundsException(msg);
1998     }
1999 
2000     /**
2001      * {@inheritDoc} <!--workaround-->
2002      */
2003     @Override
2004     public abstract
2005     FloatVector rearrange(VectorShuffle<Float> m);
2006 
2007     /*package-private*/
2008     @ForceInline
2009     final
2010     <S extends VectorShuffle<Float>>
2011     FloatVector rearrangeTemplate(Class<S> shuffletype, S shuffle) {
2012         shuffle.checkIndexes();
2013         return VectorSupport.rearrangeOp(
2014             getClass(), shuffletype, float.class, length(),
2015             this, shuffle,
2016             (v1, s_) -> v1.uOp((i, a) -> {
2017                 int ei = s_.laneSource(i);
2018                 return v1.lane(ei);
2019             }));
2020     }
2021 
2022     /**
2023      * {@inheritDoc} <!--workaround-->
2024      */
2025     @Override
2026     public abstract
2027     FloatVector rearrange(VectorShuffle<Float> s,
2028                                    VectorMask<Float> m);
2029 
2030     /*package-private*/
2031     @ForceInline
2032     final
2033     <S extends VectorShuffle<Float>>
2034     FloatVector rearrangeTemplate(Class<S> shuffletype,

2035                                            S shuffle,
2036                                            VectorMask<Float> m) {
2037         FloatVector unmasked =
2038             VectorSupport.rearrangeOp(
2039                 getClass(), shuffletype, float.class, length(),
2040                 this, shuffle,
2041                 (v1, s_) -> v1.uOp((i, a) -> {
2042                     int ei = s_.laneSource(i);
2043                     return ei < 0 ? 0 : v1.lane(ei);
2044                 }));
2045         VectorMask<Float> valid = shuffle.laneIsValid();
2046         if (m.andNot(valid).anyTrue()) {
2047             shuffle.checkIndexes();
2048             throw new AssertionError();
2049         }
2050         return broadcast((float)0).blend(unmasked, m);






2051     }
2052 
2053     /**
2054      * {@inheritDoc} <!--workaround-->
2055      */
2056     @Override
2057     public abstract
2058     FloatVector rearrange(VectorShuffle<Float> s,
2059                                    Vector<Float> v);
2060 
2061     /*package-private*/
2062     @ForceInline
2063     final
2064     <S extends VectorShuffle<Float>>
2065     FloatVector rearrangeTemplate(Class<S> shuffletype,
2066                                            S shuffle,
2067                                            FloatVector v) {
2068         VectorMask<Float> valid = shuffle.laneIsValid();
2069         @SuppressWarnings("unchecked")
2070         S ws = (S) shuffle.wrapIndexes();
2071         FloatVector r0 =
2072             VectorSupport.rearrangeOp(
2073                 getClass(), shuffletype, float.class, length(),
2074                 this, ws,
2075                 (v0, s_) -> v0.uOp((i, a) -> {
2076                     int ei = s_.laneSource(i);
2077                     return v0.lane(ei);
2078                 }));
2079         FloatVector r1 =
2080             VectorSupport.rearrangeOp(
2081                 getClass(), shuffletype, float.class, length(),
2082                 v, ws,
2083                 (v1, s_) -> v1.uOp((i, a) -> {
2084                     int ei = s_.laneSource(i);
2085                     return v1.lane(ei);
2086                 }));
2087         return r1.blend(r0, valid);
2088     }
2089 
2090     @ForceInline
2091     private final
2092     VectorShuffle<Float> toShuffle0(FloatSpecies dsp) {
2093         float[] a = toArray();
2094         int[] sa = new int[a.length];
2095         for (int i = 0; i < a.length; i++) {
2096             sa[i] = (int) a[i];
2097         }
2098         return VectorShuffle.fromArray(dsp, sa, 0);
2099     }
2100 
2101     /*package-private*/
2102     @ForceInline
2103     final

2312      * <li>
2313      * All other reduction operations are fully commutative and
2314      * associative.  The implementation can choose any order of
2315      * processing, yet it will always produce the same result.
2316      * </ul>
2317      *
2318      * @param op the operation used to combine lane values
2319      * @param m the mask controlling lane selection
2320      * @return the reduced result accumulated from the selected lane values
2321      * @throws UnsupportedOperationException if this vector does
2322      *         not support the requested operation
2323      * @see #reduceLanes(VectorOperators.Associative)
2324      */
2325     public abstract float reduceLanes(VectorOperators.Associative op,
2326                                        VectorMask<Float> m);
2327 
2328     /*package-private*/
2329     @ForceInline
2330     final
2331     float reduceLanesTemplate(VectorOperators.Associative op,

2332                                VectorMask<Float> m) {
2333         FloatVector v = reduceIdentityVector(op).blend(this, m);
2334         return v.reduceLanesTemplate(op);








2335     }
2336 
2337     /*package-private*/
2338     @ForceInline
2339     final
2340     float reduceLanesTemplate(VectorOperators.Associative op) {
2341         if (op == FIRST_NONZERO) {
2342             // FIXME:  The JIT should handle this, and other scan ops alos.
2343             VectorMask<Integer> thisNZ
2344                 = this.viewAsIntegralLanes().compare(NE, (int) 0);
2345             return this.lane(thisNZ.firstTrue());
2346         }
2347         int opc = opCode(op);
2348         return fromBits(VectorSupport.reductionCoerced(
2349             opc, getClass(), float.class, length(),
2350             this,
2351             REDUCE_IMPL.find(op, opc, (opc_) -> {
2352               switch (opc_) {
2353               case VECTOR_OP_ADD: return v ->
2354                       toBits(v.rOp((float)0, (i, a, b) -> (float)(a + b)));
2355               case VECTOR_OP_MUL: return v ->
2356                       toBits(v.rOp((float)1, (i, a, b) -> (float)(a * b)));
2357               case VECTOR_OP_MIN: return v ->
2358                       toBits(v.rOp(MAX_OR_INF, (i, a, b) -> (float) Math.min(a, b)));
2359               case VECTOR_OP_MAX: return v ->
2360                       toBits(v.rOp(MIN_OR_INF, (i, a, b) -> (float) Math.max(a, b)));
2361               default: return null;
2362               }})));
2363     }

2364     private static final
2365     ImplCache<Associative,Function<FloatVector,Long>> REDUCE_IMPL
2366         = new ImplCache<>(Associative.class, FloatVector.class);














2367 
2368     private
2369     @ForceInline
2370     FloatVector reduceIdentityVector(VectorOperators.Associative op) {
2371         int opc = opCode(op);
2372         UnaryOperator<FloatVector> fn
2373             = REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
2374                 switch (opc_) {
2375                 case VECTOR_OP_ADD:
2376                     return v -> v.broadcast(0);
2377                 case VECTOR_OP_MUL:
2378                     return v -> v.broadcast(1);
2379                 case VECTOR_OP_MIN:
2380                     return v -> v.broadcast(MAX_OR_INF);
2381                 case VECTOR_OP_MAX:
2382                     return v -> v.broadcast(MIN_OR_INF);
2383                 default: return null;
2384                 }
2385             });
2386         return fn.apply(this);

2556      * @param species species of desired vector
2557      * @param a the byte array
2558      * @param offset the offset into the array
2559      * @param bo the intended byte order
2560      * @param m the mask controlling lane selection
2561      * @return a vector loaded from a byte array
2562      * @throws IndexOutOfBoundsException
2563      *         if {@code offset+N*ESIZE < 0}
2564      *         or {@code offset+(N+1)*ESIZE > a.length}
2565      *         for any lane {@code N} in the vector
2566      *         where the mask is set
2567      */
2568     @ForceInline
2569     public static
2570     FloatVector fromByteArray(VectorSpecies<Float> species,
2571                                        byte[] a, int offset,
2572                                        ByteOrder bo,
2573                                        VectorMask<Float> m) {
2574         FloatSpecies vsp = (FloatSpecies) species;
2575         if (offset >= 0 && offset <= (a.length - species.vectorByteSize())) {
2576             FloatVector zero = vsp.zero();
2577             FloatVector v = zero.fromByteArray0(a, offset);
2578             return zero.blend(v.maybeSwap(bo), m);
2579         }
2580 
2581         // FIXME: optimize
2582         checkMaskFromIndexSize(offset, vsp, m, 4, a.length);
2583         ByteBuffer wb = wrapper(a, bo);
2584         return vsp.ldOp(wb, offset, (AbstractMask<Float>)m,
2585                    (wb_, o, i)  -> wb_.getFloat(o + i * 4));
2586     }
2587 
2588     /**
2589      * Loads a vector from an array of type {@code float[]}
2590      * starting at an offset.
2591      * For each vector lane, where {@code N} is the vector lane index, the
2592      * array element at index {@code offset + N} is placed into the
2593      * resulting vector at lane index {@code N}.
2594      *
2595      * @param species species of desired vector
2596      * @param a the array
2597      * @param offset the offset into the array
2598      * @return the vector loaded from an array

2620      * {@code N}, otherwise the default element value is placed into the
2621      * resulting vector at lane index {@code N}.
2622      *
2623      * @param species species of desired vector
2624      * @param a the array
2625      * @param offset the offset into the array
2626      * @param m the mask controlling lane selection
2627      * @return the vector loaded from an array
2628      * @throws IndexOutOfBoundsException
2629      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2630      *         for any lane {@code N} in the vector
2631      *         where the mask is set
2632      */
2633     @ForceInline
2634     public static
2635     FloatVector fromArray(VectorSpecies<Float> species,
2636                                    float[] a, int offset,
2637                                    VectorMask<Float> m) {
2638         FloatSpecies vsp = (FloatSpecies) species;
2639         if (offset >= 0 && offset <= (a.length - species.length())) {
2640             FloatVector zero = vsp.zero();
2641             return zero.blend(zero.fromArray0(a, offset), m);
2642         }
2643 
2644         // FIXME: optimize
2645         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2646         return vsp.vOp(m, i -> a[offset + i]);
2647     }
2648 
2649     /**
2650      * Gathers a new vector composed of elements from an array of type
2651      * {@code float[]},
2652      * using indexes obtained by adding a fixed {@code offset} to a
2653      * series of secondary offsets from an <em>index map</em>.
2654      * The index map is a contiguous sequence of {@code VLENGTH}
2655      * elements in a second array of {@code int}s, starting at a given
2656      * {@code mapOffset}.
2657      * <p>
2658      * For each vector lane, where {@code N} is the vector lane index,
2659      * the lane is loaded from the array
2660      * element {@code a[f(N)]}, where {@code f(N)} is the
2661      * index mapping expression

2679      */
2680     @ForceInline
2681     public static
2682     FloatVector fromArray(VectorSpecies<Float> species,
2683                                    float[] a, int offset,
2684                                    int[] indexMap, int mapOffset) {
2685         FloatSpecies vsp = (FloatSpecies) species;
2686         IntVector.IntSpecies isp = IntVector.species(vsp.indexShape());
2687         Objects.requireNonNull(a);
2688         Objects.requireNonNull(indexMap);
2689         Class<? extends FloatVector> vectorType = vsp.vectorType();
2690 
2691         // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k]
2692         IntVector vix = IntVector
2693             .fromArray(isp, indexMap, mapOffset)
2694             .add(offset);
2695 
2696         vix = VectorIntrinsics.checkIndex(vix, a.length);
2697 
2698         return VectorSupport.loadWithMap(
2699             vectorType, float.class, vsp.laneCount(),
2700             IntVector.species(vsp.indexShape()).vectorType(),
2701             a, ARRAY_BASE, vix,
2702             a, offset, indexMap, mapOffset, vsp,
2703             (float[] c, int idx, int[] iMap, int idy, FloatSpecies s) ->
2704             s.vOp(n -> c[idx + iMap[idy+n]]));
2705         }
2706 
2707     /**
2708      * Gathers a new vector composed of elements from an array of type
2709      * {@code float[]},
2710      * under the control of a mask, and
2711      * using indexes obtained by adding a fixed {@code offset} to a
2712      * series of secondary offsets from an <em>index map</em>.
2713      * The index map is a contiguous sequence of {@code VLENGTH}
2714      * elements in a second array of {@code int}s, starting at a given
2715      * {@code mapOffset}.
2716      * <p>
2717      * For each vector lane, where {@code N} is the vector lane index,
2718      * if the lane is set in the mask,
2719      * the lane is loaded from the array
2720      * element {@code a[f(N)]}, where {@code f(N)} is the
2721      * index mapping expression
2722      * {@code offset + indexMap[mapOffset + N]]}.
2723      * Unset lanes in the resulting vector are set to zero.
2724      *
2725      * @param species species of desired vector

2733      * @return the vector loaded from the indexed elements of the array
2734      * @throws IndexOutOfBoundsException
2735      *         if {@code mapOffset+N < 0}
2736      *         or if {@code mapOffset+N >= indexMap.length},
2737      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
2738      *         is an invalid index into {@code a},
2739      *         for any lane {@code N} in the vector
2740      *         where the mask is set
2741      * @see FloatVector#toIntArray()
2742      */
2743     @ForceInline
2744     public static
2745     FloatVector fromArray(VectorSpecies<Float> species,
2746                                    float[] a, int offset,
2747                                    int[] indexMap, int mapOffset,
2748                                    VectorMask<Float> m) {
2749         if (m.allTrue()) {
2750             return fromArray(species, a, offset, indexMap, mapOffset);
2751         }
2752         else {
2753             // FIXME: Cannot vectorize yet, if there's a mask.
2754             FloatSpecies vsp = (FloatSpecies) species;
2755             return vsp.vOp(m, n -> a[offset + indexMap[mapOffset + n]]);
2756         }
2757     }
2758 
2759 
2760 
2761     /**
2762      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
2763      * starting at an offset into the byte buffer.
2764      * Bytes are composed into primitive lane elements according
2765      * to the specified byte order.
2766      * The vector is arranged into lanes according to
2767      * <a href="Vector.html#lane-order">memory ordering</a>.
2768      * <p>
2769      * This method behaves as if it returns the result of calling
2770      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2771      * fromByteBuffer()} as follows:
2772      * <pre>{@code
2773      * var m = species.maskAll(true);
2774      * return fromByteBuffer(species, bb, offset, bo, m);
2775      * }</pre>

2829      * @param species species of desired vector
2830      * @param bb the byte buffer
2831      * @param offset the offset into the byte buffer
2832      * @param bo the intended byte order
2833      * @param m the mask controlling lane selection
2834      * @return a vector loaded from a byte buffer
2835      * @throws IndexOutOfBoundsException
2836      *         if {@code offset+N*4 < 0}
2837      *         or {@code offset+N*4 >= bb.limit()}
2838      *         for any lane {@code N} in the vector
2839      *         where the mask is set
2840      */
2841     @ForceInline
2842     public static
2843     FloatVector fromByteBuffer(VectorSpecies<Float> species,
2844                                         ByteBuffer bb, int offset,
2845                                         ByteOrder bo,
2846                                         VectorMask<Float> m) {
2847         FloatSpecies vsp = (FloatSpecies) species;
2848         if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) {
2849             FloatVector zero = vsp.zero();
2850             FloatVector v = zero.fromByteBuffer0(bb, offset);
2851             return zero.blend(v.maybeSwap(bo), m);
2852         }
2853 
2854         // FIXME: optimize
2855         checkMaskFromIndexSize(offset, vsp, m, 4, bb.limit());
2856         ByteBuffer wb = wrapper(bb, bo);
2857         return vsp.ldOp(wb, offset, (AbstractMask<Float>)m,
2858                    (wb_, o, i)  -> wb_.getFloat(o + i * 4));
2859     }
2860 
2861     // Memory store operations
2862 
2863     /**
2864      * Stores this vector into an array of type {@code float[]}
2865      * starting at an offset.
2866      * <p>
2867      * For each vector lane, where {@code N} is the vector lane index,
2868      * the lane element at index {@code N} is stored into the array
2869      * element {@code a[offset+N]}.
2870      *
2871      * @param a the array, of type {@code float[]}

2903      * Lanes where the mask is unset are not stored and do not need
2904      * to correspond to legitimate elements of {@code a}.
2905      * That is, unset lanes may correspond to array indexes less than
2906      * zero or beyond the end of the array.
2907      *
2908      * @param a the array, of type {@code float[]}
2909      * @param offset the offset into the array
2910      * @param m the mask controlling lane storage
2911      * @throws IndexOutOfBoundsException
2912      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2913      *         for any lane {@code N} in the vector
2914      *         where the mask is set
2915      */
2916     @ForceInline
2917     public final
2918     void intoArray(float[] a, int offset,
2919                    VectorMask<Float> m) {
2920         if (m.allTrue()) {
2921             intoArray(a, offset);
2922         } else {
2923             // FIXME: optimize
2924             FloatSpecies vsp = vspecies();
2925             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2926             stOp(a, offset, m, (arr, off, i, v) -> arr[off+i] = v);
2927         }
2928     }
2929 
2930     /**
2931      * Scatters this vector into an array of type {@code float[]}
2932      * using indexes obtained by adding a fixed {@code offset} to a
2933      * series of secondary offsets from an <em>index map</em>.
2934      * The index map is a contiguous sequence of {@code VLENGTH}
2935      * elements in a second array of {@code int}s, starting at a given
2936      * {@code mapOffset}.
2937      * <p>
2938      * For each vector lane, where {@code N} is the vector lane index,
2939      * the lane element at index {@code N} is stored into the array
2940      * element {@code a[f(N)]}, where {@code f(N)} is the
2941      * index mapping expression
2942      * {@code offset + indexMap[mapOffset + N]]}.
2943      *
2944      * @param a the array
2945      * @param offset an offset to combine with the index map offsets
2946      * @param indexMap the index map

2950      *         or if {@code mapOffset+N >= indexMap.length},
2951      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
2952      *         is an invalid index into {@code a},
2953      *         for any lane {@code N} in the vector
2954      * @see FloatVector#toIntArray()
2955      */
2956     @ForceInline
2957     public final
2958     void intoArray(float[] a, int offset,
2959                    int[] indexMap, int mapOffset) {
2960         FloatSpecies vsp = vspecies();
2961         IntVector.IntSpecies isp = IntVector.species(vsp.indexShape());
2962         // Index vector: vix[0:n] = i -> offset + indexMap[mo + i]
2963         IntVector vix = IntVector
2964             .fromArray(isp, indexMap, mapOffset)
2965             .add(offset);
2966 
2967         vix = VectorIntrinsics.checkIndex(vix, a.length);
2968 
2969         VectorSupport.storeWithMap(
2970             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
2971             isp.vectorType(),
2972             a, arrayAddress(a, 0), vix,
2973             this,
2974             a, offset, indexMap, mapOffset,
2975             (arr, off, v, map, mo)
2976             -> v.stOp(arr, off,
2977                       (arr_, off_, i, e) -> {
2978                           int j = map[mo + i];
2979                           arr[off + j] = e;
2980                       }));
2981     }
2982 
2983     /**
2984      * Scatters this vector into an array of type {@code float[]},
2985      * under the control of a mask, and
2986      * using indexes obtained by adding a fixed {@code offset} to a
2987      * series of secondary offsets from an <em>index map</em>.
2988      * The index map is a contiguous sequence of {@code VLENGTH}
2989      * elements in a second array of {@code int}s, starting at a given
2990      * {@code mapOffset}.
2991      * <p>
2992      * For each vector lane, where {@code N} is the vector lane index,
2993      * if the mask lane at index {@code N} is set then
2994      * the lane element at index {@code N} is stored into the array
2995      * element {@code a[f(N)]}, where {@code f(N)} is the

3002      * @param mapOffset the offset into the index map
3003      * @param m the mask
3004      * @throws IndexOutOfBoundsException
3005      *         if {@code mapOffset+N < 0}
3006      *         or if {@code mapOffset+N >= indexMap.length},
3007      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3008      *         is an invalid index into {@code a},
3009      *         for any lane {@code N} in the vector
3010      *         where the mask is set
3011      * @see FloatVector#toIntArray()
3012      */
3013     @ForceInline
3014     public final
3015     void intoArray(float[] a, int offset,
3016                    int[] indexMap, int mapOffset,
3017                    VectorMask<Float> m) {
3018         if (m.allTrue()) {
3019             intoArray(a, offset, indexMap, mapOffset);
3020         }
3021         else {
3022             // FIXME: Cannot vectorize yet, if there's a mask.
3023             stOp(a, offset, m,
3024                  (arr, off, i, e) -> {
3025                      int j = indexMap[mapOffset + i];
3026                      arr[off + j] = e;
3027                  });
3028         }
3029     }
3030 
3031 
3032 
3033     /**
3034      * {@inheritDoc} <!--workaround-->
3035      */
3036     @Override
3037     @ForceInline
3038     public final
3039     void intoByteArray(byte[] a, int offset,
3040                        ByteOrder bo) {
3041         offset = checkFromIndexSize(offset, byteSize(), a.length);
3042         maybeSwap(bo).intoByteArray0(a, offset);
3043     }
3044 
3045     /**
3046      * {@inheritDoc} <!--workaround-->
3047      */
3048     @Override
3049     @ForceInline
3050     public final
3051     void intoByteArray(byte[] a, int offset,
3052                        ByteOrder bo,
3053                        VectorMask<Float> m) {
3054         if (m.allTrue()) {
3055             intoByteArray(a, offset, bo);
3056         } else {
3057             // FIXME: optimize
3058             FloatSpecies vsp = vspecies();
3059             checkMaskFromIndexSize(offset, vsp, m, 4, a.length);
3060             ByteBuffer wb = wrapper(a, bo);
3061             this.stOp(wb, offset, m,
3062                     (wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
3063         }
3064     }
3065 
3066     /**
3067      * {@inheritDoc} <!--workaround-->
3068      */
3069     @Override
3070     @ForceInline
3071     public final
3072     void intoByteBuffer(ByteBuffer bb, int offset,
3073                         ByteOrder bo) {
3074         if (bb.isReadOnly()) {
3075             throw new ReadOnlyBufferException();
3076         }
3077         offset = checkFromIndexSize(offset, byteSize(), bb.limit());
3078         maybeSwap(bo).intoByteBuffer0(bb, offset);
3079     }
3080 
3081     /**
3082      * {@inheritDoc} <!--workaround-->
3083      */
3084     @Override
3085     @ForceInline
3086     public final
3087     void intoByteBuffer(ByteBuffer bb, int offset,
3088                         ByteOrder bo,
3089                         VectorMask<Float> m) {
3090         if (m.allTrue()) {
3091             intoByteBuffer(bb, offset, bo);
3092         } else {
3093             // FIXME: optimize
3094             if (bb.isReadOnly()) {
3095                 throw new ReadOnlyBufferException();
3096             }
3097             FloatSpecies vsp = vspecies();
3098             checkMaskFromIndexSize(offset, vsp, m, 4, bb.limit());
3099             ByteBuffer wb = wrapper(bb, bo);
3100             this.stOp(wb, offset, m,
3101                     (wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
3102         }
3103     }
3104 
3105     // ================================================
3106 
3107     // Low-level memory operations.
3108     //
3109     // Note that all of these operations *must* inline into a context
3110     // where the exact species of the involved vector is a
3111     // compile-time constant.  Otherwise, the intrinsic generation
3112     // will fail and performance will suffer.
3113     //
3114     // In many cases this is achieved by re-deriving a version of the
3115     // method in each concrete subclass (per species).  The re-derived
3116     // method simply calls one of these generic methods, with exact
3117     // parameters for the controlling metadata, which is either a
3118     // typed vector or constant species instance.
3119 
3120     // Unchecked loading operations in native byte order.
3121     // Caller is responsible for applying index checks, masking, and
3122     // byte swapping.
3123 
3124     /*package-private*/
3125     abstract
3126     FloatVector fromArray0(float[] a, int offset);
3127     @ForceInline
3128     final
3129     FloatVector fromArray0Template(float[] a, int offset) {
3130         FloatSpecies vsp = vspecies();
3131         return VectorSupport.load(
3132             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3133             a, arrayAddress(a, offset),
3134             a, offset, vsp,
3135             (arr, off, s) -> s.ldOp(arr, off,
3136                                     (arr_, off_, i) -> arr_[off_ + i]));
3137     }
3138 



















































3139 
3140 
3141     @Override
3142     abstract
3143     FloatVector fromByteArray0(byte[] a, int offset);
3144     @ForceInline
3145     final
3146     FloatVector fromByteArray0Template(byte[] a, int offset) {
3147         FloatSpecies vsp = vspecies();
3148         return VectorSupport.load(
3149             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3150             a, byteArrayAddress(a, offset),
3151             a, offset, vsp,
3152             (arr, off, s) -> {
3153                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3154                 return s.ldOp(wb, off,
3155                         (wb_, o, i) -> wb_.getFloat(o + i * 4));
3156             });
3157     }
3158 



















3159     abstract
3160     FloatVector fromByteBuffer0(ByteBuffer bb, int offset);
3161     @ForceInline
3162     final
3163     FloatVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
3164         FloatSpecies vsp = vspecies();
3165         return ScopedMemoryAccess.loadFromByteBuffer(
3166                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3167                 bb, offset, vsp,
3168                 (buf, off, s) -> {
3169                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3170                     return s.ldOp(wb, off,
3171                             (wb_, o, i) -> wb_.getFloat(o + i * 4));
3172                 });
3173     }
3174 


















3175     // Unchecked storing operations in native byte order.
3176     // Caller is responsible for applying index checks, masking, and
3177     // byte swapping.
3178 
3179     abstract
3180     void intoArray0(float[] a, int offset);
3181     @ForceInline
3182     final
3183     void intoArray0Template(float[] a, int offset) {
3184         FloatSpecies vsp = vspecies();
3185         VectorSupport.store(
3186             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3187             a, arrayAddress(a, offset),
3188             this, a, offset,
3189             (arr, off, v)
3190             -> v.stOp(arr, off,
3191                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3192     }
3193 




















































3194     abstract
3195     void intoByteArray0(byte[] a, int offset);
3196     @ForceInline
3197     final
3198     void intoByteArray0Template(byte[] a, int offset) {
3199         FloatSpecies vsp = vspecies();
3200         VectorSupport.store(
3201             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3202             a, byteArrayAddress(a, offset),
3203             this, a, offset,
3204             (arr, off, v) -> {
3205                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3206                 v.stOp(wb, off,
3207                         (tb_, o, i, e) -> tb_.putFloat(o + i * 4, e));
3208             });
3209     }
3210 



















3211     @ForceInline
3212     final
3213     void intoByteBuffer0(ByteBuffer bb, int offset) {
3214         FloatSpecies vsp = vspecies();
3215         ScopedMemoryAccess.storeIntoByteBuffer(
3216                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3217                 this, bb, offset,
3218                 (buf, off, v) -> {
3219                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3220                     v.stOp(wb, off,
3221                             (wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
3222                 });
3223     }
3224 



















3225     // End of low-level memory operations.
3226 
3227     private static
3228     void checkMaskFromIndexSize(int offset,
3229                                 FloatSpecies vsp,
3230                                 VectorMask<Float> m,
3231                                 int scale,
3232                                 int limit) {
3233         ((AbstractMask<Float>)m)
3234             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3235     }
3236 
3237     @ForceInline
3238     private void conditionalStoreNYI(int offset,
3239                                      FloatSpecies vsp,
3240                                      VectorMask<Float> m,
3241                                      int scale,
3242                                      int limit) {
3243         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3244             String msg =

3522             float[] res = new float[laneCount()];
3523             boolean[] mbits = ((AbstractMask<Float>)m).getBits();
3524             for (int i = 0; i < res.length; i++) {
3525                 if (mbits[i]) {
3526                     res[i] = f.apply(i);
3527                 }
3528             }
3529             return dummyVector().vectorFactory(res);
3530         }
3531 
3532         /*package-private*/
3533         @ForceInline
3534         <M> FloatVector ldOp(M memory, int offset,
3535                                       FLdOp<M> f) {
3536             return dummyVector().ldOp(memory, offset, f);
3537         }
3538 
3539         /*package-private*/
3540         @ForceInline
3541         <M> FloatVector ldOp(M memory, int offset,
3542                                       AbstractMask<Float> m,
3543                                       FLdOp<M> f) {
3544             return dummyVector().ldOp(memory, offset, m, f);
3545         }
3546 
3547         /*package-private*/
3548         @ForceInline
3549         <M> void stOp(M memory, int offset, FStOp<M> f) {
3550             dummyVector().stOp(memory, offset, f);
3551         }
3552 
3553         /*package-private*/
3554         @ForceInline
3555         <M> void stOp(M memory, int offset,
3556                       AbstractMask<Float> m,
3557                       FStOp<M> f) {
3558             dummyVector().stOp(memory, offset, m, f);
3559         }
3560 
3561         // N.B. Make sure these constant vectors and
3562         // 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 float} values.
  50  */
  51 @SuppressWarnings("cast")  // warning: redundant cast

 155     FloatVector uOp(FUnOp f);
 156     @ForceInline
 157     final
 158     FloatVector uOpTemplate(FUnOp f) {
 159         float[] vec = vec();
 160         float[] res = new float[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     FloatVector uOp(VectorMask<Float> m,
 170                              FUnOp f);
 171     @ForceInline
 172     final
 173     FloatVector uOpTemplate(VectorMask<Float> m,
 174                                      FUnOp f) {
 175         if (m == null) {
 176             return uOpTemplate(f);
 177         }
 178         float[] vec = vec();
 179         float[] res = new float[length()];
 180         boolean[] mbits = ((AbstractMask<Float>)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         float apply(int i, float a, float b);
 192     }
 193 
 194     /*package-private*/
 195     abstract
 196     FloatVector bOp(Vector<Float> o,
 197                              FBinOp f);

 201                                      FBinOp f) {
 202         float[] res = new float[length()];
 203         float[] vec1 = this.vec();
 204         float[] vec2 = ((FloatVector)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     FloatVector bOp(Vector<Float> o,
 214                              VectorMask<Float> m,
 215                              FBinOp f);
 216     @ForceInline
 217     final
 218     FloatVector bOpTemplate(Vector<Float> o,
 219                                      VectorMask<Float> m,
 220                                      FBinOp f) {
 221         if (m == null) {
 222             return bOpTemplate(o, f);
 223         }
 224         float[] res = new float[length()];
 225         float[] vec1 = this.vec();
 226         float[] vec2 = ((FloatVector)o).vec();
 227         boolean[] mbits = ((AbstractMask<Float>)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         float apply(int i, float a, float b, float c);
 239     }
 240 
 241     /*package-private*/
 242     abstract
 243     FloatVector tOp(Vector<Float> o1,

 253         float[] vec2 = ((FloatVector)o1).vec();
 254         float[] vec3 = ((FloatVector)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     FloatVector tOp(Vector<Float> o1,
 264                              Vector<Float> o2,
 265                              VectorMask<Float> m,
 266                              FTriOp f);
 267     @ForceInline
 268     final
 269     FloatVector tOpTemplate(Vector<Float> o1,
 270                                      Vector<Float> o2,
 271                                      VectorMask<Float> m,
 272                                      FTriOp f) {
 273         if (m == null) {
 274             return tOpTemplate(o1, o2, f);
 275         }
 276         float[] res = new float[length()];
 277         float[] vec1 = this.vec();
 278         float[] vec2 = ((FloatVector)o1).vec();
 279         float[] vec3 = ((FloatVector)o2).vec();
 280         boolean[] mbits = ((AbstractMask<Float>)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     float rOp(float v, VectorMask<Float> m, FBinOp f);
 292 
 293     @ForceInline
 294     final
 295     float rOpTemplate(float v, VectorMask<Float> m, FBinOp f) {
 296         if (m == null) {
 297             return rOpTemplate(v, f);
 298         }
 299         float[] vec = vec();
 300         boolean[] mbits = ((AbstractMask<Float>)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     float rOpTemplate(float v, FBinOp f) {
 310         float[] 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         float apply(M memory, int offset, int i);
 322     }
 323 
 324     /*package-private*/
 325     @ForceInline
 326     final

 546     }
 547 
 548     // Unary lanewise support
 549 
 550     /**
 551      * {@inheritDoc} <!--workaround-->
 552      */
 553     public abstract
 554     FloatVector lanewise(VectorOperators.Unary op);
 555 
 556     @ForceInline
 557     final
 558     FloatVector lanewiseTemplate(VectorOperators.Unary op) {
 559         if (opKind(op, VO_SPECIAL)) {
 560             if (op == ZOMO) {
 561                 return blend(broadcast(-1), compare(NE, 0));
 562             }
 563         }
 564         int opc = opCode(op);
 565         return VectorSupport.unaryOp(
 566             opc, getClass(), null, float.class, length(),
 567             this, null,
 568             UN_IMPL.find(op, opc, FloatVector::unaryOperations));







































 569     }



 570 
 571     /**
 572      * {@inheritDoc} <!--workaround-->
 573      */
 574     @Override
 575     public abstract
 576     FloatVector lanewise(VectorOperators.Unary op,
 577                                   VectorMask<Float> m);
 578     @ForceInline
 579     final
 580     FloatVector lanewiseTemplate(VectorOperators.Unary op,
 581                                           Class<? extends VectorMask<Float>> maskClass,
 582                                           VectorMask<Float> m) {
 583         m.check(maskClass, this);
 584         if (opKind(op, VO_SPECIAL)) {
 585             if (op == ZOMO) {
 586                 return blend(broadcast(-1), compare(NE, 0, m));
 587             }
 588         }
 589         int opc = opCode(op);
 590         return VectorSupport.unaryOp(
 591             opc, getClass(), maskClass, float.class, length(),
 592             this, m,
 593             UN_IMPL.find(op, opc, FloatVector::unaryOperations));
 594     }
 595 
 596     private static final
 597     ImplCache<Unary, UnaryOperation<FloatVector, VectorMask<Float>>>
 598         UN_IMPL = new ImplCache<>(Unary.class, FloatVector.class);
 599 
 600     private static UnaryOperation<FloatVector, VectorMask<Float>> unaryOperations(int opc_) {
 601         switch (opc_) {
 602             case VECTOR_OP_NEG: return (v0, m) ->
 603                     v0.uOp(m, (i, a) -> (float) -a);
 604             case VECTOR_OP_ABS: return (v0, m) ->
 605                     v0.uOp(m, (i, a) -> (float) Math.abs(a));
 606             case VECTOR_OP_SIN: return (v0, m) ->
 607                     v0.uOp(m, (i, a) -> (float) Math.sin(a));
 608             case VECTOR_OP_COS: return (v0, m) ->
 609                     v0.uOp(m, (i, a) -> (float) Math.cos(a));
 610             case VECTOR_OP_TAN: return (v0, m) ->
 611                     v0.uOp(m, (i, a) -> (float) Math.tan(a));
 612             case VECTOR_OP_ASIN: return (v0, m) ->
 613                     v0.uOp(m, (i, a) -> (float) Math.asin(a));
 614             case VECTOR_OP_ACOS: return (v0, m) ->
 615                     v0.uOp(m, (i, a) -> (float) Math.acos(a));
 616             case VECTOR_OP_ATAN: return (v0, m) ->
 617                     v0.uOp(m, (i, a) -> (float) Math.atan(a));
 618             case VECTOR_OP_EXP: return (v0, m) ->
 619                     v0.uOp(m, (i, a) -> (float) Math.exp(a));
 620             case VECTOR_OP_LOG: return (v0, m) ->
 621                     v0.uOp(m, (i, a) -> (float) Math.log(a));
 622             case VECTOR_OP_LOG10: return (v0, m) ->
 623                     v0.uOp(m, (i, a) -> (float) Math.log10(a));
 624             case VECTOR_OP_SQRT: return (v0, m) ->
 625                     v0.uOp(m, (i, a) -> (float) Math.sqrt(a));
 626             case VECTOR_OP_CBRT: return (v0, m) ->
 627                     v0.uOp(m, (i, a) -> (float) Math.cbrt(a));
 628             case VECTOR_OP_SINH: return (v0, m) ->
 629                     v0.uOp(m, (i, a) -> (float) Math.sinh(a));
 630             case VECTOR_OP_COSH: return (v0, m) ->
 631                     v0.uOp(m, (i, a) -> (float) Math.cosh(a));
 632             case VECTOR_OP_TANH: return (v0, m) ->
 633                     v0.uOp(m, (i, a) -> (float) Math.tanh(a));
 634             case VECTOR_OP_EXPM1: return (v0, m) ->
 635                     v0.uOp(m, (i, a) -> (float) Math.expm1(a));
 636             case VECTOR_OP_LOG1P: return (v0, m) ->
 637                     v0.uOp(m, (i, a) -> (float) Math.log1p(a));
 638             default: return null;
 639         }
 640     }
 641 
 642     // Binary lanewise support
 643 
 644     /**
 645      * {@inheritDoc} <!--workaround-->
 646      * @see #lanewise(VectorOperators.Binary,float)
 647      * @see #lanewise(VectorOperators.Binary,float,VectorMask)
 648      */
 649     @Override
 650     public abstract
 651     FloatVector lanewise(VectorOperators.Binary op,
 652                                   Vector<Float> v);
 653     @ForceInline
 654     final
 655     FloatVector lanewiseTemplate(VectorOperators.Binary op,
 656                                           Vector<Float> v) {
 657         FloatVector that = (FloatVector) v;
 658         that.check(this);
 659 
 660         if (opKind(op, VO_SPECIAL )) {
 661             if (op == FIRST_NONZERO) {
 662                 // FIXME: Support this in the JIT.
 663                 VectorMask<Integer> thisNZ
 664                     = this.viewAsIntegralLanes().compare(NE, (int) 0);
 665                 that = that.blend((float) 0, thisNZ.cast(vspecies()));
 666                 op = OR_UNCHECKED;
 667                 // FIXME: Support OR_UNCHECKED on float/double also!
 668                 return this.viewAsIntegralLanes()
 669                     .lanewise(op, that.viewAsIntegralLanes())
 670                     .viewAsFloatingLanes();
 671             }
 672         }
 673 
 674         int opc = opCode(op);
 675         return VectorSupport.binaryOp(
 676             opc, getClass(), null, float.class, length(),
 677             this, that, null,
 678             BIN_IMPL.find(op, opc, FloatVector::binaryOperations));





















 679     }



 680 
 681     /**
 682      * {@inheritDoc} <!--workaround-->
 683      * @see #lanewise(VectorOperators.Binary,float,VectorMask)
 684      */
 685     @Override
 686     public abstract
 687     FloatVector lanewise(VectorOperators.Binary op,
 688                                   Vector<Float> v,
 689                                   VectorMask<Float> m);
 690     @ForceInline
 691     final
 692     FloatVector lanewiseTemplate(VectorOperators.Binary op,
 693                                           Class<? extends VectorMask<Float>> maskClass,
 694                                           Vector<Float> v, VectorMask<Float> m) {
 695         FloatVector that = (FloatVector) v;
 696         that.check(this);
 697         m.check(maskClass, this);
 698 
 699         if (opKind(op, VO_SPECIAL )) {
 700             if (op == FIRST_NONZERO) {
 701                 return blend(lanewise(op, v), m);
 702             }
 703         }
 704 
 705         int opc = opCode(op);
 706         return VectorSupport.binaryOp(
 707             opc, getClass(), maskClass, float.class, length(),
 708             this, that, m,
 709             BIN_IMPL.find(op, opc, FloatVector::binaryOperations));
 710     }
 711 
 712     private static final
 713     ImplCache<Binary, BinaryOperation<FloatVector, VectorMask<Float>>>
 714         BIN_IMPL = new ImplCache<>(Binary.class, FloatVector.class);
 715 
 716     private static BinaryOperation<FloatVector, VectorMask<Float>> binaryOperations(int opc_) {
 717         switch (opc_) {
 718             case VECTOR_OP_ADD: return (v0, v1, vm) ->
 719                     v0.bOp(v1, vm, (i, a, b) -> (float)(a + b));
 720             case VECTOR_OP_SUB: return (v0, v1, vm) ->
 721                     v0.bOp(v1, vm, (i, a, b) -> (float)(a - b));
 722             case VECTOR_OP_MUL: return (v0, v1, vm) ->
 723                     v0.bOp(v1, vm, (i, a, b) -> (float)(a * b));
 724             case VECTOR_OP_DIV: return (v0, v1, vm) ->
 725                     v0.bOp(v1, vm, (i, a, b) -> (float)(a / b));
 726             case VECTOR_OP_MAX: return (v0, v1, vm) ->
 727                     v0.bOp(v1, vm, (i, a, b) -> (float)Math.max(a, b));
 728             case VECTOR_OP_MIN: return (v0, v1, vm) ->
 729                     v0.bOp(v1, vm, (i, a, b) -> (float)Math.min(a, b));
 730             case VECTOR_OP_OR: return (v0, v1, vm) ->
 731                     v0.bOp(v1, vm, (i, a, b) -> fromBits(toBits(a) | toBits(b)));
 732             case VECTOR_OP_ATAN2: return (v0, v1, vm) ->
 733                     v0.bOp(v1, vm, (i, a, b) -> (float) Math.atan2(a, b));
 734             case VECTOR_OP_POW: return (v0, v1, vm) ->
 735                     v0.bOp(v1, vm, (i, a, b) -> (float) Math.pow(a, b));
 736             case VECTOR_OP_HYPOT: return (v0, v1, vm) ->
 737                     v0.bOp(v1, vm, (i, a, b) -> (float) Math.hypot(a, b));
 738             default: return null;
 739         }
 740     }
 741 
 742     // FIXME: Maybe all of the public final methods in this file (the
 743     // simple ones that just call lanewise) should be pushed down to
 744     // the X-VectorBits template.  They can't optimize properly at
 745     // this level, and must rely on inlining.  Does it work?
 746     // (If it works, of course keep the code here.)
 747 
 748     /**
 749      * Combines the lane values of this vector
 750      * with the value of a broadcast scalar.
 751      *
 752      * This is a lane-wise binary operation which applies
 753      * the selected operation to each lane.
 754      * The return value will be equal to this expression:
 755      * {@code this.lanewise(op, this.broadcast(e))}.
 756      *
 757      * @param op the operation used to process lane values
 758      * @param e the input scalar
 759      * @return the result of applying the operation lane-wise
 760      *         to the two input vectors
 761      * @throws UnsupportedOperationException if this vector does

 778      * This is a masked lane-wise binary operation which applies
 779      * the selected operation to each lane.
 780      * The return value will be equal to this expression:
 781      * {@code this.lanewise(op, this.broadcast(e), m)}.
 782      *
 783      * @param op the operation used to process lane values
 784      * @param e the input scalar
 785      * @param m the mask controlling lane selection
 786      * @return the result of applying the operation lane-wise
 787      *         to the input vector and the scalar
 788      * @throws UnsupportedOperationException if this vector does
 789      *         not support the requested operation
 790      * @see #lanewise(VectorOperators.Binary,Vector,VectorMask)
 791      * @see #lanewise(VectorOperators.Binary,float)
 792      */
 793     @ForceInline
 794     public final
 795     FloatVector lanewise(VectorOperators.Binary op,
 796                                   float e,
 797                                   VectorMask<Float> m) {
 798         return lanewise(op, broadcast(e), m);
 799     }
 800 
 801     /**
 802      * {@inheritDoc} <!--workaround-->
 803      * @apiNote
 804      * When working with vector subtypes like {@code FloatVector},
 805      * {@linkplain #lanewise(VectorOperators.Binary,float)
 806      * the more strongly typed method}
 807      * is typically selected.  It can be explicitly selected
 808      * using a cast: {@code v.lanewise(op,(float)e)}.
 809      * The two expressions will produce numerically identical results.
 810      */
 811     @ForceInline
 812     public final
 813     FloatVector lanewise(VectorOperators.Binary op,
 814                                   long e) {
 815         float e1 = (float) e;
 816         if ((long)e1 != e) {

 817             vspecies().checkValue(e);  // for exception
 818         }
 819         return lanewise(op, e1);
 820     }
 821 
 822     /**
 823      * {@inheritDoc} <!--workaround-->
 824      * @apiNote
 825      * When working with vector subtypes like {@code FloatVector},
 826      * {@linkplain #lanewise(VectorOperators.Binary,float,VectorMask)
 827      * the more strongly typed method}
 828      * is typically selected.  It can be explicitly selected
 829      * using a cast: {@code v.lanewise(op,(float)e,m)}.
 830      * The two expressions will produce numerically identical results.
 831      */
 832     @ForceInline
 833     public final
 834     FloatVector lanewise(VectorOperators.Binary op,
 835                                   long e, VectorMask<Float> m) {
 836         float e1 = (float) e;
 837         if ((long)e1 != e) {
 838             vspecies().checkValue(e);  // for exception
 839         }
 840         return lanewise(op, e1, m);
 841     }
 842 
 843 
 844     // Ternary lanewise support
 845 
 846     // Ternary operators come in eight variations:
 847     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2])
 848     //   lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask)
 849 
 850     // It is annoying to support all of these variations of masking
 851     // and broadcast, but it would be more surprising not to continue
 852     // the obvious pattern started by unary and binary.
 853 
 854    /**
 855      * {@inheritDoc} <!--workaround-->
 856      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)
 857      * @see #lanewise(VectorOperators.Ternary,Vector,float,VectorMask)
 858      * @see #lanewise(VectorOperators.Ternary,float,Vector,VectorMask)
 859      * @see #lanewise(VectorOperators.Ternary,float,float)
 860      * @see #lanewise(VectorOperators.Ternary,Vector,float)

 862      */
 863     @Override
 864     public abstract
 865     FloatVector lanewise(VectorOperators.Ternary op,
 866                                                   Vector<Float> v1,
 867                                                   Vector<Float> v2);
 868     @ForceInline
 869     final
 870     FloatVector lanewiseTemplate(VectorOperators.Ternary op,
 871                                           Vector<Float> v1,
 872                                           Vector<Float> v2) {
 873         FloatVector that = (FloatVector) v1;
 874         FloatVector tother = (FloatVector) v2;
 875         // It's a word: https://www.dictionary.com/browse/tother
 876         // See also Chapter 11 of Dickens, Our Mutual Friend:
 877         // "Totherest Governor," replied Mr Riderhood...
 878         that.check(this);
 879         tother.check(this);
 880         int opc = opCode(op);
 881         return VectorSupport.ternaryOp(
 882             opc, getClass(), null, float.class, length(),
 883             this, that, tother, null,
 884             TERN_IMPL.find(op, opc, FloatVector::ternaryOperations));





 885     }



 886 
 887     /**
 888      * {@inheritDoc} <!--workaround-->
 889      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)
 890      * @see #lanewise(VectorOperators.Ternary,Vector,float,VectorMask)
 891      * @see #lanewise(VectorOperators.Ternary,float,Vector,VectorMask)
 892      */
 893     @Override
 894     public abstract
 895     FloatVector lanewise(VectorOperators.Ternary op,
 896                                   Vector<Float> v1,
 897                                   Vector<Float> v2,
 898                                   VectorMask<Float> m);
 899     @ForceInline
 900     final
 901     FloatVector lanewiseTemplate(VectorOperators.Ternary op,
 902                                           Class<? extends VectorMask<Float>> maskClass,
 903                                           Vector<Float> v1,
 904                                           Vector<Float> v2,
 905                                           VectorMask<Float> m) {
 906         FloatVector that = (FloatVector) v1;
 907         FloatVector tother = (FloatVector) v2;
 908         // It's a word: https://www.dictionary.com/browse/tother
 909         // See also Chapter 11 of Dickens, Our Mutual Friend:
 910         // "Totherest Governor," replied Mr Riderhood...
 911         that.check(this);
 912         tother.check(this);
 913         m.check(maskClass, this);
 914 
 915         int opc = opCode(op);
 916         return VectorSupport.ternaryOp(
 917             opc, getClass(), maskClass, float.class, length(),
 918             this, that, tother, m,
 919             TERN_IMPL.find(op, opc, FloatVector::ternaryOperations));
 920     }
 921 
 922     private static final
 923     ImplCache<Ternary, TernaryOperation<FloatVector, VectorMask<Float>>>
 924         TERN_IMPL = new ImplCache<>(Ternary.class, FloatVector.class);
 925 
 926     private static TernaryOperation<FloatVector, VectorMask<Float>> ternaryOperations(int opc_) {
 927         switch (opc_) {
 928             case VECTOR_OP_FMA: return (v0, v1_, v2_, m) ->
 929                     v0.tOp(v1_, v2_, m, (i, a, b, c) -> Math.fma(a, b, c));
 930             default: return null;
 931         }
 932     }
 933 
 934     /**
 935      * Combines the lane values of this vector
 936      * with the values of two broadcast scalars.
 937      *
 938      * This is a lane-wise ternary operation which applies
 939      * the selected operation to each lane.
 940      * The return value will be equal to this expression:
 941      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}.
 942      *
 943      * @param op the operation used to combine lane values
 944      * @param e1 the first input scalar
 945      * @param e2 the second input scalar
 946      * @return the result of applying the operation lane-wise
 947      *         to the input vector and the scalars
 948      * @throws UnsupportedOperationException if this vector does
 949      *         not support the requested operation
 950      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
 951      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)

 968      * The return value will be equal to this expression:
 969      * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}.
 970      *
 971      * @param op the operation used to combine lane values
 972      * @param e1 the first input scalar
 973      * @param e2 the second input scalar
 974      * @param m the mask controlling lane selection
 975      * @return the result of applying the operation lane-wise
 976      *         to the input vector and the scalars
 977      * @throws UnsupportedOperationException if this vector does
 978      *         not support the requested operation
 979      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
 980      * @see #lanewise(VectorOperators.Ternary,float,float)
 981      */
 982     @ForceInline
 983     public final
 984     FloatVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m)
 985                                   float e1,
 986                                   float e2,
 987                                   VectorMask<Float> m) {
 988         return lanewise(op, broadcast(e1), broadcast(e2), m);
 989     }
 990 
 991     /**
 992      * Combines the lane values of this vector
 993      * with the values of another vector and a broadcast scalar.
 994      *
 995      * This is a lane-wise ternary operation which applies
 996      * the selected operation to each lane.
 997      * The return value will be equal to this expression:
 998      * {@code this.lanewise(op, v1, this.broadcast(e2))}.
 999      *
1000      * @param op the operation used to combine lane values
1001      * @param v1 the other input vector
1002      * @param e2 the input scalar
1003      * @return the result of applying the operation lane-wise
1004      *         to the input vectors and the scalar
1005      * @throws UnsupportedOperationException if this vector does
1006      *         not support the requested operation
1007      * @see #lanewise(VectorOperators.Ternary,float,float)
1008      * @see #lanewise(VectorOperators.Ternary,Vector,float,VectorMask)

1026      * {@code this.lanewise(op, v1, this.broadcast(e2), m)}.
1027      *
1028      * @param op the operation used to combine lane values
1029      * @param v1 the other input vector
1030      * @param e2 the input scalar
1031      * @param m the mask controlling lane selection
1032      * @return the result of applying the operation lane-wise
1033      *         to the input vectors and the scalar
1034      * @throws UnsupportedOperationException if this vector does
1035      *         not support the requested operation
1036      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1037      * @see #lanewise(VectorOperators.Ternary,float,float,VectorMask)
1038      * @see #lanewise(VectorOperators.Ternary,Vector,float)
1039      */
1040     @ForceInline
1041     public final
1042     FloatVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m)
1043                                   Vector<Float> v1,
1044                                   float e2,
1045                                   VectorMask<Float> m) {
1046         return lanewise(op, v1, broadcast(e2), m);
1047     }
1048 
1049     /**
1050      * Combines the lane values of this vector
1051      * with the values of another vector and a broadcast scalar.
1052      *
1053      * This is a lane-wise ternary operation which applies
1054      * the selected operation to each lane.
1055      * The return value will be equal to this expression:
1056      * {@code this.lanewise(op, this.broadcast(e1), v2)}.
1057      *
1058      * @param op the operation used to combine lane values
1059      * @param e1 the input scalar
1060      * @param v2 the other input vector
1061      * @return the result of applying the operation lane-wise
1062      *         to the input vectors and the scalar
1063      * @throws UnsupportedOperationException if this vector does
1064      *         not support the requested operation
1065      * @see #lanewise(VectorOperators.Ternary,Vector,Vector)
1066      * @see #lanewise(VectorOperators.Ternary,float,Vector,VectorMask)

1083      * The return value will be equal to this expression:
1084      * {@code this.lanewise(op, this.broadcast(e1), v2, m)}.
1085      *
1086      * @param op the operation used to combine lane values
1087      * @param e1 the input scalar
1088      * @param v2 the other input vector
1089      * @param m the mask controlling lane selection
1090      * @return the result of applying the operation lane-wise
1091      *         to the input vectors and the scalar
1092      * @throws UnsupportedOperationException if this vector does
1093      *         not support the requested operation
1094      * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask)
1095      * @see #lanewise(VectorOperators.Ternary,float,Vector)
1096      */
1097     @ForceInline
1098     public final
1099     FloatVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m)
1100                                   float e1,
1101                                   Vector<Float> v2,
1102                                   VectorMask<Float> m) {
1103         return lanewise(op, broadcast(e1), v2, m);
1104     }
1105 
1106     // (Thus endeth the Great and Mighty Ternary Ogdoad.)
1107     // https://en.wikipedia.org/wiki/Ogdoad
1108 
1109     /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV
1110     //
1111     // These include masked and non-masked versions.
1112     // This subclass adds broadcast (masked or not).
1113 
1114     /**
1115      * {@inheritDoc} <!--workaround-->
1116      * @see #add(float)
1117      */
1118     @Override
1119     @ForceInline
1120     public final FloatVector add(Vector<Float> v) {
1121         return lanewise(ADD, v);
1122     }
1123 

1739     @Override
1740     @ForceInline
1741     public final
1742     VectorMask<Float> test(VectorOperators.Test op,
1743                                   VectorMask<Float> m) {
1744         return test(op).and(m);
1745     }
1746 
1747     /**
1748      * {@inheritDoc} <!--workaround-->
1749      */
1750     @Override
1751     public abstract
1752     VectorMask<Float> compare(VectorOperators.Comparison op, Vector<Float> v);
1753 
1754     /*package-private*/
1755     @ForceInline
1756     final
1757     <M extends VectorMask<Float>>
1758     M compareTemplate(Class<M> maskType, Comparison op, Vector<Float> v) {


1759         FloatVector that = (FloatVector) v;
1760         that.check(this);
1761         int opc = opCode(op);
1762         return VectorSupport.compare(
1763             opc, getClass(), maskType, float.class, length(),
1764             this, that, null,
1765             (cond, v0, v1, m1) -> {
1766                 AbstractMask<Float> m
1767                     = v0.bTest(cond, v1, (cond_, i, a, b)
1768                                -> compareWithOp(cond, a, b));
1769                 @SuppressWarnings("unchecked")
1770                 M m2 = (M) m;
1771                 return m2;
1772             });
1773     }
1774 
1775     /*package-private*/
1776     @ForceInline
1777     final
1778     <M extends VectorMask<Float>>
1779     M compareTemplate(Class<M> maskType, Comparison op, Vector<Float> v, M m) {
1780         FloatVector that = (FloatVector) v;
1781         that.check(this);
1782         m.check(maskType, this);
1783         int opc = opCode(op);
1784         return VectorSupport.compare(
1785             opc, getClass(), maskType, float.class, length(),
1786             this, that, m,
1787             (cond, v0, v1, m1) -> {
1788                 AbstractMask<Float> cmpM
1789                     = v0.bTest(cond, v1, (cond_, i, a, b)
1790                                -> compareWithOp(cond, a, b));
1791                 @SuppressWarnings("unchecked")
1792                 M m2 = (M) cmpM.and(m1);
1793                 return m2;
1794             });
1795     }
1796 
1797     @ForceInline
1798     private static boolean compareWithOp(int cond, float a, float b) {
1799         return switch (cond) {
1800             case BT_eq -> a == b;
1801             case BT_ne -> a != b;
1802             case BT_lt -> a < b;
1803             case BT_le -> a <= b;
1804             case BT_gt -> a > b;
1805             case BT_ge -> a >= b;
1806             default -> throw new AssertionError();
1807         };
1808     }
1809 












1810     /**
1811      * Tests this vector by comparing it with an input scalar,
1812      * according to the given comparison operation.
1813      *
1814      * This is a lane-wise binary test operation which applies
1815      * the comparison operation to each lane.
1816      * <p>
1817      * The result is the same as
1818      * {@code compare(op, broadcast(species(), e))}.
1819      * That is, the scalar may be regarded as broadcast to
1820      * a vector of the same species, and then compared
1821      * against the original vector, using the selected
1822      * comparison operation.
1823      *
1824      * @param op the operation used to compare lane values
1825      * @param e the input scalar
1826      * @return the mask result of testing lane-wise if this vector
1827      *         compares to the input, according to the selected
1828      *         comparison operator
1829      * @see FloatVector#compare(VectorOperators.Comparison,Vector)

1848      *
1849      * This is a masked lane-wise binary test operation which applies
1850      * to each pair of corresponding lane values.
1851      *
1852      * The returned result is equal to the expression
1853      * {@code compare(op,s).and(m)}.
1854      *
1855      * @param op the operation used to compare lane values
1856      * @param e the input scalar
1857      * @param m the mask controlling lane selection
1858      * @return the mask result of testing lane-wise if this vector
1859      *         compares to the input, according to the selected
1860      *         comparison operator,
1861      *         and only in the lanes selected by the mask
1862      * @see FloatVector#compare(VectorOperators.Comparison,Vector,VectorMask)
1863      */
1864     @ForceInline
1865     public final VectorMask<Float> compare(VectorOperators.Comparison op,
1866                                                float e,
1867                                                VectorMask<Float> m) {
1868         return compare(op, broadcast(e), m);
1869     }
1870 
1871     /**
1872      * {@inheritDoc} <!--workaround-->
1873      */
1874     @Override
1875     public abstract
1876     VectorMask<Float> compare(Comparison op, long e);
1877 
1878     /*package-private*/
1879     @ForceInline
1880     final
1881     <M extends VectorMask<Float>>
1882     M compareTemplate(Class<M> maskType, Comparison op, long e) {
1883         return compareTemplate(maskType, op, broadcast(e));
1884     }
1885 
1886     /**
1887      * {@inheritDoc} <!--workaround-->
1888      */

2099     wrongPartForSlice(int part) {
2100         String msg = String.format("bad part number %d for slice operation",
2101                                    part);
2102         return new ArrayIndexOutOfBoundsException(msg);
2103     }
2104 
2105     /**
2106      * {@inheritDoc} <!--workaround-->
2107      */
2108     @Override
2109     public abstract
2110     FloatVector rearrange(VectorShuffle<Float> m);
2111 
2112     /*package-private*/
2113     @ForceInline
2114     final
2115     <S extends VectorShuffle<Float>>
2116     FloatVector rearrangeTemplate(Class<S> shuffletype, S shuffle) {
2117         shuffle.checkIndexes();
2118         return VectorSupport.rearrangeOp(
2119             getClass(), shuffletype, null, float.class, length(),
2120             this, shuffle, null,
2121             (v1, s_, m_) -> v1.uOp((i, a) -> {
2122                 int ei = s_.laneSource(i);
2123                 return v1.lane(ei);
2124             }));
2125     }
2126 
2127     /**
2128      * {@inheritDoc} <!--workaround-->
2129      */
2130     @Override
2131     public abstract
2132     FloatVector rearrange(VectorShuffle<Float> s,
2133                                    VectorMask<Float> m);
2134 
2135     /*package-private*/
2136     @ForceInline
2137     final
2138     <S extends VectorShuffle<Float>, M extends VectorMask<Float>>
2139     FloatVector rearrangeTemplate(Class<S> shuffletype,
2140                                            Class<M> masktype,
2141                                            S shuffle,
2142                                            M m) {
2143 
2144         m.check(masktype, this);






2145         VectorMask<Float> valid = shuffle.laneIsValid();
2146         if (m.andNot(valid).anyTrue()) {
2147             shuffle.checkIndexes();
2148             throw new AssertionError();
2149         }
2150         return VectorSupport.rearrangeOp(
2151                    getClass(), shuffletype, masktype, float.class, length(),
2152                    this, shuffle, m,
2153                    (v1, s_, m_) -> v1.uOp((i, a) -> {
2154                         int ei = s_.laneSource(i);
2155                         return ei < 0  || !m_.laneIsSet(i) ? 0 : v1.lane(ei);
2156                    }));
2157     }
2158 
2159     /**
2160      * {@inheritDoc} <!--workaround-->
2161      */
2162     @Override
2163     public abstract
2164     FloatVector rearrange(VectorShuffle<Float> s,
2165                                    Vector<Float> v);
2166 
2167     /*package-private*/
2168     @ForceInline
2169     final
2170     <S extends VectorShuffle<Float>>
2171     FloatVector rearrangeTemplate(Class<S> shuffletype,
2172                                            S shuffle,
2173                                            FloatVector v) {
2174         VectorMask<Float> valid = shuffle.laneIsValid();
2175         @SuppressWarnings("unchecked")
2176         S ws = (S) shuffle.wrapIndexes();
2177         FloatVector r0 =
2178             VectorSupport.rearrangeOp(
2179                 getClass(), shuffletype, null, float.class, length(),
2180                 this, ws, null,
2181                 (v0, s_, m_) -> v0.uOp((i, a) -> {
2182                     int ei = s_.laneSource(i);
2183                     return v0.lane(ei);
2184                 }));
2185         FloatVector r1 =
2186             VectorSupport.rearrangeOp(
2187                 getClass(), shuffletype, null, float.class, length(),
2188                 v, ws, null,
2189                 (v1, s_, m_) -> v1.uOp((i, a) -> {
2190                     int ei = s_.laneSource(i);
2191                     return v1.lane(ei);
2192                 }));
2193         return r1.blend(r0, valid);
2194     }
2195 
2196     @ForceInline
2197     private final
2198     VectorShuffle<Float> toShuffle0(FloatSpecies dsp) {
2199         float[] a = toArray();
2200         int[] sa = new int[a.length];
2201         for (int i = 0; i < a.length; i++) {
2202             sa[i] = (int) a[i];
2203         }
2204         return VectorShuffle.fromArray(dsp, sa, 0);
2205     }
2206 
2207     /*package-private*/
2208     @ForceInline
2209     final

2418      * <li>
2419      * All other reduction operations are fully commutative and
2420      * associative.  The implementation can choose any order of
2421      * processing, yet it will always produce the same result.
2422      * </ul>
2423      *
2424      * @param op the operation used to combine lane values
2425      * @param m the mask controlling lane selection
2426      * @return the reduced result accumulated from the selected lane values
2427      * @throws UnsupportedOperationException if this vector does
2428      *         not support the requested operation
2429      * @see #reduceLanes(VectorOperators.Associative)
2430      */
2431     public abstract float reduceLanes(VectorOperators.Associative op,
2432                                        VectorMask<Float> m);
2433 
2434     /*package-private*/
2435     @ForceInline
2436     final
2437     float reduceLanesTemplate(VectorOperators.Associative op,
2438                                Class<? extends VectorMask<Float>> maskClass,
2439                                VectorMask<Float> m) {
2440         m.check(maskClass, this);
2441         if (op == FIRST_NONZERO) {
2442             FloatVector v = reduceIdentityVector(op).blend(this, m);
2443             return v.reduceLanesTemplate(op);
2444         }
2445         int opc = opCode(op);
2446         return fromBits(VectorSupport.reductionCoerced(
2447             opc, getClass(), maskClass, float.class, length(),
2448             this, m,
2449             REDUCE_IMPL.find(op, opc, FloatVector::reductionOperations)));
2450     }
2451 
2452     /*package-private*/
2453     @ForceInline
2454     final
2455     float reduceLanesTemplate(VectorOperators.Associative op) {
2456         if (op == FIRST_NONZERO) {
2457             // FIXME:  The JIT should handle this, and other scan ops alos.
2458             VectorMask<Integer> thisNZ
2459                 = this.viewAsIntegralLanes().compare(NE, (int) 0);
2460             return this.lane(thisNZ.firstTrue());
2461         }
2462         int opc = opCode(op);
2463         return fromBits(VectorSupport.reductionCoerced(
2464             opc, getClass(), null, float.class, length(),
2465             this, null,
2466             REDUCE_IMPL.find(op, opc, FloatVector::reductionOperations)));











2467     }
2468 
2469     private static final
2470     ImplCache<Associative, ReductionOperation<FloatVector, VectorMask<Float>>>
2471         REDUCE_IMPL = new ImplCache<>(Associative.class, FloatVector.class);
2472 
2473     private static ReductionOperation<FloatVector, VectorMask<Float>> reductionOperations(int opc_) {
2474         switch (opc_) {
2475             case VECTOR_OP_ADD: return (v, m) ->
2476                     toBits(v.rOp((float)0, m, (i, a, b) -> (float)(a + b)));
2477             case VECTOR_OP_MUL: return (v, m) ->
2478                     toBits(v.rOp((float)1, m, (i, a, b) -> (float)(a * b)));
2479             case VECTOR_OP_MIN: return (v, m) ->
2480                     toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (float) Math.min(a, b)));
2481             case VECTOR_OP_MAX: return (v, m) ->
2482                     toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (float) Math.max(a, b)));
2483             default: return null;
2484         }
2485     }
2486 
2487     private
2488     @ForceInline
2489     FloatVector reduceIdentityVector(VectorOperators.Associative op) {
2490         int opc = opCode(op);
2491         UnaryOperator<FloatVector> fn
2492             = REDUCE_ID_IMPL.find(op, opc, (opc_) -> {
2493                 switch (opc_) {
2494                 case VECTOR_OP_ADD:
2495                     return v -> v.broadcast(0);
2496                 case VECTOR_OP_MUL:
2497                     return v -> v.broadcast(1);
2498                 case VECTOR_OP_MIN:
2499                     return v -> v.broadcast(MAX_OR_INF);
2500                 case VECTOR_OP_MAX:
2501                     return v -> v.broadcast(MIN_OR_INF);
2502                 default: return null;
2503                 }
2504             });
2505         return fn.apply(this);

2675      * @param species species of desired vector
2676      * @param a the byte array
2677      * @param offset the offset into the array
2678      * @param bo the intended byte order
2679      * @param m the mask controlling lane selection
2680      * @return a vector loaded from a byte array
2681      * @throws IndexOutOfBoundsException
2682      *         if {@code offset+N*ESIZE < 0}
2683      *         or {@code offset+(N+1)*ESIZE > a.length}
2684      *         for any lane {@code N} in the vector
2685      *         where the mask is set
2686      */
2687     @ForceInline
2688     public static
2689     FloatVector fromByteArray(VectorSpecies<Float> species,
2690                                        byte[] a, int offset,
2691                                        ByteOrder bo,
2692                                        VectorMask<Float> m) {
2693         FloatSpecies vsp = (FloatSpecies) species;
2694         if (offset >= 0 && offset <= (a.length - species.vectorByteSize())) {
2695             return vsp.dummyVector().fromByteArray0(a, offset, m).maybeSwap(bo);


2696         }
2697 
2698         // FIXME: optimize
2699         checkMaskFromIndexSize(offset, vsp, m, 4, a.length);
2700         ByteBuffer wb = wrapper(a, bo);
2701         return vsp.ldOp(wb, offset, (AbstractMask<Float>)m,
2702                    (wb_, o, i)  -> wb_.getFloat(o + i * 4));
2703     }
2704 
2705     /**
2706      * Loads a vector from an array of type {@code float[]}
2707      * starting at an offset.
2708      * For each vector lane, where {@code N} is the vector lane index, the
2709      * array element at index {@code offset + N} is placed into the
2710      * resulting vector at lane index {@code N}.
2711      *
2712      * @param species species of desired vector
2713      * @param a the array
2714      * @param offset the offset into the array
2715      * @return the vector loaded from an array

2737      * {@code N}, otherwise the default element value is placed into the
2738      * resulting vector at lane index {@code N}.
2739      *
2740      * @param species species of desired vector
2741      * @param a the array
2742      * @param offset the offset into the array
2743      * @param m the mask controlling lane selection
2744      * @return the vector loaded from an array
2745      * @throws IndexOutOfBoundsException
2746      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2747      *         for any lane {@code N} in the vector
2748      *         where the mask is set
2749      */
2750     @ForceInline
2751     public static
2752     FloatVector fromArray(VectorSpecies<Float> species,
2753                                    float[] a, int offset,
2754                                    VectorMask<Float> m) {
2755         FloatSpecies vsp = (FloatSpecies) species;
2756         if (offset >= 0 && offset <= (a.length - species.length())) {
2757             return vsp.dummyVector().fromArray0(a, offset, m);

2758         }
2759 
2760         // FIXME: optimize
2761         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2762         return vsp.vOp(m, i -> a[offset + i]);
2763     }
2764 
2765     /**
2766      * Gathers a new vector composed of elements from an array of type
2767      * {@code float[]},
2768      * using indexes obtained by adding a fixed {@code offset} to a
2769      * series of secondary offsets from an <em>index map</em>.
2770      * The index map is a contiguous sequence of {@code VLENGTH}
2771      * elements in a second array of {@code int}s, starting at a given
2772      * {@code mapOffset}.
2773      * <p>
2774      * For each vector lane, where {@code N} is the vector lane index,
2775      * the lane is loaded from the array
2776      * element {@code a[f(N)]}, where {@code f(N)} is the
2777      * index mapping expression

2795      */
2796     @ForceInline
2797     public static
2798     FloatVector fromArray(VectorSpecies<Float> species,
2799                                    float[] a, int offset,
2800                                    int[] indexMap, int mapOffset) {
2801         FloatSpecies vsp = (FloatSpecies) species;
2802         IntVector.IntSpecies isp = IntVector.species(vsp.indexShape());
2803         Objects.requireNonNull(a);
2804         Objects.requireNonNull(indexMap);
2805         Class<? extends FloatVector> vectorType = vsp.vectorType();
2806 
2807         // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k]
2808         IntVector vix = IntVector
2809             .fromArray(isp, indexMap, mapOffset)
2810             .add(offset);
2811 
2812         vix = VectorIntrinsics.checkIndex(vix, a.length);
2813 
2814         return VectorSupport.loadWithMap(
2815             vectorType, null, float.class, vsp.laneCount(),
2816             isp.vectorType(),
2817             a, ARRAY_BASE, vix, null,
2818             a, offset, indexMap, mapOffset, vsp,
2819             (c, idx, iMap, idy, s, vm) ->
2820             s.vOp(n -> c[idx + iMap[idy+n]]));
2821     }
2822 
2823     /**
2824      * Gathers a new vector composed of elements from an array of type
2825      * {@code float[]},
2826      * under the control of a mask, and
2827      * using indexes obtained by adding a fixed {@code offset} to a
2828      * series of secondary offsets from an <em>index map</em>.
2829      * The index map is a contiguous sequence of {@code VLENGTH}
2830      * elements in a second array of {@code int}s, starting at a given
2831      * {@code mapOffset}.
2832      * <p>
2833      * For each vector lane, where {@code N} is the vector lane index,
2834      * if the lane is set in the mask,
2835      * the lane is loaded from the array
2836      * element {@code a[f(N)]}, where {@code f(N)} is the
2837      * index mapping expression
2838      * {@code offset + indexMap[mapOffset + N]]}.
2839      * Unset lanes in the resulting vector are set to zero.
2840      *
2841      * @param species species of desired vector

2849      * @return the vector loaded from the indexed elements of the array
2850      * @throws IndexOutOfBoundsException
2851      *         if {@code mapOffset+N < 0}
2852      *         or if {@code mapOffset+N >= indexMap.length},
2853      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
2854      *         is an invalid index into {@code a},
2855      *         for any lane {@code N} in the vector
2856      *         where the mask is set
2857      * @see FloatVector#toIntArray()
2858      */
2859     @ForceInline
2860     public static
2861     FloatVector fromArray(VectorSpecies<Float> species,
2862                                    float[] a, int offset,
2863                                    int[] indexMap, int mapOffset,
2864                                    VectorMask<Float> m) {
2865         if (m.allTrue()) {
2866             return fromArray(species, a, offset, indexMap, mapOffset);
2867         }
2868         else {

2869             FloatSpecies vsp = (FloatSpecies) species;
2870             return vsp.dummyVector().fromArray0(a, offset, indexMap, mapOffset, m);
2871         }
2872     }
2873 
2874 
2875 
2876     /**
2877      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
2878      * starting at an offset into the byte buffer.
2879      * Bytes are composed into primitive lane elements according
2880      * to the specified byte order.
2881      * The vector is arranged into lanes according to
2882      * <a href="Vector.html#lane-order">memory ordering</a>.
2883      * <p>
2884      * This method behaves as if it returns the result of calling
2885      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2886      * fromByteBuffer()} as follows:
2887      * <pre>{@code
2888      * var m = species.maskAll(true);
2889      * return fromByteBuffer(species, bb, offset, bo, m);
2890      * }</pre>

2944      * @param species species of desired vector
2945      * @param bb the byte buffer
2946      * @param offset the offset into the byte buffer
2947      * @param bo the intended byte order
2948      * @param m the mask controlling lane selection
2949      * @return a vector loaded from a byte buffer
2950      * @throws IndexOutOfBoundsException
2951      *         if {@code offset+N*4 < 0}
2952      *         or {@code offset+N*4 >= bb.limit()}
2953      *         for any lane {@code N} in the vector
2954      *         where the mask is set
2955      */
2956     @ForceInline
2957     public static
2958     FloatVector fromByteBuffer(VectorSpecies<Float> species,
2959                                         ByteBuffer bb, int offset,
2960                                         ByteOrder bo,
2961                                         VectorMask<Float> m) {
2962         FloatSpecies vsp = (FloatSpecies) species;
2963         if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) {
2964             return vsp.dummyVector().fromByteBuffer0(bb, offset, m).maybeSwap(bo);


2965         }
2966 
2967         // FIXME: optimize
2968         checkMaskFromIndexSize(offset, vsp, m, 4, bb.limit());
2969         ByteBuffer wb = wrapper(bb, bo);
2970         return vsp.ldOp(wb, offset, (AbstractMask<Float>)m,
2971                    (wb_, o, i)  -> wb_.getFloat(o + i * 4));
2972     }
2973 
2974     // Memory store operations
2975 
2976     /**
2977      * Stores this vector into an array of type {@code float[]}
2978      * starting at an offset.
2979      * <p>
2980      * For each vector lane, where {@code N} is the vector lane index,
2981      * the lane element at index {@code N} is stored into the array
2982      * element {@code a[offset+N]}.
2983      *
2984      * @param a the array, of type {@code float[]}

3016      * Lanes where the mask is unset are not stored and do not need
3017      * to correspond to legitimate elements of {@code a}.
3018      * That is, unset lanes may correspond to array indexes less than
3019      * zero or beyond the end of the array.
3020      *
3021      * @param a the array, of type {@code float[]}
3022      * @param offset the offset into the array
3023      * @param m the mask controlling lane storage
3024      * @throws IndexOutOfBoundsException
3025      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3026      *         for any lane {@code N} in the vector
3027      *         where the mask is set
3028      */
3029     @ForceInline
3030     public final
3031     void intoArray(float[] a, int offset,
3032                    VectorMask<Float> m) {
3033         if (m.allTrue()) {
3034             intoArray(a, offset);
3035         } else {

3036             FloatSpecies vsp = vspecies();
3037             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3038             intoArray0(a, offset, m);
3039         }
3040     }
3041 
3042     /**
3043      * Scatters this vector into an array of type {@code float[]}
3044      * using indexes obtained by adding a fixed {@code offset} to a
3045      * series of secondary offsets from an <em>index map</em>.
3046      * The index map is a contiguous sequence of {@code VLENGTH}
3047      * elements in a second array of {@code int}s, starting at a given
3048      * {@code mapOffset}.
3049      * <p>
3050      * For each vector lane, where {@code N} is the vector lane index,
3051      * the lane element at index {@code N} is stored into the array
3052      * element {@code a[f(N)]}, where {@code f(N)} is the
3053      * index mapping expression
3054      * {@code offset + indexMap[mapOffset + N]]}.
3055      *
3056      * @param a the array
3057      * @param offset an offset to combine with the index map offsets
3058      * @param indexMap the index map

3062      *         or if {@code mapOffset+N >= indexMap.length},
3063      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3064      *         is an invalid index into {@code a},
3065      *         for any lane {@code N} in the vector
3066      * @see FloatVector#toIntArray()
3067      */
3068     @ForceInline
3069     public final
3070     void intoArray(float[] a, int offset,
3071                    int[] indexMap, int mapOffset) {
3072         FloatSpecies vsp = vspecies();
3073         IntVector.IntSpecies isp = IntVector.species(vsp.indexShape());
3074         // Index vector: vix[0:n] = i -> offset + indexMap[mo + i]
3075         IntVector vix = IntVector
3076             .fromArray(isp, indexMap, mapOffset)
3077             .add(offset);
3078 
3079         vix = VectorIntrinsics.checkIndex(vix, a.length);
3080 
3081         VectorSupport.storeWithMap(
3082             vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(),
3083             isp.vectorType(),
3084             a, arrayAddress(a, 0), vix,
3085             this, null,
3086             a, offset, indexMap, mapOffset,
3087             (arr, off, v, map, mo, vm)
3088             -> v.stOp(arr, off,
3089                       (arr_, off_, i, e) -> {
3090                           int j = map[mo + i];
3091                           arr[off + j] = e;
3092                       }));
3093     }
3094 
3095     /**
3096      * Scatters this vector into an array of type {@code float[]},
3097      * under the control of a mask, and
3098      * using indexes obtained by adding a fixed {@code offset} to a
3099      * series of secondary offsets from an <em>index map</em>.
3100      * The index map is a contiguous sequence of {@code VLENGTH}
3101      * elements in a second array of {@code int}s, starting at a given
3102      * {@code mapOffset}.
3103      * <p>
3104      * For each vector lane, where {@code N} is the vector lane index,
3105      * if the mask lane at index {@code N} is set then
3106      * the lane element at index {@code N} is stored into the array
3107      * element {@code a[f(N)]}, where {@code f(N)} is the

3114      * @param mapOffset the offset into the index map
3115      * @param m the mask
3116      * @throws IndexOutOfBoundsException
3117      *         if {@code mapOffset+N < 0}
3118      *         or if {@code mapOffset+N >= indexMap.length},
3119      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3120      *         is an invalid index into {@code a},
3121      *         for any lane {@code N} in the vector
3122      *         where the mask is set
3123      * @see FloatVector#toIntArray()
3124      */
3125     @ForceInline
3126     public final
3127     void intoArray(float[] a, int offset,
3128                    int[] indexMap, int mapOffset,
3129                    VectorMask<Float> m) {
3130         if (m.allTrue()) {
3131             intoArray(a, offset, indexMap, mapOffset);
3132         }
3133         else {
3134             intoArray0(a, offset, indexMap, mapOffset, m);





3135         }
3136     }
3137 
3138 
3139 
3140     /**
3141      * {@inheritDoc} <!--workaround-->
3142      */
3143     @Override
3144     @ForceInline
3145     public final
3146     void intoByteArray(byte[] a, int offset,
3147                        ByteOrder bo) {
3148         offset = checkFromIndexSize(offset, byteSize(), a.length);
3149         maybeSwap(bo).intoByteArray0(a, offset);
3150     }
3151 
3152     /**
3153      * {@inheritDoc} <!--workaround-->
3154      */
3155     @Override
3156     @ForceInline
3157     public final
3158     void intoByteArray(byte[] a, int offset,
3159                        ByteOrder bo,
3160                        VectorMask<Float> m) {
3161         if (m.allTrue()) {
3162             intoByteArray(a, offset, bo);
3163         } else {

3164             FloatSpecies vsp = vspecies();
3165             checkMaskFromIndexSize(offset, vsp, m, 4, a.length);
3166             maybeSwap(bo).intoByteArray0(a, offset, m);


3167         }
3168     }
3169 
3170     /**
3171      * {@inheritDoc} <!--workaround-->
3172      */
3173     @Override
3174     @ForceInline
3175     public final
3176     void intoByteBuffer(ByteBuffer bb, int offset,
3177                         ByteOrder bo) {
3178         if (ScopedMemoryAccess.isReadOnly(bb)) {
3179             throw new ReadOnlyBufferException();
3180         }
3181         offset = checkFromIndexSize(offset, byteSize(), bb.limit());
3182         maybeSwap(bo).intoByteBuffer0(bb, offset);
3183     }
3184 
3185     /**
3186      * {@inheritDoc} <!--workaround-->
3187      */
3188     @Override
3189     @ForceInline
3190     public final
3191     void intoByteBuffer(ByteBuffer bb, int offset,
3192                         ByteOrder bo,
3193                         VectorMask<Float> m) {
3194         if (m.allTrue()) {
3195             intoByteBuffer(bb, offset, bo);
3196         } else {

3197             if (bb.isReadOnly()) {
3198                 throw new ReadOnlyBufferException();
3199             }
3200             FloatSpecies vsp = vspecies();
3201             checkMaskFromIndexSize(offset, vsp, m, 4, bb.limit());
3202             maybeSwap(bo).intoByteBuffer0(bb, offset, m);


3203         }
3204     }
3205 
3206     // ================================================
3207 
3208     // Low-level memory operations.
3209     //
3210     // Note that all of these operations *must* inline into a context
3211     // where the exact species of the involved vector is a
3212     // compile-time constant.  Otherwise, the intrinsic generation
3213     // will fail and performance will suffer.
3214     //
3215     // In many cases this is achieved by re-deriving a version of the
3216     // method in each concrete subclass (per species).  The re-derived
3217     // method simply calls one of these generic methods, with exact
3218     // parameters for the controlling metadata, which is either a
3219     // typed vector or constant species instance.
3220 
3221     // Unchecked loading operations in native byte order.
3222     // Caller is responsible for applying index checks, masking, and
3223     // byte swapping.
3224 
3225     /*package-private*/
3226     abstract
3227     FloatVector fromArray0(float[] a, int offset);
3228     @ForceInline
3229     final
3230     FloatVector fromArray0Template(float[] a, int offset) {
3231         FloatSpecies vsp = vspecies();
3232         return VectorSupport.load(
3233             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3234             a, arrayAddress(a, offset),
3235             a, offset, vsp,
3236             (arr, off, s) -> s.ldOp(arr, off,
3237                                     (arr_, off_, i) -> arr_[off_ + i]));
3238     }
3239 
3240     /*package-private*/
3241     abstract
3242     FloatVector fromArray0(float[] a, int offset, VectorMask<Float> m);
3243     @ForceInline
3244     final
3245     <M extends VectorMask<Float>>
3246     FloatVector fromArray0Template(Class<M> maskClass, float[] a, int offset, M m) {
3247         m.check(species());
3248         FloatSpecies vsp = vspecies();
3249         return VectorSupport.loadMasked(
3250             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3251             a, arrayAddress(a, offset), m,
3252             a, offset, vsp,
3253             (arr, off, s, vm) -> s.ldOp(arr, off, vm,
3254                                         (arr_, off_, i) -> arr_[off_ + i]));
3255     }
3256 
3257     /*package-private*/
3258     abstract
3259     FloatVector fromArray0(float[] a, int offset,
3260                                     int[] indexMap, int mapOffset,
3261                                     VectorMask<Float> m);
3262     @ForceInline
3263     final
3264     <M extends VectorMask<Float>>
3265     FloatVector fromArray0Template(Class<M> maskClass, float[] a, int offset,
3266                                             int[] indexMap, int mapOffset, M m) {
3267         FloatSpecies vsp = vspecies();
3268         IntVector.IntSpecies isp = IntVector.species(vsp.indexShape());
3269         Objects.requireNonNull(a);
3270         Objects.requireNonNull(indexMap);
3271         m.check(vsp);
3272         Class<? extends FloatVector> vectorType = vsp.vectorType();
3273 
3274         // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k]
3275         IntVector vix = IntVector
3276             .fromArray(isp, indexMap, mapOffset)
3277             .add(offset);
3278 
3279         // FIXME: Check index under mask controlling.
3280         vix = VectorIntrinsics.checkIndex(vix, a.length);
3281 
3282         return VectorSupport.loadWithMap(
3283             vectorType, maskClass, float.class, vsp.laneCount(),
3284             isp.vectorType(),
3285             a, ARRAY_BASE, vix, m,
3286             a, offset, indexMap, mapOffset, vsp,
3287             (c, idx, iMap, idy, s, vm) ->
3288             s.vOp(vm, n -> c[idx + iMap[idy+n]]));
3289     }
3290 
3291 
3292 
3293     @Override
3294     abstract
3295     FloatVector fromByteArray0(byte[] a, int offset);
3296     @ForceInline
3297     final
3298     FloatVector fromByteArray0Template(byte[] a, int offset) {
3299         FloatSpecies vsp = vspecies();
3300         return VectorSupport.load(
3301             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3302             a, byteArrayAddress(a, offset),
3303             a, offset, vsp,
3304             (arr, off, s) -> {
3305                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3306                 return s.ldOp(wb, off,
3307                         (wb_, o, i) -> wb_.getFloat(o + i * 4));
3308             });
3309     }
3310 
3311     abstract
3312     FloatVector fromByteArray0(byte[] a, int offset, VectorMask<Float> m);
3313     @ForceInline
3314     final
3315     <M extends VectorMask<Float>>
3316     FloatVector fromByteArray0Template(Class<M> maskClass, byte[] a, int offset, M m) {
3317         FloatSpecies vsp = vspecies();
3318         m.check(vsp);
3319         return VectorSupport.loadMasked(
3320             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3321             a, byteArrayAddress(a, offset), m,
3322             a, offset, vsp,
3323             (arr, off, s, vm) -> {
3324                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3325                 return s.ldOp(wb, off, vm,
3326                         (wb_, o, i) -> wb_.getFloat(o + i * 4));
3327             });
3328     }
3329 
3330     abstract
3331     FloatVector fromByteBuffer0(ByteBuffer bb, int offset);
3332     @ForceInline
3333     final
3334     FloatVector fromByteBuffer0Template(ByteBuffer bb, int offset) {
3335         FloatSpecies vsp = vspecies();
3336         return ScopedMemoryAccess.loadFromByteBuffer(
3337                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3338                 bb, offset, vsp,
3339                 (buf, off, s) -> {
3340                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3341                     return s.ldOp(wb, off,
3342                             (wb_, o, i) -> wb_.getFloat(o + i * 4));
3343                 });
3344     }
3345 
3346     abstract
3347     FloatVector fromByteBuffer0(ByteBuffer bb, int offset, VectorMask<Float> m);
3348     @ForceInline
3349     final
3350     <M extends VectorMask<Float>>
3351     FloatVector fromByteBuffer0Template(Class<M> maskClass, ByteBuffer bb, int offset, M m) {
3352         FloatSpecies vsp = vspecies();
3353         m.check(vsp);
3354         return ScopedMemoryAccess.loadFromByteBufferMasked(
3355                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3356                 bb, offset, m, vsp,
3357                 (buf, off, s, vm) -> {
3358                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3359                     return s.ldOp(wb, off, vm,
3360                             (wb_, o, i) -> wb_.getFloat(o + i * 4));
3361                 });
3362     }
3363 
3364     // Unchecked storing operations in native byte order.
3365     // Caller is responsible for applying index checks, masking, and
3366     // byte swapping.
3367 
3368     abstract
3369     void intoArray0(float[] a, int offset);
3370     @ForceInline
3371     final
3372     void intoArray0Template(float[] a, int offset) {
3373         FloatSpecies vsp = vspecies();
3374         VectorSupport.store(
3375             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3376             a, arrayAddress(a, offset),
3377             this, a, offset,
3378             (arr, off, v)
3379             -> v.stOp(arr, off,
3380                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3381     }
3382 
3383     abstract
3384     void intoArray0(float[] a, int offset, VectorMask<Float> m);
3385     @ForceInline
3386     final
3387     <M extends VectorMask<Float>>
3388     void intoArray0Template(Class<M> maskClass, float[] a, int offset, M m) {
3389         m.check(species());
3390         FloatSpecies vsp = vspecies();
3391         VectorSupport.storeMasked(
3392             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3393             a, arrayAddress(a, offset),
3394             this, m, a, offset,
3395             (arr, off, v, vm)
3396             -> v.stOp(arr, off, vm,
3397                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
3398     }
3399 
3400     abstract
3401     void intoArray0(float[] a, int offset,
3402                     int[] indexMap, int mapOffset,
3403                     VectorMask<Float> m);
3404     @ForceInline
3405     final
3406     <M extends VectorMask<Float>>
3407     void intoArray0Template(Class<M> maskClass, float[] a, int offset,
3408                             int[] indexMap, int mapOffset, M m) {
3409         m.check(species());
3410         FloatSpecies vsp = vspecies();
3411         IntVector.IntSpecies isp = IntVector.species(vsp.indexShape());
3412         // Index vector: vix[0:n] = i -> offset + indexMap[mo + i]
3413         IntVector vix = IntVector
3414             .fromArray(isp, indexMap, mapOffset)
3415             .add(offset);
3416 
3417         // FIXME: Check index under mask controlling.
3418         vix = VectorIntrinsics.checkIndex(vix, a.length);
3419 
3420         VectorSupport.storeWithMap(
3421             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3422             isp.vectorType(),
3423             a, arrayAddress(a, 0), vix,
3424             this, m,
3425             a, offset, indexMap, mapOffset,
3426             (arr, off, v, map, mo, vm)
3427             -> v.stOp(arr, off, vm,
3428                       (arr_, off_, i, e) -> {
3429                           int j = map[mo + i];
3430                           arr[off + j] = e;
3431                       }));
3432     }
3433 
3434 
3435     abstract
3436     void intoByteArray0(byte[] a, int offset);
3437     @ForceInline
3438     final
3439     void intoByteArray0Template(byte[] a, int offset) {
3440         FloatSpecies vsp = vspecies();
3441         VectorSupport.store(
3442             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3443             a, byteArrayAddress(a, offset),
3444             this, a, offset,
3445             (arr, off, v) -> {
3446                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3447                 v.stOp(wb, off,
3448                         (tb_, o, i, e) -> tb_.putFloat(o + i * 4, e));
3449             });
3450     }
3451 
3452     abstract
3453     void intoByteArray0(byte[] a, int offset, VectorMask<Float> m);
3454     @ForceInline
3455     final
3456     <M extends VectorMask<Float>>
3457     void intoByteArray0Template(Class<M> maskClass, byte[] a, int offset, M m) {
3458         FloatSpecies vsp = vspecies();
3459         m.check(vsp);
3460         VectorSupport.storeMasked(
3461             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3462             a, byteArrayAddress(a, offset),
3463             this, m, a, offset,
3464             (arr, off, v, vm) -> {
3465                 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN);
3466                 v.stOp(wb, off, vm,
3467                         (tb_, o, i, e) -> tb_.putFloat(o + i * 4, e));
3468             });
3469     }
3470 
3471     @ForceInline
3472     final
3473     void intoByteBuffer0(ByteBuffer bb, int offset) {
3474         FloatSpecies vsp = vspecies();
3475         ScopedMemoryAccess.storeIntoByteBuffer(
3476                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3477                 this, bb, offset,
3478                 (buf, off, v) -> {
3479                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3480                     v.stOp(wb, off,
3481                             (wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
3482                 });
3483     }
3484 
3485     abstract
3486     void intoByteBuffer0(ByteBuffer bb, int offset, VectorMask<Float> m);
3487     @ForceInline
3488     final
3489     <M extends VectorMask<Float>>
3490     void intoByteBuffer0Template(Class<M> maskClass, ByteBuffer bb, int offset, M m) {
3491         FloatSpecies vsp = vspecies();
3492         m.check(vsp);
3493         ScopedMemoryAccess.storeIntoByteBufferMasked(
3494                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3495                 this, m, bb, offset,
3496                 (buf, off, v, vm) -> {
3497                     ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN);
3498                     v.stOp(wb, off, vm,
3499                             (wb_, o, i, e) -> wb_.putFloat(o + i * 4, e));
3500                 });
3501     }
3502 
3503 
3504     // End of low-level memory operations.
3505 
3506     private static
3507     void checkMaskFromIndexSize(int offset,
3508                                 FloatSpecies vsp,
3509                                 VectorMask<Float> m,
3510                                 int scale,
3511                                 int limit) {
3512         ((AbstractMask<Float>)m)
3513             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3514     }
3515 
3516     @ForceInline
3517     private void conditionalStoreNYI(int offset,
3518                                      FloatSpecies vsp,
3519                                      VectorMask<Float> m,
3520                                      int scale,
3521                                      int limit) {
3522         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3523             String msg =

3801             float[] res = new float[laneCount()];
3802             boolean[] mbits = ((AbstractMask<Float>)m).getBits();
3803             for (int i = 0; i < res.length; i++) {
3804                 if (mbits[i]) {
3805                     res[i] = f.apply(i);
3806                 }
3807             }
3808             return dummyVector().vectorFactory(res);
3809         }
3810 
3811         /*package-private*/
3812         @ForceInline
3813         <M> FloatVector ldOp(M memory, int offset,
3814                                       FLdOp<M> f) {
3815             return dummyVector().ldOp(memory, offset, f);
3816         }
3817 
3818         /*package-private*/
3819         @ForceInline
3820         <M> FloatVector ldOp(M memory, int offset,
3821                                       VectorMask<Float> m,
3822                                       FLdOp<M> f) {
3823             return dummyVector().ldOp(memory, offset, m, f);
3824         }
3825 
3826         /*package-private*/
3827         @ForceInline
3828         <M> void stOp(M memory, int offset, FStOp<M> f) {
3829             dummyVector().stOp(memory, offset, f);
3830         }
3831 
3832         /*package-private*/
3833         @ForceInline
3834         <M> void stOp(M memory, int offset,
3835                       AbstractMask<Float> m,
3836                       FStOp<M> f) {
3837             dummyVector().stOp(memory, offset, m, f);
3838         }
3839 
3840         // N.B. Make sure these constant vectors and
3841         // masks load up correctly into registers.
< prev index next >