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,
334 * according to the native byte order of the underlying platform, and
335 * the returned vector is loaded with a mask from a primitive array
336 * obtained from the primitive buffer.
337 * The following pseudocode expresses the behaviour, where
338 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
339 * primitive element type, and {@code ESpecies<S>} is the primitive
340 * species for {@code e}:
341 * <pre>{@code
342 * EBuffer eb = b.duplicate().
343 * order(ByteOrder.nativeOrder()).position(i).
344 * asEBuffer();
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 *
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.
727 *
728 * @param v the input vector
729 * @return the bitwise AND of this vector with the input vector
730 */
731 public abstract ByteVector and(Vector<Byte> v);
732
733 /**
734 * Bitwise ANDs this vector with the broadcast of an input scalar.
735 * <p>
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
1209 * index {@code i}.
1210 *
1211 * @param i the lane index of the lane element to be replaced
1212 * @param e the value to be placed
1213 * @return the result of replacing the lane element of this vector at lane
1214 * index {@code i} with value {@code e}.
1215 * @throws IllegalArgumentException if the index is is out of range
1216 * ({@code < 0 || >= length()})
1217 */
1218 public abstract ByteVector with(int i, byte e);
1219
1220 // Type specific extractors
1227 * <pre>{@code
1228 * byte[] a = new byte[this.length()];
1229 * this.intoArray(a, 0);
1230 * return a;
1231 * }</pre>
1232 *
1233 * @return an array containing the the lane elements of this vector
1234 */
1235 @ForceInline
1236 public final byte[] toArray() {
1237 byte[] a = new byte[species().length()];
1238 intoArray(a, 0);
1239 return a;
1240 }
1241
1242 /**
1243 * Stores this vector into an array starting at offset.
1244 * <p>
1245 * For each vector lane, where {@code N} is the vector lane index,
1246 * the lane element at index {@code N} is stored into the array at index
1247 * {@code i + N}.
1248 *
1249 * @param a the array
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 */
1291 public void intoArray(byte[] a, int i, int[] indexMap, int j) {
1292 forEach((n, e) -> a[i + indexMap[j + n]] = e);
1293 }
1294
1295 /**
1296 * Stores this vector into an array using indexes obtained from an index
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,
|
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, ByteBuffer, int, VectorMask) method} as follows:
128 * <pre>{@code
129 * return fromByteBuffer(species, ByteBuffer.wrap(a), offset, VectorMask.allTrue());
130 * }</pre>
131 *
132 * @param species species of desired vector
133 * @param a the byte array
134 * @param offset the offset into the array
135 * @return a vector loaded from a byte array
136 * @throws IndexOutOfBoundsException if {@code i < 0} or
137 * {@code offset > a.length - (species.length() * species.elementSize() / Byte.SIZE)}
138 */
139 @ForceInline
140 @SuppressWarnings("unchecked")
141 public static ByteVector fromByteArray(VectorSpecies<Byte> species, byte[] a, int offset) {
142 Objects.requireNonNull(a);
143 offset = VectorIntrinsics.checkIndex(offset, a.length, species.bitSize() / Byte.SIZE);
144 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
145 a, ((long) offset) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
146 a, offset, 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, ByteBuffer, int, VectorMask) method} as follows:
164 * <pre>{@code
165 * return fromByteBuffer(species, ByteBuffer.wrap(a), offset, m);
166 * }</pre>
167 *
168 * @param species species of desired vector
169 * @param a the byte array
170 * @param offset the offset into the array
171 * @param m the mask
172 * @return a vector loaded from a byte array
173 * @throws IndexOutOfBoundsException if {@code offset < 0} or
174 * for any vector lane index {@code N} where the mask at lane {@code N}
175 * is set
176 * {@code offset >= a.length - (N * species.elementSize() / Byte.SIZE)}
177 */
178 @ForceInline
179 public static ByteVector fromByteArray(VectorSpecies<Byte> species, byte[] a, int offset, VectorMask<Byte> m) {
180 return zero(species).blend(fromByteArray(species, a, offset), m);
181 }
182
183 /**
184 * Loads a vector from an array starting at offset.
185 * <p>
186 * For each vector lane, where {@code N} is the vector lane index, the
187 * array element at index {@code offset + N} is placed into the
188 * resulting vector at lane index {@code N}.
189 *
190 * @param species species of desired vector
191 * @param a the array
192 * @param offset the offset into the array
193 * @return the vector loaded from an array
194 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
195 * {@code offset > a.length - species.length()}
196 */
197 @ForceInline
198 @SuppressWarnings("unchecked")
199 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int offset){
200 Objects.requireNonNull(a);
201 offset = VectorIntrinsics.checkIndex(offset, a.length, species.length());
202 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
203 a, (((long) offset) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
204 a, offset, species,
205 (c, idx, s) -> ((ByteSpecies)s).op(n -> c[idx + n]));
206 }
207
208
209 /**
210 * Loads a vector from an array starting at offset and using a mask.
211 * <p>
212 * For each vector lane, where {@code N} is the vector lane index,
213 * if the mask lane at index {@code N} is set then the array element at
214 * index {@code offset + N} is placed into the resulting vector at lane index
215 * {@code N}, otherwise the default element value is placed into the
216 * resulting vector at lane index {@code N}.
217 *
218 * @param species species of desired vector
219 * @param a the array
220 * @param offset the offset into the array
221 * @param m the mask
222 * @return the vector loaded from an array
223 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
224 * for any vector lane index {@code N} where the mask at lane {@code N}
225 * is set {@code offset > a.length - N}
226 */
227 @ForceInline
228 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int offset, VectorMask<Byte> m) {
229 return zero(species).blend(fromArray(species, a, offset), m);
230 }
231
232 /**
233 * Loads a vector from an array using indexes obtained from an index
234 * map.
235 * <p>
236 * For each vector lane, where {@code N} is the vector lane index, the
237 * array element at index {@code a_offset + indexMap[i_offset + N]} is placed into the
238 * resulting vector at lane index {@code N}.
239 *
240 * @param species species of desired vector
241 * @param a the array
242 * @param a_offset the offset into the array, may be negative if relative
243 * indexes in the index map compensate to produce a value within the
244 * array bounds
245 * @param indexMap the index map
246 * @param i_offset the offset into the index map
247 * @return the vector loaded from an array
248 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
249 * {@code i_offset > indexMap.length - species.length()},
250 * or for any vector lane index {@code N} the result of
251 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length}
252 */
253 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int a_offset, int[] indexMap, int i_offset) {
254 return ((ByteSpecies)species).op(n -> a[a_offset + indexMap[i_offset + n]]);
255 }
256 /**
257 * Loads a vector from an array using indexes obtained from an index
258 * map and using a mask.
259 * <p>
260 * For each vector lane, where {@code N} is the vector lane index,
261 * if the mask lane at index {@code N} is set then the array element at
262 * index {@code a_offset + indexMap[i_offset + N]} is placed into the resulting vector
263 * at lane index {@code N}.
264 *
265 * @param species species of desired vector
266 * @param a the array
267 * @param a_offset the offset into the array, may be negative if relative
268 * indexes in the index map compensate to produce a value within the
269 * array bounds
270 * @param m the mask
271 * @param indexMap the index map
272 * @param i_offset the offset into the index map
273 * @return the vector loaded from an array
274 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
275 * {@code i_offset > indexMap.length - species.length()},
276 * or for any vector lane index {@code N} where the mask at lane
277 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is
278 * {@code < 0} or {@code >= a.length}
279 */
280 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int a_offset, VectorMask<Byte> m, int[] indexMap, int i_offset) {
281 return ((ByteSpecies)species).op(m, n -> a[a_offset + indexMap[i_offset + n]]);
282 }
283
284 /**
285 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
286 * offset into the byte buffer.
287 * <p>
288 * Bytes are composed into primitive lane elements according to the
289 * native byte order of the underlying platform.
290 * <p>
291 * This method behaves as if it returns the result of calling the
292 * byte buffer, offset, and mask accepting
293 * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask)} method} as follows:
294 * <pre>{@code
295 * return fromByteBuffer(b, offset, VectorMask.allTrue())
296 * }</pre>
297 *
298 * @param species species of desired vector
299 * @param bb the byte buffer
300 * @param offset the offset into the byte buffer
301 * @return a vector loaded from a byte buffer
302 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
303 * or {@code > b.limit()},
304 * or if there are fewer than
305 * {@code species.length() * species.elementSize() / Byte.SIZE} bytes
306 * remaining in the byte buffer from the given offset
307 */
308 @ForceInline
309 @SuppressWarnings("unchecked")
310 public static ByteVector fromByteBuffer(VectorSpecies<Byte> species, ByteBuffer bb, int offset) {
311 if (bb.order() != ByteOrder.nativeOrder()) {
312 throw new IllegalArgumentException();
313 }
314 offset = VectorIntrinsics.checkIndex(offset, bb.limit(), species.bitSize() / Byte.SIZE);
315 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
316 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + offset,
317 bb, offset, species,
318 (c, idx, s) -> {
319 ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
320 ByteBuffer tb = bbc;
321 return ((ByteSpecies)s).op(i -> tb.get());
322 });
323 }
324
325 /**
326 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
327 * offset into the byte buffer and using a mask.
328 * <p>
329 * This method behaves as if the byte buffer is viewed as a primitive
330 * {@link java.nio.Buffer buffer} for the primitive element type,
331 * according to the native byte order of the underlying platform, and
332 * the returned vector is loaded with a mask from a primitive array
333 * obtained from the primitive buffer.
334 * The following pseudocode expresses the behaviour, where
335 * {@code EBuffer} is the primitive buffer type, {@code e} is the
336 * primitive element type, and {@code ESpecies} is the primitive
337 * species for {@code e}:
338 * <pre>{@code
339 * EBuffer eb = b.duplicate().
340 * order(ByteOrder.nativeOrder()).position(offset).
341 * asEBuffer();
342 * e[] es = new e[species.length()];
343 * for (int n = 0; n < t.length; n++) {
344 * if (m.isSet(n))
345 * es[n] = eb.get(n);
346 * }
347 * EVector r = EVector.fromArray(es, 0, m);
348 * }</pre>
349 *
350 * @param species species of desired vector
351 * @param bb the byte buffer
352 * @param offset the offset into the byte buffer
353 * @param m the mask
354 * @return a vector loaded from a byte buffer
355 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
356 * or {@code > b.limit()},
357 * for any vector lane index {@code N} where the mask at lane {@code N}
358 * is set
359 * {@code offset >= b.limit() - (N * species.elementSize() / Byte.SIZE)}
360 */
361 @ForceInline
362 public static ByteVector fromByteBuffer(VectorSpecies<Byte> species, ByteBuffer bb, int offset, VectorMask<Byte> m) {
363 return zero(species).blend(fromByteBuffer(species, bb, offset), m);
364 }
365
366 /**
367 * Returns a vector where all lane elements are set to the primitive
368 * value {@code e}.
369 *
370 * @param species species of the desired vector
371 * @param e the value
372 * @return a vector of vector where all lane elements are set to
373 * the primitive value {@code e}
374 */
375 @ForceInline
376 @SuppressWarnings("unchecked")
377 public static ByteVector broadcast(VectorSpecies<Byte> species, byte e) {
378 return VectorIntrinsics.broadcastCoerced(
379 (Class<ByteVector>) species.boxType(), byte.class, species.length(),
380 e, species,
381 ((bits, sp) -> ((ByteSpecies)sp).op(i -> (byte)bits)));
382 }
383
384 /**
385 * Returns a vector where each lane element is set to given
386 * primitive values.
387 * <p>
388 * For each vector lane, where {@code N} is the vector lane index, the
389 * the primitive value at index {@code N} is placed into the resulting
390 * vector at lane index {@code N}.
391 *
392 * @param species species of the desired vector
393 * @param es the given primitive values
394 * @return a vector where each lane element is set to given primitive
395 * values
396 * @throws IndexOutOfBoundsException if {@code es.length < species.length()}
397 */
398 @ForceInline
399 @SuppressWarnings("unchecked")
400 public static ByteVector scalars(VectorSpecies<Byte> species, byte... es) {
401 Objects.requireNonNull(es);
402 int ix = VectorIntrinsics.checkIndex(0, es.length, species.length());
403 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
404 es, Unsafe.ARRAY_BYTE_BASE_OFFSET,
405 es, ix, species,
406 (c, idx, sp) -> ((ByteSpecies)sp).op(n -> c[idx + n]));
407 }
408
409 /**
410 * Returns a vector where the first lane element is set to the primtive
411 * value {@code e}, all other lane elements are set to the default
412 * value.
413 *
414 * @param species species of the desired vector
415 * @param e the value
416 * @return a vector where the first lane element is set to the primitive
417 * value {@code e}
418 */
419 @ForceInline
420 public static final ByteVector single(VectorSpecies<Byte> species, byte e) {
421 return zero(species).with(0, e);
422 }
423
424 /**
425 * Returns a vector where each lane element is set to a randomly
426 * generated primitive value.
427 *
428 * The semantics are equivalent to calling
429 * (byte){@link ThreadLocalRandom#nextInt()}
430 *
431 * @param species species of the desired vector
432 * @return a vector where each lane elements is set to a randomly
433 * generated primitive value
434 */
435 public static ByteVector random(VectorSpecies<Byte> species) {
436 ThreadLocalRandom r = ThreadLocalRandom.current();
437 return ((ByteSpecies)species).op(i -> (byte) r.nextInt());
438 }
439
440 // Ops
441
442 @Override
443 public abstract ByteVector add(Vector<Byte> v);
444
445 /**
446 * Adds this vector to the broadcast of an input scalar.
447 * <p>
448 * This is a lane-wise binary operation which applies the primitive addition operation
449 * ({@code +}) to each lane.
450 *
451 * @param s the input scalar
452 * @return the result of adding this vector to the broadcast of an input
453 * scalar
454 */
455 public abstract ByteVector add(byte s);
456
457 @Override
458 public abstract ByteVector add(Vector<Byte> v, VectorMask<Byte> m);
459
460 /**
461 * Adds this vector to broadcast of an input scalar,
462 * selecting lane elements controlled by a mask.
463 * <p>
464 * This is a lane-wise binary operation which applies the primitive addition operation
465 * ({@code +}) to each lane.
466 *
467 * @param s the input scalar
468 * @param m the mask controlling lane selection
469 * @return the result of adding this vector to the broadcast of an input
470 * scalar
471 */
472 public abstract ByteVector add(byte s, VectorMask<Byte> m);
473
474 @Override
475 public abstract ByteVector sub(Vector<Byte> v);
476
477 /**
478 * Subtracts the broadcast of an input scalar from this vector.
479 * <p>
480 * This is a lane-wise binary operation which applies the primitive subtraction
481 * operation ({@code -}) to each lane.
482 *
483 * @param s the input scalar
484 * @return the result of subtracting the broadcast of an input
485 * scalar from this vector
486 */
487 public abstract ByteVector sub(byte s);
488
489 @Override
490 public abstract ByteVector sub(Vector<Byte> v, VectorMask<Byte> m);
491
492 /**
493 * Subtracts the broadcast of an input scalar from this vector, selecting
494 * lane elements controlled by a mask.
495 * <p>
496 * This is a lane-wise binary operation which applies the primitive subtraction
497 * operation ({@code -}) to each lane.
498 *
499 * @param s the input scalar
500 * @param m the mask controlling lane selection
501 * @return the result of subtracting the broadcast of an input
502 * scalar from this vector
503 */
504 public abstract ByteVector sub(byte s, VectorMask<Byte> m);
505
506 @Override
507 public abstract ByteVector mul(Vector<Byte> v);
508
509 /**
510 * Multiplies this vector with the broadcast of an input scalar.
511 * <p>
512 * This is a lane-wise binary operation which applies the primitive multiplication
513 * operation ({@code *}) to each lane.
514 *
515 * @param s the input scalar
516 * @return the result of multiplying this vector with the broadcast of an
517 * input scalar
518 */
519 public abstract ByteVector mul(byte s);
520
521 @Override
522 public abstract ByteVector mul(Vector<Byte> v, VectorMask<Byte> m);
523
524 /**
525 * Multiplies this vector with the broadcast of an input scalar, selecting
526 * lane elements controlled by a mask.
527 * <p>
528 * This is a lane-wise binary operation which applies the primitive multiplication
529 * operation ({@code *}) to each lane.
530 *
531 * @param s the input scalar
532 * @param m the mask controlling lane selection
533 * @return the result of multiplying this vector with the broadcast of an
534 * input scalar
535 */
536 public abstract ByteVector mul(byte s, VectorMask<Byte> m);
537
538 @Override
539 public abstract ByteVector neg();
540
541 @Override
542 public abstract ByteVector neg(VectorMask<Byte> m);
543
544 @Override
545 public abstract ByteVector abs();
546
547 @Override
548 public abstract ByteVector abs(VectorMask<Byte> m);
549
550 @Override
551 public abstract ByteVector min(Vector<Byte> v);
552
553 @Override
554 public abstract ByteVector min(Vector<Byte> v, VectorMask<Byte> m);
555
556 /**
557 * Returns the minimum of this vector and the broadcast of an input scalar.
558 * <p>
559 * This is a lane-wise binary operation which applies the operation
560 * {@code (a, b) -> Math.min(a, b)} to each lane.
561 *
562 * @param s the input scalar
563 * @return the minimum of this vector and the broadcast of an input scalar
564 */
565 public abstract ByteVector min(byte s);
566
567 @Override
568 public abstract ByteVector max(Vector<Byte> v);
569
570 @Override
571 public abstract ByteVector max(Vector<Byte> v, VectorMask<Byte> m);
572
573 /**
574 * Returns the maximum of this vector and the broadcast of an input scalar.
575 * <p>
576 * This is a lane-wise binary operation which applies the operation
577 * {@code (a, b) -> Math.max(a, b)} to each lane.
578 *
579 * @param s the input scalar
580 * @return the maximum of this vector and the broadcast of an input scalar
581 */
582 public abstract ByteVector max(byte s);
583
584 @Override
585 public abstract VectorMask<Byte> equal(Vector<Byte> v);
586
587 /**
588 * Tests if this vector is equal to the broadcast of an input scalar.
589 * <p>
590 * This is a lane-wise binary test operation which applies the primitive equals
591 * operation ({@code ==}) each lane.
592 *
593 * @param s the input scalar
594 * @return the result mask of testing if this vector is equal to the
595 * broadcast of an input scalar
596 */
597 public abstract VectorMask<Byte> equal(byte s);
598
599 @Override
600 public abstract VectorMask<Byte> notEqual(Vector<Byte> v);
601
602 /**
603 * Tests if this vector is not equal to the broadcast of an input scalar.
604 * <p>
605 * This is a lane-wise binary test operation which applies the primitive not equals
606 * operation ({@code !=}) to each lane.
607 *
608 * @param s the input scalar
609 * @return the result mask of testing if this vector is not equal to the
610 * broadcast of an input scalar
611 */
612 public abstract VectorMask<Byte> notEqual(byte s);
613
614 @Override
615 public abstract VectorMask<Byte> lessThan(Vector<Byte> v);
616
617 /**
618 * Tests if this vector is less than the broadcast of an input scalar.
619 * <p>
620 * This is a lane-wise binary test operation which applies the primitive less than
621 * operation ({@code <}) to each lane.
622 *
623 * @param s the input scalar
624 * @return the mask result of testing if this vector is less than the
625 * broadcast of an input scalar
626 */
627 public abstract VectorMask<Byte> lessThan(byte s);
628
629 @Override
630 public abstract VectorMask<Byte> lessThanEq(Vector<Byte> v);
631
632 /**
633 * Tests if this vector is less or equal to the broadcast of an input scalar.
634 * <p>
635 * This is a lane-wise binary test operation which applies the primitive less than
636 * or equal to operation ({@code <=}) to each lane.
637 *
638 * @param s the input scalar
639 * @return the mask result of testing if this vector is less than or equal
640 * to the broadcast of an input scalar
641 */
642 public abstract VectorMask<Byte> lessThanEq(byte s);
643
644 @Override
645 public abstract VectorMask<Byte> greaterThan(Vector<Byte> v);
646
647 /**
648 * Tests if this vector is greater than the broadcast of an input scalar.
649 * <p>
650 * This is a lane-wise binary test operation which applies the primitive greater than
651 * operation ({@code >}) to each lane.
652 *
653 * @param s the input scalar
654 * @return the mask result of testing if this vector is greater than the
655 * broadcast of an input scalar
656 */
657 public abstract VectorMask<Byte> greaterThan(byte s);
658
659 @Override
660 public abstract VectorMask<Byte> greaterThanEq(Vector<Byte> v);
661
662 /**
663 * Tests if this vector is greater than or equal to the broadcast of an
664 * input scalar.
665 * <p>
666 * This is a lane-wise binary test operation which applies the primitive greater than
667 * or equal to operation ({@code >=}) to each lane.
668 *
669 * @param s the input scalar
670 * @return the mask result of testing if this vector is greater than or
671 * equal to the broadcast of an input scalar
672 */
673 public abstract VectorMask<Byte> greaterThanEq(byte s);
674
675 @Override
676 public abstract ByteVector blend(Vector<Byte> v, VectorMask<Byte> m);
677
678 /**
679 * Blends the lane elements of this vector with those of the broadcast of an
680 * input scalar, selecting lanes controlled by a mask.
681 * <p>
682 * For each lane of the mask, at lane index {@code N}, if the mask lane
683 * is set then the lane element at {@code N} from the input vector is
684 * selected and placed into the resulting vector at {@code N},
685 * otherwise the the lane element at {@code N} from this input vector is
686 * selected and placed into the resulting vector at {@code N}.
687 *
702 @Override
703 public abstract ByteVector reshape(VectorSpecies<Byte> s);
704
705 @Override
706 public abstract ByteVector rotateEL(int i);
707
708 @Override
709 public abstract ByteVector rotateER(int i);
710
711 @Override
712 public abstract ByteVector shiftEL(int i);
713
714 @Override
715 public abstract ByteVector shiftER(int i);
716
717
718
719 /**
720 * Bitwise ANDs this vector with an input vector.
721 * <p>
722 * This is a lane-wise binary operation which applies the primitive bitwise AND
723 * operation ({@code &}) to each lane.
724 *
725 * @param v the input vector
726 * @return the bitwise AND of this vector with the input vector
727 */
728 public abstract ByteVector and(Vector<Byte> v);
729
730 /**
731 * Bitwise ANDs this vector with the broadcast of an input scalar.
732 * <p>
733 * This is a lane-wise binary operation which applies the primitive bitwise AND
734 * operation ({@code &}) to each lane.
735 *
736 * @param s the input scalar
737 * @return the bitwise AND of this vector with the broadcast of an input
738 * scalar
739 */
740 public abstract ByteVector and(byte s);
741
742 /**
743 * Bitwise ANDs this vector with an input vector, selecting lane elements
744 * controlled by a mask.
745 * <p>
746 * This is a lane-wise binary operation which applies the primitive bitwise AND
747 * operation ({@code &}) to each lane.
748 *
749 * @param v the input vector
750 * @param m the mask controlling lane selection
751 * @return the bitwise AND of this vector with the input vector
752 */
753 public abstract ByteVector and(Vector<Byte> v, VectorMask<Byte> m);
754
755 /**
756 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
757 * lane elements controlled by a mask.
758 * <p>
759 * This is a lane-wise binary operation which applies the primitive bitwise AND
760 * operation ({@code &}) to each lane.
761 *
762 * @param s the input scalar
763 * @param m the mask controlling lane selection
764 * @return the bitwise AND of this vector with the broadcast of an input
765 * scalar
766 */
767 public abstract ByteVector and(byte s, VectorMask<Byte> m);
768
769 /**
770 * Bitwise ORs this vector with an input vector.
771 * <p>
772 * This is a lane-wise binary operation which applies the primitive bitwise OR
773 * operation ({@code |}) to each lane.
774 *
775 * @param v the input vector
776 * @return the bitwise OR of this vector with the input vector
777 */
778 public abstract ByteVector or(Vector<Byte> v);
779
780 /**
781 * Bitwise ORs this vector with the broadcast of an input scalar.
782 * <p>
783 * This is a lane-wise binary operation which applies the primitive bitwise OR
784 * operation ({@code |}) to each lane.
785 *
786 * @param s the input scalar
787 * @return the bitwise OR of this vector with the broadcast of an input
788 * scalar
789 */
790 public abstract ByteVector or(byte s);
791
792 /**
793 * Bitwise ORs this vector with an input vector, selecting lane elements
794 * controlled by a mask.
795 * <p>
796 * This is a lane-wise binary operation which applies the primitive bitwise OR
797 * operation ({@code |}) to each lane.
798 *
799 * @param v the input vector
800 * @param m the mask controlling lane selection
801 * @return the bitwise OR of this vector with the input vector
802 */
803 public abstract ByteVector or(Vector<Byte> v, VectorMask<Byte> m);
804
805 /**
806 * Bitwise ORs this vector with the broadcast of an input scalar, selecting
807 * lane elements controlled by a mask.
808 * <p>
809 * This is a lane-wise binary operation which applies the primitive bitwise OR
810 * operation ({@code |}) to each lane.
811 *
812 * @param s the input scalar
813 * @param m the mask controlling lane selection
814 * @return the bitwise OR of this vector with the broadcast of an input
815 * scalar
816 */
817 public abstract ByteVector or(byte s, VectorMask<Byte> m);
818
819 /**
820 * Bitwise XORs this vector with an input vector.
821 * <p>
822 * This is a lane-wise binary operation which applies the primitive bitwise XOR
823 * operation ({@code ^}) to each lane.
824 *
825 * @param v the input vector
826 * @return the bitwise XOR of this vector with the input vector
827 */
828 public abstract ByteVector xor(Vector<Byte> v);
829
830 /**
831 * Bitwise XORs this vector with the broadcast of an input scalar.
832 * <p>
833 * This is a lane-wise binary operation which applies the primitive bitwise XOR
834 * operation ({@code ^}) to each lane.
835 *
836 * @param s the input scalar
837 * @return the bitwise XOR of this vector with the broadcast of an input
838 * scalar
839 */
840 public abstract ByteVector xor(byte s);
841
842 /**
843 * Bitwise XORs this vector with an input vector, selecting lane elements
844 * controlled by a mask.
845 * <p>
846 * This is a lane-wise binary operation which applies the primitive bitwise XOR
847 * operation ({@code ^}) to each lane.
848 *
849 * @param v the input vector
850 * @param m the mask controlling lane selection
851 * @return the bitwise XOR of this vector with the input vector
852 */
853 public abstract ByteVector xor(Vector<Byte> v, VectorMask<Byte> m);
854
855 /**
856 * Bitwise XORs this vector with the broadcast of an input scalar, selecting
857 * lane elements controlled by a mask.
858 * <p>
859 * This is a lane-wise binary operation which applies the primitive bitwise XOR
860 * operation ({@code ^}) to each lane.
861 *
862 * @param s the input scalar
863 * @param m the mask controlling lane selection
864 * @return the bitwise XOR of this vector with the broadcast of an input
865 * scalar
866 */
867 public abstract ByteVector xor(byte s, VectorMask<Byte> m);
868
869 /**
870 * Bitwise NOTs this vector.
871 * <p>
872 * This is a lane-wise unary operation which applies the primitive bitwise NOT
873 * operation ({@code ~}) to each lane.
874 *
875 * @return the bitwise NOT of this vector
876 */
877 public abstract ByteVector not();
878
879 /**
880 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
881 * <p>
882 * This is a lane-wise unary operation which applies the primitive bitwise NOT
883 * operation ({@code ~}) to each lane.
884 *
885 * @param m the mask controlling lane selection
886 * @return the bitwise NOT of this vector
887 */
888 public abstract ByteVector not(VectorMask<Byte> m);
889
890 /**
891 * Logically left shifts this vector by the broadcast of an input scalar.
892 * <p>
893 * This is a lane-wise binary operation which applies the primitive logical left shift
894 * operation ({@code <<}) to each lane to left shift the
895 * element by shift value as specified by the input scalar. Only the 3
896 * lowest-order bits of shift value are used. It is as if the shift value
897 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
898 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
899 *
900 * @param s the input scalar; the number of the bits to left shift
901 * @return the result of logically left shifting left this vector by the
902 * broadcast of an input scalar
903 */
904 public abstract ByteVector shiftL(int s);
905
906 /**
907 * Logically left shifts this vector by the broadcast of an input scalar,
908 * selecting lane elements controlled by a mask.
909 * <p>
910 * This is a lane-wise binary operation which applies the primitive logical left shift
911 * operation ({@code <<}) to each lane to left shift the
912 * element by shift value as specified by the input scalar. Only the 3
913 * lowest-order bits of shift value are used. It is as if the shift value
914 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
915 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
916 *
917 * @param s the input scalar; the number of the bits to left shift
918 * @param m the mask controlling lane selection
919 * @return the result of logically left shifting left this vector by the
920 * broadcast of an input scalar
921 */
922 public abstract ByteVector shiftL(int s, VectorMask<Byte> m);
923
924
925 // logical, or unsigned, shift right
926
927 /**
928 * Logically right shifts (or unsigned right shifts) this vector by the
929 * broadcast of an input scalar.
930 * <p>
931 * This is a lane-wise binary operation which applies the primitive logical right shift
932 * operation ({@code >>>}) to each lane to logically right shift the
933 * element by shift value as specified by the input scalar. Only the 3
934 * lowest-order bits of shift value are used. It is as if the shift value
935 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
936 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
937 *
938 * @param s the input scalar; the number of the bits to right shift
939 * @return the result of logically right shifting this vector by the
940 * broadcast of an input scalar
941 */
942 public abstract ByteVector shiftR(int s);
943
944 /**
945 * Logically right shifts (or unsigned right shifts) this vector by the
946 * broadcast of an input scalar, selecting lane elements controlled by a
947 * mask.
948 * <p>
949 * This is a lane-wise binary operation which applies the primitive logical right shift
950 * operation ({@code >>}) to each lane to logically right shift the
951 * element by shift value as specified by the input scalar. Only the 3
952 * lowest-order bits of shift value are used. It is as if the shift value
953 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
954 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
955 *
956 * @param s the input scalar; the number of the bits to right shift
957 * @param m the mask controlling lane selection
958 * @return the result of logically right shifting this vector by the
959 * broadcast of an input scalar
960 */
961 public abstract ByteVector shiftR(int s, VectorMask<Byte> m);
962
963
964 /**
965 * Arithmetically right shifts (or signed right shifts) this vector by the
966 * broadcast of an input scalar.
967 * <p>
968 * This is a lane-wise binary operation which applies the primitive arithmetic right
969 * shift operation ({@code >>}) to each lane to arithmetically
970 * right shift the element by shift value as specified by the input scalar.
971 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
972 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
973 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
974 *
975 * @param s the input scalar; the number of the bits to right shift
976 * @return the result of arithmetically right shifting this vector by the
977 * broadcast of an input scalar
978 */
979 public abstract ByteVector aShiftR(int s);
980
981 /**
982 * Arithmetically right shifts (or signed right shifts) this vector by the
983 * broadcast of an input scalar, selecting lane elements controlled by a
984 * mask.
985 * <p>
986 * This is a lane-wise binary operation which applies the primitive arithmetic right
987 * shift operation ({@code >>}) to each lane to arithmetically
988 * right shift the element by shift value as specified by the input scalar.
989 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
990 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
991 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
992 *
993 * @param s the input scalar; the number of the bits to right shift
994 * @param m the mask controlling lane selection
995 * @return the result of arithmetically right shifting this vector by the
996 * broadcast of an input scalar
997 */
998 public abstract ByteVector aShiftR(int s, VectorMask<Byte> m);
999
1000
1001 @Override
1002 public abstract void intoByteArray(byte[] a, int ix);
1003
1004 @Override
1005 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Byte> m);
1006
1007 @Override
1008 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1009
1010 @Override
1011 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Byte> m);
1012
1013
1014 // Type specific horizontal reductions
1015 /**
1016 * Adds all lane elements of this vector.
1017 * <p>
1018 * This is an associative cross-lane reduction operation which applies the addition
1019 * operation ({@code +}) to lane elements,
1020 * and the identity value is {@code 0}.
1021 *
1022 * @return the addition of all the lane elements of this vector
1023 */
1024 public abstract byte addAll();
1025
1026 /**
1027 * Adds all lane elements of this vector, selecting lane elements
1028 * controlled by a mask.
1029 * <p>
1030 * This is an associative cross-lane reduction operation which applies the addition
1031 * operation ({@code +}) to lane elements,
1032 * and the identity value is {@code 0}.
1033 *
1034 * @param m the mask controlling lane selection
1035 * @return the addition of the selected lane elements of this vector
1036 */
1037 public abstract byte addAll(VectorMask<Byte> m);
1038
1039 /**
1040 * Multiplies all lane elements of this vector.
1041 * <p>
1042 * This is an associative cross-lane reduction operation which applies the
1043 * multiplication operation ({@code *}) to lane elements,
1044 * and the identity value is {@code 1}.
1045 *
1046 * @return the multiplication of all the lane elements of this vector
1047 */
1048 public abstract byte mulAll();
1049
1050 /**
1051 * Multiplies all lane elements of this vector, selecting lane elements
1052 * controlled by a mask.
1053 * <p>
1054 * This is an associative cross-lane reduction operation which applies the
1055 * multiplication operation ({@code *}) to lane elements,
1056 * and the identity value is {@code 1}.
1057 *
1058 * @param m the mask controlling lane selection
1059 * @return the multiplication of all the lane elements of this vector
1060 */
1061 public abstract byte mulAll(VectorMask<Byte> m);
1062
1063 /**
1064 * Returns the minimum lane element of this vector.
1065 * <p>
1066 * This is an associative cross-lane reduction operation which applies the operation
1067 * {@code (a, b) -> Math.min(a, b)} to lane elements,
1068 * and the identity value is
1069 * {@link Byte#MAX_VALUE}.
1070 *
1071 * @return the minimum lane element of this vector
1072 */
1073 public abstract byte minAll();
1074
1075 /**
1076 * Returns the minimum lane element of this vector, selecting lane elements
1077 * controlled by a mask.
1078 * <p>
1079 * This is an associative cross-lane reduction operation which applies the operation
1080 * {@code (a, b) -> Math.min(a, b)} to lane elements,
1081 * and the identity value is
1082 * {@link Byte#MAX_VALUE}.
1083 *
1084 * @param m the mask controlling lane selection
1085 * @return the minimum lane element of this vector
1086 */
1087 public abstract byte minAll(VectorMask<Byte> m);
1088
1089 /**
1090 * Returns the maximum lane element of this vector.
1091 * <p>
1092 * This is an associative cross-lane reduction operation which applies the operation
1093 * {@code (a, b) -> Math.max(a, b)} to lane elements,
1094 * and the identity value is
1095 * {@link Byte#MIN_VALUE}.
1096 *
1097 * @return the maximum lane element of this vector
1098 */
1099 public abstract byte maxAll();
1100
1101 /**
1102 * Returns the maximum lane element of this vector, selecting lane elements
1103 * controlled by a mask.
1104 * <p>
1105 * This is an associative cross-lane reduction operation which applies the operation
1106 * {@code (a, b) -> Math.max(a, b)} to lane elements,
1107 * and the identity value is
1108 * {@link Byte#MIN_VALUE}.
1109 *
1110 * @param m the mask controlling lane selection
1111 * @return the maximum lane element of this vector
1112 */
1113 public abstract byte maxAll(VectorMask<Byte> m);
1114
1115 /**
1116 * Logically ORs all lane elements of this vector.
1117 * <p>
1118 * This is an associative cross-lane reduction operation which applies the logical OR
1119 * operation ({@code |}) to lane elements,
1120 * and the identity value is {@code 0}.
1121 *
1122 * @return the logical OR all the lane elements of this vector
1123 */
1124 public abstract byte orAll();
1125
1126 /**
1127 * Logically ORs all lane elements of this vector, selecting lane elements
1128 * controlled by a mask.
1129 * <p>
1130 * This is an associative cross-lane reduction operation which applies the logical OR
1131 * operation ({@code |}) to lane elements,
1132 * and the identity value is {@code 0}.
1133 *
1134 * @param m the mask controlling lane selection
1135 * @return the logical OR all the lane elements of this vector
1136 */
1137 public abstract byte orAll(VectorMask<Byte> m);
1138
1139 /**
1140 * Logically ANDs all lane elements of this vector.
1141 * <p>
1142 * This is an associative cross-lane reduction operation which applies the logical AND
1143 * operation ({@code |}) to lane elements,
1144 * and the identity value is {@code -1}.
1145 *
1146 * @return the logical AND all the lane elements of this vector
1147 */
1148 public abstract byte andAll();
1149
1150 /**
1151 * Logically ANDs all lane elements of this vector, selecting lane elements
1152 * controlled by a mask.
1153 * <p>
1154 * This is an associative cross-lane reduction operation which applies the logical AND
1155 * operation ({@code |}) to lane elements,
1156 * and the identity value is {@code -1}.
1157 *
1158 * @param m the mask controlling lane selection
1159 * @return the logical AND all the lane elements of this vector
1160 */
1161 public abstract byte andAll(VectorMask<Byte> m);
1162
1163 /**
1164 * Logically XORs all lane elements of this vector.
1165 * <p>
1166 * This is an associative cross-lane reduction operation which applies the logical XOR
1167 * operation ({@code ^}) to lane elements,
1168 * and the identity value is {@code 0}.
1169 *
1170 * @return the logical XOR all the lane elements of this vector
1171 */
1172 public abstract byte xorAll();
1173
1174 /**
1175 * Logically XORs all lane elements of this vector, selecting lane elements
1176 * controlled by a mask.
1177 * <p>
1178 * This is an associative cross-lane reduction operation which applies the logical XOR
1179 * operation ({@code ^}) to lane elements,
1180 * and the identity value is {@code 0}.
1181 *
1182 * @param m the mask controlling lane selection
1183 * @return the logical XOR all the lane elements of this vector
1184 */
1185 public abstract byte xorAll(VectorMask<Byte> m);
1186
1187 // Type specific accessors
1188
1189 /**
1190 * Gets the lane element at lane index {@code i}
1191 *
1192 * @param i the lane index
1193 * @return the lane element at lane index {@code i}
1194 * @throws IllegalArgumentException if the index is is out of range
1195 * ({@code < 0 || >= length()})
1196 */
1197 public abstract byte lane(int i);
1198
1199 /**
1200 * Replaces the lane element of this vector at lane index {@code i} with
1201 * value {@code e}.
1202 * <p>
1203 * This is a cross-lane operation and behaves as if it returns the result
1204 * of blending this vector with an input vector that is the result of
1205 * broadcasting {@code e} and a mask that has only one lane set at lane
1206 * index {@code i}.
1207 *
1208 * @param i the lane index of the lane element to be replaced
1209 * @param e the value to be placed
1210 * @return the result of replacing the lane element of this vector at lane
1211 * index {@code i} with value {@code e}.
1212 * @throws IllegalArgumentException if the index is is out of range
1213 * ({@code < 0 || >= length()})
1214 */
1215 public abstract ByteVector with(int i, byte e);
1216
1217 // Type specific extractors
1224 * <pre>{@code
1225 * byte[] a = new byte[this.length()];
1226 * this.intoArray(a, 0);
1227 * return a;
1228 * }</pre>
1229 *
1230 * @return an array containing the the lane elements of this vector
1231 */
1232 @ForceInline
1233 public final byte[] toArray() {
1234 byte[] a = new byte[species().length()];
1235 intoArray(a, 0);
1236 return a;
1237 }
1238
1239 /**
1240 * Stores this vector into an array starting at offset.
1241 * <p>
1242 * For each vector lane, where {@code N} is the vector lane index,
1243 * the lane element at index {@code N} is stored into the array at index
1244 * {@code offset + N}.
1245 *
1246 * @param a the array
1247 * @param offset the offset into the array
1248 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1249 * {@code offset > a.length - this.length()}
1250 */
1251 public abstract void intoArray(byte[] a, int offset);
1252
1253 /**
1254 * Stores this vector into an array starting at offset and using a mask.
1255 * <p>
1256 * For each vector lane, where {@code N} is the vector lane index,
1257 * if the mask lane at index {@code N} is set then the lane element at
1258 * index {@code N} is stored into the array index {@code offset + N}.
1259 *
1260 * @param a the array
1261 * @param offset the offset into the array
1262 * @param m the mask
1263 * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1264 * for any vector lane index {@code N} where the mask at lane {@code N}
1265 * is set {@code offset >= a.length - N}
1266 */
1267 public abstract void intoArray(byte[] a, int offset, VectorMask<Byte> m);
1268
1269 /**
1270 * Stores this vector into an array using indexes obtained from an index
1271 * map.
1272 * <p>
1273 * For each vector lane, where {@code N} is the vector lane index, the
1274 * lane element at index {@code N} is stored into the array at index
1275 * {@code a_offset + indexMap[i_offset + N]}.
1276 *
1277 * @param a the array
1278 * @param a_offset the offset into the array, may be negative if relative
1279 * indexes in the index map compensate to produce a value within the
1280 * array bounds
1281 * @param indexMap the index map
1282 * @param i_offset the offset into the index map
1283 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
1284 * {@code i_offset > indexMap.length - this.length()},
1285 * or for any vector lane index {@code N} the result of
1286 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length}
1287 */
1288 public void intoArray(byte[] a, int a_offset, int[] indexMap, int i_offset) {
1289 forEach((n, e) -> a[a_offset + indexMap[i_offset + n]] = e);
1290 }
1291
1292 /**
1293 * Stores this vector into an array using indexes obtained from an index
1294 * map and using a mask.
1295 * <p>
1296 * For each vector lane, where {@code N} is the vector lane index,
1297 * if the mask lane at index {@code N} is set then the lane element at
1298 * index {@code N} is stored into the array at index
1299 * {@code a_offset + indexMap[i_offset + N]}.
1300 *
1301 * @param a the array
1302 * @param a_offset the offset into the array, may be negative if relative
1303 * indexes in the index map compensate to produce a value within the
1304 * array bounds
1305 * @param m the mask
1306 * @param indexMap the index map
1307 * @param i_offset the offset into the index map
1308 * @throws IndexOutOfBoundsException if {@code j < 0}, or
1309 * {@code i_offset > indexMap.length - this.length()},
1310 * or for any vector lane index {@code N} where the mask at lane
1311 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is
1312 * {@code < 0} or {@code >= a.length}
1313 */
1314 public void intoArray(byte[] a, int a_offset, VectorMask<Byte> m, int[] indexMap, int i_offset) {
1315 forEach(m, (n, e) -> a[a_offset + indexMap[i_offset + n]] = e);
1316 }
1317 // Species
1318
1319 @Override
1320 public abstract VectorSpecies<Byte> species();
1321
1322 /**
1323 * Class representing {@link ByteVector}'s of the same {@link VectorShape VectorShape}.
1324 */
1325 static final class ByteSpecies extends AbstractSpecies<Byte> {
1326 final Function<byte[], ByteVector> vectorFactory;
1327
1328 private ByteSpecies(VectorShape shape,
1329 Class<?> boxType,
1330 Class<?> maskType,
1331 Function<byte[], ByteVector> vectorFactory,
1332 Function<boolean[], VectorMask<Byte>> maskFactory,
1333 Function<IntUnaryOperator, VectorShuffle<Byte>> shuffleFromArrayFactory,
1334 fShuffleFromArray<Byte> shuffleFromOpFactory) {
1335 super(shape, byte.class, Byte.SIZE, boxType, maskType, maskFactory,
|