< prev index next >

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

Print this page

   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have 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 byte} values.
  50  */
  51 @SuppressWarnings("cast")  // warning: redundant cast
  52 public abstract class ByteVector extends AbstractVector<Byte> {
  53 
  54     ByteVector(byte[] vec) {
  55         super(vec);
  56     }
  57 
  58     static final int FORBID_OPCODE_KIND = VO_ONLYFP;
  59 


  60     @ForceInline
  61     static int opCode(Operator op) {
  62         return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND);
  63     }
  64     @ForceInline
  65     static int opCode(Operator op, int requireKind) {
  66         requireKind |= VO_OPCODE_VALID;
  67         return VectorOperators.opCode(op, requireKind, FORBID_OPCODE_KIND);
  68     }
  69     @ForceInline
  70     static boolean opKind(Operator op, int bit) {
  71         return VectorOperators.opKind(op, bit);
  72     }
  73 
  74     // Virtualized factories and operators,
  75     // coded with portable definitions.
  76     // These are all @ForceInline in case
  77     // they need to be used performantly.
  78     // The various shape-specific subclasses
  79     // also specialize them by wrapping

 334         return vectorFactory(res);
 335     }
 336 
 337     /*package-private*/
 338     @ForceInline
 339     final
 340     <M> ByteVector ldOp(M memory, int offset,
 341                                   VectorMask<Byte> m,
 342                                   FLdOp<M> f) {
 343         //byte[] vec = vec();
 344         byte[] res = new byte[length()];
 345         boolean[] mbits = ((AbstractMask<Byte>)m).getBits();
 346         for (int i = 0; i < res.length; i++) {
 347             if (mbits[i]) {
 348                 res[i] = f.apply(memory, offset, i);
 349             }
 350         }
 351         return vectorFactory(res);
 352     }
 353 







































 354     interface FStOp<M> {
 355         void apply(M memory, int offset, int i, byte a);
 356     }
 357 
 358     /*package-private*/
 359     @ForceInline
 360     final
 361     <M> void stOp(M memory, int offset,
 362                   FStOp<M> f) {
 363         byte[] vec = vec();
 364         for (int i = 0; i < vec.length; i++) {
 365             f.apply(memory, offset, i, vec[i]);
 366         }
 367     }
 368 
 369     /*package-private*/
 370     @ForceInline
 371     final
 372     <M> void stOp(M memory, int offset,
 373                   VectorMask<Byte> m,
 374                   FStOp<M> f) {
 375         byte[] vec = vec();
 376         boolean[] mbits = ((AbstractMask<Byte>)m).getBits();
 377         for (int i = 0; i < vec.length; i++) {
 378             if (mbits[i]) {
 379                 f.apply(memory, offset, i, vec[i]);
 380             }
 381         }
 382     }
 383 


































 384     // Binary test
 385 
 386     /*package-private*/
 387     interface FBinTest {
 388         boolean apply(int cond, int i, byte a, byte b);
 389     }
 390 
 391     /*package-private*/
 392     @ForceInline
 393     final
 394     AbstractMask<Byte> bTest(int cond,
 395                                   Vector<Byte> o,
 396                                   FBinTest f) {
 397         byte[] vec1 = vec();
 398         byte[] vec2 = ((ByteVector)o).vec();
 399         boolean[] bits = new boolean[length()];
 400         for (int i = 0; i < length(); i++){
 401             bits[i] = f.apply(cond, i, vec1[i], vec2[i]);
 402         }
 403         return maskFactory(bits);

 414     static byte rotateRight(byte a, int n) {
 415         return (byte)(((((byte)a) & Byte.toUnsignedInt((byte)-1)) >>> (n & Byte.SIZE-1)) | ((((byte)a) & Byte.toUnsignedInt((byte)-1)) << (Byte.SIZE - (n & Byte.SIZE-1))));
 416     }
 417 
 418     /*package-private*/
 419     @Override
 420     abstract ByteSpecies vspecies();
 421 
 422     /*package-private*/
 423     @ForceInline
 424     static long toBits(byte e) {
 425         return  e;
 426     }
 427 
 428     /*package-private*/
 429     @ForceInline
 430     static byte fromBits(long bits) {
 431         return ((byte)bits);
 432     }
 433 






























 434     // Static factories (other than memory operations)
 435 
 436     // Note: A surprising behavior in javadoc
 437     // sometimes makes a lone /** {@inheritDoc} */
 438     // comment drop the method altogether,
 439     // apparently if the method mentions an
 440     // parameter or return type of Vector<Byte>
 441     // instead of Vector<E> as originally specified.
 442     // Adding an empty HTML fragment appears to
 443     // nudge javadoc into providing the desired
 444     // inherited documentation.  We use the HTML
 445     // comment <!--workaround--> for this.
 446 
 447     /**
 448      * Returns a vector of the given species
 449      * where all lane elements are set to
 450      * zero, the default primitive value.
 451      *
 452      * @param species species of the desired zero vector
 453      * @return a zero vector

 603                 return lanewise(XOR, broadcast(-1), m);
 604             }
 605         }
 606         int opc = opCode(op);
 607         return VectorSupport.unaryOp(
 608             opc, getClass(), maskClass, byte.class, length(),
 609             this, m,
 610             UN_IMPL.find(op, opc, ByteVector::unaryOperations));
 611     }
 612 
 613     private static final
 614     ImplCache<Unary, UnaryOperation<ByteVector, VectorMask<Byte>>>
 615         UN_IMPL = new ImplCache<>(Unary.class, ByteVector.class);
 616 
 617     private static UnaryOperation<ByteVector, VectorMask<Byte>> unaryOperations(int opc_) {
 618         switch (opc_) {
 619             case VECTOR_OP_NEG: return (v0, m) ->
 620                     v0.uOp(m, (i, a) -> (byte) -a);
 621             case VECTOR_OP_ABS: return (v0, m) ->
 622                     v0.uOp(m, (i, a) -> (byte) Math.abs(a));










 623             default: return null;
 624         }
 625     }
 626 
 627     // Binary lanewise support
 628 
 629     /**
 630      * {@inheritDoc} <!--workaround-->
 631      * @see #lanewise(VectorOperators.Binary,byte)
 632      * @see #lanewise(VectorOperators.Binary,byte,VectorMask)
 633      */
 634     @Override
 635     public abstract
 636     ByteVector lanewise(VectorOperators.Binary op,
 637                                   Vector<Byte> v);
 638     @ForceInline
 639     final
 640     ByteVector lanewiseTemplate(VectorOperators.Binary op,
 641                                           Vector<Byte> v) {
 642         ByteVector that = (ByteVector) v;

1729     /**
1730      * {@inheritDoc} <!--workaround-->
1731      */
1732     @Override
1733     @ForceInline
1734     public final
1735     ByteVector neg() {
1736         return lanewise(NEG);
1737     }
1738 
1739     /**
1740      * {@inheritDoc} <!--workaround-->
1741      */
1742     @Override
1743     @ForceInline
1744     public final
1745     ByteVector abs() {
1746         return lanewise(ABS);
1747     }
1748 



















1749     // not (~)
1750     /**
1751      * Computes the bitwise logical complement ({@code ~})
1752      * of this vector.
1753      *
1754      * This is a lane-wise binary operation which applies the
1755      * the primitive bitwise "not" operation ({@code ~})
1756      * to each lane value.
1757      *
1758      * This method is also equivalent to the expression
1759      * {@link #lanewise(VectorOperators.Unary)
1760      *    lanewise}{@code (}{@link VectorOperators#NOT
1761      *    NOT}{@code )}.
1762      *
1763      * <p>
1764      * This is not a full-service named operation like
1765      * {@link #add(Vector) add}.  A masked version of
1766      * this operation is not directly available
1767      * but may be obtained via the masked version of
1768      * {@code lanewise}.

2355         byte[] a = toArray();
2356         int[] sa = new int[a.length];
2357         for (int i = 0; i < a.length; i++) {
2358             sa[i] = (int) a[i];
2359         }
2360         return VectorShuffle.fromArray(dsp, sa, 0);
2361     }
2362 
2363     /*package-private*/
2364     @ForceInline
2365     final
2366     VectorShuffle<Byte> toShuffleTemplate(Class<?> shuffleType) {
2367         ByteSpecies vsp = vspecies();
2368         return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST,
2369                                      getClass(), byte.class, length(),
2370                                      shuffleType, byte.class, length(),
2371                                      this, vsp,
2372                                      ByteVector::toShuffle0);
2373     }
2374 







































2375     /**
2376      * {@inheritDoc} <!--workaround-->
2377      */
2378     @Override
2379     public abstract
2380     ByteVector selectFrom(Vector<Byte> v);
2381 
2382     /*package-private*/
2383     @ForceInline
2384     final ByteVector selectFromTemplate(ByteVector v) {
2385         return v.rearrange(this.toShuffle());
2386     }
2387 
2388     /**
2389      * {@inheritDoc} <!--workaround-->
2390      */
2391     @Override
2392     public abstract
2393     ByteVector selectFrom(Vector<Byte> s, VectorMask<Byte> m);
2394 

2767         return res;
2768     }
2769 
2770     /** {@inheritDoc} <!--workaround-->
2771      * @implNote
2772      * When this method is used on used on vectors
2773      * of type {@code ByteVector},
2774      * there will be no loss of precision.
2775      */
2776     @ForceInline
2777     @Override
2778     public final double[] toDoubleArray() {
2779         byte[] a = toArray();
2780         double[] res = new double[a.length];
2781         for (int i = 0; i < a.length; i++) {
2782             res[i] = (double) a[i];
2783         }
2784         return res;
2785     }
2786 
2787     /**
2788      * Loads a vector from a byte array starting at an offset.
2789      * Bytes are composed into primitive lane elements according
2790      * to the specified byte order.
2791      * The vector is arranged into lanes according to
2792      * <a href="Vector.html#lane-order">memory ordering</a>.
2793      * <p>
2794      * This method behaves as if it returns the result of calling
2795      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2796      * fromByteBuffer()} as follows:
2797      * <pre>{@code
2798      * var bb = ByteBuffer.wrap(a);
2799      * var m = species.maskAll(true);
2800      * return fromByteBuffer(species, bb, offset, bo, m);
2801      * }</pre>
2802      *
2803      * @param species species of desired vector
2804      * @param a the byte array
2805      * @param offset the offset into the array
2806      * @param bo the intended byte order
2807      * @return a vector loaded from a byte array
2808      * @throws IndexOutOfBoundsException
2809      *         if {@code offset+N*ESIZE < 0}
2810      *         or {@code offset+(N+1)*ESIZE > a.length}
2811      *         for any lane {@code N} in the vector
2812      */
2813     @ForceInline
2814     public static
2815     ByteVector fromByteArray(VectorSpecies<Byte> species,
2816                                        byte[] a, int offset,
2817                                        ByteOrder bo) {
2818         offset = checkFromIndexSize(offset, species.vectorByteSize(), a.length);
2819         ByteSpecies vsp = (ByteSpecies) species;
2820         return vsp.dummyVector().fromByteArray0(a, offset).maybeSwap(bo);
2821     }
2822 
2823     /**
2824      * Loads a vector from a byte array starting at an offset
2825      * and using a mask.
2826      * Lanes where the mask is unset are filled with the default
2827      * value of {@code byte} (zero).
2828      * Bytes are composed into primitive lane elements according
2829      * to the specified byte order.
2830      * The vector is arranged into lanes according to
2831      * <a href="Vector.html#lane-order">memory ordering</a>.
2832      * <p>
2833      * This method behaves as if it returns the result of calling
2834      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
2835      * fromByteBuffer()} as follows:
2836      * <pre>{@code
2837      * var bb = ByteBuffer.wrap(a);
2838      * return fromByteBuffer(species, bb, offset, bo, m);
2839      * }</pre>
2840      *
2841      * @param species species of desired vector
2842      * @param a the byte array
2843      * @param offset the offset into the array
2844      * @param bo the intended byte order
2845      * @param m the mask controlling lane selection
2846      * @return a vector loaded from a byte array
2847      * @throws IndexOutOfBoundsException
2848      *         if {@code offset+N*ESIZE < 0}
2849      *         or {@code offset+(N+1)*ESIZE > a.length}
2850      *         for any lane {@code N} in the vector
2851      *         where the mask is set
2852      */
2853     @ForceInline
2854     public static
2855     ByteVector fromByteArray(VectorSpecies<Byte> species,
2856                                        byte[] a, int offset,
2857                                        ByteOrder bo,
2858                                        VectorMask<Byte> m) {
2859         ByteSpecies vsp = (ByteSpecies) species;
2860         if (offset >= 0 && offset <= (a.length - species.vectorByteSize())) {
2861             return vsp.dummyVector().fromByteArray0(a, offset, m).maybeSwap(bo);
2862         }
2863 
2864         // FIXME: optimize
2865         checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
2866         ByteBuffer wb = wrapper(a, bo);
2867         return vsp.ldOp(wb, offset, (AbstractMask<Byte>)m,
2868                    (wb_, o, i)  -> wb_.get(o + i * 1));
2869     }
2870 
2871     /**
2872      * Loads a vector from an array of type {@code byte[]}
2873      * starting at an offset.
2874      * For each vector lane, where {@code N} is the vector lane index, the
2875      * array element at index {@code offset + N} is placed into the
2876      * resulting vector at lane index {@code N}.
2877      *
2878      * @param species species of desired vector
2879      * @param a the array
2880      * @param offset the offset into the array
2881      * @return the vector loaded from an array
2882      * @throws IndexOutOfBoundsException
2883      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2884      *         for any lane {@code N} in the vector
2885      */
2886     @ForceInline
2887     public static
2888     ByteVector fromArray(VectorSpecies<Byte> species,
2889                                    byte[] a, int offset) {
2890         offset = checkFromIndexSize(offset, species.length(), a.length);

3157      *         if {@code mapOffset+N < 0}
3158      *         or if {@code mapOffset+N >= indexMap.length},
3159      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3160      *         is an invalid index into {@code a},
3161      *         for any lane {@code N} in the vector
3162      *         where the mask is set
3163      * @see ByteVector#toIntArray()
3164      */
3165     @ForceInline
3166     public static
3167     ByteVector fromBooleanArray(VectorSpecies<Byte> species,
3168                                           boolean[] a, int offset,
3169                                           int[] indexMap, int mapOffset,
3170                                           VectorMask<Byte> m) {
3171         // FIXME: optimize
3172         ByteSpecies vsp = (ByteSpecies) species;
3173         return vsp.vOp(m, n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0));
3174     }
3175 
3176     /**
3177      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
3178      * starting at an offset into the byte buffer.
3179      * Bytes are composed into primitive lane elements according
3180      * to the specified byte order.
3181      * The vector is arranged into lanes according to
3182      * <a href="Vector.html#lane-order">memory ordering</a>.
3183      * <p>
3184      * This method behaves as if it returns the result of calling
3185      * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask)
3186      * fromByteBuffer()} as follows:
3187      * <pre>{@code
3188      * var m = species.maskAll(true);
3189      * return fromByteBuffer(species, bb, offset, bo, m);
3190      * }</pre>
3191      *
3192      * @param species species of desired vector
3193      * @param bb the byte buffer
3194      * @param offset the offset into the byte buffer
3195      * @param bo the intended byte order
3196      * @return a vector loaded from a byte buffer
3197      * @throws IndexOutOfBoundsException
3198      *         if {@code offset+N*1 < 0}
3199      *         or {@code offset+N*1 >= bb.limit()}
3200      *         for any lane {@code N} in the vector





3201      */
3202     @ForceInline
3203     public static
3204     ByteVector fromByteBuffer(VectorSpecies<Byte> species,
3205                                         ByteBuffer bb, int offset,
3206                                         ByteOrder bo) {
3207         offset = checkFromIndexSize(offset, species.vectorByteSize(), bb.limit());
3208         ByteSpecies vsp = (ByteSpecies) species;
3209         return vsp.dummyVector().fromByteBuffer0(bb, offset).maybeSwap(bo);
3210     }
3211 
3212     /**
3213      * Loads a vector from a {@linkplain ByteBuffer byte buffer}
3214      * starting at an offset into the byte buffer
3215      * and using a mask.
3216      * Lanes where the mask is unset are filled with the default
3217      * value of {@code byte} (zero).
3218      * Bytes are composed into primitive lane elements according
3219      * to the specified byte order.
3220      * The vector is arranged into lanes according to
3221      * <a href="Vector.html#lane-order">memory ordering</a>.
3222      * <p>
3223      * The following pseudocode illustrates the behavior:
3224      * <pre>{@code
3225      * ByteBuffer eb = bb.duplicate()
3226      *     .position(offset);
3227      * byte[] ar = new byte[species.length()];
3228      * for (int n = 0; n < ar.length; n++) {
3229      *     if (m.laneIsSet(n)) {
3230      *         ar[n] = eb.get(n);
3231      *     }
3232      * }
3233      * ByteVector r = ByteVector.fromArray(species, ar, 0);
3234      * }</pre>
3235      * @implNote
3236      * The byte order argument is ignored.
3237      *
3238      * @param species species of desired vector
3239      * @param bb the byte buffer
3240      * @param offset the offset into the byte buffer
3241      * @param bo the intended byte order
3242      * @param m the mask controlling lane selection
3243      * @return a vector loaded from a byte buffer
3244      * @throws IndexOutOfBoundsException
3245      *         if {@code offset+N*1 < 0}
3246      *         or {@code offset+N*1 >= bb.limit()}
3247      *         for any lane {@code N} in the vector
3248      *         where the mask is set





3249      */
3250     @ForceInline
3251     public static
3252     ByteVector fromByteBuffer(VectorSpecies<Byte> species,
3253                                         ByteBuffer bb, int offset,
3254                                         ByteOrder bo,
3255                                         VectorMask<Byte> m) {
3256         ByteSpecies vsp = (ByteSpecies) species;
3257         if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) {
3258             return vsp.dummyVector().fromByteBuffer0(bb, offset, m).maybeSwap(bo);
3259         }
3260 
3261         // FIXME: optimize
3262         checkMaskFromIndexSize(offset, vsp, m, 1, bb.limit());
3263         ByteBuffer wb = wrapper(bb, bo);
3264         return vsp.ldOp(wb, offset, (AbstractMask<Byte>)m,
3265                    (wb_, o, i)  -> wb_.get(o + i * 1));
3266     }
3267 
3268     // Memory store operations
3269 
3270     /**
3271      * Stores this vector into an array of type {@code byte[]}
3272      * starting at an offset.
3273      * <p>
3274      * For each vector lane, where {@code N} is the vector lane index,
3275      * the lane element at index {@code N} is stored into the array
3276      * element {@code a[offset+N]}.
3277      *
3278      * @param a the array, of type {@code byte[]}
3279      * @param offset the offset into the array
3280      * @throws IndexOutOfBoundsException
3281      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3282      *         for any lane {@code N} in the vector
3283      */
3284     @ForceInline
3285     public final
3286     void intoArray(byte[] a, int offset) {
3287         offset = checkFromIndexSize(offset, length(), a.length);
3288         ByteSpecies vsp = vspecies();
3289         VectorSupport.store(
3290             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3291             a, arrayAddress(a, offset),
3292             this,
3293             a, offset,
3294             (arr, off, v)
3295             -> v.stOp(arr, off,
3296                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
3297     }
3298 
3299     /**
3300      * Stores this vector into an array of type {@code byte[]}
3301      * starting at offset and using a mask.
3302      * <p>
3303      * For each vector lane, where {@code N} is the vector lane index,
3304      * the lane element at index {@code N} is stored into the array
3305      * element {@code a[offset+N]}.
3306      * If the mask lane at {@code N} is unset then the corresponding
3307      * array element {@code a[offset+N]} is left unchanged.
3308      * <p>
3309      * Array range checking is done for lanes where the mask is set.
3310      * Lanes where the mask is unset are not stored and do not need
3311      * to correspond to legitimate elements of {@code a}.
3312      * That is, unset lanes may correspond to array indexes less than
3313      * zero or beyond the end of the array.
3314      *
3315      * @param a the array, of type {@code byte[]}

3426      * expression {@code (b & 1) != 0} where {@code b} is the byte value.
3427      *
3428      * @param a the array
3429      * @param offset the offset into the array
3430      * @throws IndexOutOfBoundsException
3431      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3432      *         for any lane {@code N} in the vector
3433      */
3434     @ForceInline
3435     public final
3436     void intoBooleanArray(boolean[] a, int offset) {
3437         offset = checkFromIndexSize(offset, length(), a.length);
3438         ByteSpecies vsp = vspecies();
3439         ByteVector normalized = this.and((byte) 1);
3440         VectorSupport.store(
3441             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3442             a, booleanArrayAddress(a, offset),
3443             normalized,
3444             a, offset,
3445             (arr, off, v)
3446             -> v.stOp(arr, off,
3447                       (arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0));
3448     }
3449 
3450     /**
3451      * Stores this vector into an array of type {@code boolean[]}
3452      * starting at offset and using a mask.
3453      * <p>
3454      * For each vector lane, where {@code N} is the vector lane index,
3455      * the lane element at index {@code N}
3456      * is first converted to a {@code boolean} value and then
3457      * stored into the array element {@code a[offset+N]}.
3458      * If the mask lane at {@code N} is unset then the corresponding
3459      * array element {@code a[offset+N]} is left unchanged.
3460      * <p>
3461      * A {@code byte} value is converted to a {@code boolean} value by applying the
3462      * expression {@code (b & 1) != 0} where {@code b} is the byte value.
3463      * <p>
3464      * Array range checking is done for lanes where the mask is set.
3465      * Lanes where the mask is unset are not stored and do not need
3466      * to correspond to legitimate elements of {@code a}.

3564      *         is an invalid index into {@code a},
3565      *         for any lane {@code N} in the vector
3566      *         where the mask is set
3567      * @see ByteVector#toIntArray()
3568      */
3569     @ForceInline
3570     public final
3571     void intoBooleanArray(boolean[] a, int offset,
3572                           int[] indexMap, int mapOffset,
3573                           VectorMask<Byte> m) {
3574         // FIXME: optimize
3575         stOp(a, offset, m,
3576              (arr, off, i, e) -> {
3577                  int j = indexMap[mapOffset + i];
3578                  arr[off + j] = (e & 1) != 0;
3579              });
3580     }
3581 
3582     /**
3583      * {@inheritDoc} <!--workaround-->

3584      */
3585     @Override
3586     @ForceInline
3587     public final
3588     void intoByteArray(byte[] a, int offset,
3589                        ByteOrder bo) {
3590         offset = checkFromIndexSize(offset, byteSize(), a.length);
3591         maybeSwap(bo).intoByteArray0(a, offset);
3592     }
3593 
3594     /**
3595      * {@inheritDoc} <!--workaround-->
3596      */
3597     @Override
3598     @ForceInline
3599     public final
3600     void intoByteArray(byte[] a, int offset,
3601                        ByteOrder bo,
3602                        VectorMask<Byte> m) {
3603         if (m.allTrue()) {
3604             intoByteArray(a, offset, bo);
3605         } else {
3606             ByteSpecies vsp = vspecies();
3607             checkMaskFromIndexSize(offset, vsp, m, 1, a.length);
3608             maybeSwap(bo).intoByteArray0(a, offset, m);
3609         }
3610     }
3611 
3612     /**
3613      * {@inheritDoc} <!--workaround-->
3614      */
3615     @Override
3616     @ForceInline
3617     public final
3618     void intoByteBuffer(ByteBuffer bb, int offset,
3619                         ByteOrder bo) {
3620         if (ScopedMemoryAccess.isReadOnly(bb)) {
3621             throw new ReadOnlyBufferException();
3622         }
3623         offset = checkFromIndexSize(offset, byteSize(), bb.limit());
3624         maybeSwap(bo).intoByteBuffer0(bb, offset);
3625     }
3626 
3627     /**
3628      * {@inheritDoc} <!--workaround-->

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










3940     @ForceInline
3941     private void conditionalStoreNYI(int offset,
3942                                      ByteSpecies vsp,
3943                                      VectorMask<Byte> m,
3944                                      int scale,
3945                                      int limit) {
3946         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3947             String msg =
3948                 String.format("unimplemented: store @%d in [0..%d), %s in %s",
3949                               offset, limit, m, vsp);
3950             throw new AssertionError(msg);
3951         }
3952     }
3953 
3954     /*package-private*/
3955     @Override
3956     @ForceInline
3957     final
3958     ByteVector maybeSwap(ByteOrder bo) {
3959         return this;

4239                 }
4240             }
4241             return dummyVector().vectorFactory(res);
4242         }
4243 
4244         /*package-private*/
4245         @ForceInline
4246         <M> ByteVector ldOp(M memory, int offset,
4247                                       FLdOp<M> f) {
4248             return dummyVector().ldOp(memory, offset, f);
4249         }
4250 
4251         /*package-private*/
4252         @ForceInline
4253         <M> ByteVector ldOp(M memory, int offset,
4254                                       VectorMask<Byte> m,
4255                                       FLdOp<M> f) {
4256             return dummyVector().ldOp(memory, offset, m, f);
4257         }
4258 















4259         /*package-private*/
4260         @ForceInline
4261         <M> void stOp(M memory, int offset, FStOp<M> f) {
4262             dummyVector().stOp(memory, offset, f);
4263         }
4264 
4265         /*package-private*/
4266         @ForceInline
4267         <M> void stOp(M memory, int offset,
4268                       AbstractMask<Byte> m,
4269                       FStOp<M> f) {
4270             dummyVector().stOp(memory, offset, m, f);
4271         }
4272 














4273         // N.B. Make sure these constant vectors and
4274         // masks load up correctly into registers.
4275         //
4276         // Also, see if we can avoid all that switching.
4277         // Could we cache both vectors and both masks in
4278         // this species object?
4279 
4280         // Zero and iota vector access
4281         @Override
4282         @ForceInline
4283         public final ByteVector zero() {
4284             if ((Class<?>) vectorType() == ByteMaxVector.class)
4285                 return ByteMaxVector.ZERO;
4286             switch (vectorBitSize()) {
4287                 case 64: return Byte64Vector.ZERO;
4288                 case 128: return Byte128Vector.ZERO;
4289                 case 256: return Byte256Vector.ZERO;
4290                 case 512: return Byte512Vector.ZERO;
4291             }
4292             throw new AssertionError();

   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 

  27 import java.nio.ByteOrder;

  28 import java.util.Arrays;
  29 import java.util.Objects;
  30 import java.util.function.Function;

  31 
  32 import jdk.incubator.foreign.MemorySegment;
  33 import jdk.incubator.foreign.ValueLayout;
  34 import jdk.internal.access.foreign.MemorySegmentProxy;
  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 byte} values.
  50  */
  51 @SuppressWarnings("cast")  // warning: redundant cast
  52 public abstract class ByteVector extends AbstractVector<Byte> {
  53 
  54     ByteVector(byte[] vec) {
  55         super(vec);
  56     }
  57 
  58     static final int FORBID_OPCODE_KIND = VO_ONLYFP;
  59 
  60     static final ValueLayout.OfByte ELEMENT_LAYOUT = ValueLayout.JAVA_BYTE.withBitAlignment(8);
  61 
  62     @ForceInline
  63     static int opCode(Operator op) {
  64         return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND);
  65     }
  66     @ForceInline
  67     static int opCode(Operator op, int requireKind) {
  68         requireKind |= VO_OPCODE_VALID;
  69         return VectorOperators.opCode(op, requireKind, FORBID_OPCODE_KIND);
  70     }
  71     @ForceInline
  72     static boolean opKind(Operator op, int bit) {
  73         return VectorOperators.opKind(op, bit);
  74     }
  75 
  76     // Virtualized factories and operators,
  77     // coded with portable definitions.
  78     // These are all @ForceInline in case
  79     // they need to be used performantly.
  80     // The various shape-specific subclasses
  81     // also specialize them by wrapping

 336         return vectorFactory(res);
 337     }
 338 
 339     /*package-private*/
 340     @ForceInline
 341     final
 342     <M> ByteVector ldOp(M memory, int offset,
 343                                   VectorMask<Byte> m,
 344                                   FLdOp<M> f) {
 345         //byte[] vec = vec();
 346         byte[] res = new byte[length()];
 347         boolean[] mbits = ((AbstractMask<Byte>)m).getBits();
 348         for (int i = 0; i < res.length; i++) {
 349             if (mbits[i]) {
 350                 res[i] = f.apply(memory, offset, i);
 351             }
 352         }
 353         return vectorFactory(res);
 354     }
 355 
 356     /*package-private*/
 357     interface FLdLongOp {
 358         byte apply(MemorySegment memory, long offset, int i);
 359     }
 360 
 361     /*package-private*/
 362     @ForceInline
 363     final
 364     ByteVector ldLongOp(MemorySegment memory, long offset,
 365                                   FLdLongOp f) {
 366         //dummy; no vec = vec();
 367         byte[] res = new byte[length()];
 368         for (int i = 0; i < res.length; i++) {
 369             res[i] = f.apply(memory, offset, i);
 370         }
 371         return vectorFactory(res);
 372     }
 373 
 374     /*package-private*/
 375     @ForceInline
 376     final
 377     ByteVector ldLongOp(MemorySegment memory, long offset,
 378                                   VectorMask<Byte> m,
 379                                   FLdLongOp f) {
 380         //byte[] vec = vec();
 381         byte[] res = new byte[length()];
 382         boolean[] mbits = ((AbstractMask<Byte>)m).getBits();
 383         for (int i = 0; i < res.length; i++) {
 384             if (mbits[i]) {
 385                 res[i] = f.apply(memory, offset, i);
 386             }
 387         }
 388         return vectorFactory(res);
 389     }
 390 
 391     static byte memorySegmentGet(MemorySegment ms, long o, int i) {
 392         return ms.get(ELEMENT_LAYOUT, o + i * 1L);
 393     }
 394 
 395     interface FStOp<M> {
 396         void apply(M memory, int offset, int i, byte a);
 397     }
 398 
 399     /*package-private*/
 400     @ForceInline
 401     final
 402     <M> void stOp(M memory, int offset,
 403                   FStOp<M> f) {
 404         byte[] vec = vec();
 405         for (int i = 0; i < vec.length; i++) {
 406             f.apply(memory, offset, i, vec[i]);
 407         }
 408     }
 409 
 410     /*package-private*/
 411     @ForceInline
 412     final
 413     <M> void stOp(M memory, int offset,
 414                   VectorMask<Byte> m,
 415                   FStOp<M> f) {
 416         byte[] vec = vec();
 417         boolean[] mbits = ((AbstractMask<Byte>)m).getBits();
 418         for (int i = 0; i < vec.length; i++) {
 419             if (mbits[i]) {
 420                 f.apply(memory, offset, i, vec[i]);
 421             }
 422         }
 423     }
 424 
 425     interface FStLongOp {
 426         void apply(MemorySegment memory, long offset, int i, byte a);
 427     }
 428 
 429     /*package-private*/
 430     @ForceInline
 431     final
 432     void stLongOp(MemorySegment memory, long offset,
 433                   FStLongOp f) {
 434         byte[] vec = vec();
 435         for (int i = 0; i < vec.length; i++) {
 436             f.apply(memory, offset, i, vec[i]);
 437         }
 438     }
 439 
 440     /*package-private*/
 441     @ForceInline
 442     final
 443     void stLongOp(MemorySegment memory, long offset,
 444                   VectorMask<Byte> m,
 445                   FStLongOp f) {
 446         byte[] vec = vec();
 447         boolean[] mbits = ((AbstractMask<Byte>)m).getBits();
 448         for (int i = 0; i < vec.length; i++) {
 449             if (mbits[i]) {
 450                 f.apply(memory, offset, i, vec[i]);
 451             }
 452         }
 453     }
 454 
 455     static void memorySegmentSet(MemorySegment ms, long o, int i, byte e) {
 456         ms.set(ELEMENT_LAYOUT, o + i * 1L, e);
 457     }
 458 
 459     // Binary test
 460 
 461     /*package-private*/
 462     interface FBinTest {
 463         boolean apply(int cond, int i, byte a, byte b);
 464     }
 465 
 466     /*package-private*/
 467     @ForceInline
 468     final
 469     AbstractMask<Byte> bTest(int cond,
 470                                   Vector<Byte> o,
 471                                   FBinTest f) {
 472         byte[] vec1 = vec();
 473         byte[] vec2 = ((ByteVector)o).vec();
 474         boolean[] bits = new boolean[length()];
 475         for (int i = 0; i < length(); i++){
 476             bits[i] = f.apply(cond, i, vec1[i], vec2[i]);
 477         }
 478         return maskFactory(bits);

 489     static byte rotateRight(byte a, int n) {
 490         return (byte)(((((byte)a) & Byte.toUnsignedInt((byte)-1)) >>> (n & Byte.SIZE-1)) | ((((byte)a) & Byte.toUnsignedInt((byte)-1)) << (Byte.SIZE - (n & Byte.SIZE-1))));
 491     }
 492 
 493     /*package-private*/
 494     @Override
 495     abstract ByteSpecies vspecies();
 496 
 497     /*package-private*/
 498     @ForceInline
 499     static long toBits(byte e) {
 500         return  e;
 501     }
 502 
 503     /*package-private*/
 504     @ForceInline
 505     static byte fromBits(long bits) {
 506         return ((byte)bits);
 507     }
 508 
 509     static ByteVector expandHelper(Vector<Byte> v, VectorMask<Byte> m) {
 510         VectorSpecies<Byte> vsp = m.vectorSpecies();
 511         ByteVector r  = (ByteVector) vsp.zero();
 512         ByteVector vi = (ByteVector) v;
 513         if (m.allTrue()) {
 514             return vi;
 515         }
 516         for (int i = 0, j = 0; i < vsp.length(); i++) {
 517             if (m.laneIsSet(i)) {
 518                 r = r.withLane(i, vi.lane(j++));
 519             }
 520         }
 521         return r;
 522     }
 523 
 524     static ByteVector compressHelper(Vector<Byte> v, VectorMask<Byte> m) {
 525         VectorSpecies<Byte> vsp = m.vectorSpecies();
 526         ByteVector r  = (ByteVector) vsp.zero();
 527         ByteVector vi = (ByteVector) v;
 528         if (m.allTrue()) {
 529             return vi;
 530         }
 531         for (int i = 0, j = 0; i < vsp.length(); i++) {
 532             if (m.laneIsSet(i)) {
 533                 r = r.withLane(j++, vi.lane(i));
 534             }
 535         }
 536         return r;
 537     }
 538 
 539     // Static factories (other than memory operations)
 540 
 541     // Note: A surprising behavior in javadoc
 542     // sometimes makes a lone /** {@inheritDoc} */
 543     // comment drop the method altogether,
 544     // apparently if the method mentions an
 545     // parameter or return type of Vector<Byte>
 546     // instead of Vector<E> as originally specified.
 547     // Adding an empty HTML fragment appears to
 548     // nudge javadoc into providing the desired
 549     // inherited documentation.  We use the HTML
 550     // comment <!--workaround--> for this.
 551 
 552     /**
 553      * Returns a vector of the given species
 554      * where all lane elements are set to
 555      * zero, the default primitive value.
 556      *
 557      * @param species species of the desired zero vector
 558      * @return a zero vector

 708                 return lanewise(XOR, broadcast(-1), m);
 709             }
 710         }
 711         int opc = opCode(op);
 712         return VectorSupport.unaryOp(
 713             opc, getClass(), maskClass, byte.class, length(),
 714             this, m,
 715             UN_IMPL.find(op, opc, ByteVector::unaryOperations));
 716     }
 717 
 718     private static final
 719     ImplCache<Unary, UnaryOperation<ByteVector, VectorMask<Byte>>>
 720         UN_IMPL = new ImplCache<>(Unary.class, ByteVector.class);
 721 
 722     private static UnaryOperation<ByteVector, VectorMask<Byte>> unaryOperations(int opc_) {
 723         switch (opc_) {
 724             case VECTOR_OP_NEG: return (v0, m) ->
 725                     v0.uOp(m, (i, a) -> (byte) -a);
 726             case VECTOR_OP_ABS: return (v0, m) ->
 727                     v0.uOp(m, (i, a) -> (byte) Math.abs(a));
 728             case VECTOR_OP_BIT_COUNT: return (v0, m) ->
 729                     v0.uOp(m, (i, a) -> (byte) bitCount(a));
 730             case VECTOR_OP_TZ_COUNT: return (v0, m) ->
 731                     v0.uOp(m, (i, a) -> (byte) numberOfTrailingZeros(a));
 732             case VECTOR_OP_LZ_COUNT: return (v0, m) ->
 733                     v0.uOp(m, (i, a) -> (byte) numberOfLeadingZeros(a));
 734             case VECTOR_OP_REVERSE: return (v0, m) ->
 735                     v0.uOp(m, (i, a) -> reverse(a));
 736             case VECTOR_OP_REVERSE_BYTES: return (v0, m) ->
 737                     v0.uOp(m, (i, a) -> a);
 738             default: return null;
 739         }
 740     }
 741 
 742     // Binary lanewise support
 743 
 744     /**
 745      * {@inheritDoc} <!--workaround-->
 746      * @see #lanewise(VectorOperators.Binary,byte)
 747      * @see #lanewise(VectorOperators.Binary,byte,VectorMask)
 748      */
 749     @Override
 750     public abstract
 751     ByteVector lanewise(VectorOperators.Binary op,
 752                                   Vector<Byte> v);
 753     @ForceInline
 754     final
 755     ByteVector lanewiseTemplate(VectorOperators.Binary op,
 756                                           Vector<Byte> v) {
 757         ByteVector that = (ByteVector) v;

1844     /**
1845      * {@inheritDoc} <!--workaround-->
1846      */
1847     @Override
1848     @ForceInline
1849     public final
1850     ByteVector neg() {
1851         return lanewise(NEG);
1852     }
1853 
1854     /**
1855      * {@inheritDoc} <!--workaround-->
1856      */
1857     @Override
1858     @ForceInline
1859     public final
1860     ByteVector abs() {
1861         return lanewise(ABS);
1862     }
1863 
1864     static int bitCount(byte a) {
1865         return Integer.bitCount((int)a & 0xFF);
1866     }
1867     static int numberOfTrailingZeros(byte a) {
1868         return a != 0 ? Integer.numberOfTrailingZeros(a) : 8;
1869     }
1870     static int numberOfLeadingZeros(byte a) {
1871         return a >= 0 ? Integer.numberOfLeadingZeros(a) - 24 : 0;
1872     }
1873 
1874     static byte reverse(byte a) {
1875         if (a == 0 || a == -1) return a;
1876 
1877         byte b = rotateLeft(a, 4);
1878         b = (byte) (((b & 0x55) << 1) | ((b & 0xAA) >>> 1));
1879         b = (byte) (((b & 0x33) << 2) | ((b & 0xCC) >>> 2));
1880         return b;
1881     }
1882 
1883     // not (~)
1884     /**
1885      * Computes the bitwise logical complement ({@code ~})
1886      * of this vector.
1887      *
1888      * This is a lane-wise binary operation which applies the
1889      * the primitive bitwise "not" operation ({@code ~})
1890      * to each lane value.
1891      *
1892      * This method is also equivalent to the expression
1893      * {@link #lanewise(VectorOperators.Unary)
1894      *    lanewise}{@code (}{@link VectorOperators#NOT
1895      *    NOT}{@code )}.
1896      *
1897      * <p>
1898      * This is not a full-service named operation like
1899      * {@link #add(Vector) add}.  A masked version of
1900      * this operation is not directly available
1901      * but may be obtained via the masked version of
1902      * {@code lanewise}.

2489         byte[] a = toArray();
2490         int[] sa = new int[a.length];
2491         for (int i = 0; i < a.length; i++) {
2492             sa[i] = (int) a[i];
2493         }
2494         return VectorShuffle.fromArray(dsp, sa, 0);
2495     }
2496 
2497     /*package-private*/
2498     @ForceInline
2499     final
2500     VectorShuffle<Byte> toShuffleTemplate(Class<?> shuffleType) {
2501         ByteSpecies vsp = vspecies();
2502         return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST,
2503                                      getClass(), byte.class, length(),
2504                                      shuffleType, byte.class, length(),
2505                                      this, vsp,
2506                                      ByteVector::toShuffle0);
2507     }
2508 
2509     /**
2510      * {@inheritDoc} <!--workaround-->
2511      * @since 19
2512      */
2513     @Override
2514     public abstract
2515     ByteVector compress(VectorMask<Byte> m);
2516 
2517     /*package-private*/
2518     @ForceInline
2519     final
2520     <M extends AbstractMask<Byte>>
2521     ByteVector compressTemplate(Class<M> masktype, M m) {
2522       m.check(masktype, this);
2523       return (ByteVector) VectorSupport.comExpOp(VectorSupport.VECTOR_OP_COMPRESS, getClass(), masktype,
2524                                                    byte.class, length(), this, m,
2525                                                    (v1, m1) -> compressHelper(v1, m1));
2526     }
2527 
2528     /**
2529      * {@inheritDoc} <!--workaround-->
2530      * @since 19
2531      */
2532     @Override
2533     public abstract
2534     ByteVector expand(VectorMask<Byte> m);
2535 
2536     /*package-private*/
2537     @ForceInline
2538     final
2539     <M extends AbstractMask<Byte>>
2540     ByteVector expandTemplate(Class<M> masktype, M m) {
2541       m.check(masktype, this);
2542       return (ByteVector) VectorSupport.comExpOp(VectorSupport.VECTOR_OP_EXPAND, getClass(), masktype,
2543                                                    byte.class, length(), this, m,
2544                                                    (v1, m1) -> expandHelper(v1, m1));
2545     }
2546 
2547 
2548     /**
2549      * {@inheritDoc} <!--workaround-->
2550      */
2551     @Override
2552     public abstract
2553     ByteVector selectFrom(Vector<Byte> v);
2554 
2555     /*package-private*/
2556     @ForceInline
2557     final ByteVector selectFromTemplate(ByteVector v) {
2558         return v.rearrange(this.toShuffle());
2559     }
2560 
2561     /**
2562      * {@inheritDoc} <!--workaround-->
2563      */
2564     @Override
2565     public abstract
2566     ByteVector selectFrom(Vector<Byte> s, VectorMask<Byte> m);
2567 

2940         return res;
2941     }
2942 
2943     /** {@inheritDoc} <!--workaround-->
2944      * @implNote
2945      * When this method is used on used on vectors
2946      * of type {@code ByteVector},
2947      * there will be no loss of precision.
2948      */
2949     @ForceInline
2950     @Override
2951     public final double[] toDoubleArray() {
2952         byte[] a = toArray();
2953         double[] res = new double[a.length];
2954         for (int i = 0; i < a.length; i++) {
2955             res[i] = (double) a[i];
2956         }
2957         return res;
2958     }
2959 




















































































