39
40 /**
41 * A specialized {@link Vector} representing an ordered immutable sequence of
42 * {@code int} values.
43 */
44 @SuppressWarnings("cast")
45 public abstract class IntVector extends Vector<Integer> {
46
47 IntVector() {}
48
49 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
50
51 // Unary operator
52
53 interface FUnOp {
54 int apply(int i, int a);
55 }
56
57 abstract IntVector uOp(FUnOp f);
58
59 abstract IntVector uOp(Mask<Integer> m, FUnOp f);
60
61 // Binary operator
62
63 interface FBinOp {
64 int apply(int i, int a, int b);
65 }
66
67 abstract IntVector bOp(Vector<Integer> v, FBinOp f);
68
69 abstract IntVector bOp(Vector<Integer> v, Mask<Integer> m, FBinOp f);
70
71 // Trinary operator
72
73 interface FTriOp {
74 int apply(int i, int a, int b, int c);
75 }
76
77 abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, FTriOp f);
78
79 abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, Mask<Integer> m, FTriOp f);
80
81 // Reduction operator
82
83 abstract int rOp(int v, FBinOp f);
84
85 // Binary test
86
87 interface FBinTest {
88 boolean apply(int i, int a, int b);
89 }
90
91 abstract Mask<Integer> bTest(Vector<Integer> v, FBinTest f);
92
93 // Foreach
94
95 interface FUnCon {
96 void apply(int i, int a);
97 }
98
99 abstract void forEach(FUnCon f);
100
101 abstract void forEach(Mask<Integer> m, FUnCon f);
102
103 // Static factories
104
105 /**
106 * Returns a vector where all lane elements are set to the default
107 * primitive value.
108 *
109 * @param species species of desired vector
110 * @return a zero vector of given species
111 */
112 @ForceInline
113 @SuppressWarnings("unchecked")
114 public static IntVector zero(Species<Integer> species) {
115 return VectorIntrinsics.broadcastCoerced((Class<IntVector>) species.boxType(), int.class, species.length(),
116 0, species,
117 ((bits, s) -> ((IntSpecies)s).op(i -> (int)bits)));
118 }
119
120 /**
121 * Loads a vector from a byte array starting at an offset.
122 * <p>
123 * Bytes are composed into primitive lane elements according to the
124 * native byte order of the underlying platform
125 * <p>
126 * This method behaves as if it returns the result of calling the
127 * byte buffer, offset, and mask accepting
128 * {@link #fromByteBuffer(Species<Integer>, ByteBuffer, int, Mask) method} as follows:
129 * <pre>{@code
130 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
131 * }</pre>
132 *
133 * @param species species of desired vector
134 * @param a the byte array
135 * @param ix the offset into the array
136 * @return a vector loaded from a byte array
137 * @throws IndexOutOfBoundsException if {@code i < 0} or
138 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
139 */
140 @ForceInline
141 @SuppressWarnings("unchecked")
142 public static IntVector fromByteArray(Species<Integer> species, byte[] a, int ix) {
143 Objects.requireNonNull(a);
144 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
145 return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
146 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
147 a, ix, species,
148 (c, idx, s) -> {
149 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
150 IntBuffer tb = bbc.asIntBuffer();
151 return ((IntSpecies)s).op(i -> tb.get());
152 });
153 }
154
155 /**
156 * Loads a vector from a byte array starting at an offset and using a
157 * mask.
158 * <p>
159 * Bytes are composed into primitive lane elements according to the
160 * native byte order of the underlying platform.
161 * <p>
162 * This method behaves as if it returns the result of calling the
163 * byte buffer, offset, and mask accepting
164 * {@link #fromByteBuffer(Species<Integer>, ByteBuffer, int, Mask) method} as follows:
165 * <pre>{@code
166 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
167 * }</pre>
168 *
169 * @param species species of desired vector
170 * @param a the byte array
171 * @param ix the offset into the array
172 * @param m the mask
173 * @return a vector loaded from a byte array
174 * @throws IndexOutOfBoundsException if {@code i < 0} or
175 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
176 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
177 * or {@code > a.length},
178 * for any vector lane index {@code N} where the mask at lane {@code N}
179 * is set
180 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
181 */
182 @ForceInline
183 public static IntVector fromByteArray(Species<Integer> species, byte[] a, int ix, Mask<Integer> m) {
184 return zero(species).blend(fromByteArray(species, a, ix), m);
185 }
186
187 /**
188 * Loads a vector from an array starting at offset.
189 * <p>
190 * For each vector lane, where {@code N} is the vector lane index, the
191 * array element at index {@code i + N} is placed into the
192 * resulting vector at lane index {@code N}.
193 *
194 * @param species species of desired vector
195 * @param a the array
196 * @param i the offset into the array
197 * @return the vector loaded from an array
198 * @throws IndexOutOfBoundsException if {@code i < 0}, or
199 * {@code i > a.length - this.length()}
200 */
201 @ForceInline
202 @SuppressWarnings("unchecked")
203 public static IntVector fromArray(Species<Integer> species, int[] a, int i){
204 Objects.requireNonNull(a);
205 i = VectorIntrinsics.checkIndex(i, a.length, species.length());
206 return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
207 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_INT_BASE_OFFSET,
208 a, i, species,
209 (c, idx, s) -> ((IntSpecies)s).op(n -> c[idx + n]));
210 }
211
212
213 /**
214 * Loads a vector from an array starting at offset and using a mask.
215 * <p>
216 * For each vector lane, where {@code N} is the vector lane index,
217 * if the mask lane at index {@code N} is set then the array element at
218 * index {@code i + N} is placed into the resulting vector at lane index
219 * {@code N}, otherwise the default element value is placed into the
220 * resulting vector at lane index {@code N}.
221 *
222 * @param species species of desired vector
223 * @param a the array
224 * @param i the offset into the array
225 * @param m the mask
226 * @return the vector loaded from an array
227 * @throws IndexOutOfBoundsException if {@code i < 0}, or
228 * for any vector lane index {@code N} where the mask at lane {@code N}
229 * is set {@code i > a.length - N}
230 */
231 @ForceInline
232 public static IntVector fromArray(Species<Integer> species, int[] a, int i, Mask<Integer> m) {
233 return zero(species).blend(fromArray(species, a, i), m);
234 }
235
236 /**
237 * Loads a vector from an array using indexes obtained from an index
238 * map.
239 * <p>
240 * For each vector lane, where {@code N} is the vector lane index, the
241 * array element at index {@code i + indexMap[j + N]} is placed into the
242 * resulting vector at lane index {@code N}.
243 *
244 * @param species species of desired vector
245 * @param a the array
246 * @param i the offset into the array, may be negative if relative
247 * indexes in the index map compensate to produce a value within the
248 * array bounds
249 * @param indexMap the index map
250 * @param j the offset into the index map
251 * @return the vector loaded from an array
252 * @throws IndexOutOfBoundsException if {@code j < 0}, or
253 * {@code j > indexMap.length - this.length()},
254 * or for any vector lane index {@code N} the result of
255 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
256 */
257 @ForceInline
258 @SuppressWarnings("unchecked")
259 public static IntVector fromArray(Species<Integer> species, int[] a, int i, int[] indexMap, int j) {
260 Objects.requireNonNull(a);
261 Objects.requireNonNull(indexMap);
262
263
264 // Index vector: vix[0:n] = k -> i + indexMap[j + k]
265 IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
266
267 vix = VectorIntrinsics.checkIndex(vix, a.length);
268
269 return VectorIntrinsics.loadWithMap((Class<IntVector>) species.boxType(), int.class, species.length(),
270 IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_INT_BASE_OFFSET, vix,
271 a, i, indexMap, j, species,
272 (int[] c, int idx, int[] iMap, int idy, Species<Integer> s) ->
273 ((IntSpecies)s).op(n -> c[idx + iMap[idy+n]]));
274 }
275
276 /**
277 * Loads a vector from an array using indexes obtained from an index
278 * map and using a mask.
279 * <p>
280 * For each vector lane, where {@code N} is the vector lane index,
281 * if the mask lane at index {@code N} is set then the array element at
282 * index {@code i + indexMap[j + N]} is placed into the resulting vector
283 * at lane index {@code N}.
284 *
285 * @param species species of desired vector
286 * @param a the array
287 * @param i the offset into the array, may be negative if relative
288 * indexes in the index map compensate to produce a value within the
289 * array bounds
290 * @param m the mask
291 * @param indexMap the index map
292 * @param j the offset into the index map
293 * @return the vector loaded from an array
294 * @throws IndexOutOfBoundsException if {@code j < 0}, or
295 * {@code j > indexMap.length - this.length()},
296 * or for any vector lane index {@code N} where the mask at lane
297 * {@code N} is set the result of {@code i + indexMap[j + N]} is
298 * {@code < 0} or {@code >= a.length}
299 */
300 @ForceInline
301 @SuppressWarnings("unchecked")
302 public static IntVector fromArray(Species<Integer> species, int[] a, int i, Mask<Integer> m, int[] indexMap, int j) {
303 // @@@ This can result in out of bounds errors for unset mask lanes
304 return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
305 }
306
307
308 /**
309 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
310 * offset into the byte buffer.
311 * <p>
312 * Bytes are composed into primitive lane elements according to the
313 * native byte order of the underlying platform.
314 * <p>
315 * This method behaves as if it returns the result of calling the
316 * byte buffer, offset, and mask accepting
317 * {@link #fromByteBuffer(Species<Integer>, ByteBuffer, int, Mask)} method} as follows:
318 * <pre>{@code
319 * return this.fromByteBuffer(b, i, this.maskAllTrue())
320 * }</pre>
321 *
322 * @param species species of desired vector
323 * @param bb the byte buffer
324 * @param ix the offset into the byte buffer
325 * @return a vector loaded from a byte buffer
326 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
327 * or {@code > b.limit()},
328 * or if there are fewer than
329 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
330 * remaining in the byte buffer from the given offset
331 */
332 @ForceInline
333 @SuppressWarnings("unchecked")
334 public static IntVector fromByteBuffer(Species<Integer> species, ByteBuffer bb, int ix) {
335 if (bb.order() != ByteOrder.nativeOrder()) {
336 throw new IllegalArgumentException();
337 }
338 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
339 return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
340 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
341 bb, ix, species,
342 (c, idx, s) -> {
343 ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
344 IntBuffer tb = bbc.asIntBuffer();
345 return ((IntSpecies)s).op(i -> tb.get());
346 });
347 }
348
349 /**
350 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
351 * offset into the byte buffer and using a mask.
352 * <p>
353 * This method behaves as if the byte buffer is viewed as a primitive
354 * {@link java.nio.Buffer buffer} for the primitive element type,
366 * e[] es = new e[this.length()];
367 * for (int n = 0; n < t.length; n++) {
368 * if (m.isSet(n))
369 * es[n] = eb.get(n);
370 * }
371 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
372 * }</pre>
373 *
374 * @param species species of desired vector
375 * @param bb the byte buffer
376 * @param ix the offset into the byte buffer
377 * @param m the mask
378 * @return a vector loaded from a byte buffer
379 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
380 * or {@code > b.limit()},
381 * for any vector lane index {@code N} where the mask at lane {@code N}
382 * is set
383 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
384 */
385 @ForceInline
386 public static IntVector fromByteBuffer(Species<Integer> species, ByteBuffer bb, int ix, Mask<Integer> m) {
387 return zero(species).blend(fromByteBuffer(species, bb, ix), m);
388 }
389
390 /**
391 * Returns a vector where all lane elements are set to the primitive
392 * value {@code e}.
393 *
394 * @param s species of the desired vector
395 * @param e the value
396 * @return a vector of vector where all lane elements are set to
397 * the primitive value {@code e}
398 */
399 @ForceInline
400 @SuppressWarnings("unchecked")
401 public static IntVector broadcast(Species<Integer> s, int e) {
402 return VectorIntrinsics.broadcastCoerced(
403 (Class<IntVector>) s.boxType(), int.class, s.length(),
404 e, s,
405 ((bits, sp) -> ((IntSpecies)sp).op(i -> (int)bits)));
406 }
407
408 /**
409 * Returns a vector where each lane element is set to a given
410 * primitive value.
411 * <p>
412 * For each vector lane, where {@code N} is the vector lane index, the
413 * the primitive value at index {@code N} is placed into the resulting
414 * vector at lane index {@code N}.
415 *
416 * @param s species of the desired vector
417 * @param es the given primitive values
418 * @return a vector where each lane element is set to a given primitive
419 * value
420 * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
421 */
422 @ForceInline
423 @SuppressWarnings("unchecked")
424 public static IntVector scalars(Species<Integer> s, int... es) {
425 Objects.requireNonNull(es);
426 int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
427 return VectorIntrinsics.load((Class<IntVector>) s.boxType(), int.class, s.length(),
428 es, Unsafe.ARRAY_INT_BASE_OFFSET,
429 es, ix, s,
430 (c, idx, sp) -> ((IntSpecies)sp).op(n -> c[idx + n]));
431 }
432
433 /**
434 * Returns a vector where the first lane element is set to the primtive
435 * value {@code e}, all other lane elements are set to the default
436 * value.
437 *
438 * @param s species of the desired vector
439 * @param e the value
440 * @return a vector where the first lane element is set to the primitive
441 * value {@code e}
442 */
443 @ForceInline
444 public static final IntVector single(Species<Integer> s, int e) {
445 return zero(s).with(0, e);
446 }
447
448 /**
449 * Returns a vector where each lane element is set to a randomly
450 * generated primitive value.
451 *
452 * The semantics are equivalent to calling
453 * {@link ThreadLocalRandom#nextInt()}
454 *
455 * @param s species of the desired vector
456 * @return a vector where each lane elements is set to a randomly
457 * generated primitive value
458 */
459 public static IntVector random(Species<Integer> s) {
460 ThreadLocalRandom r = ThreadLocalRandom.current();
461 return ((IntSpecies)s).op(i -> r.nextInt());
462 }
463
464 /**
465 * Returns a mask where each lane is set or unset according to given
466 * {@code boolean} values
467 * <p>
468 * For each mask lane, where {@code N} is the mask lane index,
469 * if the given {@code boolean} value at index {@code N} is {@code true}
470 * then the mask lane at index {@code N} is set, otherwise it is unset.
471 *
472 * @param species mask species
473 * @param bits the given {@code boolean} values
474 * @return a mask where each lane is set or unset according to the given {@code boolean} value
475 * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
476 */
477 @ForceInline
478 public static Mask<Integer> maskFromValues(Species<Integer> species, boolean... bits) {
479 if (species.boxType() == IntMaxVector.class)
480 return new IntMaxVector.IntMaxMask(bits);
481 switch (species.bitSize()) {
482 case 64: return new Int64Vector.Int64Mask(bits);
483 case 128: return new Int128Vector.Int128Mask(bits);
484 case 256: return new Int256Vector.Int256Mask(bits);
485 case 512: return new Int512Vector.Int512Mask(bits);
486 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
487 }
488 }
489
490 // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
491 static Mask<Integer> trueMask(Species<Integer> species) {
492 if (species.boxType() == IntMaxVector.class)
493 return IntMaxVector.IntMaxMask.TRUE_MASK;
494 switch (species.bitSize()) {
495 case 64: return Int64Vector.Int64Mask.TRUE_MASK;
496 case 128: return Int128Vector.Int128Mask.TRUE_MASK;
497 case 256: return Int256Vector.Int256Mask.TRUE_MASK;
498 case 512: return Int512Vector.Int512Mask.TRUE_MASK;
499 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
500 }
501 }
502
503 static Mask<Integer> falseMask(Species<Integer> species) {
504 if (species.boxType() == IntMaxVector.class)
505 return IntMaxVector.IntMaxMask.FALSE_MASK;
506 switch (species.bitSize()) {
507 case 64: return Int64Vector.Int64Mask.FALSE_MASK;
508 case 128: return Int128Vector.Int128Mask.FALSE_MASK;
509 case 256: return Int256Vector.Int256Mask.FALSE_MASK;
510 case 512: return Int512Vector.Int512Mask.FALSE_MASK;
511 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
512 }
513 }
514
515 /**
516 * Loads a mask from a {@code boolean} array starting at an offset.
517 * <p>
518 * For each mask lane, where {@code N} is the mask lane index,
519 * if the array element at index {@code ix + N} is {@code true} then the
520 * mask lane at index {@code N} is set, otherwise it is unset.
521 *
522 * @param species mask species
523 * @param bits the {@code boolean} array
524 * @param ix the offset into the array
525 * @return the mask loaded from a {@code boolean} array
526 * @throws IndexOutOfBoundsException if {@code ix < 0}, or
527 * {@code ix > bits.length - species.length()}
528 */
529 @ForceInline
530 @SuppressWarnings("unchecked")
531 public static Mask<Integer> maskFromArray(Species<Integer> species, boolean[] bits, int ix) {
532 Objects.requireNonNull(bits);
533 ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
534 return VectorIntrinsics.load((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
535 bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
536 bits, ix, species,
537 (c, idx, s) -> (Mask<Integer>) ((IntSpecies)s).opm(n -> c[idx + n]));
538 }
539
540 /**
541 * Returns a mask where all lanes are set.
542 *
543 * @param species mask species
544 * @return a mask where all lanes are set
545 */
546 @ForceInline
547 @SuppressWarnings("unchecked")
548 public static Mask<Integer> maskAllTrue(Species<Integer> species) {
549 return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
550 (int)-1, species,
551 ((z, s) -> trueMask(s)));
552 }
553
554 /**
555 * Returns a mask where all lanes are unset.
556 *
557 * @param species mask species
558 * @return a mask where all lanes are unset
559 */
560 @ForceInline
561 @SuppressWarnings("unchecked")
562 public static Mask<Integer> maskAllFalse(Species<Integer> species) {
563 return VectorIntrinsics.broadcastCoerced((Class<Mask<Integer>>) species.maskType(), int.class, species.length(),
564 0, species,
565 ((z, s) -> falseMask(s)));
566 }
567
568 /**
569 * Returns a shuffle of mapped indexes where each lane element is
570 * the result of applying a mapping function to the corresponding lane
571 * index.
572 * <p>
573 * Care should be taken to ensure Shuffle values produced from this
574 * method are consumed as constants to ensure optimal generation of
575 * code. For example, values held in static final fields or values
576 * held in loop constant local variables.
577 * <p>
578 * This method behaves as if a shuffle is created from an array of
579 * mapped indexes as follows:
580 * <pre>{@code
581 * int[] a = new int[species.length()];
582 * for (int i = 0; i < a.length; i++) {
583 * a[i] = f.applyAsInt(i);
584 * }
585 * return this.shuffleFromValues(a);
586 * }</pre>
587 *
588 * @param species shuffle species
589 * @param f the lane index mapping function
590 * @return a shuffle of mapped indexes
591 */
592 @ForceInline
593 public static Shuffle<Integer> shuffle(Species<Integer> species, IntUnaryOperator f) {
594 if (species.boxType() == IntMaxVector.class)
595 return new IntMaxVector.IntMaxShuffle(f);
596 switch (species.bitSize()) {
597 case 64: return new Int64Vector.Int64Shuffle(f);
598 case 128: return new Int128Vector.Int128Shuffle(f);
599 case 256: return new Int256Vector.Int256Shuffle(f);
600 case 512: return new Int512Vector.Int512Shuffle(f);
601 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
602 }
603 }
604
605 /**
606 * Returns a shuffle where each lane element is the value of its
607 * corresponding lane index.
608 * <p>
609 * This method behaves as if a shuffle is created from an identity
610 * index mapping function as follows:
611 * <pre>{@code
612 * return this.shuffle(i -> i);
613 * }</pre>
614 *
615 * @param species shuffle species
616 * @return a shuffle of lane indexes
617 */
618 @ForceInline
619 public static Shuffle<Integer> shuffleIota(Species<Integer> species) {
620 if (species.boxType() == IntMaxVector.class)
621 return new IntMaxVector.IntMaxShuffle(AbstractShuffle.IDENTITY);
622 switch (species.bitSize()) {
623 case 64: return new Int64Vector.Int64Shuffle(AbstractShuffle.IDENTITY);
624 case 128: return new Int128Vector.Int128Shuffle(AbstractShuffle.IDENTITY);
625 case 256: return new Int256Vector.Int256Shuffle(AbstractShuffle.IDENTITY);
626 case 512: return new Int512Vector.Int512Shuffle(AbstractShuffle.IDENTITY);
627 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
628 }
629 }
630
631 /**
632 * Returns a shuffle where each lane element is set to a given
633 * {@code int} value logically AND'ed by the species length minus one.
634 * <p>
635 * For each shuffle lane, where {@code N} is the shuffle lane index, the
636 * the {@code int} value at index {@code N} logically AND'ed by
637 * {@code species.length() - 1} is placed into the resulting shuffle at
638 * lane index {@code N}.
639 *
640 * @param species shuffle species
641 * @param ixs the given {@code int} values
642 * @return a shuffle where each lane element is set to a given
643 * {@code int} value
644 * @throws IndexOutOfBoundsException if the number of int values is
645 * {@code < species.length()}
646 */
647 @ForceInline
648 public static Shuffle<Integer> shuffleFromValues(Species<Integer> species, int... ixs) {
649 if (species.boxType() == IntMaxVector.class)
650 return new IntMaxVector.IntMaxShuffle(ixs);
651 switch (species.bitSize()) {
652 case 64: return new Int64Vector.Int64Shuffle(ixs);
653 case 128: return new Int128Vector.Int128Shuffle(ixs);
654 case 256: return new Int256Vector.Int256Shuffle(ixs);
655 case 512: return new Int512Vector.Int512Shuffle(ixs);
656 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
657 }
658 }
659
660 /**
661 * Loads a shuffle from an {@code int} array starting at an offset.
662 * <p>
663 * For each shuffle lane, where {@code N} is the shuffle lane index, the
664 * array element at index {@code i + N} logically AND'ed by
665 * {@code species.length() - 1} is placed into the resulting shuffle at lane
666 * index {@code N}.
667 *
668 * @param species shuffle species
669 * @param ixs the {@code int} array
670 * @param i the offset into the array
671 * @return a shuffle loaded from the {@code int} array
672 * @throws IndexOutOfBoundsException if {@code i < 0}, or
673 * {@code i > a.length - species.length()}
674 */
675 @ForceInline
676 public static Shuffle<Integer> shuffleFromArray(Species<Integer> species, int[] ixs, int i) {
677 if (species.boxType() == IntMaxVector.class)
678 return new IntMaxVector.IntMaxShuffle(ixs, i);
679 switch (species.bitSize()) {
680 case 64: return new Int64Vector.Int64Shuffle(ixs, i);
681 case 128: return new Int128Vector.Int128Shuffle(ixs, i);
682 case 256: return new Int256Vector.Int256Shuffle(ixs, i);
683 case 512: return new Int512Vector.Int512Shuffle(ixs, i);
684 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
685 }
686 }
687
688 // Ops
689
690 @Override
691 public abstract IntVector add(Vector<Integer> v);
692
693 /**
694 * Adds this vector to the broadcast of an input scalar.
695 * <p>
696 * This is a vector binary operation where the primitive addition operation
697 * ({@code +}) is applied to lane elements.
698 *
699 * @param s the input scalar
700 * @return the result of adding this vector to the broadcast of an input
701 * scalar
702 */
703 public abstract IntVector add(int s);
704
705 @Override
706 public abstract IntVector add(Vector<Integer> v, Mask<Integer> m);
707
708 /**
709 * Adds this vector to broadcast of an input scalar,
710 * selecting lane elements controlled by a mask.
711 * <p>
712 * This is a vector binary operation where the primitive addition operation
713 * ({@code +}) is applied to lane elements.
714 *
715 * @param s the input scalar
716 * @param m the mask controlling lane selection
717 * @return the result of adding this vector to the broadcast of an input
718 * scalar
719 */
720 public abstract IntVector add(int s, Mask<Integer> m);
721
722 @Override
723 public abstract IntVector sub(Vector<Integer> v);
724
725 /**
726 * Subtracts the broadcast of an input scalar from this vector.
727 * <p>
728 * This is a vector binary operation where the primitive subtraction
729 * operation ({@code -}) is applied to lane elements.
730 *
731 * @param s the input scalar
732 * @return the result of subtracting the broadcast of an input
733 * scalar from this vector
734 */
735 public abstract IntVector sub(int s);
736
737 @Override
738 public abstract IntVector sub(Vector<Integer> v, Mask<Integer> m);
739
740 /**
741 * Subtracts the broadcast of an input scalar from this vector, selecting
742 * lane elements controlled by a mask.
743 * <p>
744 * This is a vector binary operation where the primitive subtraction
745 * operation ({@code -}) is applied to lane elements.
746 *
747 * @param s the input scalar
748 * @param m the mask controlling lane selection
749 * @return the result of subtracting the broadcast of an input
750 * scalar from this vector
751 */
752 public abstract IntVector sub(int s, Mask<Integer> m);
753
754 @Override
755 public abstract IntVector mul(Vector<Integer> v);
756
757 /**
758 * Multiplies this vector with the broadcast of an input scalar.
759 * <p>
760 * This is a vector binary operation where the primitive multiplication
761 * operation ({@code *}) is applied to lane elements.
762 *
763 * @param s the input scalar
764 * @return the result of multiplying this vector with the broadcast of an
765 * input scalar
766 */
767 public abstract IntVector mul(int s);
768
769 @Override
770 public abstract IntVector mul(Vector<Integer> v, Mask<Integer> m);
771
772 /**
773 * Multiplies this vector with the broadcast of an input scalar, selecting
774 * lane elements controlled by a mask.
775 * <p>
776 * This is a vector binary operation where the primitive multiplication
777 * operation ({@code *}) is applied to lane elements.
778 *
779 * @param s the input scalar
780 * @param m the mask controlling lane selection
781 * @return the result of multiplying this vector with the broadcast of an
782 * input scalar
783 */
784 public abstract IntVector mul(int s, Mask<Integer> m);
785
786 @Override
787 public abstract IntVector neg();
788
789 @Override
790 public abstract IntVector neg(Mask<Integer> m);
791
792 @Override
793 public abstract IntVector abs();
794
795 @Override
796 public abstract IntVector abs(Mask<Integer> m);
797
798 @Override
799 public abstract IntVector min(Vector<Integer> v);
800
801 @Override
802 public abstract IntVector min(Vector<Integer> v, Mask<Integer> m);
803
804 /**
805 * Returns the minimum of this vector and the broadcast of an input scalar.
806 * <p>
807 * This is a vector binary operation where the operation
808 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
809 *
810 * @param s the input scalar
811 * @return the minimum of this vector and the broadcast of an input scalar
812 */
813 public abstract IntVector min(int s);
814
815 @Override
816 public abstract IntVector max(Vector<Integer> v);
817
818 @Override
819 public abstract IntVector max(Vector<Integer> v, Mask<Integer> m);
820
821 /**
822 * Returns the maximum of this vector and the broadcast of an input scalar.
823 * <p>
824 * This is a vector binary operation where the operation
825 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
826 *
827 * @param s the input scalar
828 * @return the maximum of this vector and the broadcast of an input scalar
829 */
830 public abstract IntVector max(int s);
831
832 @Override
833 public abstract Mask<Integer> equal(Vector<Integer> v);
834
835 /**
836 * Tests if this vector is equal to the broadcast of an input scalar.
837 * <p>
838 * This is a vector binary test operation where the primitive equals
839 * operation ({@code ==}) is applied to lane elements.
840 *
841 * @param s the input scalar
842 * @return the result mask of testing if this vector is equal to the
843 * broadcast of an input scalar
844 */
845 public abstract Mask<Integer> equal(int s);
846
847 @Override
848 public abstract Mask<Integer> notEqual(Vector<Integer> v);
849
850 /**
851 * Tests if this vector is not equal to the broadcast of an input scalar.
852 * <p>
853 * This is a vector binary test operation where the primitive not equals
854 * operation ({@code !=}) is applied to lane elements.
855 *
856 * @param s the input scalar
857 * @return the result mask of testing if this vector is not equal to the
858 * broadcast of an input scalar
859 */
860 public abstract Mask<Integer> notEqual(int s);
861
862 @Override
863 public abstract Mask<Integer> lessThan(Vector<Integer> v);
864
865 /**
866 * Tests if this vector is less than the broadcast of an input scalar.
867 * <p>
868 * This is a vector binary test operation where the primitive less than
869 * operation ({@code <}) is applied to lane elements.
870 *
871 * @param s the input scalar
872 * @return the mask result of testing if this vector is less than the
873 * broadcast of an input scalar
874 */
875 public abstract Mask<Integer> lessThan(int s);
876
877 @Override
878 public abstract Mask<Integer> lessThanEq(Vector<Integer> v);
879
880 /**
881 * Tests if this vector is less or equal to the broadcast of an input scalar.
882 * <p>
883 * This is a vector binary test operation where the primitive less than
884 * or equal to operation ({@code <=}) is applied to lane elements.
885 *
886 * @param s the input scalar
887 * @return the mask result of testing if this vector is less than or equal
888 * to the broadcast of an input scalar
889 */
890 public abstract Mask<Integer> lessThanEq(int s);
891
892 @Override
893 public abstract Mask<Integer> greaterThan(Vector<Integer> v);
894
895 /**
896 * Tests if this vector is greater than the broadcast of an input scalar.
897 * <p>
898 * This is a vector binary test operation where the primitive greater than
899 * operation ({@code >}) is applied to lane elements.
900 *
901 * @param s the input scalar
902 * @return the mask result of testing if this vector is greater than the
903 * broadcast of an input scalar
904 */
905 public abstract Mask<Integer> greaterThan(int s);
906
907 @Override
908 public abstract Mask<Integer> greaterThanEq(Vector<Integer> v);
909
910 /**
911 * Tests if this vector is greater than or equal to the broadcast of an
912 * input scalar.
913 * <p>
914 * This is a vector binary test operation where the primitive greater than
915 * or equal to operation ({@code >=}) is applied to lane elements.
916 *
917 * @param s the input scalar
918 * @return the mask result of testing if this vector is greater than or
919 * equal to the broadcast of an input scalar
920 */
921 public abstract Mask<Integer> greaterThanEq(int s);
922
923 @Override
924 public abstract IntVector blend(Vector<Integer> v, Mask<Integer> m);
925
926 /**
927 * Blends the lane elements of this vector with those of the broadcast of an
928 * input scalar, selecting lanes controlled by a mask.
929 * <p>
930 * For each lane of the mask, at lane index {@code N}, if the mask lane
931 * is set then the lane element at {@code N} from the input vector is
932 * selected and placed into the resulting vector at {@code N},
933 * otherwise the the lane element at {@code N} from this input vector is
934 * selected and placed into the resulting vector at {@code N}.
935 *
936 * @param s the input scalar
937 * @param m the mask controlling lane selection
938 * @return the result of blending the lane elements of this vector with
939 * those of the broadcast of an input scalar
940 */
941 public abstract IntVector blend(int s, Mask<Integer> m);
942
943 @Override
944 public abstract IntVector rearrange(Vector<Integer> v,
945 Shuffle<Integer> s, Mask<Integer> m);
946
947 @Override
948 public abstract IntVector rearrange(Shuffle<Integer> m);
949
950 @Override
951 public abstract IntVector reshape(Species<Integer> s);
952
953 @Override
954 public abstract IntVector rotateEL(int i);
955
956 @Override
957 public abstract IntVector rotateER(int i);
958
959 @Override
960 public abstract IntVector shiftEL(int i);
961
962 @Override
963 public abstract IntVector shiftER(int i);
964
965
966
967 /**
968 * Bitwise ANDs this vector with an input vector.
969 * <p>
970 * This is a vector binary operation where the primitive bitwise AND
971 * operation ({@code &}) is applied to lane elements.
981 * This is a vector binary operation where the primitive bitwise AND
982 * operation ({@code &}) is applied to lane elements.
983 *
984 * @param s the input scalar
985 * @return the bitwise AND of this vector with the broadcast of an input
986 * scalar
987 */
988 public abstract IntVector and(int s);
989
990 /**
991 * Bitwise ANDs this vector with an input vector, selecting lane elements
992 * controlled by a mask.
993 * <p>
994 * This is a vector binary operation where the primitive bitwise AND
995 * operation ({@code &}) is applied to lane elements.
996 *
997 * @param v the input vector
998 * @param m the mask controlling lane selection
999 * @return the bitwise AND of this vector with the input vector
1000 */
1001 public abstract IntVector and(Vector<Integer> v, Mask<Integer> m);
1002
1003 /**
1004 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
1005 * lane elements controlled by a mask.
1006 * <p>
1007 * This is a vector binary operation where the primitive bitwise AND
1008 * operation ({@code &}) is applied to lane elements.
1009 *
1010 * @param s the input scalar
1011 * @param m the mask controlling lane selection
1012 * @return the bitwise AND of this vector with the broadcast of an input
1013 * scalar
1014 */
1015 public abstract IntVector and(int s, Mask<Integer> m);
1016
1017 /**
1018 * Bitwise ORs this vector with an input vector.
1019 * <p>
1020 * This is a vector binary operation where the primitive bitwise OR
1021 * operation ({@code |}) is applied to lane elements.
1022 *
1023 * @param v the input vector
1024 * @return the bitwise OR of this vector with the input vector
1025 */
1026 public abstract IntVector or(Vector<Integer> v);
1027
1028 /**
1029 * Bitwise ORs this vector with the broadcast of an input scalar.
1030 * <p>
1031 * This is a vector binary operation where the primitive bitwise OR
1032 * operation ({@code |}) is applied to lane elements.
1033 *
1034 * @param s the input scalar
1035 * @return the bitwise OR of this vector with the broadcast of an input
1036 * scalar
1037 */
1038 public abstract IntVector or(int s);
1039
1040 /**
1041 * Bitwise ORs this vector with an input vector, selecting lane elements
1042 * controlled by a mask.
1043 * <p>
1044 * This is a vector binary operation where the primitive bitwise OR
1045 * operation ({@code |}) is applied to lane elements.
1046 *
1047 * @param v the input vector
1048 * @param m the mask controlling lane selection
1049 * @return the bitwise OR of this vector with the input vector
1050 */
1051 public abstract IntVector or(Vector<Integer> v, Mask<Integer> m);
1052
1053 /**
1054 * Bitwise ORs this vector with the broadcast of an input scalar, selecting
1055 * lane elements controlled by a mask.
1056 * <p>
1057 * This is a vector binary operation where the primitive bitwise OR
1058 * operation ({@code |}) is applied to lane elements.
1059 *
1060 * @param s the input scalar
1061 * @param m the mask controlling lane selection
1062 * @return the bitwise OR of this vector with the broadcast of an input
1063 * scalar
1064 */
1065 public abstract IntVector or(int s, Mask<Integer> m);
1066
1067 /**
1068 * Bitwise XORs this vector with an input vector.
1069 * <p>
1070 * This is a vector binary operation where the primitive bitwise XOR
1071 * operation ({@code ^}) is applied to lane elements.
1072 *
1073 * @param v the input vector
1074 * @return the bitwise XOR of this vector with the input vector
1075 */
1076 public abstract IntVector xor(Vector<Integer> v);
1077
1078 /**
1079 * Bitwise XORs this vector with the broadcast of an input scalar.
1080 * <p>
1081 * This is a vector binary operation where the primitive bitwise XOR
1082 * operation ({@code ^}) is applied to lane elements.
1083 *
1084 * @param s the input scalar
1085 * @return the bitwise XOR of this vector with the broadcast of an input
1086 * scalar
1087 */
1088 public abstract IntVector xor(int s);
1089
1090 /**
1091 * Bitwise XORs this vector with an input vector, selecting lane elements
1092 * controlled by a mask.
1093 * <p>
1094 * This is a vector binary operation where the primitive bitwise XOR
1095 * operation ({@code ^}) is applied to lane elements.
1096 *
1097 * @param v the input vector
1098 * @param m the mask controlling lane selection
1099 * @return the bitwise XOR of this vector with the input vector
1100 */
1101 public abstract IntVector xor(Vector<Integer> v, Mask<Integer> m);
1102
1103 /**
1104 * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1105 * lane elements controlled by a mask.
1106 * <p>
1107 * This is a vector binary operation where the primitive bitwise XOR
1108 * operation ({@code ^}) is applied to lane elements.
1109 *
1110 * @param s the input scalar
1111 * @param m the mask controlling lane selection
1112 * @return the bitwise XOR of this vector with the broadcast of an input
1113 * scalar
1114 */
1115 public abstract IntVector xor(int s, Mask<Integer> m);
1116
1117 /**
1118 * Bitwise NOTs this vector.
1119 * <p>
1120 * This is a vector unary operation where the primitive bitwise NOT
1121 * operation ({@code ~}) is applied to lane elements.
1122 *
1123 * @return the bitwise NOT of this vector
1124 */
1125 public abstract IntVector not();
1126
1127 /**
1128 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1129 * <p>
1130 * This is a vector unary operation where the primitive bitwise NOT
1131 * operation ({@code ~}) is applied to lane elements.
1132 *
1133 * @param m the mask controlling lane selection
1134 * @return the bitwise NOT of this vector
1135 */
1136 public abstract IntVector not(Mask<Integer> m);
1137
1138 /**
1139 * Logically left shifts this vector by the broadcast of an input scalar.
1140 * <p>
1141 * This is a vector binary operation where the primitive logical left shift
1142 * operation ({@code <<}) is applied to lane elements.
1143 *
1144 * @param s the input scalar; the number of the bits to left shift
1145 * @return the result of logically left shifting left this vector by the
1146 * broadcast of an input scalar
1147 */
1148 public abstract IntVector shiftL(int s);
1149
1150 /**
1151 * Logically left shifts this vector by the broadcast of an input scalar,
1152 * selecting lane elements controlled by a mask.
1153 * <p>
1154 * This is a vector binary operation where the primitive logical left shift
1155 * operation ({@code <<}) is applied to lane elements.
1156 *
1157 * @param s the input scalar; the number of the bits to left shift
1158 * @param m the mask controlling lane selection
1159 * @return the result of logically left shifting this vector by the
1160 * broadcast of an input scalar
1161 */
1162 public abstract IntVector shiftL(int s, Mask<Integer> m);
1163
1164 /**
1165 * Logically left shifts this vector by an input vector.
1166 * <p>
1167 * This is a vector binary operation where the primitive logical left shift
1168 * operation ({@code <<}) is applied to lane elements.
1169 *
1170 * @param v the input vector
1171 * @return the result of logically left shifting this vector by the input
1172 * vector
1173 */
1174 public abstract IntVector shiftL(Vector<Integer> v);
1175
1176 /**
1177 * Logically left shifts this vector by an input vector, selecting lane
1178 * elements controlled by a mask.
1179 * <p>
1180 * This is a vector binary operation where the primitive logical left shift
1181 * operation ({@code <<}) is applied to lane elements.
1182 *
1183 * @param v the input vector
1184 * @param m the mask controlling lane selection
1185 * @return the result of logically left shifting this vector by the input
1186 * vector
1187 */
1188 public IntVector shiftL(Vector<Integer> v, Mask<Integer> m) {
1189 return bOp(v, m, (i, a, b) -> (int) (a << b));
1190 }
1191
1192 // logical, or unsigned, shift right
1193
1194 /**
1195 * Logically right shifts (or unsigned right shifts) this vector by the
1196 * broadcast of an input scalar.
1197 * <p>
1198 * This is a vector binary operation where the primitive logical right shift
1199 * operation ({@code >>>}) is applied to lane elements.
1200 *
1201 * @param s the input scalar; the number of the bits to right shift
1202 * @return the result of logically right shifting this vector by the
1203 * broadcast of an input scalar
1204 */
1205 public abstract IntVector shiftR(int s);
1206
1207 /**
1208 * Logically right shifts (or unsigned right shifts) this vector by the
1209 * broadcast of an input scalar, selecting lane elements controlled by a
1210 * mask.
1211 * <p>
1212 * This is a vector binary operation where the primitive logical right shift
1213 * operation ({@code >>>}) is applied to lane elements.
1214 *
1215 * @param s the input scalar; the number of the bits to right shift
1216 * @param m the mask controlling lane selection
1217 * @return the result of logically right shifting this vector by the
1218 * broadcast of an input scalar
1219 */
1220 public abstract IntVector shiftR(int s, Mask<Integer> m);
1221
1222 /**
1223 * Logically right shifts (or unsigned right shifts) this vector by an
1224 * input vector.
1225 * <p>
1226 * This is a vector binary operation where the primitive logical right shift
1227 * operation ({@code >>>}) is applied to lane elements.
1228 *
1229 * @param v the input vector
1230 * @return the result of logically right shifting this vector by the
1231 * input vector
1232 */
1233 public abstract IntVector shiftR(Vector<Integer> v);
1234
1235 /**
1236 * Logically right shifts (or unsigned right shifts) this vector by an
1237 * input vector, selecting lane elements controlled by a mask.
1238 * <p>
1239 * This is a vector binary operation where the primitive logical right shift
1240 * operation ({@code >>>}) is applied to lane elements.
1241 *
1242 * @param v the input vector
1243 * @param m the mask controlling lane selection
1244 * @return the result of logically right shifting this vector by the
1245 * input vector
1246 */
1247 public IntVector shiftR(Vector<Integer> v, Mask<Integer> m) {
1248 return bOp(v, m, (i, a, b) -> (int) (a >>> b));
1249 }
1250
1251 /**
1252 * Arithmetically right shifts (or signed right shifts) this vector by the
1253 * broadcast of an input scalar.
1254 * <p>
1255 * This is a vector binary operation where the primitive arithmetic right
1256 * shift operation ({@code >>}) is applied to lane elements.
1257 *
1258 * @param s the input scalar; the number of the bits to right shift
1259 * @return the result of arithmetically right shifting this vector by the
1260 * broadcast of an input scalar
1261 */
1262 public abstract IntVector aShiftR(int s);
1263
1264 /**
1265 * Arithmetically right shifts (or signed right shifts) this vector by the
1266 * broadcast of an input scalar, selecting lane elements controlled by a
1267 * mask.
1268 * <p>
1269 * This is a vector binary operation where the primitive arithmetic right
1270 * shift operation ({@code >>}) is applied to lane elements.
1271 *
1272 * @param s the input scalar; the number of the bits to right shift
1273 * @param m the mask controlling lane selection
1274 * @return the result of arithmetically right shifting this vector by the
1275 * broadcast of an input scalar
1276 */
1277 public abstract IntVector aShiftR(int s, Mask<Integer> m);
1278
1279 /**
1280 * Arithmetically right shifts (or signed right shifts) this vector by an
1281 * input vector.
1282 * <p>
1283 * This is a vector binary operation where the primitive arithmetic right
1284 * shift operation ({@code >>}) is applied to lane elements.
1285 *
1286 * @param v the input vector
1287 * @return the result of arithmetically right shifting this vector by the
1288 * input vector
1289 */
1290 public abstract IntVector aShiftR(Vector<Integer> v);
1291
1292 /**
1293 * Arithmetically right shifts (or signed right shifts) this vector by an
1294 * input vector, selecting lane elements controlled by a mask.
1295 * <p>
1296 * This is a vector binary operation where the primitive arithmetic right
1297 * shift operation ({@code >>}) is applied to lane elements.
1298 *
1299 * @param v the input vector
1300 * @param m the mask controlling lane selection
1301 * @return the result of arithmetically right shifting this vector by the
1302 * input vector
1303 */
1304 public IntVector aShiftR(Vector<Integer> v, Mask<Integer> m) {
1305 return bOp(v, m, (i, a, b) -> (int) (a >> b));
1306 }
1307
1308 /**
1309 * Rotates left this vector by the broadcast of an input scalar.
1310 * <p>
1311 * This is a vector binary operation where the operation
1312 * {@link Integer#rotateLeft} is applied to lane elements and where
1313 * lane elements of this vector apply to the first argument, and lane
1314 * elements of the broadcast vector apply to the second argument (the
1315 * rotation distance).
1316 *
1317 * @param s the input scalar; the number of the bits to rotate left
1318 * @return the result of rotating left this vector by the broadcast of an
1319 * input scalar
1320 */
1321 @ForceInline
1322 public final IntVector rotateL(int s) {
1323 return shiftL(s).or(shiftR(-s));
1324 }
1325
1326 /**
1327 * Rotates left this vector by the broadcast of an input scalar, selecting
1328 * lane elements controlled by a mask.
1329 * <p>
1330 * This is a vector binary operation where the operation
1331 * {@link Integer#rotateLeft} is applied to lane elements and where
1332 * lane elements of this vector apply to the first argument, and lane
1333 * elements of the broadcast vector apply to the second argument (the
1334 * rotation distance).
1335 *
1336 * @param s the input scalar; the number of the bits to rotate left
1337 * @param m the mask controlling lane selection
1338 * @return the result of rotating left this vector by the broadcast of an
1339 * input scalar
1340 */
1341 @ForceInline
1342 public final IntVector rotateL(int s, Mask<Integer> m) {
1343 return shiftL(s, m).or(shiftR(-s, m), m);
1344 }
1345
1346 /**
1347 * Rotates right this vector by the broadcast of an input scalar.
1348 * <p>
1349 * This is a vector binary operation where the operation
1350 * {@link Integer#rotateRight} is applied to lane elements and where
1351 * lane elements of this vector apply to the first argument, and lane
1352 * elements of the broadcast vector apply to the second argument (the
1353 * rotation distance).
1354 *
1355 * @param s the input scalar; the number of the bits to rotate right
1356 * @return the result of rotating right this vector by the broadcast of an
1357 * input scalar
1358 */
1359 @ForceInline
1360 public final IntVector rotateR(int s) {
1361 return shiftR(s).or(shiftL(-s));
1362 }
1363
1364 /**
1365 * Rotates right this vector by the broadcast of an input scalar, selecting
1366 * lane elements controlled by a mask.
1367 * <p>
1368 * This is a vector binary operation where the operation
1369 * {@link Integer#rotateRight} is applied to lane elements and where
1370 * lane elements of this vector apply to the first argument, and lane
1371 * elements of the broadcast vector apply to the second argument (the
1372 * rotation distance).
1373 *
1374 * @param s the input scalar; the number of the bits to rotate right
1375 * @param m the mask controlling lane selection
1376 * @return the result of rotating right this vector by the broadcast of an
1377 * input scalar
1378 */
1379 @ForceInline
1380 public final IntVector rotateR(int s, Mask<Integer> m) {
1381 return shiftR(s, m).or(shiftL(-s, m), m);
1382 }
1383
1384 @Override
1385 public abstract void intoByteArray(byte[] a, int ix);
1386
1387 @Override
1388 public abstract void intoByteArray(byte[] a, int ix, Mask<Integer> m);
1389
1390 @Override
1391 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1392
1393 @Override
1394 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Integer> m);
1395
1396
1397 // Type specific horizontal reductions
1398 /**
1399 * Adds all lane elements of this vector.
1400 * <p>
1401 * This is an associative vector reduction operation where the addition
1402 * operation ({@code +}) is applied to lane elements,
1403 * and the identity value is {@code 0}.
1404 *
1405 * @return the addition of all the lane elements of this vector
1406 */
1407 public abstract int addAll();
1408
1409 /**
1410 * Adds all lane elements of this vector, selecting lane elements
1411 * controlled by a mask.
1412 * <p>
1413 * This is an associative vector reduction operation where the addition
1414 * operation ({@code +}) is applied to lane elements,
1415 * and the identity value is {@code 0}.
1416 *
1417 * @param m the mask controlling lane selection
1418 * @return the addition of the selected lane elements of this vector
1419 */
1420 public abstract int addAll(Mask<Integer> m);
1421
1422 /**
1423 * Multiplies all lane elements of this vector.
1424 * <p>
1425 * This is an associative vector reduction operation where the
1426 * multiplication operation ({@code *}) is applied to lane elements,
1427 * and the identity value is {@code 1}.
1428 *
1429 * @return the multiplication of all the lane elements of this vector
1430 */
1431 public abstract int mulAll();
1432
1433 /**
1434 * Multiplies all lane elements of this vector, selecting lane elements
1435 * controlled by a mask.
1436 * <p>
1437 * This is an associative vector reduction operation where the
1438 * multiplication operation ({@code *}) is applied to lane elements,
1439 * and the identity value is {@code 1}.
1440 *
1441 * @param m the mask controlling lane selection
1442 * @return the multiplication of all the lane elements of this vector
1443 */
1444 public abstract int mulAll(Mask<Integer> m);
1445
1446 /**
1447 * Returns the minimum lane element of this vector.
1448 * <p>
1449 * This is an associative vector reduction operation where the operation
1450 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1451 * and the identity value is
1452 * {@link Integer#MAX_VALUE}.
1453 *
1454 * @return the minimum lane element of this vector
1455 */
1456 public abstract int minAll();
1457
1458 /**
1459 * Returns the minimum lane element of this vector, selecting lane elements
1460 * controlled by a mask.
1461 * <p>
1462 * This is an associative vector reduction operation where the operation
1463 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1464 * and the identity value is
1465 * {@link Integer#MAX_VALUE}.
1466 *
1467 * @param m the mask controlling lane selection
1468 * @return the minimum lane element of this vector
1469 */
1470 public abstract int minAll(Mask<Integer> m);
1471
1472 /**
1473 * Returns the maximum lane element of this vector.
1474 * <p>
1475 * This is an associative vector reduction operation where the operation
1476 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1477 * and the identity value is
1478 * {@link Integer#MIN_VALUE}.
1479 *
1480 * @return the maximum lane element of this vector
1481 */
1482 public abstract int maxAll();
1483
1484 /**
1485 * Returns the maximum lane element of this vector, selecting lane elements
1486 * controlled by a mask.
1487 * <p>
1488 * This is an associative vector reduction operation where the operation
1489 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1490 * and the identity value is
1491 * {@link Integer#MIN_VALUE}.
1492 *
1493 * @param m the mask controlling lane selection
1494 * @return the maximum lane element of this vector
1495 */
1496 public abstract int maxAll(Mask<Integer> m);
1497
1498 /**
1499 * Logically ORs all lane elements of this vector.
1500 * <p>
1501 * This is an associative vector reduction operation where the logical OR
1502 * operation ({@code |}) is applied to lane elements,
1503 * and the identity value is {@code 0}.
1504 *
1505 * @return the logical OR all the lane elements of this vector
1506 */
1507 public abstract int orAll();
1508
1509 /**
1510 * Logically ORs all lane elements of this vector, selecting lane elements
1511 * controlled by a mask.
1512 * <p>
1513 * This is an associative vector reduction operation where the logical OR
1514 * operation ({@code |}) is applied to lane elements,
1515 * and the identity value is {@code 0}.
1516 *
1517 * @param m the mask controlling lane selection
1518 * @return the logical OR all the lane elements of this vector
1519 */
1520 public abstract int orAll(Mask<Integer> m);
1521
1522 /**
1523 * Logically ANDs all lane elements of this vector.
1524 * <p>
1525 * This is an associative vector reduction operation where the logical AND
1526 * operation ({@code |}) is applied to lane elements,
1527 * and the identity value is {@code -1}.
1528 *
1529 * @return the logical AND all the lane elements of this vector
1530 */
1531 public abstract int andAll();
1532
1533 /**
1534 * Logically ANDs all lane elements of this vector, selecting lane elements
1535 * controlled by a mask.
1536 * <p>
1537 * This is an associative vector reduction operation where the logical AND
1538 * operation ({@code |}) is applied to lane elements,
1539 * and the identity value is {@code -1}.
1540 *
1541 * @param m the mask controlling lane selection
1542 * @return the logical AND all the lane elements of this vector
1543 */
1544 public abstract int andAll(Mask<Integer> m);
1545
1546 /**
1547 * Logically XORs all lane elements of this vector.
1548 * <p>
1549 * This is an associative vector reduction operation where the logical XOR
1550 * operation ({@code ^}) is applied to lane elements,
1551 * and the identity value is {@code 0}.
1552 *
1553 * @return the logical XOR all the lane elements of this vector
1554 */
1555 public abstract int xorAll();
1556
1557 /**
1558 * Logically XORs all lane elements of this vector, selecting lane elements
1559 * controlled by a mask.
1560 * <p>
1561 * This is an associative vector reduction operation where the logical XOR
1562 * operation ({@code ^}) is applied to lane elements,
1563 * and the identity value is {@code 0}.
1564 *
1565 * @param m the mask controlling lane selection
1566 * @return the logical XOR all the lane elements of this vector
1567 */
1568 public abstract int xorAll(Mask<Integer> m);
1569
1570 // Type specific accessors
1571
1572 /**
1573 * Gets the lane element at lane index {@code i}
1574 *
1575 * @param i the lane index
1576 * @return the lane element at lane index {@code i}
1577 * @throws IllegalArgumentException if the index is is out of range
1578 * ({@code < 0 || >= length()})
1579 */
1580 public abstract int get(int i);
1581
1582 /**
1583 * Replaces the lane element of this vector at lane index {@code i} with
1584 * value {@code e}.
1585 * <p>
1586 * This is a cross-lane operation and behaves as if it returns the result
1587 * of blending this vector with an input vector that is the result of
1588 * broadcasting {@code e} and a mask that has only one lane set at lane
1630 * @param i the offset into the array
1631 * @throws IndexOutOfBoundsException if {@code i < 0}, or
1632 * {@code i > a.length - this.length()}
1633 */
1634 public abstract void intoArray(int[] a, int i);
1635
1636 /**
1637 * Stores this vector into an array starting at offset and using a mask.
1638 * <p>
1639 * For each vector lane, where {@code N} is the vector lane index,
1640 * if the mask lane at index {@code N} is set then the lane element at
1641 * index {@code N} is stored into the array index {@code i + N}.
1642 *
1643 * @param a the array
1644 * @param i the offset into the array
1645 * @param m the mask
1646 * @throws IndexOutOfBoundsException if {@code i < 0}, or
1647 * for any vector lane index {@code N} where the mask at lane {@code N}
1648 * is set {@code i >= a.length - N}
1649 */
1650 public abstract void intoArray(int[] a, int i, Mask<Integer> m);
1651
1652 /**
1653 * Stores this vector into an array using indexes obtained from an index
1654 * map.
1655 * <p>
1656 * For each vector lane, where {@code N} is the vector lane index, the
1657 * lane element at index {@code N} is stored into the array at index
1658 * {@code i + indexMap[j + N]}.
1659 *
1660 * @param a the array
1661 * @param i the offset into the array, may be negative if relative
1662 * indexes in the index map compensate to produce a value within the
1663 * array bounds
1664 * @param indexMap the index map
1665 * @param j the offset into the index map
1666 * @throws IndexOutOfBoundsException if {@code j < 0}, or
1667 * {@code j > indexMap.length - this.length()},
1668 * or for any vector lane index {@code N} the result of
1669 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1670 */
1675 * map and using a mask.
1676 * <p>
1677 * For each vector lane, where {@code N} is the vector lane index,
1678 * if the mask lane at index {@code N} is set then the lane element at
1679 * index {@code N} is stored into the array at index
1680 * {@code i + indexMap[j + N]}.
1681 *
1682 * @param a the array
1683 * @param i the offset into the array, may be negative if relative
1684 * indexes in the index map compensate to produce a value within the
1685 * array bounds
1686 * @param m the mask
1687 * @param indexMap the index map
1688 * @param j the offset into the index map
1689 * @throws IndexOutOfBoundsException if {@code j < 0}, or
1690 * {@code j > indexMap.length - this.length()},
1691 * or for any vector lane index {@code N} where the mask at lane
1692 * {@code N} is set the result of {@code i + indexMap[j + N]} is
1693 * {@code < 0} or {@code >= a.length}
1694 */
1695 public abstract void intoArray(int[] a, int i, Mask<Integer> m, int[] indexMap, int j);
1696 // Species
1697
1698 @Override
1699 public abstract Species<Integer> species();
1700
1701 /**
1702 * Class representing {@link IntVector}'s of the same {@link Vector.Shape Shape}.
1703 */
1704 static final class IntSpecies extends Vector.AbstractSpecies<Integer> {
1705 final Function<int[], IntVector> vectorFactory;
1706 final Function<boolean[], Vector.Mask<Integer>> maskFactory;
1707
1708 private IntSpecies(Vector.Shape shape,
1709 Class<?> boxType,
1710 Class<?> maskType,
1711 Function<int[], IntVector> vectorFactory,
1712 Function<boolean[], Vector.Mask<Integer>> maskFactory) {
1713 super(shape, int.class, Integer.SIZE, boxType, maskType);
1714 this.vectorFactory = vectorFactory;
1715 this.maskFactory = maskFactory;
1716 }
1717
1718 interface FOp {
1719 int apply(int i);
1720 }
1721
1722 interface FOpm {
1723 boolean apply(int i);
1724 }
1725
1726 IntVector op(FOp f) {
1727 int[] res = new int[length()];
1728 for (int i = 0; i < length(); i++) {
1729 res[i] = f.apply(i);
1730 }
1731 return vectorFactory.apply(res);
1732 }
1733
1734 IntVector op(Vector.Mask<Integer> o, FOp f) {
1735 int[] res = new int[length()];
1736 boolean[] mbits = ((AbstractMask<Integer>)o).getBits();
1737 for (int i = 0; i < length(); i++) {
1738 if (mbits[i]) {
1739 res[i] = f.apply(i);
1740 }
1741 }
1742 return vectorFactory.apply(res);
1743 }
1744
1745 Vector.Mask<Integer> opm(IntVector.IntSpecies.FOpm f) {
1746 boolean[] res = new boolean[length()];
1747 for (int i = 0; i < length(); i++) {
1748 res[i] = (boolean)f.apply(i);
1749 }
1750 return maskFactory.apply(res);
1751 }
1752 }
1753
1754 /**
1755 * Finds the preferred species for an element type of {@code int}.
1756 * <p>
1757 * A preferred species is a species chosen by the platform that has a
1758 * shape of maximal bit size. A preferred species for different element
1759 * types will have the same shape, and therefore vectors, masks, and
1760 * shuffles created from such species will be shape compatible.
1761 *
1762 * @return the preferred species for an element type of {@code int}
1763 */
1764 private static IntSpecies preferredSpecies() {
1765 return (IntSpecies) Species.ofPreferred(int.class);
1766 }
1767
1768 /**
1769 * Finds a species for an element type of {@code int} and shape.
1770 *
1771 * @param s the shape
1772 * @return a species for an element type of {@code int} and shape
1773 * @throws IllegalArgumentException if no such species exists for the shape
1774 */
1775 static IntSpecies species(Vector.Shape s) {
1776 Objects.requireNonNull(s);
1777 switch (s) {
1778 case S_64_BIT: return (IntSpecies) SPECIES_64;
1779 case S_128_BIT: return (IntSpecies) SPECIES_128;
1780 case S_256_BIT: return (IntSpecies) SPECIES_256;
1781 case S_512_BIT: return (IntSpecies) SPECIES_512;
1782 case S_Max_BIT: return (IntSpecies) SPECIES_MAX;
1783 default: throw new IllegalArgumentException("Bad shape: " + s);
1784 }
1785 }
1786
1787 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_64_BIT Shape.S_64_BIT}. */
1788 public static final Species<Integer> SPECIES_64 = new IntSpecies(Shape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class,
1789 Int64Vector::new, Int64Vector.Int64Mask::new);
1790
1791 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_128_BIT Shape.S_128_BIT}. */
1792 public static final Species<Integer> SPECIES_128 = new IntSpecies(Shape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class,
1793 Int128Vector::new, Int128Vector.Int128Mask::new);
1794
1795 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_256_BIT Shape.S_256_BIT}. */
1796 public static final Species<Integer> SPECIES_256 = new IntSpecies(Shape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class,
1797 Int256Vector::new, Int256Vector.Int256Mask::new);
1798
1799 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_512_BIT Shape.S_512_BIT}. */
1800 public static final Species<Integer> SPECIES_512 = new IntSpecies(Shape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class,
1801 Int512Vector::new, Int512Vector.Int512Mask::new);
1802
1803 /** Species representing {@link IntVector}s of {@link Vector.Shape#S_Max_BIT Shape.S_Max_BIT}. */
1804 public static final Species<Integer> SPECIES_MAX = new IntSpecies(Shape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class,
1805 IntMaxVector::new, IntMaxVector.IntMaxMask::new);
1806
1807 /**
1808 * Preferred species for {@link IntVector}s.
1809 * A preferred species is a species of maximal bit size for the platform.
1810 */
1811 public static final Species<Integer> SPECIES_PREFERRED = (Species<Integer>) preferredSpecies();
1812 }
|
39
40 /**
41 * A specialized {@link Vector} representing an ordered immutable sequence of
42 * {@code int} values.
43 */
44 @SuppressWarnings("cast")
45 public abstract class IntVector extends Vector<Integer> {
46
47 IntVector() {}
48
49 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_INT_INDEX_SCALE);
50
51 // Unary operator
52
53 interface FUnOp {
54 int apply(int i, int a);
55 }
56
57 abstract IntVector uOp(FUnOp f);
58
59 abstract IntVector uOp(VectorMask<Integer> m, FUnOp f);
60
61 // Binary operator
62
63 interface FBinOp {
64 int apply(int i, int a, int b);
65 }
66
67 abstract IntVector bOp(Vector<Integer> v, FBinOp f);
68
69 abstract IntVector bOp(Vector<Integer> v, VectorMask<Integer> m, FBinOp f);
70
71 // Trinary operator
72
73 interface FTriOp {
74 int apply(int i, int a, int b, int c);
75 }
76
77 abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, FTriOp f);
78
79 abstract IntVector tOp(Vector<Integer> v1, Vector<Integer> v2, VectorMask<Integer> m, FTriOp f);
80
81 // Reduction operator
82
83 abstract int rOp(int v, FBinOp f);
84
85 // Binary test
86
87 interface FBinTest {
88 boolean apply(int i, int a, int b);
89 }
90
91 abstract VectorMask<Integer> bTest(Vector<Integer> v, FBinTest f);
92
93 // Foreach
94
95 interface FUnCon {
96 void apply(int i, int a);
97 }
98
99 abstract void forEach(FUnCon f);
100
101 abstract void forEach(VectorMask<Integer> m, FUnCon f);
102
103 // Static factories
104
105 /**
106 * Returns a vector where all lane elements are set to the default
107 * primitive value.
108 *
109 * @param species species of desired vector
110 * @return a zero vector of given species
111 */
112 @ForceInline
113 @SuppressWarnings("unchecked")
114 public static IntVector zero(VectorSpecies<Integer> species) {
115 return VectorIntrinsics.broadcastCoerced((Class<IntVector>) species.boxType(), int.class, species.length(),
116 0, species,
117 ((bits, s) -> ((IntSpecies)s).op(i -> (int)bits)));
118 }
119
120 /**
121 * Loads a vector from a byte array starting at an offset.
122 * <p>
123 * Bytes are composed into primitive lane elements according to the
124 * native byte order of the underlying platform
125 * <p>
126 * This method behaves as if it returns the result of calling the
127 * byte buffer, offset, and mask accepting
128 * {@link #fromByteBuffer(VectorSpecies<Integer>, ByteBuffer, int, VectorMask) method} as follows:
129 * <pre>{@code
130 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
131 * }</pre>
132 *
133 * @param species species of desired vector
134 * @param a the byte array
135 * @param ix the offset into the array
136 * @return a vector loaded from a byte array
137 * @throws IndexOutOfBoundsException if {@code i < 0} or
138 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
139 */
140 @ForceInline
141 @SuppressWarnings("unchecked")
142 public static IntVector fromByteArray(VectorSpecies<Integer> species, byte[] a, int ix) {
143 Objects.requireNonNull(a);
144 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
145 return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
146 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
147 a, ix, species,
148 (c, idx, s) -> {
149 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
150 IntBuffer tb = bbc.asIntBuffer();
151 return ((IntSpecies)s).op(i -> tb.get());
152 });
153 }
154
155 /**
156 * Loads a vector from a byte array starting at an offset and using a
157 * mask.
158 * <p>
159 * Bytes are composed into primitive lane elements according to the
160 * native byte order of the underlying platform.
161 * <p>
162 * This method behaves as if it returns the result of calling the
163 * byte buffer, offset, and mask accepting
164 * {@link #fromByteBuffer(VectorSpecies<Integer>, ByteBuffer, int, VectorMask) method} as follows:
165 * <pre>{@code
166 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
167 * }</pre>
168 *
169 * @param species species of desired vector
170 * @param a the byte array
171 * @param ix the offset into the array
172 * @param m the mask
173 * @return a vector loaded from a byte array
174 * @throws IndexOutOfBoundsException if {@code i < 0} or
175 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
176 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
177 * or {@code > a.length},
178 * for any vector lane index {@code N} where the mask at lane {@code N}
179 * is set
180 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
181 */
182 @ForceInline
183 public static IntVector fromByteArray(VectorSpecies<Integer> species, byte[] a, int ix, VectorMask<Integer> m) {
184 return zero(species).blend(fromByteArray(species, a, ix), m);
185 }
186
187 /**
188 * Loads a vector from an array starting at offset.
189 * <p>
190 * For each vector lane, where {@code N} is the vector lane index, the
191 * array element at index {@code i + N} is placed into the
192 * resulting vector at lane index {@code N}.
193 *
194 * @param species species of desired vector
195 * @param a the array
196 * @param i the offset into the array
197 * @return the vector loaded from an array
198 * @throws IndexOutOfBoundsException if {@code i < 0}, or
199 * {@code i > a.length - this.length()}
200 */
201 @ForceInline
202 @SuppressWarnings("unchecked")
203 public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i){
204 Objects.requireNonNull(a);
205 i = VectorIntrinsics.checkIndex(i, a.length, species.length());
206 return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
207 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_INT_BASE_OFFSET,
208 a, i, species,
209 (c, idx, s) -> ((IntSpecies)s).op(n -> c[idx + n]));
210 }
211
212
213 /**
214 * Loads a vector from an array starting at offset and using a mask.
215 * <p>
216 * For each vector lane, where {@code N} is the vector lane index,
217 * if the mask lane at index {@code N} is set then the array element at
218 * index {@code i + N} is placed into the resulting vector at lane index
219 * {@code N}, otherwise the default element value is placed into the
220 * resulting vector at lane index {@code N}.
221 *
222 * @param species species of desired vector
223 * @param a the array
224 * @param i the offset into the array
225 * @param m the mask
226 * @return the vector loaded from an array
227 * @throws IndexOutOfBoundsException if {@code i < 0}, or
228 * for any vector lane index {@code N} where the mask at lane {@code N}
229 * is set {@code i > a.length - N}
230 */
231 @ForceInline
232 public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i, VectorMask<Integer> m) {
233 return zero(species).blend(fromArray(species, a, i), m);
234 }
235
236 /**
237 * Loads a vector from an array using indexes obtained from an index
238 * map.
239 * <p>
240 * For each vector lane, where {@code N} is the vector lane index, the
241 * array element at index {@code i + indexMap[j + N]} is placed into the
242 * resulting vector at lane index {@code N}.
243 *
244 * @param species species of desired vector
245 * @param a the array
246 * @param i the offset into the array, may be negative if relative
247 * indexes in the index map compensate to produce a value within the
248 * array bounds
249 * @param indexMap the index map
250 * @param j the offset into the index map
251 * @return the vector loaded from an array
252 * @throws IndexOutOfBoundsException if {@code j < 0}, or
253 * {@code j > indexMap.length - this.length()},
254 * or for any vector lane index {@code N} the result of
255 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
256 */
257 @ForceInline
258 @SuppressWarnings("unchecked")
259 public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i, int[] indexMap, int j) {
260 Objects.requireNonNull(a);
261 Objects.requireNonNull(indexMap);
262
263
264 // Index vector: vix[0:n] = k -> i + indexMap[j + k]
265 IntVector vix = IntVector.fromArray(IntVector.species(species.indexShape()), indexMap, j).add(i);
266
267 vix = VectorIntrinsics.checkIndex(vix, a.length);
268
269 return VectorIntrinsics.loadWithMap((Class<IntVector>) species.boxType(), int.class, species.length(),
270 IntVector.species(species.indexShape()).boxType(), a, Unsafe.ARRAY_INT_BASE_OFFSET, vix,
271 a, i, indexMap, j, species,
272 (int[] c, int idx, int[] iMap, int idy, VectorSpecies<Integer> s) ->
273 ((IntSpecies)s).op(n -> c[idx + iMap[idy+n]]));
274 }
275
276 /**
277 * Loads a vector from an array using indexes obtained from an index
278 * map and using a mask.
279 * <p>
280 * For each vector lane, where {@code N} is the vector lane index,
281 * if the mask lane at index {@code N} is set then the array element at
282 * index {@code i + indexMap[j + N]} is placed into the resulting vector
283 * at lane index {@code N}.
284 *
285 * @param species species of desired vector
286 * @param a the array
287 * @param i the offset into the array, may be negative if relative
288 * indexes in the index map compensate to produce a value within the
289 * array bounds
290 * @param m the mask
291 * @param indexMap the index map
292 * @param j the offset into the index map
293 * @return the vector loaded from an array
294 * @throws IndexOutOfBoundsException if {@code j < 0}, or
295 * {@code j > indexMap.length - this.length()},
296 * or for any vector lane index {@code N} where the mask at lane
297 * {@code N} is set the result of {@code i + indexMap[j + N]} is
298 * {@code < 0} or {@code >= a.length}
299 */
300 @ForceInline
301 @SuppressWarnings("unchecked")
302 public static IntVector fromArray(VectorSpecies<Integer> species, int[] a, int i, VectorMask<Integer> m, int[] indexMap, int j) {
303 // @@@ This can result in out of bounds errors for unset mask lanes
304 return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
305 }
306
307
308 /**
309 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
310 * offset into the byte buffer.
311 * <p>
312 * Bytes are composed into primitive lane elements according to the
313 * native byte order of the underlying platform.
314 * <p>
315 * This method behaves as if it returns the result of calling the
316 * byte buffer, offset, and mask accepting
317 * {@link #fromByteBuffer(VectorSpecies<Integer>, ByteBuffer, int, VectorMask)} method} as follows:
318 * <pre>{@code
319 * return this.fromByteBuffer(b, i, this.maskAllTrue())
320 * }</pre>
321 *
322 * @param species species of desired vector
323 * @param bb the byte buffer
324 * @param ix the offset into the byte buffer
325 * @return a vector loaded from a byte buffer
326 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
327 * or {@code > b.limit()},
328 * or if there are fewer than
329 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
330 * remaining in the byte buffer from the given offset
331 */
332 @ForceInline
333 @SuppressWarnings("unchecked")
334 public static IntVector fromByteBuffer(VectorSpecies<Integer> species, ByteBuffer bb, int ix) {
335 if (bb.order() != ByteOrder.nativeOrder()) {
336 throw new IllegalArgumentException();
337 }
338 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
339 return VectorIntrinsics.load((Class<IntVector>) species.boxType(), int.class, species.length(),
340 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
341 bb, ix, species,
342 (c, idx, s) -> {
343 ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
344 IntBuffer tb = bbc.asIntBuffer();
345 return ((IntSpecies)s).op(i -> tb.get());
346 });
347 }
348
349 /**
350 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
351 * offset into the byte buffer and using a mask.
352 * <p>
353 * This method behaves as if the byte buffer is viewed as a primitive
354 * {@link java.nio.Buffer buffer} for the primitive element type,
366 * e[] es = new e[this.length()];
367 * for (int n = 0; n < t.length; n++) {
368 * if (m.isSet(n))
369 * es[n] = eb.get(n);
370 * }
371 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
372 * }</pre>
373 *
374 * @param species species of desired vector
375 * @param bb the byte buffer
376 * @param ix the offset into the byte buffer
377 * @param m the mask
378 * @return a vector loaded from a byte buffer
379 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
380 * or {@code > b.limit()},
381 * for any vector lane index {@code N} where the mask at lane {@code N}
382 * is set
383 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
384 */
385 @ForceInline
386 public static IntVector fromByteBuffer(VectorSpecies<Integer> species, ByteBuffer bb, int ix, VectorMask<Integer> m) {
387 return zero(species).blend(fromByteBuffer(species, bb, ix), m);
388 }
389
390 /**
391 * Returns a vector where all lane elements are set to the primitive
392 * value {@code e}.
393 *
394 * @param s species of the desired vector
395 * @param e the value
396 * @return a vector of vector where all lane elements are set to
397 * the primitive value {@code e}
398 */
399 @ForceInline
400 @SuppressWarnings("unchecked")
401 public static IntVector broadcast(VectorSpecies<Integer> s, int e) {
402 return VectorIntrinsics.broadcastCoerced(
403 (Class<IntVector>) s.boxType(), int.class, s.length(),
404 e, s,
405 ((bits, sp) -> ((IntSpecies)sp).op(i -> (int)bits)));
406 }
407
408 /**
409 * Returns a vector where each lane element is set to a given
410 * primitive value.
411 * <p>
412 * For each vector lane, where {@code N} is the vector lane index, the
413 * the primitive value at index {@code N} is placed into the resulting
414 * vector at lane index {@code N}.
415 *
416 * @param s species of the desired vector
417 * @param es the given primitive values
418 * @return a vector where each lane element is set to a given primitive
419 * value
420 * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
421 */
422 @ForceInline
423 @SuppressWarnings("unchecked")
424 public static IntVector scalars(VectorSpecies<Integer> s, int... es) {
425 Objects.requireNonNull(es);
426 int ix = VectorIntrinsics.checkIndex(0, es.length, s.length());
427 return VectorIntrinsics.load((Class<IntVector>) s.boxType(), int.class, s.length(),
428 es, Unsafe.ARRAY_INT_BASE_OFFSET,
429 es, ix, s,
430 (c, idx, sp) -> ((IntSpecies)sp).op(n -> c[idx + n]));
431 }
432
433 /**
434 * Returns a vector where the first lane element is set to the primtive
435 * value {@code e}, all other lane elements are set to the default
436 * value.
437 *
438 * @param s species of the desired vector
439 * @param e the value
440 * @return a vector where the first lane element is set to the primitive
441 * value {@code e}
442 */
443 @ForceInline
444 public static final IntVector single(VectorSpecies<Integer> s, int e) {
445 return zero(s).with(0, e);
446 }
447
448 /**
449 * Returns a vector where each lane element is set to a randomly
450 * generated primitive value.
451 *
452 * The semantics are equivalent to calling
453 * {@link ThreadLocalRandom#nextInt()}
454 *
455 * @param s species of the desired vector
456 * @return a vector where each lane elements is set to a randomly
457 * generated primitive value
458 */
459 public static IntVector random(VectorSpecies<Integer> s) {
460 ThreadLocalRandom r = ThreadLocalRandom.current();
461 return ((IntSpecies)s).op(i -> r.nextInt());
462 }
463
464 // Ops
465
466 @Override
467 public abstract IntVector add(Vector<Integer> v);
468
469 /**
470 * Adds this vector to the broadcast of an input scalar.
471 * <p>
472 * This is a vector binary operation where the primitive addition operation
473 * ({@code +}) is applied to lane elements.
474 *
475 * @param s the input scalar
476 * @return the result of adding this vector to the broadcast of an input
477 * scalar
478 */
479 public abstract IntVector add(int s);
480
481 @Override
482 public abstract IntVector add(Vector<Integer> v, VectorMask<Integer> m);
483
484 /**
485 * Adds this vector to broadcast of an input scalar,
486 * selecting lane elements controlled by a mask.
487 * <p>
488 * This is a vector binary operation where the primitive addition operation
489 * ({@code +}) is applied to lane elements.
490 *
491 * @param s the input scalar
492 * @param m the mask controlling lane selection
493 * @return the result of adding this vector to the broadcast of an input
494 * scalar
495 */
496 public abstract IntVector add(int s, VectorMask<Integer> m);
497
498 @Override
499 public abstract IntVector sub(Vector<Integer> v);
500
501 /**
502 * Subtracts the broadcast of an input scalar from this vector.
503 * <p>
504 * This is a vector binary operation where the primitive subtraction
505 * operation ({@code -}) is applied to lane elements.
506 *
507 * @param s the input scalar
508 * @return the result of subtracting the broadcast of an input
509 * scalar from this vector
510 */
511 public abstract IntVector sub(int s);
512
513 @Override
514 public abstract IntVector sub(Vector<Integer> v, VectorMask<Integer> m);
515
516 /**
517 * Subtracts the broadcast of an input scalar from this vector, selecting
518 * lane elements controlled by a mask.
519 * <p>
520 * This is a vector binary operation where the primitive subtraction
521 * operation ({@code -}) is applied to lane elements.
522 *
523 * @param s the input scalar
524 * @param m the mask controlling lane selection
525 * @return the result of subtracting the broadcast of an input
526 * scalar from this vector
527 */
528 public abstract IntVector sub(int s, VectorMask<Integer> m);
529
530 @Override
531 public abstract IntVector mul(Vector<Integer> v);
532
533 /**
534 * Multiplies this vector with the broadcast of an input scalar.
535 * <p>
536 * This is a vector binary operation where the primitive multiplication
537 * operation ({@code *}) is applied to lane elements.
538 *
539 * @param s the input scalar
540 * @return the result of multiplying this vector with the broadcast of an
541 * input scalar
542 */
543 public abstract IntVector mul(int s);
544
545 @Override
546 public abstract IntVector mul(Vector<Integer> v, VectorMask<Integer> m);
547
548 /**
549 * Multiplies this vector with the broadcast of an input scalar, selecting
550 * lane elements controlled by a mask.
551 * <p>
552 * This is a vector binary operation where the primitive multiplication
553 * operation ({@code *}) is applied to lane elements.
554 *
555 * @param s the input scalar
556 * @param m the mask controlling lane selection
557 * @return the result of multiplying this vector with the broadcast of an
558 * input scalar
559 */
560 public abstract IntVector mul(int s, VectorMask<Integer> m);
561
562 @Override
563 public abstract IntVector neg();
564
565 @Override
566 public abstract IntVector neg(VectorMask<Integer> m);
567
568 @Override
569 public abstract IntVector abs();
570
571 @Override
572 public abstract IntVector abs(VectorMask<Integer> m);
573
574 @Override
575 public abstract IntVector min(Vector<Integer> v);
576
577 @Override
578 public abstract IntVector min(Vector<Integer> v, VectorMask<Integer> m);
579
580 /**
581 * Returns the minimum of this vector and the broadcast of an input scalar.
582 * <p>
583 * This is a vector binary operation where the operation
584 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
585 *
586 * @param s the input scalar
587 * @return the minimum of this vector and the broadcast of an input scalar
588 */
589 public abstract IntVector min(int s);
590
591 @Override
592 public abstract IntVector max(Vector<Integer> v);
593
594 @Override
595 public abstract IntVector max(Vector<Integer> v, VectorMask<Integer> m);
596
597 /**
598 * Returns the maximum of this vector and the broadcast of an input scalar.
599 * <p>
600 * This is a vector binary operation where the operation
601 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
602 *
603 * @param s the input scalar
604 * @return the maximum of this vector and the broadcast of an input scalar
605 */
606 public abstract IntVector max(int s);
607
608 @Override
609 public abstract VectorMask<Integer> equal(Vector<Integer> v);
610
611 /**
612 * Tests if this vector is equal to the broadcast of an input scalar.
613 * <p>
614 * This is a vector binary test operation where the primitive equals
615 * operation ({@code ==}) is applied to lane elements.
616 *
617 * @param s the input scalar
618 * @return the result mask of testing if this vector is equal to the
619 * broadcast of an input scalar
620 */
621 public abstract VectorMask<Integer> equal(int s);
622
623 @Override
624 public abstract VectorMask<Integer> notEqual(Vector<Integer> v);
625
626 /**
627 * Tests if this vector is not equal to the broadcast of an input scalar.
628 * <p>
629 * This is a vector binary test operation where the primitive not equals
630 * operation ({@code !=}) is applied to lane elements.
631 *
632 * @param s the input scalar
633 * @return the result mask of testing if this vector is not equal to the
634 * broadcast of an input scalar
635 */
636 public abstract VectorMask<Integer> notEqual(int s);
637
638 @Override
639 public abstract VectorMask<Integer> lessThan(Vector<Integer> v);
640
641 /**
642 * Tests if this vector is less than the broadcast of an input scalar.
643 * <p>
644 * This is a vector binary test operation where the primitive less than
645 * operation ({@code <}) is applied to lane elements.
646 *
647 * @param s the input scalar
648 * @return the mask result of testing if this vector is less than the
649 * broadcast of an input scalar
650 */
651 public abstract VectorMask<Integer> lessThan(int s);
652
653 @Override
654 public abstract VectorMask<Integer> lessThanEq(Vector<Integer> v);
655
656 /**
657 * Tests if this vector is less or equal to the broadcast of an input scalar.
658 * <p>
659 * This is a vector binary test operation where the primitive less than
660 * or equal to operation ({@code <=}) is applied to lane elements.
661 *
662 * @param s the input scalar
663 * @return the mask result of testing if this vector is less than or equal
664 * to the broadcast of an input scalar
665 */
666 public abstract VectorMask<Integer> lessThanEq(int s);
667
668 @Override
669 public abstract VectorMask<Integer> greaterThan(Vector<Integer> v);
670
671 /**
672 * Tests if this vector is greater than the broadcast of an input scalar.
673 * <p>
674 * This is a vector binary test operation where the primitive greater than
675 * operation ({@code >}) is applied to lane elements.
676 *
677 * @param s the input scalar
678 * @return the mask result of testing if this vector is greater than the
679 * broadcast of an input scalar
680 */
681 public abstract VectorMask<Integer> greaterThan(int s);
682
683 @Override
684 public abstract VectorMask<Integer> greaterThanEq(Vector<Integer> v);
685
686 /**
687 * Tests if this vector is greater than or equal to the broadcast of an
688 * input scalar.
689 * <p>
690 * This is a vector binary test operation where the primitive greater than
691 * or equal to operation ({@code >=}) is applied to lane elements.
692 *
693 * @param s the input scalar
694 * @return the mask result of testing if this vector is greater than or
695 * equal to the broadcast of an input scalar
696 */
697 public abstract VectorMask<Integer> greaterThanEq(int s);
698
699 @Override
700 public abstract IntVector blend(Vector<Integer> v, VectorMask<Integer> m);
701
702 /**
703 * Blends the lane elements of this vector with those of the broadcast of an
704 * input scalar, selecting lanes controlled by a mask.
705 * <p>
706 * For each lane of the mask, at lane index {@code N}, if the mask lane
707 * is set then the lane element at {@code N} from the input vector is
708 * selected and placed into the resulting vector at {@code N},
709 * otherwise the the lane element at {@code N} from this input vector is
710 * selected and placed into the resulting vector at {@code N}.
711 *
712 * @param s the input scalar
713 * @param m the mask controlling lane selection
714 * @return the result of blending the lane elements of this vector with
715 * those of the broadcast of an input scalar
716 */
717 public abstract IntVector blend(int s, VectorMask<Integer> m);
718
719 @Override
720 public abstract IntVector rearrange(Vector<Integer> v,
721 VectorShuffle<Integer> s, VectorMask<Integer> m);
722
723 @Override
724 public abstract IntVector rearrange(VectorShuffle<Integer> m);
725
726 @Override
727 public abstract IntVector reshape(VectorSpecies<Integer> s);
728
729 @Override
730 public abstract IntVector rotateEL(int i);
731
732 @Override
733 public abstract IntVector rotateER(int i);
734
735 @Override
736 public abstract IntVector shiftEL(int i);
737
738 @Override
739 public abstract IntVector shiftER(int i);
740
741
742
743 /**
744 * Bitwise ANDs this vector with an input vector.
745 * <p>
746 * This is a vector binary operation where the primitive bitwise AND
747 * operation ({@code &}) is applied to lane elements.
757 * This is a vector binary operation where the primitive bitwise AND
758 * operation ({@code &}) is applied to lane elements.
759 *
760 * @param s the input scalar
761 * @return the bitwise AND of this vector with the broadcast of an input
762 * scalar
763 */
764 public abstract IntVector and(int s);
765
766 /**
767 * Bitwise ANDs this vector with an input vector, selecting lane elements
768 * controlled by a mask.
769 * <p>
770 * This is a vector binary operation where the primitive bitwise AND
771 * operation ({@code &}) is applied to lane elements.
772 *
773 * @param v the input vector
774 * @param m the mask controlling lane selection
775 * @return the bitwise AND of this vector with the input vector
776 */
777 public abstract IntVector and(Vector<Integer> v, VectorMask<Integer> m);
778
779 /**
780 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
781 * lane elements controlled by a mask.
782 * <p>
783 * This is a vector binary operation where the primitive bitwise AND
784 * operation ({@code &}) is applied to lane elements.
785 *
786 * @param s the input scalar
787 * @param m the mask controlling lane selection
788 * @return the bitwise AND of this vector with the broadcast of an input
789 * scalar
790 */
791 public abstract IntVector and(int s, VectorMask<Integer> m);
792
793 /**
794 * Bitwise ORs this vector with an input vector.
795 * <p>
796 * This is a vector binary operation where the primitive bitwise OR
797 * operation ({@code |}) is applied to lane elements.
798 *
799 * @param v the input vector
800 * @return the bitwise OR of this vector with the input vector
801 */
802 public abstract IntVector or(Vector<Integer> v);
803
804 /**
805 * Bitwise ORs this vector with the broadcast of an input scalar.
806 * <p>
807 * This is a vector binary operation where the primitive bitwise OR
808 * operation ({@code |}) is applied to lane elements.
809 *
810 * @param s the input scalar
811 * @return the bitwise OR of this vector with the broadcast of an input
812 * scalar
813 */
814 public abstract IntVector or(int s);
815
816 /**
817 * Bitwise ORs this vector with an input vector, selecting lane elements
818 * controlled by a mask.
819 * <p>
820 * This is a vector binary operation where the primitive bitwise OR
821 * operation ({@code |}) is applied to lane elements.
822 *
823 * @param v the input vector
824 * @param m the mask controlling lane selection
825 * @return the bitwise OR of this vector with the input vector
826 */
827 public abstract IntVector or(Vector<Integer> v, VectorMask<Integer> m);
828
829 /**
830 * Bitwise ORs this vector with the broadcast of an input scalar, selecting
831 * lane elements controlled by a mask.
832 * <p>
833 * This is a vector binary operation where the primitive bitwise OR
834 * operation ({@code |}) is applied to lane elements.
835 *
836 * @param s the input scalar
837 * @param m the mask controlling lane selection
838 * @return the bitwise OR of this vector with the broadcast of an input
839 * scalar
840 */
841 public abstract IntVector or(int s, VectorMask<Integer> m);
842
843 /**
844 * Bitwise XORs this vector with an input vector.
845 * <p>
846 * This is a vector binary operation where the primitive bitwise XOR
847 * operation ({@code ^}) is applied to lane elements.
848 *
849 * @param v the input vector
850 * @return the bitwise XOR of this vector with the input vector
851 */
852 public abstract IntVector xor(Vector<Integer> v);
853
854 /**
855 * Bitwise XORs this vector with the broadcast of an input scalar.
856 * <p>
857 * This is a vector binary operation where the primitive bitwise XOR
858 * operation ({@code ^}) is applied to lane elements.
859 *
860 * @param s the input scalar
861 * @return the bitwise XOR of this vector with the broadcast of an input
862 * scalar
863 */
864 public abstract IntVector xor(int s);
865
866 /**
867 * Bitwise XORs this vector with an input vector, selecting lane elements
868 * controlled by a mask.
869 * <p>
870 * This is a vector binary operation where the primitive bitwise XOR
871 * operation ({@code ^}) is applied to lane elements.
872 *
873 * @param v the input vector
874 * @param m the mask controlling lane selection
875 * @return the bitwise XOR of this vector with the input vector
876 */
877 public abstract IntVector xor(Vector<Integer> v, VectorMask<Integer> m);
878
879 /**
880 * Bitwise XORs this vector with the broadcast of an input scalar, selecting
881 * lane elements controlled by a mask.
882 * <p>
883 * This is a vector binary operation where the primitive bitwise XOR
884 * operation ({@code ^}) is applied to lane elements.
885 *
886 * @param s the input scalar
887 * @param m the mask controlling lane selection
888 * @return the bitwise XOR of this vector with the broadcast of an input
889 * scalar
890 */
891 public abstract IntVector xor(int s, VectorMask<Integer> m);
892
893 /**
894 * Bitwise NOTs this vector.
895 * <p>
896 * This is a vector unary operation where the primitive bitwise NOT
897 * operation ({@code ~}) is applied to lane elements.
898 *
899 * @return the bitwise NOT of this vector
900 */
901 public abstract IntVector not();
902
903 /**
904 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
905 * <p>
906 * This is a vector unary operation where the primitive bitwise NOT
907 * operation ({@code ~}) is applied to lane elements.
908 *
909 * @param m the mask controlling lane selection
910 * @return the bitwise NOT of this vector
911 */
912 public abstract IntVector not(VectorMask<Integer> m);
913
914 /**
915 * Logically left shifts this vector by the broadcast of an input scalar.
916 * <p>
917 * This is a vector binary operation where the primitive logical left shift
918 * operation ({@code <<}) is applied to lane elements.
919 *
920 * @param s the input scalar; the number of the bits to left shift
921 * @return the result of logically left shifting left this vector by the
922 * broadcast of an input scalar
923 */
924 public abstract IntVector shiftL(int s);
925
926 /**
927 * Logically left shifts this vector by the broadcast of an input scalar,
928 * selecting lane elements controlled by a mask.
929 * <p>
930 * This is a vector binary operation where the primitive logical left shift
931 * operation ({@code <<}) is applied to lane elements.
932 *
933 * @param s the input scalar; the number of the bits to left shift
934 * @param m the mask controlling lane selection
935 * @return the result of logically left shifting this vector by the
936 * broadcast of an input scalar
937 */
938 public abstract IntVector shiftL(int s, VectorMask<Integer> m);
939
940 /**
941 * Logically left shifts this vector by an input vector.
942 * <p>
943 * This is a vector binary operation where the primitive logical left shift
944 * operation ({@code <<}) is applied to lane elements.
945 *
946 * @param v the input vector
947 * @return the result of logically left shifting this vector by the input
948 * vector
949 */
950 public abstract IntVector shiftL(Vector<Integer> v);
951
952 /**
953 * Logically left shifts this vector by an input vector, selecting lane
954 * elements controlled by a mask.
955 * <p>
956 * This is a vector binary operation where the primitive logical left shift
957 * operation ({@code <<}) is applied to lane elements.
958 *
959 * @param v the input vector
960 * @param m the mask controlling lane selection
961 * @return the result of logically left shifting this vector by the input
962 * vector
963 */
964 public IntVector shiftL(Vector<Integer> v, VectorMask<Integer> m) {
965 return bOp(v, m, (i, a, b) -> (int) (a << b));
966 }
967
968 // logical, or unsigned, shift right
969
970 /**
971 * Logically right shifts (or unsigned right shifts) this vector by the
972 * broadcast of an input scalar.
973 * <p>
974 * This is a vector binary operation where the primitive logical right shift
975 * operation ({@code >>>}) is applied to lane elements.
976 *
977 * @param s the input scalar; the number of the bits to right shift
978 * @return the result of logically right shifting this vector by the
979 * broadcast of an input scalar
980 */
981 public abstract IntVector shiftR(int s);
982
983 /**
984 * Logically right shifts (or unsigned right shifts) this vector by the
985 * broadcast of an input scalar, selecting lane elements controlled by a
986 * mask.
987 * <p>
988 * This is a vector binary operation where the primitive logical right shift
989 * operation ({@code >>>}) is applied to lane elements.
990 *
991 * @param s the input scalar; the number of the bits to right shift
992 * @param m the mask controlling lane selection
993 * @return the result of logically right shifting this vector by the
994 * broadcast of an input scalar
995 */
996 public abstract IntVector shiftR(int s, VectorMask<Integer> m);
997
998 /**
999 * Logically right shifts (or unsigned right shifts) this vector by an
1000 * input vector.
1001 * <p>
1002 * This is a vector binary operation where the primitive logical right shift
1003 * operation ({@code >>>}) is applied to lane elements.
1004 *
1005 * @param v the input vector
1006 * @return the result of logically right shifting this vector by the
1007 * input vector
1008 */
1009 public abstract IntVector shiftR(Vector<Integer> v);
1010
1011 /**
1012 * Logically right shifts (or unsigned right shifts) this vector by an
1013 * input vector, selecting lane elements controlled by a mask.
1014 * <p>
1015 * This is a vector binary operation where the primitive logical right shift
1016 * operation ({@code >>>}) is applied to lane elements.
1017 *
1018 * @param v the input vector
1019 * @param m the mask controlling lane selection
1020 * @return the result of logically right shifting this vector by the
1021 * input vector
1022 */
1023 public IntVector shiftR(Vector<Integer> v, VectorMask<Integer> m) {
1024 return bOp(v, m, (i, a, b) -> (int) (a >>> b));
1025 }
1026
1027 /**
1028 * Arithmetically right shifts (or signed right shifts) this vector by the
1029 * broadcast of an input scalar.
1030 * <p>
1031 * This is a vector binary operation where the primitive arithmetic right
1032 * shift operation ({@code >>}) is applied to lane elements.
1033 *
1034 * @param s the input scalar; the number of the bits to right shift
1035 * @return the result of arithmetically right shifting this vector by the
1036 * broadcast of an input scalar
1037 */
1038 public abstract IntVector aShiftR(int s);
1039
1040 /**
1041 * Arithmetically right shifts (or signed right shifts) this vector by the
1042 * broadcast of an input scalar, selecting lane elements controlled by a
1043 * mask.
1044 * <p>
1045 * This is a vector binary operation where the primitive arithmetic right
1046 * shift operation ({@code >>}) is applied to lane elements.
1047 *
1048 * @param s the input scalar; the number of the bits to right shift
1049 * @param m the mask controlling lane selection
1050 * @return the result of arithmetically right shifting this vector by the
1051 * broadcast of an input scalar
1052 */
1053 public abstract IntVector aShiftR(int s, VectorMask<Integer> m);
1054
1055 /**
1056 * Arithmetically right shifts (or signed right shifts) this vector by an
1057 * input vector.
1058 * <p>
1059 * This is a vector binary operation where the primitive arithmetic right
1060 * shift operation ({@code >>}) is applied to lane elements.
1061 *
1062 * @param v the input vector
1063 * @return the result of arithmetically right shifting this vector by the
1064 * input vector
1065 */
1066 public abstract IntVector aShiftR(Vector<Integer> v);
1067
1068 /**
1069 * Arithmetically right shifts (or signed right shifts) this vector by an
1070 * input vector, selecting lane elements controlled by a mask.
1071 * <p>
1072 * This is a vector binary operation where the primitive arithmetic right
1073 * shift operation ({@code >>}) is applied to lane elements.
1074 *
1075 * @param v the input vector
1076 * @param m the mask controlling lane selection
1077 * @return the result of arithmetically right shifting this vector by the
1078 * input vector
1079 */
1080 public IntVector aShiftR(Vector<Integer> v, VectorMask<Integer> m) {
1081 return bOp(v, m, (i, a, b) -> (int) (a >> b));
1082 }
1083
1084 /**
1085 * Rotates left this vector by the broadcast of an input scalar.
1086 * <p>
1087 * This is a vector binary operation where the operation
1088 * {@link Integer#rotateLeft} is applied to lane elements and where
1089 * lane elements of this vector apply to the first argument, and lane
1090 * elements of the broadcast vector apply to the second argument (the
1091 * rotation distance).
1092 *
1093 * @param s the input scalar; the number of the bits to rotate left
1094 * @return the result of rotating left this vector by the broadcast of an
1095 * input scalar
1096 */
1097 @ForceInline
1098 public final IntVector rotateL(int s) {
1099 return shiftL(s).or(shiftR(-s));
1100 }
1101
1102 /**
1103 * Rotates left this vector by the broadcast of an input scalar, selecting
1104 * lane elements controlled by a mask.
1105 * <p>
1106 * This is a vector binary operation where the operation
1107 * {@link Integer#rotateLeft} is applied to lane elements and where
1108 * lane elements of this vector apply to the first argument, and lane
1109 * elements of the broadcast vector apply to the second argument (the
1110 * rotation distance).
1111 *
1112 * @param s the input scalar; the number of the bits to rotate left
1113 * @param m the mask controlling lane selection
1114 * @return the result of rotating left this vector by the broadcast of an
1115 * input scalar
1116 */
1117 @ForceInline
1118 public final IntVector rotateL(int s, VectorMask<Integer> m) {
1119 return shiftL(s, m).or(shiftR(-s, m), m);
1120 }
1121
1122 /**
1123 * Rotates right this vector by the broadcast of an input scalar.
1124 * <p>
1125 * This is a vector binary operation where the operation
1126 * {@link Integer#rotateRight} is applied to lane elements and where
1127 * lane elements of this vector apply to the first argument, and lane
1128 * elements of the broadcast vector apply to the second argument (the
1129 * rotation distance).
1130 *
1131 * @param s the input scalar; the number of the bits to rotate right
1132 * @return the result of rotating right this vector by the broadcast of an
1133 * input scalar
1134 */
1135 @ForceInline
1136 public final IntVector rotateR(int s) {
1137 return shiftR(s).or(shiftL(-s));
1138 }
1139
1140 /**
1141 * Rotates right this vector by the broadcast of an input scalar, selecting
1142 * lane elements controlled by a mask.
1143 * <p>
1144 * This is a vector binary operation where the operation
1145 * {@link Integer#rotateRight} is applied to lane elements and where
1146 * lane elements of this vector apply to the first argument, and lane
1147 * elements of the broadcast vector apply to the second argument (the
1148 * rotation distance).
1149 *
1150 * @param s the input scalar; the number of the bits to rotate right
1151 * @param m the mask controlling lane selection
1152 * @return the result of rotating right this vector by the broadcast of an
1153 * input scalar
1154 */
1155 @ForceInline
1156 public final IntVector rotateR(int s, VectorMask<Integer> m) {
1157 return shiftR(s, m).or(shiftL(-s, m), m);
1158 }
1159
1160 @Override
1161 public abstract void intoByteArray(byte[] a, int ix);
1162
1163 @Override
1164 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Integer> m);
1165
1166 @Override
1167 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1168
1169 @Override
1170 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Integer> m);
1171
1172
1173 // Type specific horizontal reductions
1174 /**
1175 * Adds all lane elements of this vector.
1176 * <p>
1177 * This is an associative vector reduction operation where the addition
1178 * operation ({@code +}) is applied to lane elements,
1179 * and the identity value is {@code 0}.
1180 *
1181 * @return the addition of all the lane elements of this vector
1182 */
1183 public abstract int addAll();
1184
1185 /**
1186 * Adds all lane elements of this vector, selecting lane elements
1187 * controlled by a mask.
1188 * <p>
1189 * This is an associative vector reduction operation where the addition
1190 * operation ({@code +}) is applied to lane elements,
1191 * and the identity value is {@code 0}.
1192 *
1193 * @param m the mask controlling lane selection
1194 * @return the addition of the selected lane elements of this vector
1195 */
1196 public abstract int addAll(VectorMask<Integer> m);
1197
1198 /**
1199 * Multiplies all lane elements of this vector.
1200 * <p>
1201 * This is an associative vector reduction operation where the
1202 * multiplication operation ({@code *}) is applied to lane elements,
1203 * and the identity value is {@code 1}.
1204 *
1205 * @return the multiplication of all the lane elements of this vector
1206 */
1207 public abstract int mulAll();
1208
1209 /**
1210 * Multiplies all lane elements of this vector, selecting lane elements
1211 * controlled by a mask.
1212 * <p>
1213 * This is an associative vector reduction operation where the
1214 * multiplication operation ({@code *}) is applied to lane elements,
1215 * and the identity value is {@code 1}.
1216 *
1217 * @param m the mask controlling lane selection
1218 * @return the multiplication of all the lane elements of this vector
1219 */
1220 public abstract int mulAll(VectorMask<Integer> m);
1221
1222 /**
1223 * Returns the minimum lane element of this vector.
1224 * <p>
1225 * This is an associative vector reduction operation where the operation
1226 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1227 * and the identity value is
1228 * {@link Integer#MAX_VALUE}.
1229 *
1230 * @return the minimum lane element of this vector
1231 */
1232 public abstract int minAll();
1233
1234 /**
1235 * Returns the minimum lane element of this vector, selecting lane elements
1236 * controlled by a mask.
1237 * <p>
1238 * This is an associative vector reduction operation where the operation
1239 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1240 * and the identity value is
1241 * {@link Integer#MAX_VALUE}.
1242 *
1243 * @param m the mask controlling lane selection
1244 * @return the minimum lane element of this vector
1245 */
1246 public abstract int minAll(VectorMask<Integer> m);
1247
1248 /**
1249 * Returns the maximum lane element of this vector.
1250 * <p>
1251 * This is an associative vector reduction operation where the operation
1252 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1253 * and the identity value is
1254 * {@link Integer#MIN_VALUE}.
1255 *
1256 * @return the maximum lane element of this vector
1257 */
1258 public abstract int maxAll();
1259
1260 /**
1261 * Returns the maximum lane element of this vector, selecting lane elements
1262 * controlled by a mask.
1263 * <p>
1264 * This is an associative vector reduction operation where the operation
1265 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1266 * and the identity value is
1267 * {@link Integer#MIN_VALUE}.
1268 *
1269 * @param m the mask controlling lane selection
1270 * @return the maximum lane element of this vector
1271 */
1272 public abstract int maxAll(VectorMask<Integer> m);
1273
1274 /**
1275 * Logically ORs all lane elements of this vector.
1276 * <p>
1277 * This is an associative vector reduction operation where the logical OR
1278 * operation ({@code |}) is applied to lane elements,
1279 * and the identity value is {@code 0}.
1280 *
1281 * @return the logical OR all the lane elements of this vector
1282 */
1283 public abstract int orAll();
1284
1285 /**
1286 * Logically ORs all lane elements of this vector, selecting lane elements
1287 * controlled by a mask.
1288 * <p>
1289 * This is an associative vector reduction operation where the logical OR
1290 * operation ({@code |}) is applied to lane elements,
1291 * and the identity value is {@code 0}.
1292 *
1293 * @param m the mask controlling lane selection
1294 * @return the logical OR all the lane elements of this vector
1295 */
1296 public abstract int orAll(VectorMask<Integer> m);
1297
1298 /**
1299 * Logically ANDs all lane elements of this vector.
1300 * <p>
1301 * This is an associative vector reduction operation where the logical AND
1302 * operation ({@code |}) is applied to lane elements,
1303 * and the identity value is {@code -1}.
1304 *
1305 * @return the logical AND all the lane elements of this vector
1306 */
1307 public abstract int andAll();
1308
1309 /**
1310 * Logically ANDs all lane elements of this vector, selecting lane elements
1311 * controlled by a mask.
1312 * <p>
1313 * This is an associative vector reduction operation where the logical AND
1314 * operation ({@code |}) is applied to lane elements,
1315 * and the identity value is {@code -1}.
1316 *
1317 * @param m the mask controlling lane selection
1318 * @return the logical AND all the lane elements of this vector
1319 */
1320 public abstract int andAll(VectorMask<Integer> m);
1321
1322 /**
1323 * Logically XORs all lane elements of this vector.
1324 * <p>
1325 * This is an associative vector reduction operation where the logical XOR
1326 * operation ({@code ^}) is applied to lane elements,
1327 * and the identity value is {@code 0}.
1328 *
1329 * @return the logical XOR all the lane elements of this vector
1330 */
1331 public abstract int xorAll();
1332
1333 /**
1334 * Logically XORs all lane elements of this vector, selecting lane elements
1335 * controlled by a mask.
1336 * <p>
1337 * This is an associative vector reduction operation where the logical XOR
1338 * operation ({@code ^}) is applied to lane elements,
1339 * and the identity value is {@code 0}.
1340 *
1341 * @param m the mask controlling lane selection
1342 * @return the logical XOR all the lane elements of this vector
1343 */
1344 public abstract int xorAll(VectorMask<Integer> m);
1345
1346 // Type specific accessors
1347
1348 /**
1349 * Gets the lane element at lane index {@code i}
1350 *
1351 * @param i the lane index
1352 * @return the lane element at lane index {@code i}
1353 * @throws IllegalArgumentException if the index is is out of range
1354 * ({@code < 0 || >= length()})
1355 */
1356 public abstract int get(int i);
1357
1358 /**
1359 * Replaces the lane element of this vector at lane index {@code i} with
1360 * value {@code e}.
1361 * <p>
1362 * This is a cross-lane operation and behaves as if it returns the result
1363 * of blending this vector with an input vector that is the result of
1364 * broadcasting {@code e} and a mask that has only one lane set at lane
1406 * @param i the offset into the array
1407 * @throws IndexOutOfBoundsException if {@code i < 0}, or
1408 * {@code i > a.length - this.length()}
1409 */
1410 public abstract void intoArray(int[] a, int i);
1411
1412 /**
1413 * Stores this vector into an array starting at offset and using a mask.
1414 * <p>
1415 * For each vector lane, where {@code N} is the vector lane index,
1416 * if the mask lane at index {@code N} is set then the lane element at
1417 * index {@code N} is stored into the array index {@code i + N}.
1418 *
1419 * @param a the array
1420 * @param i the offset into the array
1421 * @param m the mask
1422 * @throws IndexOutOfBoundsException if {@code i < 0}, or
1423 * for any vector lane index {@code N} where the mask at lane {@code N}
1424 * is set {@code i >= a.length - N}
1425 */
1426 public abstract void intoArray(int[] a, int i, VectorMask<Integer> m);
1427
1428 /**
1429 * Stores this vector into an array using indexes obtained from an index
1430 * map.
1431 * <p>
1432 * For each vector lane, where {@code N} is the vector lane index, the
1433 * lane element at index {@code N} is stored into the array at index
1434 * {@code i + indexMap[j + N]}.
1435 *
1436 * @param a the array
1437 * @param i the offset into the array, may be negative if relative
1438 * indexes in the index map compensate to produce a value within the
1439 * array bounds
1440 * @param indexMap the index map
1441 * @param j the offset into the index map
1442 * @throws IndexOutOfBoundsException if {@code j < 0}, or
1443 * {@code j > indexMap.length - this.length()},
1444 * or for any vector lane index {@code N} the result of
1445 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1446 */
1451 * map and using a mask.
1452 * <p>
1453 * For each vector lane, where {@code N} is the vector lane index,
1454 * if the mask lane at index {@code N} is set then the lane element at
1455 * index {@code N} is stored into the array at index
1456 * {@code i + indexMap[j + N]}.
1457 *
1458 * @param a the array
1459 * @param i the offset into the array, may be negative if relative
1460 * indexes in the index map compensate to produce a value within the
1461 * array bounds
1462 * @param m the mask
1463 * @param indexMap the index map
1464 * @param j the offset into the index map
1465 * @throws IndexOutOfBoundsException if {@code j < 0}, or
1466 * {@code j > indexMap.length - this.length()},
1467 * or for any vector lane index {@code N} where the mask at lane
1468 * {@code N} is set the result of {@code i + indexMap[j + N]} is
1469 * {@code < 0} or {@code >= a.length}
1470 */
1471 public abstract void intoArray(int[] a, int i, VectorMask<Integer> m, int[] indexMap, int j);
1472 // Species
1473
1474 @Override
1475 public abstract VectorSpecies<Integer> species();
1476
1477 /**
1478 * Class representing {@link IntVector}'s of the same {@link VectorShape VectorShape}.
1479 */
1480 static final class IntSpecies extends AbstractSpecies<Integer> {
1481 final Function<int[], IntVector> vectorFactory;
1482
1483 private IntSpecies(VectorShape shape,
1484 Class<?> boxType,
1485 Class<?> maskType,
1486 Function<int[], IntVector> vectorFactory,
1487 Function<boolean[], VectorMask<Integer>> maskFactory,
1488 Function<IntUnaryOperator, VectorShuffle<Integer>> shuffleFromArrayFactory,
1489 fShuffleFromArray<Integer> shuffleFromOpFactory) {
1490 super(shape, int.class, Integer.SIZE, boxType, maskType, maskFactory,
1491 shuffleFromArrayFactory, shuffleFromOpFactory);
1492 this.vectorFactory = vectorFactory;
1493 }
1494
1495 interface FOp {
1496 int apply(int i);
1497 }
1498
1499 IntVector op(FOp f) {
1500 int[] res = new int[length()];
1501 for (int i = 0; i < length(); i++) {
1502 res[i] = f.apply(i);
1503 }
1504 return vectorFactory.apply(res);
1505 }
1506
1507 IntVector op(VectorMask<Integer> o, FOp f) {
1508 int[] res = new int[length()];
1509 boolean[] mbits = ((AbstractMask<Integer>)o).getBits();
1510 for (int i = 0; i < length(); i++) {
1511 if (mbits[i]) {
1512 res[i] = f.apply(i);
1513 }
1514 }
1515 return vectorFactory.apply(res);
1516 }
1517 }
1518
1519 /**
1520 * Finds the preferred species for an element type of {@code int}.
1521 * <p>
1522 * A preferred species is a species chosen by the platform that has a
1523 * shape of maximal bit size. A preferred species for different element
1524 * types will have the same shape, and therefore vectors, masks, and
1525 * shuffles created from such species will be shape compatible.
1526 *
1527 * @return the preferred species for an element type of {@code int}
1528 */
1529 private static IntSpecies preferredSpecies() {
1530 return (IntSpecies) VectorSpecies.ofPreferred(int.class);
1531 }
1532
1533 /**
1534 * Finds a species for an element type of {@code int} and shape.
1535 *
1536 * @param s the shape
1537 * @return a species for an element type of {@code int} and shape
1538 * @throws IllegalArgumentException if no such species exists for the shape
1539 */
1540 static IntSpecies species(VectorShape s) {
1541 Objects.requireNonNull(s);
1542 switch (s) {
1543 case S_64_BIT: return (IntSpecies) SPECIES_64;
1544 case S_128_BIT: return (IntSpecies) SPECIES_128;
1545 case S_256_BIT: return (IntSpecies) SPECIES_256;
1546 case S_512_BIT: return (IntSpecies) SPECIES_512;
1547 case S_Max_BIT: return (IntSpecies) SPECIES_MAX;
1548 default: throw new IllegalArgumentException("Bad shape: " + s);
1549 }
1550 }
1551
1552 /** Species representing {@link IntVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
1553 public static final VectorSpecies<Integer> SPECIES_64 = new IntSpecies(VectorShape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class,
1554 Int64Vector::new, Int64Vector.Int64Mask::new,
1555 Int64Vector.Int64Shuffle::new, Int64Vector.Int64Shuffle::new);
1556
1557 /** Species representing {@link IntVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
1558 public static final VectorSpecies<Integer> SPECIES_128 = new IntSpecies(VectorShape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class,
1559 Int128Vector::new, Int128Vector.Int128Mask::new,
1560 Int128Vector.Int128Shuffle::new, Int128Vector.Int128Shuffle::new);
1561
1562 /** Species representing {@link IntVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
1563 public static final VectorSpecies<Integer> SPECIES_256 = new IntSpecies(VectorShape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class,
1564 Int256Vector::new, Int256Vector.Int256Mask::new,
1565 Int256Vector.Int256Shuffle::new, Int256Vector.Int256Shuffle::new);
1566
1567 /** Species representing {@link IntVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
1568 public static final VectorSpecies<Integer> SPECIES_512 = new IntSpecies(VectorShape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class,
1569 Int512Vector::new, Int512Vector.Int512Mask::new,
1570 Int512Vector.Int512Shuffle::new, Int512Vector.Int512Shuffle::new);
1571
1572 /** Species representing {@link IntVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
1573 public static final VectorSpecies<Integer> SPECIES_MAX = new IntSpecies(VectorShape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class,
1574 IntMaxVector::new, IntMaxVector.IntMaxMask::new,
1575 IntMaxVector.IntMaxShuffle::new, IntMaxVector.IntMaxShuffle::new);
1576
1577 /**
1578 * Preferred species for {@link IntVector}s.
1579 * A preferred species is a species of maximal bit size for the platform.
1580 */
1581 public static final VectorSpecies<Integer> SPECIES_PREFERRED = (VectorSpecies<Integer>) preferredSpecies();
1582 }
|