< prev index next >

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

Print this page
rev 54658 : refactored mask and shuffle creation methods, moved classes to top-level


  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code byte} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class ByteVector extends Vector<Byte> {
  45 
  46     ByteVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE);
  49 
  50     // Unary operator
  51 
  52     interface FUnOp {
  53         byte apply(int i, byte a);
  54     }
  55 
  56     abstract ByteVector uOp(FUnOp f);
  57 
  58     abstract ByteVector uOp(Mask<Byte> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         byte apply(int i, byte a, byte b);
  64     }
  65 
  66     abstract ByteVector bOp(Vector<Byte> v, FBinOp f);
  67 
  68     abstract ByteVector bOp(Vector<Byte> v, Mask<Byte> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         byte apply(int i, byte a, byte b, byte c);
  74     }
  75 
  76     abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, FTriOp f);
  77 
  78     abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, Mask<Byte> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract byte rOp(byte v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, byte a, byte b);
  88     }
  89 
  90     abstract Mask<Byte> bTest(Vector<Byte> v, FBinTest f);
  91 
  92     // Foreach
  93 
  94     interface FUnCon {
  95         void apply(int i, byte a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(Mask<Byte> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @param species species of desired vector
 109      * @return a zero vector of given species
 110      */
 111     @ForceInline
 112     @SuppressWarnings("unchecked")
 113     public static ByteVector zero(Species<Byte> species) {
 114         return VectorIntrinsics.broadcastCoerced((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 115                                                  0, species,
 116                                                  ((bits, s) -> ((ByteSpecies)s).op(i -> (byte)bits)));
 117     }
 118 
 119     /**
 120      * Loads a vector from a byte array starting at an offset.
 121      * <p>
 122      * Bytes are composed into primitive lane elements according to the
 123      * native byte order of the underlying platform
 124      * <p>
 125      * This method behaves as if it returns the result of calling the
 126      * byte buffer, offset, and mask accepting
 127      * {@link #fromByteBuffer(Species<Byte>, ByteBuffer, int, Mask) method} as follows:
 128      * <pre>{@code
 129      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 130      * }</pre>
 131      *
 132      * @param species species of desired vector
 133      * @param a the byte array
 134      * @param ix the offset into the array
 135      * @return a vector loaded from a byte array
 136      * @throws IndexOutOfBoundsException if {@code i < 0} or
 137      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 138      */
 139     @ForceInline
 140     @SuppressWarnings("unchecked")
 141     public static ByteVector fromByteArray(Species<Byte> species, byte[] a, int ix) {
 142         Objects.requireNonNull(a);
 143         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 144         return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 145                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 146                                      a, ix, species,
 147                                      (c, idx, s) -> {
 148                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 149                                          ByteBuffer tb = bbc;
 150                                          return ((ByteSpecies)s).op(i -> tb.get());
 151                                      });
 152     }
 153 
 154     /**
 155      * Loads a vector from a byte array starting at an offset and using a
 156      * mask.
 157      * <p>
 158      * Bytes are composed into primitive lane elements according to the
 159      * native byte order of the underlying platform.
 160      * <p>
 161      * This method behaves as if it returns the result of calling the
 162      * byte buffer, offset, and mask accepting
 163      * {@link #fromByteBuffer(Species<Byte>, ByteBuffer, int, Mask) method} as follows:
 164      * <pre>{@code
 165      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 166      * }</pre>
 167      *
 168      * @param species species of desired vector
 169      * @param a the byte array
 170      * @param ix the offset into the array
 171      * @param m the mask
 172      * @return a vector loaded from a byte array
 173      * @throws IndexOutOfBoundsException if {@code i < 0} or
 174      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 175      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 176      * or {@code > a.length},
 177      * for any vector lane index {@code N} where the mask at lane {@code N}
 178      * is set
 179      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 180      */
 181     @ForceInline
 182     public static ByteVector fromByteArray(Species<Byte> species, byte[] a, int ix, Mask<Byte> m) {
 183         return zero(species).blend(fromByteArray(species, a, ix), m);
 184     }
 185 
 186     /**
 187      * Loads a vector from an array starting at offset.
 188      * <p>
 189      * For each vector lane, where {@code N} is the vector lane index, the
 190      * array element at index {@code i + N} is placed into the
 191      * resulting vector at lane index {@code N}.
 192      *
 193      * @param species species of desired vector
 194      * @param a the array
 195      * @param i the offset into the array
 196      * @return the vector loaded from an array
 197      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 198      * {@code i > a.length - this.length()}
 199      */
 200     @ForceInline
 201     @SuppressWarnings("unchecked")
 202     public static ByteVector fromArray(Species<Byte> species, byte[] a, int i){
 203         Objects.requireNonNull(a);
 204         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 205         return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 206                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 207                                      a, i, species,
 208                                      (c, idx, s) -> ((ByteSpecies)s).op(n -> c[idx + n]));
 209     }
 210 
 211 
 212     /**
 213      * Loads a vector from an array starting at offset and using a mask.
 214      * <p>
 215      * For each vector lane, where {@code N} is the vector lane index,
 216      * if the mask lane at index {@code N} is set then the array element at
 217      * index {@code i + N} is placed into the resulting vector at lane index
 218      * {@code N}, otherwise the default element value is placed into the
 219      * resulting vector at lane index {@code N}.
 220      *
 221      * @param species species of desired vector
 222      * @param a the array
 223      * @param i the offset into the array
 224      * @param m the mask
 225      * @return the vector loaded from an array
 226      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 227      * for any vector lane index {@code N} where the mask at lane {@code N}
 228      * is set {@code i > a.length - N}
 229      */
 230     @ForceInline
 231     public static ByteVector fromArray(Species<Byte> species, byte[] a, int i, Mask<Byte> m) {
 232         return zero(species).blend(fromArray(species, a, i), m);
 233     }
 234 
 235     /**
 236      * Loads a vector from an array using indexes obtained from an index
 237      * map.
 238      * <p>
 239      * For each vector lane, where {@code N} is the vector lane index, the
 240      * array element at index {@code i + indexMap[j + N]} is placed into the
 241      * resulting vector at lane index {@code N}.
 242      *
 243      * @param species species of desired vector
 244      * @param a the array
 245      * @param i the offset into the array, may be negative if relative
 246      * indexes in the index map compensate to produce a value within the
 247      * array bounds
 248      * @param indexMap the index map
 249      * @param j the offset into the index map
 250      * @return the vector loaded from an array
 251      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 252      * {@code j > indexMap.length - this.length()},
 253      * or for any vector lane index {@code N} the result of
 254      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 255      */
 256     public static ByteVector fromArray(Species<Byte> species, byte[] a, int i, int[] indexMap, int j) {
 257         return ((ByteSpecies)species).op(n -> a[i + indexMap[j + n]]);
 258     }
 259     /**
 260      * Loads a vector from an array using indexes obtained from an index
 261      * map and using a mask.
 262      * <p>
 263      * For each vector lane, where {@code N} is the vector lane index,
 264      * if the mask lane at index {@code N} is set then the array element at
 265      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 266      * at lane index {@code N}.
 267      *
 268      * @param species species of desired vector
 269      * @param a the array
 270      * @param i the offset into the array, may be negative if relative
 271      * indexes in the index map compensate to produce a value within the
 272      * array bounds
 273      * @param m the mask
 274      * @param indexMap the index map
 275      * @param j the offset into the index map
 276      * @return the vector loaded from an array
 277      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 278      * {@code j > indexMap.length - this.length()},
 279      * or for any vector lane index {@code N} where the mask at lane
 280      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 281      * {@code < 0} or {@code >= a.length}
 282      */
 283     public static ByteVector fromArray(Species<Byte> species, byte[] a, int i, Mask<Byte> m, int[] indexMap, int j) {
 284         return ((ByteSpecies)species).op(m, n -> a[i + indexMap[j + n]]);
 285     }
 286 
 287     /**
 288      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 289      * offset into the byte buffer.
 290      * <p>
 291      * Bytes are composed into primitive lane elements according to the
 292      * native byte order of the underlying platform.
 293      * <p>
 294      * This method behaves as if it returns the result of calling the
 295      * byte buffer, offset, and mask accepting
 296      * {@link #fromByteBuffer(Species<Byte>, ByteBuffer, int, Mask)} method} as follows:
 297      * <pre>{@code
 298      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 299      * }</pre>
 300      *
 301      * @param species species of desired vector
 302      * @param bb the byte buffer
 303      * @param ix the offset into the byte buffer
 304      * @return a vector loaded from a byte buffer
 305      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 306      * or {@code > b.limit()},
 307      * or if there are fewer than
 308      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 309      * remaining in the byte buffer from the given offset
 310      */
 311     @ForceInline
 312     @SuppressWarnings("unchecked")
 313     public static ByteVector fromByteBuffer(Species<Byte> species, ByteBuffer bb, int ix) {
 314         if (bb.order() != ByteOrder.nativeOrder()) {
 315             throw new IllegalArgumentException();
 316         }
 317         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 318         return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 319                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 320                                      bb, ix, species,
 321                                      (c, idx, s) -> {
 322                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 323                                          ByteBuffer tb = bbc;
 324                                          return ((ByteSpecies)s).op(i -> tb.get());
 325                                      });
 326     }
 327 
 328     /**
 329      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 330      * offset into the byte buffer and using a mask.
 331      * <p>
 332      * This method behaves as if the byte buffer is viewed as a primitive
 333      * {@link java.nio.Buffer buffer} for the primitive element type,


 345      * e[] es = new e[this.length()];
 346      * for (int n = 0; n < t.length; n++) {
 347      *     if (m.isSet(n))
 348      *         es[n] = eb.get(n);
 349      * }
 350      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 351      * }</pre>
 352      *
 353      * @param species species of desired vector
 354      * @param bb the byte buffer
 355      * @param ix the offset into the byte buffer
 356      * @param m the mask
 357      * @return a vector loaded from a byte buffer
 358      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 359      * or {@code > b.limit()},
 360      * for any vector lane index {@code N} where the mask at lane {@code N}
 361      * is set
 362      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 363      */
 364     @ForceInline
 365     public static ByteVector fromByteBuffer(Species<Byte> species, ByteBuffer bb, int ix, Mask<Byte> m) {
 366         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 367     }
 368 
 369     /**
 370      * Returns a vector where all lane elements are set to the primitive
 371      * value {@code e}.
 372      *
 373      * @param s species of the desired vector
 374      * @param e the value
 375      * @return a vector of vector where all lane elements are set to
 376      * the primitive value {@code e}
 377      */
 378     @ForceInline
 379     @SuppressWarnings("unchecked")
 380     public static ByteVector broadcast(Species<Byte> s, byte e) {
 381         return VectorIntrinsics.broadcastCoerced(
 382             (Class<ByteVector>) s.boxType(), byte.class, s.length(),
 383             e, s,
 384             ((bits, sp) -> ((ByteSpecies)sp).op(i -> (byte)bits)));
 385     }
 386 
 387     /**
 388      * Returns a vector where each lane element is set to a given
 389      * primitive value.
 390      * <p>
 391      * For each vector lane, where {@code N} is the vector lane index, the
 392      * the primitive value at index {@code N} is placed into the resulting
 393      * vector at lane index {@code N}.
 394      *
 395      * @param s species of the desired vector
 396      * @param es the given primitive values
 397      * @return a vector where each lane element is set to a given primitive
 398      * value
 399      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 400      */
 401     @ForceInline
 402     @SuppressWarnings("unchecked")
 403     public static ByteVector scalars(Species<Byte> s, byte... es) {
 404         Objects.requireNonNull(es);
 405         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 406         return VectorIntrinsics.load((Class<ByteVector>) s.boxType(), byte.class, s.length(),
 407                                      es, Unsafe.ARRAY_BYTE_BASE_OFFSET,
 408                                      es, ix, s,
 409                                      (c, idx, sp) -> ((ByteSpecies)sp).op(n -> c[idx + n]));
 410     }
 411 
 412     /**
 413      * Returns a vector where the first lane element is set to the primtive
 414      * value {@code e}, all other lane elements are set to the default
 415      * value.
 416      *
 417      * @param s species of the desired vector
 418      * @param e the value
 419      * @return a vector where the first lane element is set to the primitive
 420      * value {@code e}
 421      */
 422     @ForceInline
 423     public static final ByteVector single(Species<Byte> s, byte e) {
 424         return zero(s).with(0, e);
 425     }
 426 
 427     /**
 428      * Returns a vector where each lane element is set to a randomly
 429      * generated primitive value.
 430      *
 431      * The semantics are equivalent to calling
 432      * (byte){@link ThreadLocalRandom#nextInt()}
 433      *
 434      * @param s species of the desired vector
 435      * @return a vector where each lane elements is set to a randomly
 436      * generated primitive value
 437      */
 438     public static ByteVector random(Species<Byte> s) {
 439         ThreadLocalRandom r = ThreadLocalRandom.current();
 440         return ((ByteSpecies)s).op(i -> (byte) r.nextInt());
 441     }
 442 
 443     /**
 444      * Returns a mask where each lane is set or unset according to given
 445      * {@code boolean} values
 446      * <p>
 447      * For each mask lane, where {@code N} is the mask lane index,
 448      * if the given {@code boolean} value at index {@code N} is {@code true}
 449      * then the mask lane at index {@code N} is set, otherwise it is unset.
 450      *
 451      * @param species mask species
 452      * @param bits the given {@code boolean} values
 453      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 454      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 455      */
 456     @ForceInline
 457     public static Mask<Byte> maskFromValues(Species<Byte> species, boolean... bits) {
 458         if (species.boxType() == ByteMaxVector.class)
 459             return new ByteMaxVector.ByteMaxMask(bits);
 460         switch (species.bitSize()) {
 461             case 64: return new Byte64Vector.Byte64Mask(bits);
 462             case 128: return new Byte128Vector.Byte128Mask(bits);
 463             case 256: return new Byte256Vector.Byte256Mask(bits);
 464             case 512: return new Byte512Vector.Byte512Mask(bits);
 465             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 466         }
 467     }
 468 
 469     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 470     static Mask<Byte> trueMask(Species<Byte> species) {
 471         if (species.boxType() == ByteMaxVector.class)
 472             return ByteMaxVector.ByteMaxMask.TRUE_MASK;
 473         switch (species.bitSize()) {
 474             case 64: return Byte64Vector.Byte64Mask.TRUE_MASK;
 475             case 128: return Byte128Vector.Byte128Mask.TRUE_MASK;
 476             case 256: return Byte256Vector.Byte256Mask.TRUE_MASK;
 477             case 512: return Byte512Vector.Byte512Mask.TRUE_MASK;
 478             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 479         }
 480     }
 481 
 482     static Mask<Byte> falseMask(Species<Byte> species) {
 483         if (species.boxType() == ByteMaxVector.class)
 484             return ByteMaxVector.ByteMaxMask.FALSE_MASK;
 485         switch (species.bitSize()) {
 486             case 64: return Byte64Vector.Byte64Mask.FALSE_MASK;
 487             case 128: return Byte128Vector.Byte128Mask.FALSE_MASK;
 488             case 256: return Byte256Vector.Byte256Mask.FALSE_MASK;
 489             case 512: return Byte512Vector.Byte512Mask.FALSE_MASK;
 490             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 491         }
 492     }
 493 
 494     /**
 495      * Loads a mask from a {@code boolean} array starting at an offset.
 496      * <p>
 497      * For each mask lane, where {@code N} is the mask lane index,
 498      * if the array element at index {@code ix + N} is {@code true} then the
 499      * mask lane at index {@code N} is set, otherwise it is unset.
 500      *
 501      * @param species mask species
 502      * @param bits the {@code boolean} array
 503      * @param ix the offset into the array
 504      * @return the mask loaded from a {@code boolean} array
 505      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 506      * {@code ix > bits.length - species.length()}
 507      */
 508     @ForceInline
 509     @SuppressWarnings("unchecked")
 510     public static Mask<Byte> maskFromArray(Species<Byte> species, boolean[] bits, int ix) {
 511         Objects.requireNonNull(bits);
 512         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 513         return VectorIntrinsics.load((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
 514                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 515                                      bits, ix, species,
 516                                      (c, idx, s) -> (Mask<Byte>) ((ByteSpecies)s).opm(n -> c[idx + n]));
 517     }
 518 
 519     /**
 520      * Returns a mask where all lanes are set.
 521      *
 522      * @param species mask species
 523      * @return a mask where all lanes are set
 524      */
 525     @ForceInline
 526     @SuppressWarnings("unchecked")
 527     public static Mask<Byte> maskAllTrue(Species<Byte> species) {
 528         return VectorIntrinsics.broadcastCoerced((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
 529                                                  (byte)-1,  species,
 530                                                  ((z, s) -> trueMask(s)));
 531     }
 532 
 533     /**
 534      * Returns a mask where all lanes are unset.
 535      *
 536      * @param species mask species
 537      * @return a mask where all lanes are unset
 538      */
 539     @ForceInline
 540     @SuppressWarnings("unchecked")
 541     public static Mask<Byte> maskAllFalse(Species<Byte> species) {
 542         return VectorIntrinsics.broadcastCoerced((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
 543                                                  0, species, 
 544                                                  ((z, s) -> falseMask(s)));
 545     }
 546 
 547     /**
 548      * Returns a shuffle of mapped indexes where each lane element is
 549      * the result of applying a mapping function to the corresponding lane
 550      * index.
 551      * <p>
 552      * Care should be taken to ensure Shuffle values produced from this
 553      * method are consumed as constants to ensure optimal generation of
 554      * code.  For example, values held in static final fields or values
 555      * held in loop constant local variables.
 556      * <p>
 557      * This method behaves as if a shuffle is created from an array of
 558      * mapped indexes as follows:
 559      * <pre>{@code
 560      *   int[] a = new int[species.length()];
 561      *   for (int i = 0; i < a.length; i++) {
 562      *       a[i] = f.applyAsInt(i);
 563      *   }
 564      *   return this.shuffleFromValues(a);
 565      * }</pre>
 566      *
 567      * @param species shuffle species
 568      * @param f the lane index mapping function
 569      * @return a shuffle of mapped indexes
 570      */
 571     @ForceInline
 572     public static Shuffle<Byte> shuffle(Species<Byte> species, IntUnaryOperator f) {
 573         if (species.boxType() == ByteMaxVector.class)
 574             return new ByteMaxVector.ByteMaxShuffle(f);
 575         switch (species.bitSize()) {
 576             case 64: return new Byte64Vector.Byte64Shuffle(f);
 577             case 128: return new Byte128Vector.Byte128Shuffle(f);
 578             case 256: return new Byte256Vector.Byte256Shuffle(f);
 579             case 512: return new Byte512Vector.Byte512Shuffle(f);
 580             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 581         }
 582     }
 583 
 584     /**
 585      * Returns a shuffle where each lane element is the value of its
 586      * corresponding lane index.
 587      * <p>
 588      * This method behaves as if a shuffle is created from an identity
 589      * index mapping function as follows:
 590      * <pre>{@code
 591      *   return this.shuffle(i -> i);
 592      * }</pre>
 593      *
 594      * @param species shuffle species
 595      * @return a shuffle of lane indexes
 596      */
 597     @ForceInline
 598     public static Shuffle<Byte> shuffleIota(Species<Byte> species) {
 599         if (species.boxType() == ByteMaxVector.class)
 600             return new ByteMaxVector.ByteMaxShuffle(AbstractShuffle.IDENTITY);
 601         switch (species.bitSize()) {
 602             case 64: return new Byte64Vector.Byte64Shuffle(AbstractShuffle.IDENTITY);
 603             case 128: return new Byte128Vector.Byte128Shuffle(AbstractShuffle.IDENTITY);
 604             case 256: return new Byte256Vector.Byte256Shuffle(AbstractShuffle.IDENTITY);
 605             case 512: return new Byte512Vector.Byte512Shuffle(AbstractShuffle.IDENTITY);
 606             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 607         }
 608     }
 609 
 610     /**
 611      * Returns a shuffle where each lane element is set to a given
 612      * {@code int} value logically AND'ed by the species length minus one.
 613      * <p>
 614      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 615      * the {@code int} value at index {@code N} logically AND'ed by
 616      * {@code species.length() - 1} is placed into the resulting shuffle at
 617      * lane index {@code N}.
 618      *
 619      * @param species shuffle species
 620      * @param ixs the given {@code int} values
 621      * @return a shuffle where each lane element is set to a given
 622      * {@code int} value
 623      * @throws IndexOutOfBoundsException if the number of int values is
 624      * {@code < species.length()}
 625      */
 626     @ForceInline
 627     public static Shuffle<Byte> shuffleFromValues(Species<Byte> species, int... ixs) {
 628         if (species.boxType() == ByteMaxVector.class)
 629             return new ByteMaxVector.ByteMaxShuffle(ixs);
 630         switch (species.bitSize()) {
 631             case 64: return new Byte64Vector.Byte64Shuffle(ixs);
 632             case 128: return new Byte128Vector.Byte128Shuffle(ixs);
 633             case 256: return new Byte256Vector.Byte256Shuffle(ixs);
 634             case 512: return new Byte512Vector.Byte512Shuffle(ixs);
 635             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 636         }
 637     }
 638 
 639     /**
 640      * Loads a shuffle from an {@code int} array starting at an offset.
 641      * <p>
 642      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 643      * array element at index {@code i + N} logically AND'ed by
 644      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 645      * index {@code N}.
 646      *
 647      * @param species shuffle species
 648      * @param ixs the {@code int} array
 649      * @param i the offset into the array
 650      * @return a shuffle loaded from the {@code int} array
 651      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 652      * {@code i > a.length - species.length()}
 653      */
 654     @ForceInline
 655     public static Shuffle<Byte> shuffleFromArray(Species<Byte> species, int[] ixs, int i) {
 656         if (species.boxType() == ByteMaxVector.class)
 657             return new ByteMaxVector.ByteMaxShuffle(ixs, i);
 658         switch (species.bitSize()) {
 659             case 64: return new Byte64Vector.Byte64Shuffle(ixs, i);
 660             case 128: return new Byte128Vector.Byte128Shuffle(ixs, i);
 661             case 256: return new Byte256Vector.Byte256Shuffle(ixs, i);
 662             case 512: return new Byte512Vector.Byte512Shuffle(ixs, i);
 663             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 664         }
 665     }
 666 
 667     // Ops
 668 
 669     @Override
 670     public abstract ByteVector add(Vector<Byte> v);
 671 
 672     /**
 673      * Adds this vector to the broadcast of an input scalar.
 674      * <p>
 675      * This is a vector binary operation where the primitive addition operation
 676      * ({@code +}) is applied to lane elements.
 677      *
 678      * @param s the input scalar
 679      * @return the result of adding this vector to the broadcast of an input
 680      * scalar
 681      */
 682     public abstract ByteVector add(byte s);
 683 
 684     @Override
 685     public abstract ByteVector add(Vector<Byte> v, Mask<Byte> m);
 686 
 687     /**
 688      * Adds this vector to broadcast of an input scalar,
 689      * selecting lane elements controlled by a mask.
 690      * <p>
 691      * This is a vector binary operation where the primitive addition operation
 692      * ({@code +}) is applied to lane elements.
 693      *
 694      * @param s the input scalar
 695      * @param m the mask controlling lane selection
 696      * @return the result of adding this vector to the broadcast of an input
 697      * scalar
 698      */
 699     public abstract ByteVector add(byte s, Mask<Byte> m);
 700 
 701     @Override
 702     public abstract ByteVector sub(Vector<Byte> v);
 703 
 704     /**
 705      * Subtracts the broadcast of an input scalar from this vector.
 706      * <p>
 707      * This is a vector binary operation where the primitive subtraction
 708      * operation ({@code -}) is applied to lane elements.
 709      *
 710      * @param s the input scalar
 711      * @return the result of subtracting the broadcast of an input
 712      * scalar from this vector
 713      */
 714     public abstract ByteVector sub(byte s);
 715 
 716     @Override
 717     public abstract ByteVector sub(Vector<Byte> v, Mask<Byte> m);
 718 
 719     /**
 720      * Subtracts the broadcast of an input scalar from this vector, selecting
 721      * lane elements controlled by a mask.
 722      * <p>
 723      * This is a vector binary operation where the primitive subtraction
 724      * operation ({@code -}) is applied to lane elements.
 725      *
 726      * @param s the input scalar
 727      * @param m the mask controlling lane selection
 728      * @return the result of subtracting the broadcast of an input
 729      * scalar from this vector
 730      */
 731     public abstract ByteVector sub(byte s, Mask<Byte> m);
 732 
 733     @Override
 734     public abstract ByteVector mul(Vector<Byte> v);
 735 
 736     /**
 737      * Multiplies this vector with the broadcast of an input scalar.
 738      * <p>
 739      * This is a vector binary operation where the primitive multiplication
 740      * operation ({@code *}) is applied to lane elements.
 741      *
 742      * @param s the input scalar
 743      * @return the result of multiplying this vector with the broadcast of an
 744      * input scalar
 745      */
 746     public abstract ByteVector mul(byte s);
 747 
 748     @Override
 749     public abstract ByteVector mul(Vector<Byte> v, Mask<Byte> m);
 750 
 751     /**
 752      * Multiplies this vector with the broadcast of an input scalar, selecting
 753      * lane elements controlled by a mask.
 754      * <p>
 755      * This is a vector binary operation where the primitive multiplication
 756      * operation ({@code *}) is applied to lane elements.
 757      *
 758      * @param s the input scalar
 759      * @param m the mask controlling lane selection
 760      * @return the result of multiplying this vector with the broadcast of an
 761      * input scalar
 762      */
 763     public abstract ByteVector mul(byte s, Mask<Byte> m);
 764 
 765     @Override
 766     public abstract ByteVector neg();
 767 
 768     @Override
 769     public abstract ByteVector neg(Mask<Byte> m);
 770 
 771     @Override
 772     public abstract ByteVector abs();
 773 
 774     @Override
 775     public abstract ByteVector abs(Mask<Byte> m);
 776 
 777     @Override
 778     public abstract ByteVector min(Vector<Byte> v);
 779 
 780     @Override
 781     public abstract ByteVector min(Vector<Byte> v, Mask<Byte> m);
 782 
 783     /**
 784      * Returns the minimum of this vector and the broadcast of an input scalar.
 785      * <p>
 786      * This is a vector binary operation where the operation
 787      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 788      *
 789      * @param s the input scalar
 790      * @return the minimum of this vector and the broadcast of an input scalar
 791      */
 792     public abstract ByteVector min(byte s);
 793 
 794     @Override
 795     public abstract ByteVector max(Vector<Byte> v);
 796 
 797     @Override
 798     public abstract ByteVector max(Vector<Byte> v, Mask<Byte> m);
 799 
 800     /**
 801      * Returns the maximum of this vector and the broadcast of an input scalar.
 802      * <p>
 803      * This is a vector binary operation where the operation
 804      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 805      *
 806      * @param s the input scalar
 807      * @return the maximum of this vector and the broadcast of an input scalar
 808      */
 809     public abstract ByteVector max(byte s);
 810 
 811     @Override
 812     public abstract Mask<Byte> equal(Vector<Byte> v);
 813 
 814     /**
 815      * Tests if this vector is equal to the broadcast of an input scalar.
 816      * <p>
 817      * This is a vector binary test operation where the primitive equals
 818      * operation ({@code ==}) is applied to lane elements.
 819      *
 820      * @param s the input scalar
 821      * @return the result mask of testing if this vector is equal to the
 822      * broadcast of an input scalar
 823      */
 824     public abstract Mask<Byte> equal(byte s);
 825 
 826     @Override
 827     public abstract Mask<Byte> notEqual(Vector<Byte> v);
 828 
 829     /**
 830      * Tests if this vector is not equal to the broadcast of an input scalar.
 831      * <p>
 832      * This is a vector binary test operation where the primitive not equals
 833      * operation ({@code !=}) is applied to lane elements.
 834      *
 835      * @param s the input scalar
 836      * @return the result mask of testing if this vector is not equal to the
 837      * broadcast of an input scalar
 838      */
 839     public abstract Mask<Byte> notEqual(byte s);
 840 
 841     @Override
 842     public abstract Mask<Byte> lessThan(Vector<Byte> v);
 843 
 844     /**
 845      * Tests if this vector is less than the broadcast of an input scalar.
 846      * <p>
 847      * This is a vector binary test operation where the primitive less than
 848      * operation ({@code <}) is applied to lane elements.
 849      *
 850      * @param s the input scalar
 851      * @return the mask result of testing if this vector is less than the
 852      * broadcast of an input scalar
 853      */
 854     public abstract Mask<Byte> lessThan(byte s);
 855 
 856     @Override
 857     public abstract Mask<Byte> lessThanEq(Vector<Byte> v);
 858 
 859     /**
 860      * Tests if this vector is less or equal to the broadcast of an input scalar.
 861      * <p>
 862      * This is a vector binary test operation where the primitive less than
 863      * or equal to operation ({@code <=}) is applied to lane elements.
 864      *
 865      * @param s the input scalar
 866      * @return the mask result of testing if this vector is less than or equal
 867      * to the broadcast of an input scalar
 868      */
 869     public abstract Mask<Byte> lessThanEq(byte s);
 870 
 871     @Override
 872     public abstract Mask<Byte> greaterThan(Vector<Byte> v);
 873 
 874     /**
 875      * Tests if this vector is greater than the broadcast of an input scalar.
 876      * <p>
 877      * This is a vector binary test operation where the primitive greater than
 878      * operation ({@code >}) is applied to lane elements.
 879      *
 880      * @param s the input scalar
 881      * @return the mask result of testing if this vector is greater than the
 882      * broadcast of an input scalar
 883      */
 884     public abstract Mask<Byte> greaterThan(byte s);
 885 
 886     @Override
 887     public abstract Mask<Byte> greaterThanEq(Vector<Byte> v);
 888 
 889     /**
 890      * Tests if this vector is greater than or equal to the broadcast of an
 891      * input scalar.
 892      * <p>
 893      * This is a vector binary test operation where the primitive greater than
 894      * or equal to operation ({@code >=}) is applied to lane elements.
 895      *
 896      * @param s the input scalar
 897      * @return the mask result of testing if this vector is greater than or
 898      * equal to the broadcast of an input scalar
 899      */
 900     public abstract Mask<Byte> greaterThanEq(byte s);
 901 
 902     @Override
 903     public abstract ByteVector blend(Vector<Byte> v, Mask<Byte> m);
 904 
 905     /**
 906      * Blends the lane elements of this vector with those of the broadcast of an
 907      * input scalar, selecting lanes controlled by a mask.
 908      * <p>
 909      * For each lane of the mask, at lane index {@code N}, if the mask lane
 910      * is set then the lane element at {@code N} from the input vector is
 911      * selected and placed into the resulting vector at {@code N},
 912      * otherwise the the lane element at {@code N} from this input vector is
 913      * selected and placed into the resulting vector at {@code N}.
 914      *
 915      * @param s the input scalar
 916      * @param m the mask controlling lane selection
 917      * @return the result of blending the lane elements of this vector with
 918      * those of the broadcast of an input scalar
 919      */
 920     public abstract ByteVector blend(byte s, Mask<Byte> m);
 921 
 922     @Override
 923     public abstract ByteVector rearrange(Vector<Byte> v,
 924                                                       Shuffle<Byte> s, Mask<Byte> m);
 925 
 926     @Override
 927     public abstract ByteVector rearrange(Shuffle<Byte> m);
 928 
 929     @Override
 930     public abstract ByteVector reshape(Species<Byte> s);
 931 
 932     @Override
 933     public abstract ByteVector rotateEL(int i);
 934 
 935     @Override
 936     public abstract ByteVector rotateER(int i);
 937 
 938     @Override
 939     public abstract ByteVector shiftEL(int i);
 940 
 941     @Override
 942     public abstract ByteVector shiftER(int i);
 943 
 944 
 945 
 946     /**
 947      * Bitwise ANDs this vector with an input vector.
 948      * <p>
 949      * This is a vector binary operation where the primitive bitwise AND
 950      * operation ({@code &}) is applied to lane elements.


 960      * This is a vector binary operation where the primitive bitwise AND
 961      * operation ({@code &}) is applied to lane elements.
 962      *
 963      * @param s the input scalar
 964      * @return the bitwise AND of this vector with the broadcast of an input
 965      * scalar
 966      */
 967     public abstract ByteVector and(byte s);
 968 
 969     /**
 970      * Bitwise ANDs this vector with an input vector, selecting lane elements
 971      * controlled by a mask.
 972      * <p>
 973      * This is a vector binary operation where the primitive bitwise AND
 974      * operation ({@code &}) is applied to lane elements.
 975      *
 976      * @param v the input vector
 977      * @param m the mask controlling lane selection
 978      * @return the bitwise AND of this vector with the input vector
 979      */
 980     public abstract ByteVector and(Vector<Byte> v, Mask<Byte> m);
 981 
 982     /**
 983      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 984      * lane elements controlled by a mask.
 985      * <p>
 986      * This is a vector binary operation where the primitive bitwise AND
 987      * operation ({@code &}) is applied to lane elements.
 988      *
 989      * @param s the input scalar
 990      * @param m the mask controlling lane selection
 991      * @return the bitwise AND of this vector with the broadcast of an input
 992      * scalar
 993      */
 994     public abstract ByteVector and(byte s, Mask<Byte> m);
 995 
 996     /**
 997      * Bitwise ORs this vector with an input vector.
 998      * <p>
 999      * This is a vector binary operation where the primitive bitwise OR
1000      * operation ({@code |}) is applied to lane elements.
1001      *
1002      * @param v the input vector
1003      * @return the bitwise OR of this vector with the input vector
1004      */
1005     public abstract ByteVector or(Vector<Byte> v);
1006 
1007     /**
1008      * Bitwise ORs this vector with the broadcast of an input scalar.
1009      * <p>
1010      * This is a vector binary operation where the primitive bitwise OR
1011      * operation ({@code |}) is applied to lane elements.
1012      *
1013      * @param s the input scalar
1014      * @return the bitwise OR of this vector with the broadcast of an input
1015      * scalar
1016      */
1017     public abstract ByteVector or(byte s);
1018 
1019     /**
1020      * Bitwise ORs this vector with an input vector, selecting lane elements
1021      * controlled by a mask.
1022      * <p>
1023      * This is a vector binary operation where the primitive bitwise OR
1024      * operation ({@code |}) is applied to lane elements.
1025      *
1026      * @param v the input vector
1027      * @param m the mask controlling lane selection
1028      * @return the bitwise OR of this vector with the input vector
1029      */
1030     public abstract ByteVector or(Vector<Byte> v, Mask<Byte> m);
1031 
1032     /**
1033      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
1034      * lane elements controlled by a mask.
1035      * <p>
1036      * This is a vector binary operation where the primitive bitwise OR
1037      * operation ({@code |}) is applied to lane elements.
1038      *
1039      * @param s the input scalar
1040      * @param m the mask controlling lane selection
1041      * @return the bitwise OR of this vector with the broadcast of an input
1042      * scalar
1043      */
1044     public abstract ByteVector or(byte s, Mask<Byte> m);
1045 
1046     /**
1047      * Bitwise XORs this vector with an input vector.
1048      * <p>
1049      * This is a vector binary operation where the primitive bitwise XOR
1050      * operation ({@code ^}) is applied to lane elements.
1051      *
1052      * @param v the input vector
1053      * @return the bitwise XOR of this vector with the input vector
1054      */
1055     public abstract ByteVector xor(Vector<Byte> v);
1056 
1057     /**
1058      * Bitwise XORs this vector with the broadcast of an input scalar.
1059      * <p>
1060      * This is a vector binary operation where the primitive bitwise XOR
1061      * operation ({@code ^}) is applied to lane elements.
1062      *
1063      * @param s the input scalar
1064      * @return the bitwise XOR of this vector with the broadcast of an input
1065      * scalar
1066      */
1067     public abstract ByteVector xor(byte s);
1068 
1069     /**
1070      * Bitwise XORs this vector with an input vector, selecting lane elements
1071      * controlled by a mask.
1072      * <p>
1073      * This is a vector binary operation where the primitive bitwise XOR
1074      * operation ({@code ^}) is applied to lane elements.
1075      *
1076      * @param v the input vector
1077      * @param m the mask controlling lane selection
1078      * @return the bitwise XOR of this vector with the input vector
1079      */
1080     public abstract ByteVector xor(Vector<Byte> v, Mask<Byte> m);
1081 
1082     /**
1083      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1084      * lane elements controlled by a mask.
1085      * <p>
1086      * This is a vector binary operation where the primitive bitwise XOR
1087      * operation ({@code ^}) is applied to lane elements.
1088      *
1089      * @param s the input scalar
1090      * @param m the mask controlling lane selection
1091      * @return the bitwise XOR of this vector with the broadcast of an input
1092      * scalar
1093      */
1094     public abstract ByteVector xor(byte s, Mask<Byte> m);
1095 
1096     /**
1097      * Bitwise NOTs this vector.
1098      * <p>
1099      * This is a vector unary operation where the primitive bitwise NOT
1100      * operation ({@code ~}) is applied to lane elements.
1101      *
1102      * @return the bitwise NOT of this vector
1103      */
1104     public abstract ByteVector not();
1105 
1106     /**
1107      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1108      * <p>
1109      * This is a vector unary operation where the primitive bitwise NOT
1110      * operation ({@code ~}) is applied to lane elements.
1111      *
1112      * @param m the mask controlling lane selection
1113      * @return the bitwise NOT of this vector
1114      */
1115     public abstract ByteVector not(Mask<Byte> m);
1116 
1117     /**
1118      * Logically left shifts this vector by the broadcast of an input scalar.
1119      * <p>
1120      * This is a vector binary operation where the primitive logical left shift
1121      * operation ({@code <<}) is applied to lane elements to left shift the
1122      * element by shift value as specified by the input scalar. Only the 3
1123      * lowest-order bits of shift value are used. It is as if the shift value
1124      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1125      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1126      *
1127      * @param s the input scalar; the number of the bits to left shift
1128      * @return the result of logically left shifting left this vector by the
1129      * broadcast of an input scalar
1130      */
1131     public abstract ByteVector shiftL(int s);
1132 
1133     /**
1134      * Logically left shifts this vector by the broadcast of an input scalar,
1135      * selecting lane elements controlled by a mask.
1136      * <p>
1137      * This is a vector binary operation where the primitive logical left shift
1138      * operation ({@code <<}) is applied to lane elements to left shift the
1139      * element by shift value as specified by the input scalar. Only the 3
1140      * lowest-order bits of shift value are used. It is as if the shift value
1141      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1142      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1143      *
1144      * @param s the input scalar; the number of the bits to left shift
1145      * @param m the mask controlling lane selection
1146      * @return the result of logically left shifting left this vector by the
1147      * broadcast of an input scalar
1148      */
1149     public abstract ByteVector shiftL(int s, Mask<Byte> m);
1150 
1151 
1152     // logical, or unsigned, shift right
1153 
1154      /**
1155      * Logically right shifts (or unsigned right shifts) this vector by the
1156      * broadcast of an input scalar.
1157      * <p>
1158      * This is a vector binary operation where the primitive logical right shift
1159      * operation ({@code >>>}) is applied to lane elements to logically right shift the
1160      * element by shift value as specified by the input scalar. Only the 3
1161      * lowest-order bits of shift value are used. It is as if the shift value
1162      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1163      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1164      *
1165      * @param s the input scalar; the number of the bits to right shift
1166      * @return the result of logically right shifting this vector by the
1167      * broadcast of an input scalar
1168      */
1169     public abstract ByteVector shiftR(int s);
1170 
1171      /**
1172      * Logically right shifts (or unsigned right shifts) this vector by the
1173      * broadcast of an input scalar, selecting lane elements controlled by a
1174      * mask.
1175      * <p>
1176      * This is a vector binary operation where the primitive logical right shift
1177      * operation ({@code >>>}) is applied to lane elements to logically right shift the
1178      * element by shift value as specified by the input scalar. Only the 3
1179      * lowest-order bits of shift value are used. It is as if the shift value
1180      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1181      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1182      *
1183      * @param s the input scalar; the number of the bits to right shift
1184      * @param m the mask controlling lane selection
1185      * @return the result of logically right shifting this vector by the
1186      * broadcast of an input scalar
1187      */
1188     public abstract ByteVector shiftR(int s, Mask<Byte> m);
1189 
1190 
1191     /**
1192      * Arithmetically right shifts (or signed right shifts) this vector by the
1193      * broadcast of an input scalar.
1194      * <p>
1195      * This is a vector binary operation where the primitive arithmetic right
1196      * shift operation ({@code >>}) is applied to lane elements  to arithmetically
1197      * right shift the element by shift value as specified by the input scalar.
1198      * Only the 3 lowest-order bits of shift value are used. It is as if the shift
1199      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1200      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1201      *
1202      * @param s the input scalar; the number of the bits to right shift
1203      * @return the result of arithmetically right shifting this vector by the
1204      * broadcast of an input scalar
1205      */
1206     public abstract ByteVector aShiftR(int s);
1207 
1208     /**
1209      * Arithmetically right shifts (or signed right shifts) this vector by the
1210      * broadcast of an input scalar, selecting lane elements controlled by a
1211      * mask.
1212      * <p>
1213      * This is a vector binary operation where the primitive arithmetic right
1214      * shift operation ({@code >>}) is applied to lane elements  to arithmetically
1215      * right shift the element by shift value as specified by the input scalar.
1216      * Only the 3 lowest-order bits of shift value are used. It is as if the shift
1217      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1218      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1219      *
1220      * @param s the input scalar; the number of the bits to right shift
1221      * @param m the mask controlling lane selection
1222      * @return the result of arithmetically right shifting this vector by the
1223      * broadcast of an input scalar
1224      */
1225     public abstract ByteVector aShiftR(int s, Mask<Byte> m);
1226 
1227 
1228     @Override
1229     public abstract void intoByteArray(byte[] a, int ix);
1230 
1231     @Override
1232     public abstract void intoByteArray(byte[] a, int ix, Mask<Byte> m);
1233 
1234     @Override
1235     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1236 
1237     @Override
1238     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Byte> m);
1239 
1240 
1241     // Type specific horizontal reductions
1242     /**
1243      * Adds all lane elements of this vector.
1244      * <p>
1245      * This is an associative vector reduction operation where the addition
1246      * operation ({@code +}) is applied to lane elements,
1247      * and the identity value is {@code 0}.
1248      *
1249      * @return the addition of all the lane elements of this vector
1250      */
1251     public abstract byte addAll();
1252 
1253     /**
1254      * Adds all lane elements of this vector, selecting lane elements
1255      * controlled by a mask.
1256      * <p>
1257      * This is an associative vector reduction operation where the addition
1258      * operation ({@code +}) is applied to lane elements,
1259      * and the identity value is {@code 0}.
1260      *
1261      * @param m the mask controlling lane selection
1262      * @return the addition of the selected lane elements of this vector
1263      */
1264     public abstract byte addAll(Mask<Byte> m);
1265 
1266     /**
1267      * Multiplies all lane elements of this vector.
1268      * <p>
1269      * This is an associative vector reduction operation where the
1270      * multiplication operation ({@code *}) is applied to lane elements,
1271      * and the identity value is {@code 1}.
1272      *
1273      * @return the multiplication of all the lane elements of this vector
1274      */
1275     public abstract byte mulAll();
1276 
1277     /**
1278      * Multiplies all lane elements of this vector, selecting lane elements
1279      * controlled by a mask.
1280      * <p>
1281      * This is an associative vector reduction operation where the
1282      * multiplication operation ({@code *}) is applied to lane elements,
1283      * and the identity value is {@code 1}.
1284      *
1285      * @param m the mask controlling lane selection
1286      * @return the multiplication of all the lane elements of this vector
1287      */
1288     public abstract byte mulAll(Mask<Byte> m);
1289 
1290     /**
1291      * Returns the minimum lane element of this vector.
1292      * <p>
1293      * This is an associative vector reduction operation where the operation
1294      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1295      * and the identity value is
1296      * {@link Byte#MAX_VALUE}.
1297      *
1298      * @return the minimum lane element of this vector
1299      */
1300     public abstract byte minAll();
1301 
1302     /**
1303      * Returns the minimum lane element of this vector, selecting lane elements
1304      * controlled by a mask.
1305      * <p>
1306      * This is an associative vector reduction operation where the operation
1307      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1308      * and the identity value is
1309      * {@link Byte#MAX_VALUE}.
1310      *
1311      * @param m the mask controlling lane selection
1312      * @return the minimum lane element of this vector
1313      */
1314     public abstract byte minAll(Mask<Byte> m);
1315 
1316     /**
1317      * Returns the maximum lane element of this vector.
1318      * <p>
1319      * This is an associative vector reduction operation where the operation
1320      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1321      * and the identity value is
1322      * {@link Byte#MIN_VALUE}.
1323      *
1324      * @return the maximum lane element of this vector
1325      */
1326     public abstract byte maxAll();
1327 
1328     /**
1329      * Returns the maximum lane element of this vector, selecting lane elements
1330      * controlled by a mask.
1331      * <p>
1332      * This is an associative vector reduction operation where the operation
1333      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1334      * and the identity value is
1335      * {@link Byte#MIN_VALUE}.
1336      *
1337      * @param m the mask controlling lane selection
1338      * @return the maximum lane element of this vector
1339      */
1340     public abstract byte maxAll(Mask<Byte> m);
1341 
1342     /**
1343      * Logically ORs all lane elements of this vector.
1344      * <p>
1345      * This is an associative vector reduction operation where the logical OR
1346      * operation ({@code |}) is applied to lane elements,
1347      * and the identity value is {@code 0}.
1348      *
1349      * @return the logical OR all the lane elements of this vector
1350      */
1351     public abstract byte orAll();
1352 
1353     /**
1354      * Logically ORs all lane elements of this vector, selecting lane elements
1355      * controlled by a mask.
1356      * <p>
1357      * This is an associative vector reduction operation where the logical OR
1358      * operation ({@code |}) is applied to lane elements,
1359      * and the identity value is {@code 0}.
1360      *
1361      * @param m the mask controlling lane selection
1362      * @return the logical OR all the lane elements of this vector
1363      */
1364     public abstract byte orAll(Mask<Byte> m);
1365 
1366     /**
1367      * Logically ANDs all lane elements of this vector.
1368      * <p>
1369      * This is an associative vector reduction operation where the logical AND
1370      * operation ({@code |}) is applied to lane elements,
1371      * and the identity value is {@code -1}.
1372      *
1373      * @return the logical AND all the lane elements of this vector
1374      */
1375     public abstract byte andAll();
1376 
1377     /**
1378      * Logically ANDs all lane elements of this vector, selecting lane elements
1379      * controlled by a mask.
1380      * <p>
1381      * This is an associative vector reduction operation where the logical AND
1382      * operation ({@code |}) is applied to lane elements,
1383      * and the identity value is {@code -1}.
1384      *
1385      * @param m the mask controlling lane selection
1386      * @return the logical AND all the lane elements of this vector
1387      */
1388     public abstract byte andAll(Mask<Byte> m);
1389 
1390     /**
1391      * Logically XORs all lane elements of this vector.
1392      * <p>
1393      * This is an associative vector reduction operation where the logical XOR
1394      * operation ({@code ^}) is applied to lane elements,
1395      * and the identity value is {@code 0}.
1396      *
1397      * @return the logical XOR all the lane elements of this vector
1398      */
1399     public abstract byte xorAll();
1400 
1401     /**
1402      * Logically XORs all lane elements of this vector, selecting lane elements
1403      * controlled by a mask.
1404      * <p>
1405      * This is an associative vector reduction operation where the logical XOR
1406      * operation ({@code ^}) is applied to lane elements,
1407      * and the identity value is {@code 0}.
1408      *
1409      * @param m the mask controlling lane selection
1410      * @return the logical XOR all the lane elements of this vector
1411      */
1412     public abstract byte xorAll(Mask<Byte> m);
1413 
1414     // Type specific accessors
1415 
1416     /**
1417      * Gets the lane element at lane index {@code i}
1418      *
1419      * @param i the lane index
1420      * @return the lane element at lane index {@code i}
1421      * @throws IllegalArgumentException if the index is is out of range
1422      * ({@code < 0 || >= length()})
1423      */
1424     public abstract byte get(int i);
1425 
1426     /**
1427      * Replaces the lane element of this vector at lane index {@code i} with
1428      * value {@code e}.
1429      * <p>
1430      * This is a cross-lane operation and behaves as if it returns the result
1431      * of blending this vector with an input vector that is the result of
1432      * broadcasting {@code e} and a mask that has only one lane set at lane


1474      * @param i the offset into the array
1475      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1476      * {@code i > a.length - this.length()}
1477      */
1478     public abstract void intoArray(byte[] a, int i);
1479 
1480     /**
1481      * Stores this vector into an array starting at offset and using a mask.
1482      * <p>
1483      * For each vector lane, where {@code N} is the vector lane index,
1484      * if the mask lane at index {@code N} is set then the lane element at
1485      * index {@code N} is stored into the array index {@code i + N}.
1486      *
1487      * @param a the array
1488      * @param i the offset into the array
1489      * @param m the mask
1490      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1491      * for any vector lane index {@code N} where the mask at lane {@code N}
1492      * is set {@code i >= a.length - N}
1493      */
1494     public abstract void intoArray(byte[] a, int i, Mask<Byte> m);
1495 
1496     /**
1497      * Stores this vector into an array using indexes obtained from an index
1498      * map.
1499      * <p>
1500      * For each vector lane, where {@code N} is the vector lane index, the
1501      * lane element at index {@code N} is stored into the array at index
1502      * {@code i + indexMap[j + N]}.
1503      *
1504      * @param a the array
1505      * @param i the offset into the array, may be negative if relative
1506      * indexes in the index map compensate to produce a value within the
1507      * array bounds
1508      * @param indexMap the index map
1509      * @param j the offset into the index map
1510      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1511      * {@code j > indexMap.length - this.length()},
1512      * or for any vector lane index {@code N} the result of
1513      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1514      */


1521      * map and using a mask.
1522      * <p>
1523      * For each vector lane, where {@code N} is the vector lane index,
1524      * if the mask lane at index {@code N} is set then the lane element at
1525      * index {@code N} is stored into the array at index
1526      * {@code i + indexMap[j + N]}.
1527      *
1528      * @param a the array
1529      * @param i the offset into the array, may be negative if relative
1530      * indexes in the index map compensate to produce a value within the
1531      * array bounds
1532      * @param m the mask
1533      * @param indexMap the index map
1534      * @param j the offset into the index map
1535      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1536      * {@code j > indexMap.length - this.length()},
1537      * or for any vector lane index {@code N} where the mask at lane
1538      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1539      * {@code < 0} or {@code >= a.length}
1540      */
1541     public void intoArray(byte[] a, int i, Mask<Byte> m, int[] indexMap, int j) {
1542         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
1543     }
1544     // Species
1545 
1546     @Override
1547     public abstract Species<Byte> species();
1548 
1549     /**
1550      * Class representing {@link ByteVector}'s of the same {@link Vector.Shape Shape}.
1551      */
1552     static final class ByteSpecies extends Vector.AbstractSpecies<Byte> {
1553         final Function<byte[], ByteVector> vectorFactory;
1554         final Function<boolean[], Vector.Mask<Byte>> maskFactory;
1555 
1556         private ByteSpecies(Vector.Shape shape,
1557                           Class<?> boxType,
1558                           Class<?> maskType,
1559                           Function<byte[], ByteVector> vectorFactory,
1560                           Function<boolean[], Vector.Mask<Byte>> maskFactory) {
1561             super(shape, byte.class, Byte.SIZE, boxType, maskType);



1562             this.vectorFactory = vectorFactory;
1563             this.maskFactory = maskFactory;
1564         }
1565 
1566         interface FOp {
1567             byte apply(int i);
1568         }
1569 
1570         interface FOpm {
1571             boolean apply(int i);
1572         }
1573 
1574         ByteVector op(FOp f) {
1575             byte[] res = new byte[length()];
1576             for (int i = 0; i < length(); i++) {
1577                 res[i] = f.apply(i);
1578             }
1579             return vectorFactory.apply(res);
1580         }
1581 
1582         ByteVector op(Vector.Mask<Byte> o, FOp f) {
1583             byte[] res = new byte[length()];
1584             boolean[] mbits = ((AbstractMask<Byte>)o).getBits();
1585             for (int i = 0; i < length(); i++) {
1586                 if (mbits[i]) {
1587                     res[i] = f.apply(i);
1588                 }
1589             }
1590             return vectorFactory.apply(res);
1591         }
1592 
1593         Vector.Mask<Byte> opm(IntVector.IntSpecies.FOpm f) {
1594             boolean[] res = new boolean[length()];
1595             for (int i = 0; i < length(); i++) {
1596                 res[i] = (boolean)f.apply(i);
1597             }
1598             return maskFactory.apply(res);
1599         }
1600     }
1601 
1602     /**
1603      * Finds the preferred species for an element type of {@code byte}.
1604      * <p>
1605      * A preferred species is a species chosen by the platform that has a
1606      * shape of maximal bit size.  A preferred species for different element
1607      * types will have the same shape, and therefore vectors, masks, and
1608      * shuffles created from such species will be shape compatible.
1609      *
1610      * @return the preferred species for an element type of {@code byte}
1611      */
1612     private static ByteSpecies preferredSpecies() {
1613         return (ByteSpecies) Species.ofPreferred(byte.class);
1614     }
1615 
1616     /**
1617      * Finds a species for an element type of {@code byte} and shape.
1618      *
1619      * @param s the shape
1620      * @return a species for an element type of {@code byte} and shape
1621      * @throws IllegalArgumentException if no such species exists for the shape
1622      */
1623     static ByteSpecies species(Vector.Shape s) {
1624         Objects.requireNonNull(s);
1625         switch (s) {
1626             case S_64_BIT: return (ByteSpecies) SPECIES_64;
1627             case S_128_BIT: return (ByteSpecies) SPECIES_128;
1628             case S_256_BIT: return (ByteSpecies) SPECIES_256;
1629             case S_512_BIT: return (ByteSpecies) SPECIES_512;
1630             case S_Max_BIT: return (ByteSpecies) SPECIES_MAX;
1631             default: throw new IllegalArgumentException("Bad shape: " + s);
1632         }
1633     }
1634 
1635     /** Species representing {@link ByteVector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */
1636     public static final Species<Byte> SPECIES_64 = new ByteSpecies(Shape.S_64_BIT, Byte64Vector.class, Byte64Vector.Byte64Mask.class,
1637                                                                      Byte64Vector::new, Byte64Vector.Byte64Mask::new);
1638 
1639     /** Species representing {@link ByteVector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */
1640     public static final Species<Byte> SPECIES_128 = new ByteSpecies(Shape.S_128_BIT, Byte128Vector.class, Byte128Vector.Byte128Mask.class,
1641                                                                       Byte128Vector::new, Byte128Vector.Byte128Mask::new);
1642 
1643     /** Species representing {@link ByteVector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */
1644     public static final Species<Byte> SPECIES_256 = new ByteSpecies(Shape.S_256_BIT, Byte256Vector.class, Byte256Vector.Byte256Mask.class,
1645                                                                       Byte256Vector::new, Byte256Vector.Byte256Mask::new);
1646 
1647     /** Species representing {@link ByteVector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */
1648     public static final Species<Byte> SPECIES_512 = new ByteSpecies(Shape.S_512_BIT, Byte512Vector.class, Byte512Vector.Byte512Mask.class,
1649                                                                       Byte512Vector::new, Byte512Vector.Byte512Mask::new);
1650 
1651     /** Species representing {@link ByteVector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */
1652     public static final Species<Byte> SPECIES_MAX = new ByteSpecies(Shape.S_Max_BIT, ByteMaxVector.class, ByteMaxVector.ByteMaxMask.class,
1653                                                                       ByteMaxVector::new, ByteMaxVector.ByteMaxMask::new);





1654 
1655     /**
1656      * Preferred species for {@link ByteVector}s.
1657      * A preferred species is a species of maximal bit size for the platform.
1658      */
1659     public static final Species<Byte> SPECIES_PREFERRED = (Species<Byte>) preferredSpecies();
1660 }


  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code byte} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class ByteVector extends Vector<Byte> {
  45 
  46     ByteVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE);
  49 
  50     // Unary operator
  51 
  52     interface FUnOp {
  53         byte apply(int i, byte a);
  54     }
  55 
  56     abstract ByteVector uOp(FUnOp f);
  57 
  58     abstract ByteVector uOp(VectorMask<Byte> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         byte apply(int i, byte a, byte b);
  64     }
  65 
  66     abstract ByteVector bOp(Vector<Byte> v, FBinOp f);
  67 
  68     abstract ByteVector bOp(Vector<Byte> v, VectorMask<Byte> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         byte apply(int i, byte a, byte b, byte c);
  74     }
  75 
  76     abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, FTriOp f);
  77 
  78     abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, VectorMask<Byte> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract byte rOp(byte v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, byte a, byte b);
  88     }
  89 
  90     abstract VectorMask<Byte> bTest(Vector<Byte> v, FBinTest f);
  91 
  92     // Foreach
  93 
  94     interface FUnCon {
  95         void apply(int i, byte a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(VectorMask<Byte> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @param species species of desired vector
 109      * @return a zero vector of given species
 110      */
 111     @ForceInline
 112     @SuppressWarnings("unchecked")
 113     public static ByteVector zero(VectorSpecies<Byte> species) {
 114         return VectorIntrinsics.broadcastCoerced((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 115                                                  0, species,
 116                                                  ((bits, s) -> ((ByteSpecies)s).op(i -> (byte)bits)));
 117     }
 118 
 119     /**
 120      * Loads a vector from a byte array starting at an offset.
 121      * <p>
 122      * Bytes are composed into primitive lane elements according to the
 123      * native byte order of the underlying platform
 124      * <p>
 125      * This method behaves as if it returns the result of calling the
 126      * byte buffer, offset, and mask accepting
 127      * {@link #fromByteBuffer(VectorSpecies<Byte>, ByteBuffer, int, VectorMask) method} as follows:
 128      * <pre>{@code
 129      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 130      * }</pre>
 131      *
 132      * @param species species of desired vector
 133      * @param a the byte array
 134      * @param ix the offset into the array
 135      * @return a vector loaded from a byte array
 136      * @throws IndexOutOfBoundsException if {@code i < 0} or
 137      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 138      */
 139     @ForceInline
 140     @SuppressWarnings("unchecked")
 141     public static ByteVector fromByteArray(VectorSpecies<Byte> species, byte[] a, int ix) {
 142         Objects.requireNonNull(a);
 143         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 144         return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 145                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 146                                      a, ix, species,
 147                                      (c, idx, s) -> {
 148                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 149                                          ByteBuffer tb = bbc;
 150                                          return ((ByteSpecies)s).op(i -> tb.get());
 151                                      });
 152     }
 153 
 154     /**
 155      * Loads a vector from a byte array starting at an offset and using a
 156      * mask.
 157      * <p>
 158      * Bytes are composed into primitive lane elements according to the
 159      * native byte order of the underlying platform.
 160      * <p>
 161      * This method behaves as if it returns the result of calling the
 162      * byte buffer, offset, and mask accepting
 163      * {@link #fromByteBuffer(VectorSpecies<Byte>, ByteBuffer, int, VectorMask) method} as follows:
 164      * <pre>{@code
 165      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 166      * }</pre>
 167      *
 168      * @param species species of desired vector
 169      * @param a the byte array
 170      * @param ix the offset into the array
 171      * @param m the mask
 172      * @return a vector loaded from a byte array
 173      * @throws IndexOutOfBoundsException if {@code i < 0} or
 174      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 175      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 176      * or {@code > a.length},
 177      * for any vector lane index {@code N} where the mask at lane {@code N}
 178      * is set
 179      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 180      */
 181     @ForceInline
 182     public static ByteVector fromByteArray(VectorSpecies<Byte> species, byte[] a, int ix, VectorMask<Byte> m) {
 183         return zero(species).blend(fromByteArray(species, a, ix), m);
 184     }
 185 
 186     /**
 187      * Loads a vector from an array starting at offset.
 188      * <p>
 189      * For each vector lane, where {@code N} is the vector lane index, the
 190      * array element at index {@code i + N} is placed into the
 191      * resulting vector at lane index {@code N}.
 192      *
 193      * @param species species of desired vector
 194      * @param a the array
 195      * @param i the offset into the array
 196      * @return the vector loaded from an array
 197      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 198      * {@code i > a.length - this.length()}
 199      */
 200     @ForceInline
 201     @SuppressWarnings("unchecked")
 202     public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int i){
 203         Objects.requireNonNull(a);
 204         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 205         return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 206                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 207                                      a, i, species,
 208                                      (c, idx, s) -> ((ByteSpecies)s).op(n -> c[idx + n]));
 209     }
 210 
 211 
 212     /**
 213      * Loads a vector from an array starting at offset and using a mask.
 214      * <p>
 215      * For each vector lane, where {@code N} is the vector lane index,
 216      * if the mask lane at index {@code N} is set then the array element at
 217      * index {@code i + N} is placed into the resulting vector at lane index
 218      * {@code N}, otherwise the default element value is placed into the
 219      * resulting vector at lane index {@code N}.
 220      *
 221      * @param species species of desired vector
 222      * @param a the array
 223      * @param i the offset into the array
 224      * @param m the mask
 225      * @return the vector loaded from an array
 226      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 227      * for any vector lane index {@code N} where the mask at lane {@code N}
 228      * is set {@code i > a.length - N}
 229      */
 230     @ForceInline
 231     public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int i, VectorMask<Byte> m) {
 232         return zero(species).blend(fromArray(species, a, i), m);
 233     }
 234 
 235     /**
 236      * Loads a vector from an array using indexes obtained from an index
 237      * map.
 238      * <p>
 239      * For each vector lane, where {@code N} is the vector lane index, the
 240      * array element at index {@code i + indexMap[j + N]} is placed into the
 241      * resulting vector at lane index {@code N}.
 242      *
 243      * @param species species of desired vector
 244      * @param a the array
 245      * @param i the offset into the array, may be negative if relative
 246      * indexes in the index map compensate to produce a value within the
 247      * array bounds
 248      * @param indexMap the index map
 249      * @param j the offset into the index map
 250      * @return the vector loaded from an array
 251      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 252      * {@code j > indexMap.length - this.length()},
 253      * or for any vector lane index {@code N} the result of
 254      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 255      */
 256     public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int i, int[] indexMap, int j) {
 257         return ((ByteSpecies)species).op(n -> a[i + indexMap[j + n]]);
 258     }
 259     /**
 260      * Loads a vector from an array using indexes obtained from an index
 261      * map and using a mask.
 262      * <p>
 263      * For each vector lane, where {@code N} is the vector lane index,
 264      * if the mask lane at index {@code N} is set then the array element at
 265      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 266      * at lane index {@code N}.
 267      *
 268      * @param species species of desired vector
 269      * @param a the array
 270      * @param i the offset into the array, may be negative if relative
 271      * indexes in the index map compensate to produce a value within the
 272      * array bounds
 273      * @param m the mask
 274      * @param indexMap the index map
 275      * @param j the offset into the index map
 276      * @return the vector loaded from an array
 277      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 278      * {@code j > indexMap.length - this.length()},
 279      * or for any vector lane index {@code N} where the mask at lane
 280      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 281      * {@code < 0} or {@code >= a.length}
 282      */
 283     public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int i, VectorMask<Byte> m, int[] indexMap, int j) {
 284         return ((ByteSpecies)species).op(m, n -> a[i + indexMap[j + n]]);
 285     }
 286 
 287     /**
 288      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 289      * offset into the byte buffer.
 290      * <p>
 291      * Bytes are composed into primitive lane elements according to the
 292      * native byte order of the underlying platform.
 293      * <p>
 294      * This method behaves as if it returns the result of calling the
 295      * byte buffer, offset, and mask accepting
 296      * {@link #fromByteBuffer(VectorSpecies<Byte>, ByteBuffer, int, VectorMask)} method} as follows:
 297      * <pre>{@code
 298      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 299      * }</pre>
 300      *
 301      * @param species species of desired vector
 302      * @param bb the byte buffer
 303      * @param ix the offset into the byte buffer
 304      * @return a vector loaded from a byte buffer
 305      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 306      * or {@code > b.limit()},
 307      * or if there are fewer than
 308      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 309      * remaining in the byte buffer from the given offset
 310      */
 311     @ForceInline
 312     @SuppressWarnings("unchecked")
 313     public static ByteVector fromByteBuffer(VectorSpecies<Byte> species, ByteBuffer bb, int ix) {
 314         if (bb.order() != ByteOrder.nativeOrder()) {
 315             throw new IllegalArgumentException();
 316         }
 317         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 318         return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
 319                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 320                                      bb, ix, species,
 321                                      (c, idx, s) -> {
 322                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 323                                          ByteBuffer tb = bbc;
 324                                          return ((ByteSpecies)s).op(i -> tb.get());
 325                                      });
 326     }
 327 
 328     /**
 329      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 330      * offset into the byte buffer and using a mask.
 331      * <p>
 332      * This method behaves as if the byte buffer is viewed as a primitive
 333      * {@link java.nio.Buffer buffer} for the primitive element type,


 345      * e[] es = new e[this.length()];
 346      * for (int n = 0; n < t.length; n++) {
 347      *     if (m.isSet(n))
 348      *         es[n] = eb.get(n);
 349      * }
 350      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 351      * }</pre>
 352      *
 353      * @param species species of desired vector
 354      * @param bb the byte buffer
 355      * @param ix the offset into the byte buffer
 356      * @param m the mask
 357      * @return a vector loaded from a byte buffer
 358      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 359      * or {@code > b.limit()},
 360      * for any vector lane index {@code N} where the mask at lane {@code N}
 361      * is set
 362      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 363      */
 364     @ForceInline
 365     public static ByteVector fromByteBuffer(VectorSpecies<Byte> species, ByteBuffer bb, int ix, VectorMask<Byte> m) {
 366         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 367     }
 368 
 369     /**
 370      * Returns a vector where all lane elements are set to the primitive
 371      * value {@code e}.
 372      *
 373      * @param s species of the desired vector
 374      * @param e the value
 375      * @return a vector of vector where all lane elements are set to
 376      * the primitive value {@code e}
 377      */
 378     @ForceInline
 379     @SuppressWarnings("unchecked")
 380     public static ByteVector broadcast(VectorSpecies<Byte> s, byte e) {
 381         return VectorIntrinsics.broadcastCoerced(
 382             (Class<ByteVector>) s.boxType(), byte.class, s.length(),
 383             e, s,
 384             ((bits, sp) -> ((ByteSpecies)sp).op(i -> (byte)bits)));
 385     }
 386 
 387     /**
 388      * Returns a vector where each lane element is set to a given
 389      * primitive value.
 390      * <p>
 391      * For each vector lane, where {@code N} is the vector lane index, the
 392      * the primitive value at index {@code N} is placed into the resulting
 393      * vector at lane index {@code N}.
 394      *
 395      * @param s species of the desired vector
 396      * @param es the given primitive values
 397      * @return a vector where each lane element is set to a given primitive
 398      * value
 399      * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
 400      */
 401     @ForceInline
 402     @SuppressWarnings("unchecked")
 403     public static ByteVector scalars(VectorSpecies<Byte> s, byte... es) {
 404         Objects.requireNonNull(es);
 405         int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
 406         return VectorIntrinsics.load((Class<ByteVector>) s.boxType(), byte.class, s.length(),
 407                                      es, Unsafe.ARRAY_BYTE_BASE_OFFSET,
 408                                      es, ix, s,
 409                                      (c, idx, sp) -> ((ByteSpecies)sp).op(n -> c[idx + n]));
 410     }
 411 
 412     /**
 413      * Returns a vector where the first lane element is set to the primtive
 414      * value {@code e}, all other lane elements are set to the default
 415      * value.
 416      *
 417      * @param s species of the desired vector
 418      * @param e the value
 419      * @return a vector where the first lane element is set to the primitive
 420      * value {@code e}
 421      */
 422     @ForceInline
 423     public static final ByteVector single(VectorSpecies<Byte> s, byte e) {
 424         return zero(s).with(0, e);
 425     }
 426 
 427     /**
 428      * Returns a vector where each lane element is set to a randomly
 429      * generated primitive value.
 430      *
 431      * The semantics are equivalent to calling
 432      * (byte){@link ThreadLocalRandom#nextInt()}
 433      *
 434      * @param s species of the desired vector
 435      * @return a vector where each lane elements is set to a randomly
 436      * generated primitive value
 437      */
 438     public static ByteVector random(VectorSpecies<Byte> s) {
 439         ThreadLocalRandom r = ThreadLocalRandom.current();
 440         return ((ByteSpecies)s).op(i -> (byte) r.nextInt());
 441     }
 442 
































































































































































































































 443     // Ops
 444 
 445     @Override
 446     public abstract ByteVector add(Vector<Byte> v);
 447 
 448     /**
 449      * Adds this vector to the broadcast of an input scalar.
 450      * <p>
 451      * This is a vector binary operation where the primitive addition operation
 452      * ({@code +}) is applied to lane elements.
 453      *
 454      * @param s the input scalar
 455      * @return the result of adding this vector to the broadcast of an input
 456      * scalar
 457      */
 458     public abstract ByteVector add(byte s);
 459 
 460     @Override
 461     public abstract ByteVector add(Vector<Byte> v, VectorMask<Byte> m);
 462 
 463     /**
 464      * Adds this vector to broadcast of an input scalar,
 465      * selecting lane elements controlled by a mask.
 466      * <p>
 467      * This is a vector binary operation where the primitive addition operation
 468      * ({@code +}) is applied to lane elements.
 469      *
 470      * @param s the input scalar
 471      * @param m the mask controlling lane selection
 472      * @return the result of adding this vector to the broadcast of an input
 473      * scalar
 474      */
 475     public abstract ByteVector add(byte s, VectorMask<Byte> m);
 476 
 477     @Override
 478     public abstract ByteVector sub(Vector<Byte> v);
 479 
 480     /**
 481      * Subtracts the broadcast of an input scalar from this vector.
 482      * <p>
 483      * This is a vector binary operation where the primitive subtraction
 484      * operation ({@code -}) is applied to lane elements.
 485      *
 486      * @param s the input scalar
 487      * @return the result of subtracting the broadcast of an input
 488      * scalar from this vector
 489      */
 490     public abstract ByteVector sub(byte s);
 491 
 492     @Override
 493     public abstract ByteVector sub(Vector<Byte> v, VectorMask<Byte> m);
 494 
 495     /**
 496      * Subtracts the broadcast of an input scalar from this vector, selecting
 497      * lane elements controlled by a mask.
 498      * <p>
 499      * This is a vector binary operation where the primitive subtraction
 500      * operation ({@code -}) is applied to lane elements.
 501      *
 502      * @param s the input scalar
 503      * @param m the mask controlling lane selection
 504      * @return the result of subtracting the broadcast of an input
 505      * scalar from this vector
 506      */
 507     public abstract ByteVector sub(byte s, VectorMask<Byte> m);
 508 
 509     @Override
 510     public abstract ByteVector mul(Vector<Byte> v);
 511 
 512     /**
 513      * Multiplies this vector with the broadcast of an input scalar.
 514      * <p>
 515      * This is a vector binary operation where the primitive multiplication
 516      * operation ({@code *}) is applied to lane elements.
 517      *
 518      * @param s the input scalar
 519      * @return the result of multiplying this vector with the broadcast of an
 520      * input scalar
 521      */
 522     public abstract ByteVector mul(byte s);
 523 
 524     @Override
 525     public abstract ByteVector mul(Vector<Byte> v, VectorMask<Byte> m);
 526 
 527     /**
 528      * Multiplies this vector with the broadcast of an input scalar, selecting
 529      * lane elements controlled by a mask.
 530      * <p>
 531      * This is a vector binary operation where the primitive multiplication
 532      * operation ({@code *}) is applied to lane elements.
 533      *
 534      * @param s the input scalar
 535      * @param m the mask controlling lane selection
 536      * @return the result of multiplying this vector with the broadcast of an
 537      * input scalar
 538      */
 539     public abstract ByteVector mul(byte s, VectorMask<Byte> m);
 540 
 541     @Override
 542     public abstract ByteVector neg();
 543 
 544     @Override
 545     public abstract ByteVector neg(VectorMask<Byte> m);
 546 
 547     @Override
 548     public abstract ByteVector abs();
 549 
 550     @Override
 551     public abstract ByteVector abs(VectorMask<Byte> m);
 552 
 553     @Override
 554     public abstract ByteVector min(Vector<Byte> v);
 555 
 556     @Override
 557     public abstract ByteVector min(Vector<Byte> v, VectorMask<Byte> m);
 558 
 559     /**
 560      * Returns the minimum of this vector and the broadcast of an input scalar.
 561      * <p>
 562      * This is a vector binary operation where the operation
 563      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 564      *
 565      * @param s the input scalar
 566      * @return the minimum of this vector and the broadcast of an input scalar
 567      */
 568     public abstract ByteVector min(byte s);
 569 
 570     @Override
 571     public abstract ByteVector max(Vector<Byte> v);
 572 
 573     @Override
 574     public abstract ByteVector max(Vector<Byte> v, VectorMask<Byte> m);
 575 
 576     /**
 577      * Returns the maximum of this vector and the broadcast of an input scalar.
 578      * <p>
 579      * This is a vector binary operation where the operation
 580      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 581      *
 582      * @param s the input scalar
 583      * @return the maximum of this vector and the broadcast of an input scalar
 584      */
 585     public abstract ByteVector max(byte s);
 586 
 587     @Override
 588     public abstract VectorMask<Byte> equal(Vector<Byte> v);
 589 
 590     /**
 591      * Tests if this vector is equal to the broadcast of an input scalar.
 592      * <p>
 593      * This is a vector binary test operation where the primitive equals
 594      * operation ({@code ==}) is applied to lane elements.
 595      *
 596      * @param s the input scalar
 597      * @return the result mask of testing if this vector is equal to the
 598      * broadcast of an input scalar
 599      */
 600     public abstract VectorMask<Byte> equal(byte s);
 601 
 602     @Override
 603     public abstract VectorMask<Byte> notEqual(Vector<Byte> v);
 604 
 605     /**
 606      * Tests if this vector is not equal to the broadcast of an input scalar.
 607      * <p>
 608      * This is a vector binary test operation where the primitive not equals
 609      * operation ({@code !=}) is applied to lane elements.
 610      *
 611      * @param s the input scalar
 612      * @return the result mask of testing if this vector is not equal to the
 613      * broadcast of an input scalar
 614      */
 615     public abstract VectorMask<Byte> notEqual(byte s);
 616 
 617     @Override
 618     public abstract VectorMask<Byte> lessThan(Vector<Byte> v);
 619 
 620     /**
 621      * Tests if this vector is less than the broadcast of an input scalar.
 622      * <p>
 623      * This is a vector binary test operation where the primitive less than
 624      * operation ({@code <}) is applied to lane elements.
 625      *
 626      * @param s the input scalar
 627      * @return the mask result of testing if this vector is less than the
 628      * broadcast of an input scalar
 629      */
 630     public abstract VectorMask<Byte> lessThan(byte s);
 631 
 632     @Override
 633     public abstract VectorMask<Byte> lessThanEq(Vector<Byte> v);
 634 
 635     /**
 636      * Tests if this vector is less or equal to the broadcast of an input scalar.
 637      * <p>
 638      * This is a vector binary test operation where the primitive less than
 639      * or equal to operation ({@code <=}) is applied to lane elements.
 640      *
 641      * @param s the input scalar
 642      * @return the mask result of testing if this vector is less than or equal
 643      * to the broadcast of an input scalar
 644      */
 645     public abstract VectorMask<Byte> lessThanEq(byte s);
 646 
 647     @Override
 648     public abstract VectorMask<Byte> greaterThan(Vector<Byte> v);
 649 
 650     /**
 651      * Tests if this vector is greater than the broadcast of an input scalar.
 652      * <p>
 653      * This is a vector binary test operation where the primitive greater than
 654      * operation ({@code >}) is applied to lane elements.
 655      *
 656      * @param s the input scalar
 657      * @return the mask result of testing if this vector is greater than the
 658      * broadcast of an input scalar
 659      */
 660     public abstract VectorMask<Byte> greaterThan(byte s);
 661 
 662     @Override
 663     public abstract VectorMask<Byte> greaterThanEq(Vector<Byte> v);
 664 
 665     /**
 666      * Tests if this vector is greater than or equal to the broadcast of an
 667      * input scalar.
 668      * <p>
 669      * This is a vector binary test operation where the primitive greater than
 670      * or equal to operation ({@code >=}) is applied to lane elements.
 671      *
 672      * @param s the input scalar
 673      * @return the mask result of testing if this vector is greater than or
 674      * equal to the broadcast of an input scalar
 675      */
 676     public abstract VectorMask<Byte> greaterThanEq(byte s);
 677 
 678     @Override
 679     public abstract ByteVector blend(Vector<Byte> v, VectorMask<Byte> m);
 680 
 681     /**
 682      * Blends the lane elements of this vector with those of the broadcast of an
 683      * input scalar, selecting lanes controlled by a mask.
 684      * <p>
 685      * For each lane of the mask, at lane index {@code N}, if the mask lane
 686      * is set then the lane element at {@code N} from the input vector is
 687      * selected and placed into the resulting vector at {@code N},
 688      * otherwise the the lane element at {@code N} from this input vector is
 689      * selected and placed into the resulting vector at {@code N}.
 690      *
 691      * @param s the input scalar
 692      * @param m the mask controlling lane selection
 693      * @return the result of blending the lane elements of this vector with
 694      * those of the broadcast of an input scalar
 695      */
 696     public abstract ByteVector blend(byte s, VectorMask<Byte> m);
 697 
 698     @Override
 699     public abstract ByteVector rearrange(Vector<Byte> v,
 700                                                       VectorShuffle<Byte> s, VectorMask<Byte> m);
 701 
 702     @Override
 703     public abstract ByteVector rearrange(VectorShuffle<Byte> m);
 704 
 705     @Override
 706     public abstract ByteVector reshape(VectorSpecies<Byte> s);
 707 
 708     @Override
 709     public abstract ByteVector rotateEL(int i);
 710 
 711     @Override
 712     public abstract ByteVector rotateER(int i);
 713 
 714     @Override
 715     public abstract ByteVector shiftEL(int i);
 716 
 717     @Override
 718     public abstract ByteVector shiftER(int i);
 719 
 720 
 721 
 722     /**
 723      * Bitwise ANDs this vector with an input vector.
 724      * <p>
 725      * This is a vector binary operation where the primitive bitwise AND
 726      * operation ({@code &}) is applied to lane elements.


 736      * This is a vector binary operation where the primitive bitwise AND
 737      * operation ({@code &}) is applied to lane elements.
 738      *
 739      * @param s the input scalar
 740      * @return the bitwise AND of this vector with the broadcast of an input
 741      * scalar
 742      */
 743     public abstract ByteVector and(byte s);
 744 
 745     /**
 746      * Bitwise ANDs this vector with an input vector, selecting lane elements
 747      * controlled by a mask.
 748      * <p>
 749      * This is a vector binary operation where the primitive bitwise AND
 750      * operation ({@code &}) is applied to lane elements.
 751      *
 752      * @param v the input vector
 753      * @param m the mask controlling lane selection
 754      * @return the bitwise AND of this vector with the input vector
 755      */
 756     public abstract ByteVector and(Vector<Byte> v, VectorMask<Byte> m);
 757 
 758     /**
 759      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 760      * lane elements controlled by a mask.
 761      * <p>
 762      * This is a vector binary operation where the primitive bitwise AND
 763      * operation ({@code &}) is applied to lane elements.
 764      *
 765      * @param s the input scalar
 766      * @param m the mask controlling lane selection
 767      * @return the bitwise AND of this vector with the broadcast of an input
 768      * scalar
 769      */
 770     public abstract ByteVector and(byte s, VectorMask<Byte> m);
 771 
 772     /**
 773      * Bitwise ORs this vector with an input vector.
 774      * <p>
 775      * This is a vector binary operation where the primitive bitwise OR
 776      * operation ({@code |}) is applied to lane elements.
 777      *
 778      * @param v the input vector
 779      * @return the bitwise OR of this vector with the input vector
 780      */
 781     public abstract ByteVector or(Vector<Byte> v);
 782 
 783     /**
 784      * Bitwise ORs this vector with the broadcast of an input scalar.
 785      * <p>
 786      * This is a vector binary operation where the primitive bitwise OR
 787      * operation ({@code |}) is applied to lane elements.
 788      *
 789      * @param s the input scalar
 790      * @return the bitwise OR of this vector with the broadcast of an input
 791      * scalar
 792      */
 793     public abstract ByteVector or(byte s);
 794 
 795     /**
 796      * Bitwise ORs this vector with an input vector, selecting lane elements
 797      * controlled by a mask.
 798      * <p>
 799      * This is a vector binary operation where the primitive bitwise OR
 800      * operation ({@code |}) is applied to lane elements.
 801      *
 802      * @param v the input vector
 803      * @param m the mask controlling lane selection
 804      * @return the bitwise OR of this vector with the input vector
 805      */
 806     public abstract ByteVector or(Vector<Byte> v, VectorMask<Byte> m);
 807 
 808     /**
 809      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
 810      * lane elements controlled by a mask.
 811      * <p>
 812      * This is a vector binary operation where the primitive bitwise OR
 813      * operation ({@code |}) is applied to lane elements.
 814      *
 815      * @param s the input scalar
 816      * @param m the mask controlling lane selection
 817      * @return the bitwise OR of this vector with the broadcast of an input
 818      * scalar
 819      */
 820     public abstract ByteVector or(byte s, VectorMask<Byte> m);
 821 
 822     /**
 823      * Bitwise XORs this vector with an input vector.
 824      * <p>
 825      * This is a vector binary operation where the primitive bitwise XOR
 826      * operation ({@code ^}) is applied to lane elements.
 827      *
 828      * @param v the input vector
 829      * @return the bitwise XOR of this vector with the input vector
 830      */
 831     public abstract ByteVector xor(Vector<Byte> v);
 832 
 833     /**
 834      * Bitwise XORs this vector with the broadcast of an input scalar.
 835      * <p>
 836      * This is a vector binary operation where the primitive bitwise XOR
 837      * operation ({@code ^}) is applied to lane elements.
 838      *
 839      * @param s the input scalar
 840      * @return the bitwise XOR of this vector with the broadcast of an input
 841      * scalar
 842      */
 843     public abstract ByteVector xor(byte s);
 844 
 845     /**
 846      * Bitwise XORs this vector with an input vector, selecting lane elements
 847      * controlled by a mask.
 848      * <p>
 849      * This is a vector binary operation where the primitive bitwise XOR
 850      * operation ({@code ^}) is applied to lane elements.
 851      *
 852      * @param v the input vector
 853      * @param m the mask controlling lane selection
 854      * @return the bitwise XOR of this vector with the input vector
 855      */
 856     public abstract ByteVector xor(Vector<Byte> v, VectorMask<Byte> m);
 857 
 858     /**
 859      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
 860      * lane elements controlled by a mask.
 861      * <p>
 862      * This is a vector binary operation where the primitive bitwise XOR
 863      * operation ({@code ^}) is applied to lane elements.
 864      *
 865      * @param s the input scalar
 866      * @param m the mask controlling lane selection
 867      * @return the bitwise XOR of this vector with the broadcast of an input
 868      * scalar
 869      */
 870     public abstract ByteVector xor(byte s, VectorMask<Byte> m);
 871 
 872     /**
 873      * Bitwise NOTs this vector.
 874      * <p>
 875      * This is a vector unary operation where the primitive bitwise NOT
 876      * operation ({@code ~}) is applied to lane elements.
 877      *
 878      * @return the bitwise NOT of this vector
 879      */
 880     public abstract ByteVector not();
 881 
 882     /**
 883      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
 884      * <p>
 885      * This is a vector unary operation where the primitive bitwise NOT
 886      * operation ({@code ~}) is applied to lane elements.
 887      *
 888      * @param m the mask controlling lane selection
 889      * @return the bitwise NOT of this vector
 890      */
 891     public abstract ByteVector not(VectorMask<Byte> m);
 892 
 893     /**
 894      * Logically left shifts this vector by the broadcast of an input scalar.
 895      * <p>
 896      * This is a vector binary operation where the primitive logical left shift
 897      * operation ({@code <<}) is applied to lane elements to left shift the
 898      * element by shift value as specified by the input scalar. Only the 3
 899      * lowest-order bits of shift value are used. It is as if the shift value
 900      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
 901      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
 902      *
 903      * @param s the input scalar; the number of the bits to left shift
 904      * @return the result of logically left shifting left this vector by the
 905      * broadcast of an input scalar
 906      */
 907     public abstract ByteVector shiftL(int s);
 908 
 909     /**
 910      * Logically left shifts this vector by the broadcast of an input scalar,
 911      * selecting lane elements controlled by a mask.
 912      * <p>
 913      * This is a vector binary operation where the primitive logical left shift
 914      * operation ({@code <<}) is applied to lane elements to left shift the
 915      * element by shift value as specified by the input scalar. Only the 3
 916      * lowest-order bits of shift value are used. It is as if the shift value
 917      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
 918      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
 919      *
 920      * @param s the input scalar; the number of the bits to left shift
 921      * @param m the mask controlling lane selection
 922      * @return the result of logically left shifting left this vector by the
 923      * broadcast of an input scalar
 924      */
 925     public abstract ByteVector shiftL(int s, VectorMask<Byte> m);
 926 
 927 
 928     // logical, or unsigned, shift right
 929 
 930      /**
 931      * Logically right shifts (or unsigned right shifts) this vector by the
 932      * broadcast of an input scalar.
 933      * <p>
 934      * This is a vector binary operation where the primitive logical right shift
 935      * operation ({@code >>>}) is applied to lane elements to logically right shift the
 936      * element by shift value as specified by the input scalar. Only the 3
 937      * lowest-order bits of shift value are used. It is as if the shift value
 938      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
 939      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
 940      *
 941      * @param s the input scalar; the number of the bits to right shift
 942      * @return the result of logically right shifting this vector by the
 943      * broadcast of an input scalar
 944      */
 945     public abstract ByteVector shiftR(int s);
 946 
 947      /**
 948      * Logically right shifts (or unsigned right shifts) this vector by the
 949      * broadcast of an input scalar, selecting lane elements controlled by a
 950      * mask.
 951      * <p>
 952      * This is a vector binary operation where the primitive logical right shift
 953      * operation ({@code >>>}) is applied to lane elements to logically right shift the
 954      * element by shift value as specified by the input scalar. Only the 3
 955      * lowest-order bits of shift value are used. It is as if the shift value
 956      * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
 957      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
 958      *
 959      * @param s the input scalar; the number of the bits to right shift
 960      * @param m the mask controlling lane selection
 961      * @return the result of logically right shifting this vector by the
 962      * broadcast of an input scalar
 963      */
 964     public abstract ByteVector shiftR(int s, VectorMask<Byte> m);
 965 
 966 
 967     /**
 968      * Arithmetically right shifts (or signed right shifts) this vector by the
 969      * broadcast of an input scalar.
 970      * <p>
 971      * This is a vector binary operation where the primitive arithmetic right
 972      * shift operation ({@code >>}) is applied to lane elements  to arithmetically
 973      * right shift the element by shift value as specified by the input scalar.
 974      * Only the 3 lowest-order bits of shift value are used. It is as if the shift
 975      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
 976      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
 977      *
 978      * @param s the input scalar; the number of the bits to right shift
 979      * @return the result of arithmetically right shifting this vector by the
 980      * broadcast of an input scalar
 981      */
 982     public abstract ByteVector aShiftR(int s);
 983 
 984     /**
 985      * Arithmetically right shifts (or signed right shifts) this vector by the
 986      * broadcast of an input scalar, selecting lane elements controlled by a
 987      * mask.
 988      * <p>
 989      * This is a vector binary operation where the primitive arithmetic right
 990      * shift operation ({@code >>}) is applied to lane elements  to arithmetically
 991      * right shift the element by shift value as specified by the input scalar.
 992      * Only the 3 lowest-order bits of shift value are used. It is as if the shift
 993      * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
 994      * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
 995      *
 996      * @param s the input scalar; the number of the bits to right shift
 997      * @param m the mask controlling lane selection
 998      * @return the result of arithmetically right shifting this vector by the
 999      * broadcast of an input scalar
1000      */
1001     public abstract ByteVector aShiftR(int s, VectorMask<Byte> m);
1002 
1003 
1004     @Override
1005     public abstract void intoByteArray(byte[] a, int ix);
1006 
1007     @Override
1008     public abstract void intoByteArray(byte[] a, int ix, VectorMask<Byte> m);
1009 
1010     @Override
1011     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1012 
1013     @Override
1014     public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Byte> m);
1015 
1016 
1017     // Type specific horizontal reductions
1018     /**
1019      * Adds all lane elements of this vector.
1020      * <p>
1021      * This is an associative vector reduction operation where the addition
1022      * operation ({@code +}) is applied to lane elements,
1023      * and the identity value is {@code 0}.
1024      *
1025      * @return the addition of all the lane elements of this vector
1026      */
1027     public abstract byte addAll();
1028 
1029     /**
1030      * Adds all lane elements of this vector, selecting lane elements
1031      * controlled by a mask.
1032      * <p>
1033      * This is an associative vector reduction operation where the addition
1034      * operation ({@code +}) is applied to lane elements,
1035      * and the identity value is {@code 0}.
1036      *
1037      * @param m the mask controlling lane selection
1038      * @return the addition of the selected lane elements of this vector
1039      */
1040     public abstract byte addAll(VectorMask<Byte> m);
1041 
1042     /**
1043      * Multiplies all lane elements of this vector.
1044      * <p>
1045      * This is an associative vector reduction operation where the
1046      * multiplication operation ({@code *}) is applied to lane elements,
1047      * and the identity value is {@code 1}.
1048      *
1049      * @return the multiplication of all the lane elements of this vector
1050      */
1051     public abstract byte mulAll();
1052 
1053     /**
1054      * Multiplies all lane elements of this vector, selecting lane elements
1055      * controlled by a mask.
1056      * <p>
1057      * This is an associative vector reduction operation where the
1058      * multiplication operation ({@code *}) is applied to lane elements,
1059      * and the identity value is {@code 1}.
1060      *
1061      * @param m the mask controlling lane selection
1062      * @return the multiplication of all the lane elements of this vector
1063      */
1064     public abstract byte mulAll(VectorMask<Byte> m);
1065 
1066     /**
1067      * Returns the minimum lane element of this vector.
1068      * <p>
1069      * This is an associative vector reduction operation where the operation
1070      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1071      * and the identity value is
1072      * {@link Byte#MAX_VALUE}.
1073      *
1074      * @return the minimum lane element of this vector
1075      */
1076     public abstract byte minAll();
1077 
1078     /**
1079      * Returns the minimum lane element of this vector, selecting lane elements
1080      * controlled by a mask.
1081      * <p>
1082      * This is an associative vector reduction operation where the operation
1083      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1084      * and the identity value is
1085      * {@link Byte#MAX_VALUE}.
1086      *
1087      * @param m the mask controlling lane selection
1088      * @return the minimum lane element of this vector
1089      */
1090     public abstract byte minAll(VectorMask<Byte> m);
1091 
1092     /**
1093      * Returns the maximum lane element of this vector.
1094      * <p>
1095      * This is an associative vector reduction operation where the operation
1096      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1097      * and the identity value is
1098      * {@link Byte#MIN_VALUE}.
1099      *
1100      * @return the maximum lane element of this vector
1101      */
1102     public abstract byte maxAll();
1103 
1104     /**
1105      * Returns the maximum lane element of this vector, selecting lane elements
1106      * controlled by a mask.
1107      * <p>
1108      * This is an associative vector reduction operation where the operation
1109      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1110      * and the identity value is
1111      * {@link Byte#MIN_VALUE}.
1112      *
1113      * @param m the mask controlling lane selection
1114      * @return the maximum lane element of this vector
1115      */
1116     public abstract byte maxAll(VectorMask<Byte> m);
1117 
1118     /**
1119      * Logically ORs all lane elements of this vector.
1120      * <p>
1121      * This is an associative vector reduction operation where the logical OR
1122      * operation ({@code |}) is applied to lane elements,
1123      * and the identity value is {@code 0}.
1124      *
1125      * @return the logical OR all the lane elements of this vector
1126      */
1127     public abstract byte orAll();
1128 
1129     /**
1130      * Logically ORs all lane elements of this vector, selecting lane elements
1131      * controlled by a mask.
1132      * <p>
1133      * This is an associative vector reduction operation where the logical OR
1134      * operation ({@code |}) is applied to lane elements,
1135      * and the identity value is {@code 0}.
1136      *
1137      * @param m the mask controlling lane selection
1138      * @return the logical OR all the lane elements of this vector
1139      */
1140     public abstract byte orAll(VectorMask<Byte> m);
1141 
1142     /**
1143      * Logically ANDs all lane elements of this vector.
1144      * <p>
1145      * This is an associative vector reduction operation where the logical AND
1146      * operation ({@code |}) is applied to lane elements,
1147      * and the identity value is {@code -1}.
1148      *
1149      * @return the logical AND all the lane elements of this vector
1150      */
1151     public abstract byte andAll();
1152 
1153     /**
1154      * Logically ANDs all lane elements of this vector, selecting lane elements
1155      * controlled by a mask.
1156      * <p>
1157      * This is an associative vector reduction operation where the logical AND
1158      * operation ({@code |}) is applied to lane elements,
1159      * and the identity value is {@code -1}.
1160      *
1161      * @param m the mask controlling lane selection
1162      * @return the logical AND all the lane elements of this vector
1163      */
1164     public abstract byte andAll(VectorMask<Byte> m);
1165 
1166     /**
1167      * Logically XORs all lane elements of this vector.
1168      * <p>
1169      * This is an associative vector reduction operation where the logical XOR
1170      * operation ({@code ^}) is applied to lane elements,
1171      * and the identity value is {@code 0}.
1172      *
1173      * @return the logical XOR all the lane elements of this vector
1174      */
1175     public abstract byte xorAll();
1176 
1177     /**
1178      * Logically XORs all lane elements of this vector, selecting lane elements
1179      * controlled by a mask.
1180      * <p>
1181      * This is an associative vector reduction operation where the logical XOR
1182      * operation ({@code ^}) is applied to lane elements,
1183      * and the identity value is {@code 0}.
1184      *
1185      * @param m the mask controlling lane selection
1186      * @return the logical XOR all the lane elements of this vector
1187      */
1188     public abstract byte xorAll(VectorMask<Byte> m);
1189 
1190     // Type specific accessors
1191 
1192     /**
1193      * Gets the lane element at lane index {@code i}
1194      *
1195      * @param i the lane index
1196      * @return the lane element at lane index {@code i}
1197      * @throws IllegalArgumentException if the index is is out of range
1198      * ({@code < 0 || >= length()})
1199      */
1200     public abstract byte get(int i);
1201 
1202     /**
1203      * Replaces the lane element of this vector at lane index {@code i} with
1204      * value {@code e}.
1205      * <p>
1206      * This is a cross-lane operation and behaves as if it returns the result
1207      * of blending this vector with an input vector that is the result of
1208      * broadcasting {@code e} and a mask that has only one lane set at lane


1250      * @param i the offset into the array
1251      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1252      * {@code i > a.length - this.length()}
1253      */
1254     public abstract void intoArray(byte[] a, int i);
1255 
1256     /**
1257      * Stores this vector into an array starting at offset and using a mask.
1258      * <p>
1259      * For each vector lane, where {@code N} is the vector lane index,
1260      * if the mask lane at index {@code N} is set then the lane element at
1261      * index {@code N} is stored into the array index {@code i + N}.
1262      *
1263      * @param a the array
1264      * @param i the offset into the array
1265      * @param m the mask
1266      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1267      * for any vector lane index {@code N} where the mask at lane {@code N}
1268      * is set {@code i >= a.length - N}
1269      */
1270     public abstract void intoArray(byte[] a, int i, VectorMask<Byte> m);
1271 
1272     /**
1273      * Stores this vector into an array using indexes obtained from an index
1274      * map.
1275      * <p>
1276      * For each vector lane, where {@code N} is the vector lane index, the
1277      * lane element at index {@code N} is stored into the array at index
1278      * {@code i + indexMap[j + N]}.
1279      *
1280      * @param a the array
1281      * @param i the offset into the array, may be negative if relative
1282      * indexes in the index map compensate to produce a value within the
1283      * array bounds
1284      * @param indexMap the index map
1285      * @param j the offset into the index map
1286      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1287      * {@code j > indexMap.length - this.length()},
1288      * or for any vector lane index {@code N} the result of
1289      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1290      */