2960     /**
2961      * Loads a vector from an array of type {@code byte[]}
2962      * starting at an offset.
2963      * For each vector lane, where {@code N} is the vector lane index, the
2964      * array element at index {@code offset + N} is placed into the
2965      * resulting vector at lane index {@code N}.
2966      *
2967      * @param species species of desired vector
2968      * @param a the array
2969      * @param offset the offset into the array
2970      * @return the vector loaded from an array
2971      * @throws IndexOutOfBoundsException
2972      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
2973      *         for any lane {@code N} in the vector
2974      */
2975     @ForceInline
2976     public static
2977     ByteVector fromArray(VectorSpecies<Byte> species,
2978                                    byte[] a, int offset) {
2979         offset = checkFromIndexSize(offset, species.length(), a.length);

3246      *         if {@code mapOffset+N < 0}
3247      *         or if {@code mapOffset+N >= indexMap.length},
3248      *         or if {@code f(N)=offset+indexMap[mapOffset+N]}
3249      *         is an invalid index into {@code a},
3250      *         for any lane {@code N} in the vector
3251      *         where the mask is set
3252      * @see ByteVector#toIntArray()
3253      */
3254     @ForceInline
3255     public static
3256     ByteVector fromBooleanArray(VectorSpecies<Byte> species,
3257                                           boolean[] a, int offset,
3258                                           int[] indexMap, int mapOffset,
3259                                           VectorMask<Byte> m) {
3260         // FIXME: optimize
3261         ByteSpecies vsp = (ByteSpecies) species;
3262         return vsp.vOp(m, n -> (byte) (a[offset + indexMap[mapOffset + n]] ? 1 : 0));
3263     }
3264 
3265     /**
3266      * Loads a vector from a {@linkplain MemorySegment memory segment}
3267      * starting at an offset into the memory segment.
3268      * Bytes are composed into primitive lane elements according
3269      * to the specified byte order.
3270      * The vector is arranged into lanes according to
3271      * <a href="Vector.html#lane-order">memory ordering</a>.
3272      * <p>
3273      * This method behaves as if it returns the result of calling
3274      * {@link #fromMemorySegment(VectorSpecies,MemorySegment,long,ByteOrder,VectorMask)
3275      * fromMemorySegment()} as follows:
3276      * <pre>{@code
3277      * var m = species.maskAll(true);
3278      * return fromMemorySegment(species, ms, offset, bo, m);
3279      * }</pre>
3280      *
3281      * @param species species of desired vector
3282      * @param ms the memory segment
3283      * @param offset the offset into the memory segment
3284      * @param bo the intended byte order
3285      * @return a vector loaded from the memory segment
3286      * @throws IndexOutOfBoundsException
3287      *         if {@code offset+N*1 < 0}
3288      *         or {@code offset+N*1 >= ms.byteSize()}
3289      *         for any lane {@code N} in the vector
3290      * @throws IllegalArgumentException if the memory segment is a heap segment that is
3291      *         not backed by a {@code byte[]} array.
3292      * @throws IllegalStateException if the memory segment's session is not alive,
3293      *         or if access occurs from a thread other than the thread owning the session.
3294      * @since 19
3295      */
3296     @ForceInline
3297     public static
3298     ByteVector fromMemorySegment(VectorSpecies<Byte> species,
3299                                            MemorySegment ms, long offset,
3300                                            ByteOrder bo) {
3301         offset = checkFromIndexSize(offset, species.vectorByteSize(), ms.byteSize());
3302         ByteSpecies vsp = (ByteSpecies) species;
3303         return vsp.dummyVector().fromMemorySegment0(ms, offset).maybeSwap(bo);
3304     }
3305 
3306     /**
3307      * Loads a vector from a {@linkplain MemorySegment memory segment}
3308      * starting at an offset into the memory segment
3309      * and using a mask.
3310      * Lanes where the mask is unset are filled with the default
3311      * value of {@code byte} (zero).
3312      * Bytes are composed into primitive lane elements according
3313      * to the specified byte order.
3314      * The vector is arranged into lanes according to
3315      * <a href="Vector.html#lane-order">memory ordering</a>.
3316      * <p>
3317      * The following pseudocode illustrates the behavior:
3318      * <pre>{@code
3319      * var slice = ms.asSlice(offset);

3320      * byte[] ar = new byte[species.length()];
3321      * for (int n = 0; n < ar.length; n++) {
3322      *     if (m.laneIsSet(n)) {
3323      *         ar[n] = slice.getAtIndex(ValuaLayout.JAVA_BYTE.withBitAlignment(8), n);
3324      *     }
3325      * }
3326      * ByteVector r = ByteVector.fromArray(species, ar, 0);
3327      * }</pre>
3328      * @implNote
3329      * The byte order argument is ignored.
3330      *
3331      * @param species species of desired vector
3332      * @param ms the memory segment
3333      * @param offset the offset into the memory segment
3334      * @param bo the intended byte order
3335      * @param m the mask controlling lane selection
3336      * @return a vector loaded from the memory segment
3337      * @throws IndexOutOfBoundsException
3338      *         if {@code offset+N*1 < 0}
3339      *         or {@code offset+N*1 >= ms.byteSize()}
3340      *         for any lane {@code N} in the vector
3341      *         where the mask is set
3342      * @throws IllegalArgumentException if the memory segment is a heap segment that is
3343      *         not backed by a {@code byte[]} array.
3344      * @throws IllegalStateException if the memory segment's session is not alive,
3345      *         or if access occurs from a thread other than the thread owning the session.
3346      * @since 19
3347      */
3348     @ForceInline
3349     public static
3350     ByteVector fromMemorySegment(VectorSpecies<Byte> species,
3351                                            MemorySegment ms, long offset,
3352                                            ByteOrder bo,
3353                                            VectorMask<Byte> m) {
3354         ByteSpecies vsp = (ByteSpecies) species;
3355         if (offset >= 0 && offset <= (ms.byteSize() - species.vectorByteSize())) {
3356             return vsp.dummyVector().fromMemorySegment0(ms, offset, m).maybeSwap(bo);
3357         }
3358 
3359         // FIXME: optimize
3360         checkMaskFromIndexSize(offset, vsp, m, 1, ms.byteSize());
3361         return vsp.ldLongOp(ms, offset, m, ByteVector::memorySegmentGet);


3362     }
3363 
3364     // Memory store operations
3365 
3366     /**
3367      * Stores this vector into an array of type {@code byte[]}
3368      * starting at an offset.
3369      * <p>
3370      * For each vector lane, where {@code N} is the vector lane index,
3371      * the lane element at index {@code N} is stored into the array
3372      * element {@code a[offset+N]}.
3373      *
3374      * @param a the array, of type {@code byte[]}
3375      * @param offset the offset into the array
3376      * @throws IndexOutOfBoundsException
3377      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3378      *         for any lane {@code N} in the vector
3379      */
3380     @ForceInline
3381     public final
3382     void intoArray(byte[] a, int offset) {
3383         offset = checkFromIndexSize(offset, length(), a.length);
3384         ByteSpecies vsp = vspecies();
3385         VectorSupport.store(
3386             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3387             a, arrayAddress(a, offset),
3388             this,
3389             a, offset,
3390             (arr, off, v)
3391             -> v.stOp(arr, (int) off,
3392                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
3393     }
3394 
3395     /**
3396      * Stores this vector into an array of type {@code byte[]}
3397      * starting at offset and using a mask.
3398      * <p>
3399      * For each vector lane, where {@code N} is the vector lane index,
3400      * the lane element at index {@code N} is stored into the array
3401      * element {@code a[offset+N]}.
3402      * If the mask lane at {@code N} is unset then the corresponding
3403      * array element {@code a[offset+N]} is left unchanged.
3404      * <p>
3405      * Array range checking is done for lanes where the mask is set.
3406      * Lanes where the mask is unset are not stored and do not need
3407      * to correspond to legitimate elements of {@code a}.
3408      * That is, unset lanes may correspond to array indexes less than
3409      * zero or beyond the end of the array.
3410      *
3411      * @param a the array, of type {@code byte[]}

3522      * expression {@code (b & 1) != 0} where {@code b} is the byte value.
3523      *
3524      * @param a the array
3525      * @param offset the offset into the array
3526      * @throws IndexOutOfBoundsException
3527      *         if {@code offset+N < 0} or {@code offset+N >= a.length}
3528      *         for any lane {@code N} in the vector
3529      */
3530     @ForceInline
3531     public final
3532     void intoBooleanArray(boolean[] a, int offset) {
3533         offset = checkFromIndexSize(offset, length(), a.length);
3534         ByteSpecies vsp = vspecies();
3535         ByteVector normalized = this.and((byte) 1);
3536         VectorSupport.store(
3537             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3538             a, booleanArrayAddress(a, offset),
3539             normalized,
3540             a, offset,
3541             (arr, off, v)
3542             -> v.stOp(arr, (int) off,
3543                       (arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0));
3544     }
3545 
3546     /**
3547      * Stores this vector into an array of type {@code boolean[]}
3548      * starting at offset and using a mask.
3549      * <p>
3550      * For each vector lane, where {@code N} is the vector lane index,
3551      * the lane element at index {@code N}
3552      * is first converted to a {@code boolean} value and then
3553      * stored into the array element {@code a[offset+N]}.
3554      * If the mask lane at {@code N} is unset then the corresponding
3555      * array element {@code a[offset+N]} is left unchanged.
3556      * <p>
3557      * A {@code byte} value is converted to a {@code boolean} value by applying the
3558      * expression {@code (b & 1) != 0} where {@code b} is the byte value.
3559      * <p>
3560      * Array range checking is done for lanes where the mask is set.
3561      * Lanes where the mask is unset are not stored and do not need
3562      * to correspond to legitimate elements of {@code a}.

3660      *         is an invalid index into {@code a},
3661      *         for any lane {@code N} in the vector
3662      *         where the mask is set
3663      * @see ByteVector#toIntArray()
3664      */
3665     @ForceInline
3666     public final
3667     void intoBooleanArray(boolean[] a, int offset,
3668                           int[] indexMap, int mapOffset,
3669                           VectorMask<Byte> m) {
3670         // FIXME: optimize
3671         stOp(a, offset, m,
3672              (arr, off, i, e) -> {
3673                  int j = indexMap[mapOffset + i];
3674                  arr[off + j] = (e & 1) != 0;
3675              });
3676     }
3677 
3678     /**
3679      * {@inheritDoc} <!--workaround-->
3680      * @since 19
3681      */
3682     @Override
3683     @ForceInline
3684     public final
3685     void intoMemorySegment(MemorySegment ms, long offset,
3686                            ByteOrder bo) {
3687         if (ms.isReadOnly()) {
3688             throw new UnsupportedOperationException("Attempt to write a read-only segment");

















3689         }

3690 
3691         offset = checkFromIndexSize(offset, byteSize(), ms.byteSize());
3692         maybeSwap(bo).intoMemorySegment0(ms, offset);











3693     }
3694 
3695     /**
3696      * {@inheritDoc} <!--workaround-->
3697      * @since 19
3698      */
3699     @Override
3700     @ForceInline
3701     public final
3702     void intoMemorySegment(MemorySegment ms, long offset,
3703                            ByteOrder bo,
3704                            VectorMask<Byte> m) {
3705         if (m.allTrue()) {
3706             intoMemorySegment(ms, offset, bo);
3707         } else {
3708             if (ms.isReadOnly()) {
3709                 throw new UnsupportedOperationException("Attempt to write a read-only segment");
3710             }
3711             ByteSpecies vsp = vspecies();
3712             checkMaskFromIndexSize(offset, vsp, m, 1, ms.byteSize());
3713             maybeSwap(bo).intoMemorySegment0(ms, offset, m);
3714         }
3715     }
3716 
3717     // ================================================
3718 
3719     // Low-level memory operations.
3720     //
3721     // Note that all of these operations *must* inline into a context
3722     // where the exact species of the involved vector is a
3723     // compile-time constant.  Otherwise, the intrinsic generation
3724     // will fail and performance will suffer.
3725     //
3726     // In many cases this is achieved by re-deriving a version of the
3727     // method in each concrete subclass (per species).  The re-derived
3728     // method simply calls one of these generic methods, with exact
3729     // parameters for the controlling metadata, which is either a
3730     // typed vector or constant species instance.
3731 
3732     // Unchecked loading operations in native byte order.
3733     // Caller is responsible for applying index checks, masking, and
3734     // byte swapping.
3735 
3736     /*package-private*/
3737     abstract
3738     ByteVector fromArray0(byte[] a, int offset);
3739     @ForceInline
3740     final
3741     ByteVector fromArray0Template(byte[] a, int offset) {
3742         ByteSpecies vsp = vspecies();
3743         return VectorSupport.load(
3744             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3745             a, arrayAddress(a, offset),
3746             a, offset, vsp,
3747             (arr, off, s) -> s.ldOp(arr, (int) off,
3748                                     (arr_, off_, i) -> arr_[off_ + i]));
3749     }
3750 
3751     /*package-private*/
3752     abstract
3753     ByteVector fromArray0(byte[] a, int offset, VectorMask<Byte> m);
3754     @ForceInline
3755     final
3756     <M extends VectorMask<Byte>>
3757     ByteVector fromArray0Template(Class<M> maskClass, byte[] a, int offset, M m) {
3758         m.check(species());
3759         ByteSpecies vsp = vspecies();
3760         return VectorSupport.loadMasked(
3761             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3762             a, arrayAddress(a, offset), m,
3763             a, offset, vsp,
3764             (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm,
3765                                         (arr_, off_, i) -> arr_[off_ + i]));
3766     }
3767 
3768 
3769 
3770     /*package-private*/
3771     abstract
3772     ByteVector fromBooleanArray0(boolean[] a, int offset);
3773     @ForceInline
3774     final
3775     ByteVector fromBooleanArray0Template(boolean[] a, int offset) {
3776         ByteSpecies vsp = vspecies();
3777         return VectorSupport.load(
3778             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3779             a, booleanArrayAddress(a, offset),
3780             a, offset, vsp,
3781             (arr, off, s) -> s.ldOp(arr, (int) off,
3782                                     (arr_, off_, i) -> (byte) (arr_[off_ + i] ? 1 : 0)));
3783     }
3784 
3785     /*package-private*/
3786     abstract
3787     ByteVector fromBooleanArray0(boolean[] a, int offset, VectorMask<Byte> m);
3788     @ForceInline
3789     final
3790     <M extends VectorMask<Byte>>
3791     ByteVector fromBooleanArray0Template(Class<M> maskClass, boolean[] a, int offset, M m) {
3792         m.check(species());
3793         ByteSpecies vsp = vspecies();
3794         return VectorSupport.loadMasked(
3795             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3796             a, booleanArrayAddress(a, offset), m,
3797             a, offset, vsp,
3798             (arr, off, s, vm) -> s.ldOp(arr, (int) off, vm,
3799                                         (arr_, off_, i) -> (byte) (arr_[off_ + i] ? 1 : 0)));
3800     }
3801 

3802     abstract
3803     ByteVector fromMemorySegment0(MemorySegment bb, long offset);
3804     @ForceInline
3805     final
3806     ByteVector fromMemorySegment0Template(MemorySegment ms, long offset) {
3807         ByteSpecies vsp = vspecies();
3808         return ScopedMemoryAccess.loadFromMemorySegment(




































3809                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3810                 (MemorySegmentProxy) ms, offset, vsp,
3811                 (msp, off, s) -> {
3812                     return s.ldLongOp((MemorySegment) msp, off, ByteVector::memorySegmentGet);


3813                 });
3814     }
3815 
3816     abstract
3817     ByteVector fromMemorySegment0(MemorySegment ms, long offset, VectorMask<Byte> m);
3818     @ForceInline
3819     final
3820     <M extends VectorMask<Byte>>
3821     ByteVector fromMemorySegment0Template(Class<M> maskClass, MemorySegment ms, long offset, M m) {
3822         ByteSpecies vsp = vspecies();
3823         m.check(vsp);
3824         return ScopedMemoryAccess.loadFromMemorySegmentMasked(
3825                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3826                 (MemorySegmentProxy) ms, offset, m, vsp,
3827                 (msp, off, s, vm) -> {
3828                     return s.ldLongOp((MemorySegment) msp, off, vm, ByteVector::memorySegmentGet);


3829                 });
3830     }
3831 
3832     // Unchecked storing operations in native byte order.
3833     // Caller is responsible for applying index checks, masking, and
3834     // byte swapping.
3835 
3836     abstract
3837     void intoArray0(byte[] a, int offset);
3838     @ForceInline
3839     final
3840     void intoArray0Template(byte[] a, int offset) {
3841         ByteSpecies vsp = vspecies();
3842         VectorSupport.store(
3843             vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3844             a, arrayAddress(a, offset),
3845             this, a, offset,
3846             (arr, off, v)
3847             -> v.stOp(arr, (int) off,
3848                       (arr_, off_, i, e) -> arr_[off_+i] = e));
3849     }
3850 
3851     abstract
3852     void intoArray0(byte[] a, int offset, VectorMask<Byte> m);
3853     @ForceInline
3854     final
3855     <M extends VectorMask<Byte>>
3856     void intoArray0Template(Class<M> maskClass, byte[] a, int offset, M m) {
3857         m.check(species());
3858         ByteSpecies vsp = vspecies();
3859         VectorSupport.storeMasked(
3860             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3861             a, arrayAddress(a, offset),
3862             this, m, a, offset,
3863             (arr, off, v, vm)
3864             -> v.stOp(arr, (int) off, vm,
3865                       (arr_, off_, i, e) -> arr_[off_ + i] = e));
3866     }
3867 
3868 
3869     abstract
3870     void intoBooleanArray0(boolean[] a, int offset, VectorMask<Byte> m);
3871     @ForceInline
3872     final
3873     <M extends VectorMask<Byte>>
3874     void intoBooleanArray0Template(Class<M> maskClass, boolean[] a, int offset, M m) {
3875         m.check(species());
3876         ByteSpecies vsp = vspecies();
3877         ByteVector normalized = this.and((byte) 1);
3878         VectorSupport.storeMasked(
3879             vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3880             a, booleanArrayAddress(a, offset),
3881             normalized, m, a, offset,
3882             (arr, off, v, vm)
3883             -> v.stOp(arr, (int) off, vm,
3884                       (arr_, off_, i, e) -> arr_[off_ + i] = (e & 1) != 0));
3885     }
3886 




































3887     @ForceInline
3888     final
3889     void intoMemorySegment0(MemorySegment ms, long offset) {
3890         ByteSpecies vsp = vspecies();
3891         ScopedMemoryAccess.storeIntoMemorySegment(
3892                 vsp.vectorType(), vsp.elementType(), vsp.laneCount(),
3893                 this,
3894                 (MemorySegmentProxy) ms, offset,
3895                 (msp, off, v) -> {
3896                     v.stLongOp((MemorySegment) msp, off, ByteVector::memorySegmentSet);

3897                 });
3898     }
3899 
3900     abstract
3901     void intoMemorySegment0(MemorySegment bb, long offset, VectorMask<Byte> m);
3902     @ForceInline
3903     final
3904     <M extends VectorMask<Byte>>
3905     void intoMemorySegment0Template(Class<M> maskClass, MemorySegment ms, long offset, M m) {
3906         ByteSpecies vsp = vspecies();
3907         m.check(vsp);
3908         ScopedMemoryAccess.storeIntoMemorySegmentMasked(
3909                 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(),
3910                 this, m,
3911                 (MemorySegmentProxy) ms, offset,
3912                 (msp, off, v, vm) -> {
3913                     v.stLongOp((MemorySegment) msp, off, vm, ByteVector::memorySegmentSet);

3914                 });
3915     }
3916 
3917 
3918     // End of low-level memory operations.
3919 
3920     private static
3921     void checkMaskFromIndexSize(int offset,
3922                                 ByteSpecies vsp,
3923                                 VectorMask<Byte> m,
3924                                 int scale,
3925                                 int limit) {
3926         ((AbstractMask<Byte>)m)
3927             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3928     }
3929 
3930     private static
3931     void checkMaskFromIndexSize(long offset,
3932                                 ByteSpecies vsp,
3933                                 VectorMask<Byte> m,
3934                                 int scale,
3935                                 long limit) {
3936         ((AbstractMask<Byte>)m)
3937             .checkIndexByLane(offset, limit, vsp.iota(), scale);
3938     }
3939 
3940     @ForceInline
3941     private void conditionalStoreNYI(int offset,
3942                                      ByteSpecies vsp,
3943                                      VectorMask<Byte> m,
3944                                      int scale,
3945                                      int limit) {
3946         if (offset < 0 || offset + vsp.laneCount() * scale > limit) {
3947             String msg =
3948                 String.format("unimplemented: store @%d in [0..%d), %s in %s",
3949                               offset, limit, m, vsp);
3950             throw new AssertionError(msg);
3951         }
3952     }
3953 
3954     /*package-private*/
3955     @Override
3956     @ForceInline
3957     final
3958     ByteVector maybeSwap(ByteOrder bo) {
3959         return this;

4239                 }
4240             }
4241             return dummyVector().vectorFactory(res);
4242         }
4243 
4244         /*package-private*/
4245         @ForceInline
4246         <M> ByteVector ldOp(M memory, int offset,
4247                                       FLdOp<M> f) {
4248             return dummyVector().ldOp(memory, offset, f);
4249         }
4250 
4251         /*package-private*/
4252         @ForceInline
4253         <M> ByteVector ldOp(M memory, int offset,
4254                                       VectorMask<Byte> m,
4255                                       FLdOp<M> f) {
4256             return dummyVector().ldOp(memory, offset, m, f);
4257         }
4258 
4259         /*package-private*/
4260         @ForceInline
4261         ByteVector ldLongOp(MemorySegment memory, long offset,
4262                                       FLdLongOp f) {
4263             return dummyVector().ldLongOp(memory, offset, f);
4264         }
4265 
4266         /*package-private*/
4267         @ForceInline
4268         ByteVector ldLongOp(MemorySegment memory, long offset,
4269                                       VectorMask<Byte> m,
4270                                       FLdLongOp f) {
4271             return dummyVector().ldLongOp(memory, offset, m, f);
4272         }
4273 
4274         /*package-private*/
4275         @ForceInline
4276         <M> void stOp(M memory, int offset, FStOp<M> f) {
4277             dummyVector().stOp(memory, offset, f);
4278         }
4279 
4280         /*package-private*/
4281         @ForceInline
4282         <M> void stOp(M memory, int offset,
4283                       AbstractMask<Byte> m,
4284                       FStOp<M> f) {
4285             dummyVector().stOp(memory, offset, m, f);
4286         }
4287 
4288         /*package-private*/
4289         @ForceInline
4290         void stLongOp(MemorySegment memory, long offset, FStLongOp f) {
4291             dummyVector().stLongOp(memory, offset, f);
4292         }
4293 
4294         /*package-private*/
4295         @ForceInline
4296         void stLongOp(MemorySegment memory, long offset,
4297                       AbstractMask<Byte> m,
4298                       FStLongOp f) {
4299             dummyVector().stLongOp(memory, offset, m, f);
4300         }
4301 
4302         // N.B. Make sure these constant vectors and
4303         // masks load up correctly into registers.
4304         //
4305         // Also, see if we can avoid all that switching.
4306         // Could we cache both vectors and both masks in
4307         // this species object?
4308 
4309         // Zero and iota vector access
4310         @Override
4311         @ForceInline
4312         public final ByteVector zero() {
4313             if ((Class<?>) vectorType() == ByteMaxVector.class)
4314                 return ByteMaxVector.ZERO;
4315             switch (vectorBitSize()) {
4316                 case 64: return Byte64Vector.ZERO;
4317                 case 128: return Byte128Vector.ZERO;
4318                 case 256: return Byte256Vector.ZERO;
4319                 case 512: return Byte512Vector.ZERO;
4320             }
4321             throw new AssertionError();
< prev index next >