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