1297      * map and using a mask.
1298      * <p>
1299      * For each vector lane, where {@code N} is the vector lane index,
1300      * if the mask lane at index {@code N} is set then the lane element at
1301      * index {@code N} is stored into the array at index
1302      * {@code i + indexMap[j + N]}.
1303      *
1304      * @param a the array
1305      * @param i the offset into the array, may be negative if relative
1306      * indexes in the index map compensate to produce a value within the
1307      * array bounds
1308      * @param m the mask
1309      * @param indexMap the index map
1310      * @param j the offset into the index map
1311      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1312      * {@code j > indexMap.length - this.length()},
1313      * or for any vector lane index {@code N} where the mask at lane
1314      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1315      * {@code < 0} or {@code >= a.length}
1316      */
1317     public void intoArray(byte[] a, int i, VectorMask<Byte> m, int[] indexMap, int j) {
1318         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
1319     }
1320     // Species
1321 
1322     @Override
1323     public abstract VectorSpecies<Byte> species();
1324 
1325     /**
1326      * Class representing {@link ByteVector}'s of the same {@link VectorShape VectorShape}.
1327      */
1328     static final class ByteSpecies extends AbstractSpecies<Byte> {
1329         final Function<byte[], ByteVector> vectorFactory;

1330 
1331         private ByteSpecies(VectorShape shape,
1332                           Class<?> boxType,
1333                           Class<?> maskType,
1334                           Function<byte[], ByteVector> vectorFactory,
1335                           Function<boolean[], VectorMask<Byte>> maskFactory,
1336                           Function<IntUnaryOperator, VectorShuffle<Byte>> shuffleFromArrayFactory,
1337                           fShuffleFromArray<Byte> shuffleFromOpFactory) {
1338             super(shape, byte.class, Byte.SIZE, boxType, maskType, maskFactory,
1339                   shuffleFromArrayFactory, shuffleFromOpFactory);
1340             this.vectorFactory = vectorFactory;

1341         }
1342 
1343         interface FOp {
1344             byte apply(int i);
1345         }
1346 




1347         ByteVector op(FOp f) {
1348             byte[] res = new byte[length()];
1349             for (int i = 0; i < length(); i++) {
1350                 res[i] = f.apply(i);
1351             }
1352             return vectorFactory.apply(res);
1353         }
1354 
1355         ByteVector op(VectorMask<Byte> o, FOp f) {
1356             byte[] res = new byte[length()];
1357             boolean[] mbits = ((AbstractMask<Byte>)o).getBits();
1358             for (int i = 0; i < length(); i++) {
1359                 if (mbits[i]) {
1360                     res[i] = f.apply(i);
1361                 }
1362             }
1363             return vectorFactory.apply(res);
1364         }








1365     }
1366 
1367     /**
1368      * Finds the preferred species for an element type of {@code byte}.
1369      * <p>
1370      * A preferred species is a species chosen by the platform that has a
1371      * shape of maximal bit size.  A preferred species for different element
1372      * types will have the same shape, and therefore vectors, masks, and
1373      * shuffles created from such species will be shape compatible.
1374      *
1375      * @return the preferred species for an element type of {@code byte}
1376      */
1377     private static ByteSpecies preferredSpecies() {
1378         return (ByteSpecies) VectorSpecies.ofPreferred(byte.class);
1379     }
1380 
1381     /**
1382      * Finds a species for an element type of {@code byte} and shape.
1383      *
1384      * @param s the shape
1385      * @return a species for an element type of {@code byte} and shape
1386      * @throws IllegalArgumentException if no such species exists for the shape
1387      */
1388     static ByteSpecies species(VectorShape s) {
1389         Objects.requireNonNull(s);
1390         switch (s) {
1391             case S_64_BIT: return (ByteSpecies) SPECIES_64;
1392             case S_128_BIT: return (ByteSpecies) SPECIES_128;
1393             case S_256_BIT: return (ByteSpecies) SPECIES_256;
1394             case S_512_BIT: return (ByteSpecies) SPECIES_512;
1395             case S_Max_BIT: return (ByteSpecies) SPECIES_MAX;
1396             default: throw new IllegalArgumentException("Bad shape: " + s);
1397         }
1398     }
1399 
1400     /** Species representing {@link ByteVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
1401     public static final VectorSpecies<Byte> SPECIES_64 = new ByteSpecies(VectorShape.S_64_BIT, Byte64Vector.class, Byte64Vector.Byte64Mask.class,
1402                                                                      Byte64Vector::new, Byte64Vector.Byte64Mask::new,
1403                                                                      Byte64Vector.Byte64Shuffle::new, Byte64Vector.Byte64Shuffle::new);
1404 
1405     /** Species representing {@link ByteVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
1406     public static final VectorSpecies<Byte> SPECIES_128 = new ByteSpecies(VectorShape.S_128_BIT, Byte128Vector.class, Byte128Vector.Byte128Mask.class,
1407                                                                       Byte128Vector::new, Byte128Vector.Byte128Mask::new,
1408                                                                       Byte128Vector.Byte128Shuffle::new, Byte128Vector.Byte128Shuffle::new);
1409 
1410     /** Species representing {@link ByteVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
1411     public static final VectorSpecies<Byte> SPECIES_256 = new ByteSpecies(VectorShape.S_256_BIT, Byte256Vector.class, Byte256Vector.Byte256Mask.class,
1412                                                                       Byte256Vector::new, Byte256Vector.Byte256Mask::new,
1413                                                                       Byte256Vector.Byte256Shuffle::new, Byte256Vector.Byte256Shuffle::new);
1414 
1415     /** Species representing {@link ByteVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
1416     public static final VectorSpecies<Byte> SPECIES_512 = new ByteSpecies(VectorShape.S_512_BIT, Byte512Vector.class, Byte512Vector.Byte512Mask.class,
1417                                                                       Byte512Vector::new, Byte512Vector.Byte512Mask::new,
1418                                                                       Byte512Vector.Byte512Shuffle::new, Byte512Vector.Byte512Shuffle::new);
1419 
1420     /** Species representing {@link ByteVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
1421     public static final VectorSpecies<Byte> SPECIES_MAX = new ByteSpecies(VectorShape.S_Max_BIT, ByteMaxVector.class, ByteMaxVector.ByteMaxMask.class,
1422                                                                       ByteMaxVector::new, ByteMaxVector.ByteMaxMask::new,
1423                                                                       ByteMaxVector.ByteMaxShuffle::new, ByteMaxVector.ByteMaxShuffle::new);
1424 
1425     /**
1426      * Preferred species for {@link ByteVector}s.
1427      * A preferred species is a species of maximal bit size for the platform.
1428      */
1429     public static final VectorSpecies<Byte> SPECIES_PREFERRED = (VectorSpecies<Byte>) preferredSpecies();
1430 }
< prev index next >