90 }
91
92 abstract Mask<$Boxtype$> bTest(Vector<$Boxtype$> v, FBinTest f);
93
94 // Foreach
95
96 interface FUnCon {
97 void apply(int i, $type$ a);
98 }
99
100 abstract void forEach(FUnCon f);
101
102 abstract void forEach(Mask<$Boxtype$> m, FUnCon f);
103
104 // Static factories
105
106 /**
107 * Returns a vector where all lane elements are set to the default
108 * primitive value.
109 *
110 * @return a zero vector
111 */
112 @ForceInline
113 @SuppressWarnings("unchecked")
114 public static $abstractvectortype$ zero($Type$Species species) {
115 return species.zero();
116 }
117
118 /**
119 * Loads a vector from a byte array starting at an offset.
120 * <p>
121 * Bytes are composed into primitive lane elements according to the
122 * native byte order of the underlying platform
123 * <p>
124 * This method behaves as if it returns the result of calling the
125 * byte buffer, offset, and mask accepting
126 * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask) method} as follows:
127 * <pre>{@code
128 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
129 * }</pre>
130 *
131 * @param a the byte array
132 * @param ix the offset into the array
133 * @return a vector loaded from a byte array
134 * @throws IndexOutOfBoundsException if {@code i < 0} or
135 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
136 */
137 @ForceInline
138 @SuppressWarnings("unchecked")
139 public static $abstractvectortype$ fromByteArray($Type$Species species, byte[] a, int ix) {
140 Objects.requireNonNull(a);
141 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
142 return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
143 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
144 a, ix, species,
145 (c, idx, s) -> {
146 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
147 $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
148 return (($Type$Species)s).op(i -> tb.get());
149 });
150 }
151
152 /**
153 * Loads a vector from a byte array starting at an offset and using a
154 * mask.
155 * <p>
156 * Bytes are composed into primitive lane elements according to the
157 * native byte order of the underlying platform.
158 * <p>
159 * This method behaves as if it returns the result of calling the
160 * byte buffer, offset, and mask accepting
161 * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask) method} as follows:
162 * <pre>{@code
163 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
164 * }</pre>
165 *
166 * @param a the byte array
167 * @param ix the offset into the array
168 * @param m the mask
169 * @return a vector loaded from a byte array
170 * @throws IndexOutOfBoundsException if {@code i < 0} or
171 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
172 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
173 * or {@code > a.length},
174 * for any vector lane index {@code N} where the mask at lane {@code N}
175 * is set
176 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
177 */
178 @ForceInline
179 public static $abstractvectortype$ fromByteArray($Type$Species species, byte[] a, int ix, Mask<$Boxtype$> m) {
180 return zero(species).blend(fromByteArray(species, a, ix), m);
181 }
182
183 /**
184 * Loads a vector from an array starting at offset.
185 * <p>
186 * For each vector lane, where {@code N} is the vector lane index, the
187 * array element at index {@code i + N} is placed into the
188 * resulting vector at lane index {@code N}.
189 *
190 * @param a the array
191 * @param i the offset into the array
192 * @return the vector loaded from an array
193 * @throws IndexOutOfBoundsException if {@code i < 0}, or
194 * {@code i > a.length - this.length()}
195 */
196 @ForceInline
197 @SuppressWarnings("unchecked")
198 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i){
199 Objects.requireNonNull(a);
200 i = VectorIntrinsics.checkIndex(i, a.length, species.length());
201 return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
202 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_$TYPE$_BASE_OFFSET,
203 a, i, species,
204 (c, idx, s) -> (($Type$Species)s).op(n -> c[idx + n]));
205 }
206
207
208 /**
209 * Loads a vector from an array starting at offset and using a mask.
210 * <p>
211 * For each vector lane, where {@code N} is the vector lane index,
212 * if the mask lane at index {@code N} is set then the array element at
213 * index {@code i + N} is placed into the resulting vector at lane index
214 * {@code N}, otherwise the default element value is placed into the
215 * resulting vector at lane index {@code N}.
216 *
217 * @param a the array
218 * @param i the offset into the array
219 * @param m the mask
220 * @return the vector loaded from an array
221 * @throws IndexOutOfBoundsException if {@code i < 0}, or
222 * for any vector lane index {@code N} where the mask at lane {@code N}
223 * is set {@code i > a.length - N}
224 */
225 @ForceInline
226 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m) {
227 return zero(species).blend(fromArray(species, a, i), m);
228 }
229
230 /**
231 * Loads a vector from an array using indexes obtained from an index
232 * map.
233 * <p>
234 * For each vector lane, where {@code N} is the vector lane index, the
235 * array element at index {@code i + indexMap[j + N]} is placed into the
236 * resulting vector at lane index {@code N}.
237 *
238 * @param a the array
239 * @param i the offset into the array, may be negative if relative
240 * indexes in the index map compensate to produce a value within the
241 * array bounds
242 * @param indexMap the index map
243 * @param j the offset into the index map
244 * @return the vector loaded from an array
245 * @throws IndexOutOfBoundsException if {@code j < 0}, or
246 * {@code j > indexMap.length - this.length()},
247 * or for any vector lane index {@code N} the result of
248 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
249 */
250 #if[byteOrShort]
251 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, int[] indexMap, int j) {
252 return species.op(n -> a[i + indexMap[j + n]]);
253 }
254 #else[byteOrShort]
255 @ForceInline
256 @SuppressWarnings("unchecked")
257 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, int[] indexMap, int j) {
268 IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
269
270 vix = VectorIntrinsics.checkIndex(vix, a.length);
271
272 return VectorIntrinsics.loadWithMap((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
273 species.indexSpecies().vectorType(), a, Unsafe.ARRAY_$TYPE$_BASE_OFFSET, vix,
274 a, i, indexMap, j, species,
275 (c, idx, iMap, idy, s) -> (($Type$Species)s).op(n -> c[idx + iMap[idy+n]]));
276 }
277
278 #end[byteOrShort]
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 a the array
289 * @param i the offset into the array, may be negative if relative
290 * indexes in the index map compensate to produce a value within the
291 * array bounds
292 * @param indexMap the index map
293 * @param j the offset into the index map
294 * @return the vector loaded from an array
295 * @throws IndexOutOfBoundsException if {@code j < 0}, or
296 * {@code j > indexMap.length - this.length()},
297 * or for any vector lane index {@code N} where the mask at lane
298 * {@code N} is set the result of {@code i + indexMap[j + N]} is
299 * {@code < 0} or {@code >= a.length}
300 */
301 #if[byteOrShort]
302 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
303 return species.op(m, n -> a[i + indexMap[j + n]]);
304 }
305 #else[byteOrShort]
306 @ForceInline
307 @SuppressWarnings("unchecked")
308 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
309 // @@@ This can result in out of bounds errors for unset mask lanes
310 return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
311 }
312
313 #end[byteOrShort]
314
315 /**
316 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
317 * offset into the byte buffer.
318 * <p>
319 * Bytes are composed into primitive lane elements according to the
320 * native byte order of the underlying platform.
321 * <p>
322 * This method behaves as if it returns the result of calling the
323 * byte buffer, offset, and mask accepting
324 * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask)} method} as follows:
325 * <pre>{@code
326 * return this.fromByteBuffer(b, i, this.maskAllTrue())
327 * }</pre>
328 *
329 * @param bb the byte buffer
330 * @param ix the offset into the byte buffer
331 * @return a vector loaded from a byte buffer
332 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
333 * or {@code > b.limit()},
334 * or if there are fewer than
335 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
336 * remaining in the byte buffer from the given offset
337 */
338 @ForceInline
339 @SuppressWarnings("unchecked")
340 public static $abstractvectortype$ fromByteBuffer($Type$Species species, ByteBuffer bb, int ix) {
341 if (bb.order() != ByteOrder.nativeOrder()) {
342 throw new IllegalArgumentException();
343 }
344 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
345 return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
346 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
347 bb, ix, species,
348 (c, idx, s) -> {
360 * {@link java.nio.Buffer buffer} for the primitive element type,
361 * according to the native byte order of the underlying platform, and
362 * the returned vector is loaded with a mask from a primitive array
363 * obtained from the primitive buffer.
364 * The following pseudocode expresses the behaviour, where
365 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
366 * primitive element type, and {@code ESpecies<S>} is the primitive
367 * species for {@code e}:
368 * <pre>{@code
369 * EBuffer eb = b.duplicate().
370 * order(ByteOrder.nativeOrder()).position(i).
371 * asEBuffer();
372 * e[] es = new e[this.length()];
373 * for (int n = 0; n < t.length; n++) {
374 * if (m.isSet(n))
375 * es[n] = eb.get(n);
376 * }
377 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
378 * }</pre>
379 *
380 * @param bb the byte buffer
381 * @param ix the offset into the byte buffer
382 * @return a vector loaded from a byte buffer
383 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
384 * or {@code > b.limit()},
385 * for any vector lane index {@code N} where the mask at lane {@code N}
386 * is set
387 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
388 */
389 @ForceInline
390 public static $abstractvectortype$ fromByteBuffer($Type$Species species, ByteBuffer bb, int ix, Mask<$Boxtype$> m) {
391 return zero(species).blend(fromByteBuffer(species, bb, ix), m);
392 }
393
394 @ForceInline
395 public static Mask<$Boxtype$> maskFromValues($Type$Species species, boolean... bits) {
396 if (species.boxType() == $Type$MaxVector.class)
397 return new $Type$MaxVector.$Type$MaxMask(bits);
398 switch (species.bitSize()) {
399 case 64: return new $Type$64Vector.$Type$64Mask(bits);
400 case 128: return new $Type$128Vector.$Type$128Mask(bits);
401 case 256: return new $Type$256Vector.$Type$256Mask(bits);
402 case 512: return new $Type$512Vector.$Type$512Mask(bits);
403 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
404 }
405 }
406
407 // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
408 static Mask<$Boxtype$> trueMask($Type$Species species) {
409 if (species.boxType() == $Type$MaxVector.class)
410 return $Type$MaxVector.$Type$MaxMask.TRUE_MASK;
411 switch (species.bitSize()) {
412 case 64: return $Type$64Vector.$Type$64Mask.TRUE_MASK;
413 case 128: return $Type$128Vector.$Type$128Mask.TRUE_MASK;
414 case 256: return $Type$256Vector.$Type$256Mask.TRUE_MASK;
415 case 512: return $Type$512Vector.$Type$512Mask.TRUE_MASK;
416 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
417 }
418 }
419
420 static Mask<$Boxtype$> falseMask($Type$Species species) {
421 if (species.boxType() == $Type$MaxVector.class)
422 return $Type$MaxVector.$Type$MaxMask.FALSE_MASK;
423 switch (species.bitSize()) {
424 case 64: return $Type$64Vector.$Type$64Mask.FALSE_MASK;
425 case 128: return $Type$128Vector.$Type$128Mask.FALSE_MASK;
426 case 256: return $Type$256Vector.$Type$256Mask.FALSE_MASK;
427 case 512: return $Type$512Vector.$Type$512Mask.FALSE_MASK;
428 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
429 }
430 }
431
432 @ForceInline
433 @SuppressWarnings("unchecked")
434 public static Mask<$Boxtype$> maskFromArray($Type$Species species, boolean[] bits, int ix) {
435 Objects.requireNonNull(bits);
436 ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
437 return VectorIntrinsics.load((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
438 bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
439 bits, ix, species,
440 (c, idx, s) -> (Mask<$Boxtype$>) (($Type$Species)s).opm(n -> c[idx + n]));
441 }
442
443 @ForceInline
444 @SuppressWarnings("unchecked")
445 public static Mask<$Boxtype$> maskAllTrue($Type$Species species) {
446 return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
447 ($bitstype$)-1, species,
448 ((z, s) -> trueMask(($Type$Species)s)));
449 }
450
451 @ForceInline
452 @SuppressWarnings("unchecked")
453 public static Mask<$Boxtype$> maskAllFalse($Type$Species species) {
454 return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
455 0, species,
456 ((z, s) -> falseMask(($Type$Species)s)));
457 }
458
459 @ForceInline
460 public static Shuffle<$Boxtype$> shuffle($Type$Species species, IntUnaryOperator f) {
461 if (species.boxType() == $Type$MaxVector.class)
462 return new $Type$MaxVector.$Type$MaxShuffle(f);
463 switch (species.bitSize()) {
464 case 64: return new $Type$64Vector.$Type$64Shuffle(f);
465 case 128: return new $Type$128Vector.$Type$128Shuffle(f);
466 case 256: return new $Type$256Vector.$Type$256Shuffle(f);
467 case 512: return new $Type$512Vector.$Type$512Shuffle(f);
468 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
469 }
470 }
471
472 @ForceInline
473 public static Shuffle<$Boxtype$> shuffleIota($Type$Species species) {
474 if (species.boxType() == $Type$MaxVector.class)
475 return new $Type$MaxVector.$Type$MaxShuffle(AbstractShuffle.IDENTITY);
476 switch (species.bitSize()) {
477 case 64: return new $Type$64Vector.$Type$64Shuffle(AbstractShuffle.IDENTITY);
478 case 128: return new $Type$128Vector.$Type$128Shuffle(AbstractShuffle.IDENTITY);
479 case 256: return new $Type$256Vector.$Type$256Shuffle(AbstractShuffle.IDENTITY);
480 case 512: return new $Type$512Vector.$Type$512Shuffle(AbstractShuffle.IDENTITY);
481 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
482 }
483 }
484
485 @ForceInline
486 public static Shuffle<$Boxtype$> shuffleFromValues($Type$Species species, int... ixs) {
487 if (species.boxType() == $Type$MaxVector.class)
488 return new $Type$MaxVector.$Type$MaxShuffle(ixs);
489 switch (species.bitSize()) {
490 case 64: return new $Type$64Vector.$Type$64Shuffle(ixs);
491 case 128: return new $Type$128Vector.$Type$128Shuffle(ixs);
492 case 256: return new $Type$256Vector.$Type$256Shuffle(ixs);
493 case 512: return new $Type$512Vector.$Type$512Shuffle(ixs);
494 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
495 }
496 }
497
498 @ForceInline
499 public static Shuffle<$Boxtype$> shuffleFromArray($Type$Species species, int[] ixs, int i) {
500 if (species.boxType() == $Type$MaxVector.class)
501 return new $Type$MaxVector.$Type$MaxShuffle(ixs, i);
502 switch (species.bitSize()) {
503 case 64: return new $Type$64Vector.$Type$64Shuffle(ixs, i);
504 case 128: return new $Type$128Vector.$Type$128Shuffle(ixs, i);
505 case 256: return new $Type$256Vector.$Type$256Shuffle(ixs, i);
506 case 512: return new $Type$512Vector.$Type$512Shuffle(ixs, i);
507 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
508 }
509 }
510
511
512 // Ops
513
514 @Override
515 public abstract $abstractvectortype$ add(Vector<$Boxtype$> v);
516
517 /**
1807
1808 /**
1809 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1810 * <p>
1811 * This is a vector unary operation where the primitive bitwise NOT
1812 * operation ({@code ~}) is applied to lane elements.
1813 *
1814 * @param m the mask controlling lane selection
1815 * @return the bitwise NOT of this vector
1816 */
1817 public abstract $abstractvectortype$ not(Mask<$Boxtype$> m);
1818
1819 #if[byte]
1820 /**
1821 * Logically left shifts this vector by the broadcast of an input scalar.
1822 * <p>
1823 * This is a vector binary operation where the primitive logical left shift
1824 * operation ({@code <<}) is applied to lane elements to left shift the
1825 * element by shift value as specified by the input scalar. Only the 3
1826 * lowest-order bits of shift value are used. It is as if the shift value
1827 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
1828 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1829 *
1830 * @param s the input scalar; the number of the bits to left shift
1831 * @return the result of logically left shifting left this vector by the
1832 * broadcast of an input scalar
1833 */
1834 #end[byte]
1835 #if[short]
1836 /**
1837 * Logically left shifts this vector by the broadcast of an input scalar.
1838 * <p>
1839 * This is a vector binary operation where the primitive logical left shift
1840 * operation ({@code <<}) is applied to lane elements to left shift the
1841 * element by shift value as specified by the input scalar. Only the 4
1842 * lowest-order bits of shift value are used. It is as if the shift value
1843 * were subjected to a bitwise logical AND operator & with the mask value 0xF.
1844 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1845 *
1846 * @param s the input scalar; the number of the bits to left shift
1847 * @return the result of logically left shifting left this vector by the
1848 * broadcast of an input scalar
1849 */
1850 #end[short]
1851 #if[intOrLong]
1852 /**
1853 * Logically left shifts this vector by the broadcast of an input scalar.
1854 * <p>
1855 * This is a vector binary operation where the primitive logical left shift
1856 * operation ({@code <<}) is applied to lane elements.
1857 *
1858 * @param s the input scalar; the number of the bits to left shift
1859 * @return the result of logically left shifting left this vector by the
1860 * broadcast of an input scalar
1861 */
1862 #end[intOrLong]
1863 public abstract $abstractvectortype$ shiftL(int s);
1864
1865 #if[byte]
1866 /**
1867 * Logically left shifts this vector by the broadcast of an input scalar,
1868 * selecting lane elements controlled by a mask.
1869 * <p>
1870 * This is a vector binary operation where the primitive logical left shift
1871 * operation ({@code <<}) is applied to lane elements to left shift the
1872 * element by shift value as specified by the input scalar. Only the 3
1873 * lowest-order bits of shift value are used. It is as if the shift value
1874 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
1875 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1876 *
1877 * @param s the input scalar; the number of the bits to left shift
1878 * @param m the mask controlling lane selection
1879 * @return the result of logically left shifting left this vector by the
1880 * broadcast of an input scalar
1881 */
1882 #end[byte]
1883 #if[short]
1884 /**
1885 * Logically left shifts this vector by the broadcast of an input scalar,
1886 * selecting lane elements controlled by a mask.
1887 * <p>
1888 * This is a vector binary operation where the primitive logical left shift
1889 * operation ({@code <<}) is applied to lane elements to left shift the
1890 * element by shift value as specified by the input scalar. Only the 4
1891 * lowest-order bits of shift value are used. It is as if the shift value
1892 * were subjected to a bitwise logical AND operator & with the mask value 0xF.
1893 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1894 *
1895 * @param s the input scalar; the number of the bits to left shift
1896 * @param m the mask controlling lane selection
1897 * @return the result of logically left shifting left this vector by the
1898 * broadcast of an input scalar
1899 */
1900 #end[short]
1901 #if[intOrLong]
1902 /**
1903 * Logically left shifts this vector by the broadcast of an input scalar,
1904 * selecting lane elements controlled by a mask.
1905 * <p>
1906 * This is a vector binary operation where the primitive logical left shift
1907 * operation ({@code <<}) is applied to lane elements.
1908 *
1909 * @param s the input scalar; the number of the bits to left shift
1910 * @param m the mask controlling lane selection
1911 * @return the result of logically left shifting this vector by the
1912 * broadcast of an input scalar
1938 * @param m the mask controlling lane selection
1939 * @return the result of logically left shifting this vector by the input
1940 * vector
1941 */
1942 public $abstractvectortype$ shiftL(Vector<$Boxtype$> v, Mask<$Boxtype$> m) {
1943 return bOp(v, m, (i, a, b) -> ($type$) (a << b));
1944 }
1945 #end[intOrLong]
1946
1947 // logical, or unsigned, shift right
1948
1949 #if[byte]
1950 /**
1951 * Logically right shifts (or unsigned right shifts) this vector by the
1952 * broadcast of an input scalar.
1953 * <p>
1954 * This is a vector binary operation where the primitive logical right shift
1955 * operation ({@code >>>}) is applied to lane elements to logically right shift the
1956 * element by shift value as specified by the input scalar. Only the 3
1957 * lowest-order bits of shift value are used. It is as if the shift value
1958 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
1959 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1960 *
1961 * @param s the input scalar; the number of the bits to right shift
1962 * @return the result of logically right shifting this vector by the
1963 * broadcast of an input scalar
1964 */
1965 #end[byte]
1966 #if[short]
1967 /**
1968 * Logically right shifts (or unsigned right shifts) this vector by the
1969 * broadcast of an input scalar.
1970 * <p>
1971 * This is a vector binary operation where the primitive logical right shift
1972 * operation ({@code >>>}) is applied to lane elements to logically right shift the
1973 * element by shift value as specified by the input scalar. Only the 4
1974 * lowest-order bits of shift value are used. It is as if the shift value
1975 * were subjected to a bitwise logical AND operator & with the mask value 0xF.
1976 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1977 *
1978 * @param s the input scalar; the number of the bits to right shift
1979 * @return the result of logically right shifting this vector by the
1980 * broadcast of an input scalar
1981 */
1982 #end[short]
1983 #if[intOrLong]
1984 /**
1985 * Logically right shifts (or unsigned right shifts) this vector by the
1986 * broadcast of an input scalar.
1987 * <p>
1988 * This is a vector binary operation where the primitive logical right shift
1989 * operation ({@code >>>}) is applied to lane elements.
1990 *
1991 * @param s the input scalar; the number of the bits to right shift
1992 * @return the result of logically right shifting this vector by the
1993 * broadcast of an input scalar
1994 */
1995 #end[intOrLong]
1996 public abstract $abstractvectortype$ shiftR(int s);
1997
1998 #if[byte]
1999 /**
2000 * Logically right shifts (or unsigned right shifts) this vector by the
2001 * broadcast of an input scalar, selecting lane elements controlled by a
2002 * mask.
2003 * <p>
2004 * This is a vector binary operation where the primitive logical right shift
2005 * operation ({@code >>>}) is applied to lane elements to logically right shift the
2006 * element by shift value as specified by the input scalar. Only the 3
2007 * lowest-order bits of shift value are used. It is as if the shift value
2008 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
2009 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2010 *
2011 * @param s the input scalar; the number of the bits to right shift
2012 * @return the result of logically right shifting this vector by the
2013 * broadcast of an input scalar
2014 */
2015 #end[byte]
2016 #if[short]
2017 /**
2018 * Logically right shifts (or unsigned right shifts) this vector by the
2019 * broadcast of an input scalar, selecting lane elements controlled by a
2020 * mask.
2021 * <p>
2022 * This is a vector binary operation where the primitive logical right shift
2023 * operation ({@code >>>}) is applied to lane elements to logically right shift the
2024 * element by shift value as specified by the input scalar. Only the 4
2025 * lowest-order bits of shift value are used. It is as if the shift value
2026 * were subjected to a bitwise logical AND operator & with the mask value 0xF.
2027 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2028 *
2029 * @param s the input scalar; the number of the bits to right shift
2030 * @return the result of logically right shifting this vector by the
2031 * broadcast of an input scalar
2032 */
2033 #end[short]
2034 #if[intOrLong]
2035 /**
2036 * Logically right shifts (or unsigned right shifts) this vector by the
2037 * broadcast of an input scalar, selecting lane elements controlled by a
2038 * mask.
2039 * <p>
2040 * This is a vector binary operation where the primitive logical right shift
2041 * operation ({@code >>>}) is applied to lane elements.
2042 *
2043 * @param s the input scalar; the number of the bits to right shift
2044 * @return the result of logically right shifting this vector by the
2045 * broadcast of an input scalar
2046 */
2047 #end[intOrLong]
2048 public abstract $abstractvectortype$ shiftR(int s, Mask<$Boxtype$> m);
2049
2050 #if[intOrLong]
2051 /**
2052 * Logically right shifts (or unsigned right shifts) this vector by an
2053 * input vector.
2054 * <p>
2055 * This is a vector binary operation where the primitive logical right shift
2056 * operation ({@code >>>}) is applied to lane elements.
2057 *
2058 * @param v the input vector
2059 * @return the result of logically right shifting this vector by the
2060 * input vector
2061 */
2062 public abstract $abstractvectortype$ shiftR(Vector<$Boxtype$> v);
2063
2070 *
2071 * @param v the input vector
2072 * @param m the mask controlling lane selection
2073 * @return the result of logically right shifting this vector by the
2074 * input vector
2075 */
2076 public $abstractvectortype$ shiftR(Vector<$Boxtype$> v, Mask<$Boxtype$> m) {
2077 return bOp(v, m, (i, a, b) -> ($type$) (a >>> b));
2078 }
2079 #end[intOrLong]
2080
2081 #if[byte]
2082 /**
2083 * Arithmetically right shifts (or signed right shifts) this vector by the
2084 * broadcast of an input scalar.
2085 * <p>
2086 * This is a vector binary operation where the primitive arithmetic right
2087 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2088 * right shift the element by shift value as specified by the input scalar.
2089 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
2090 * value were subjected to a bitwise logical AND operator & with the mask value 0x7.
2091 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2092 *
2093 * @param s the input scalar; the number of the bits to right shift
2094 * @return the result of arithmetically right shifting this vector by the
2095 * broadcast of an input scalar
2096 */
2097 #end[byte]
2098 #if[short]
2099 /**
2100 * Arithmetically right shifts (or signed right shifts) this vector by the
2101 * broadcast of an input scalar.
2102 * <p>
2103 * This is a vector binary operation where the primitive arithmetic right
2104 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2105 * right shift the element by shift value as specified by the input scalar.
2106 * Only the 4 lowest-order bits of shift value are used. It is as if the shift
2107 * value were subjected to a bitwise logical AND operator & with the mask value 0xF.
2108 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2109 *
2110 * @param s the input scalar; the number of the bits to right shift
2111 * @return the result of arithmetically right shifting this vector by the
2112 * broadcast of an input scalar
2113 */
2114 #end[short]
2115 #if[intOrLong]
2116 /**
2117 * Arithmetically right shifts (or signed right shifts) this vector by the
2118 * broadcast of an input scalar.
2119 * <p>
2120 * This is a vector binary operation where the primitive arithmetic right
2121 * shift operation ({@code >>}) is applied to lane elements.
2122 *
2123 * @param s the input scalar; the number of the bits to right shift
2124 * @return the result of arithmetically right shifting this vector by the
2125 * broadcast of an input scalar
2126 */
2127 #end[intOrLong]
2128 public abstract $abstractvectortype$ aShiftR(int s);
2129
2130 #if[byte]
2131 /**
2132 * Arithmetically right shifts (or signed right shifts) this vector by the
2133 * broadcast of an input scalar, selecting lane elements controlled by a
2134 * mask.
2135 * <p>
2136 * This is a vector binary operation where the primitive arithmetic right
2137 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2138 * right shift the element by shift value as specified by the input scalar.
2139 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
2140 * value were subjected to a bitwise logical AND operator & with the mask value 0x7.
2141 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2142 *
2143 * @param s the input scalar; the number of the bits to right shift
2144 * @param m the mask controlling lane selection
2145 * @return the result of arithmetically right shifting this vector by the
2146 * broadcast of an input scalar
2147 */
2148 #end[byte]
2149 #if[short]
2150 /**
2151 * Arithmetically right shifts (or signed right shifts) this vector by the
2152 * broadcast of an input scalar, selecting lane elements controlled by a
2153 * mask.
2154 * <p>
2155 * This is a vector binary operation where the primitive arithmetic right
2156 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2157 * right shift the element by shift value as specified by the input scalar.
2158 * Only the 4 lowest-order bits of shift value are used. It is as if the shift
2159 * value were subjected to a bitwise logical AND operator & with the mask value 0xF.
2160 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2161 *
2162 * @param s the input scalar; the number of the bits to right shift
2163 * @param m the mask controlling lane selection
2164 * @return the result of arithmetically right shifting this vector by the
2165 * broadcast of an input scalar
2166 */
2167 #end[short]
2168 #if[intOrLong]
2169 /**
2170 * Arithmetically right shifts (or signed right shifts) this vector by the
2171 * broadcast of an input scalar, selecting lane elements controlled by a
2172 * mask.
2173 * <p>
2174 * This is a vector binary operation where the primitive arithmetic right
2175 * shift operation ({@code >>}) is applied to lane elements.
2176 *
2177 * @param s the input scalar; the number of the bits to right shift
2178 * @param m the mask controlling lane selection
2179 * @return the result of arithmetically right shifting this vector by the
2287 public final $abstractvectortype$ rotateR(int s, Mask<$Boxtype$> m) {
2288 return shiftR(s, m).or(shiftL(-s, m), m);
2289 }
2290 #end[intOrLong]
2291 #end[BITWISE]
2292
2293 @Override
2294 public abstract void intoByteArray(byte[] a, int ix);
2295
2296 @Override
2297 public abstract void intoByteArray(byte[] a, int ix, Mask<$Boxtype$> m);
2298
2299 @Override
2300 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
2301
2302 @Override
2303 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$> m);
2304
2305
2306 // Type specific horizontal reductions
2307
2308 /**
2309 * Adds all lane elements of this vector.
2310 * <p>
2311 * This is an associative vector reduction operation where the addition
2312 * operation ({@code +}) is applied to lane elements,
2313 * and the identity value is {@code 0}.
2314 *
2315 * @return the addition of all the lane elements of this vector
2316 */
2317 public abstract $type$ addAll();
2318
2319 /**
2320 * Adds all lane elements of this vector, selecting lane elements
2321 * controlled by a mask.
2322 * <p>
2323 * This is an associative vector reduction operation where the addition
2324 * operation ({@code +}) is applied to lane elements,
2325 * and the identity value is {@code 0}.
2326 *
2327 * @param m the mask controlling lane selection
2328 * @return the addition of all the lane elements of this vector
2329 */
2330 public abstract $type$ addAll(Mask<$Boxtype$> m);
2331
2332 /**
2333 * Subtracts all lane elements of this vector.
2334 * <p>
2335 * This is an associative vector reduction operation where the subtraction
2336 * operation ({@code -}) is applied to lane elements,
2337 * and the identity value is {@code 0}.
2338 *
2339 * @return the subtraction of all the lane elements of this vector
2340 */
2341 public abstract $type$ subAll();
2342
2343 /**
2344 * Subtracts all lane elements of this vector, selecting lane elements
2345 * controlled by a mask.
2346 * <p>
2347 * This is an associative vector reduction operation where the subtraction
2348 * operation ({@code -}) is applied to lane elements,
2349 * and the identity value is {@code 0}.
2350 *
2351 * @param m the mask controlling lane selection
2352 * @return the subtraction of all the lane elements of this vector
2353 */
2354 public abstract $type$ subAll(Mask<$Boxtype$> m);
2355
2356 /**
2357 * Multiplies all lane elements of this vector.
2358 * <p>
2359 * This is an associative vector reduction operation where the
2360 * multiplication operation ({@code *}) is applied to lane elements,
2361 * and the identity value is {@code 1}.
2362 *
2363 * @return the multiplication of all the lane elements of this vector
2364 */
2365 public abstract $type$ mulAll();
2366
2367 /**
2368 * Multiplies all lane elements of this vector, selecting lane elements
2369 * controlled by a mask.
2370 * <p>
2371 * This is an associative vector reduction operation where the
2372 * multiplication operation ({@code *}) is applied to lane elements,
2373 * and the identity value is {@code 1}.
2374 *
2375 * @param m the mask controlling lane selection
2376 * @return the multiplication of all the lane elements of this vector
2377 */
2378 public abstract $type$ mulAll(Mask<$Boxtype$> m);
2379
2380 /**
2381 * Returns the minimum lane element of this vector.
2382 * <p>
2383 * This is an associative vector reduction operation where the operation
2384 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
2385 * and the identity value is {@link $Boxtype$#MAX_VALUE}.
2386 *
2387 * @return the minimum lane element of this vector
2388 */
2389 public abstract $type$ minAll();
2390
2391 /**
2392 * Returns the minimum lane element of this vector, selecting lane elements
2393 * controlled by a mask.
2394 * <p>
2395 * This is an associative vector reduction operation where the operation
2396 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
2397 * and the identity value is {@link $Boxtype$#MAX_VALUE}.
2398 *
2399 * @param m the mask controlling lane selection
2400 * @return the minimum lane element of this vector
2401 */
2402 public abstract $type$ minAll(Mask<$Boxtype$> m);
2403
2404 /**
2405 * Returns the maximum lane element of this vector.
2406 * <p>
2407 * This is an associative vector reduction operation where the operation
2408 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
2409 * and the identity value is {@link $Boxtype$#MIN_VALUE}.
2410 *
2411 * @return the maximum lane element of this vector
2412 */
2413 public abstract $type$ maxAll();
2414
2415 /**
2416 * Returns the maximum lane element of this vector, selecting lane elements
2417 * controlled by a mask.
2418 * <p>
2419 * This is an associative vector reduction operation where the operation
2420 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
2421 * and the identity value is {@link $Boxtype$#MIN_VALUE}.
2422 *
2423 * @param m the mask controlling lane selection
2424 * @return the maximum lane element of this vector
2425 */
2426 public abstract $type$ maxAll(Mask<$Boxtype$> m);
2427
2428 #if[BITWISE]
2429 /**
2430 * Logically ORs all lane elements of this vector.
2431 * <p>
2432 * This is an associative vector reduction operation where the logical OR
2433 * operation ({@code |}) is applied to lane elements,
2434 * and the identity value is {@code 0}.
2435 *
2436 * @return the logical OR all the lane elements of this vector
2437 */
2438 public abstract $type$ orAll();
2439
2440 /**
2441 * Logically ORs all lane elements of this vector, selecting lane elements
2626 * @param j the offset into the index map
2627 * @throws IndexOutOfBoundsException if {@code j < 0}, or
2628 * {@code j > indexMap.length - this.length()},
2629 * or for any vector lane index {@code N} where the mask at lane
2630 * {@code N} is set the result of {@code i + indexMap[j + N]} is
2631 * {@code < 0} or {@code >= a.length}
2632 */
2633 #if[byteOrShort]
2634 public void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
2635 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
2636 }
2637 #else[byteOrShort]
2638 public abstract void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j);
2639 #end[byteOrShort]
2640 // Species
2641
2642 @Override
2643 public abstract $Type$Species species();
2644
2645 /**
2646 * A specialized factory for creating {@link $abstractvectortype$} value of the same
2647 * shape, and a {@link Mask} and {@link Shuffle} values of the same shape
2648 * and {@code int} element type.
2649 */
2650 public static abstract class $Type$Species extends Vector.Species<$Boxtype$> {
2651 interface FOp {
2652 $type$ apply(int i);
2653 }
2654
2655 abstract $abstractvectortype$ op(FOp f);
2656
2657 abstract $abstractvectortype$ op(Mask<$Boxtype$> m, FOp f);
2658
2659 interface FOpm {
2660 boolean apply(int i);
2661 }
2662
2663 abstract Mask<$Boxtype$> opm(FOpm f);
2664
2665 #if[!byteOrShort]
2666 abstract IntVector.IntSpecies indexSpecies();
2667 #end[!byteOrShort]
2668
2684
2685 /**
2686 * Returns a vector where the first lane element is set to the primtive
2687 * value {@code e}, all other lane elements are set to the default
2688 * value.
2689 *
2690 * @param e the value
2691 * @return a vector where the first lane element is set to the primitive
2692 * value {@code e}
2693 */
2694 @ForceInline
2695 public final $abstractvectortype$ single($type$ e) {
2696 return zero().with(0, e);
2697 }
2698
2699 /**
2700 * Returns a vector where each lane element is set to a randomly
2701 * generated primitive value.
2702 *
2703 * The semantics are equivalent to calling
2704 * {@link {#if[FP]?ThreadLocalRandom#next$Type$:($type$)ThreadLocalRandom#nextInt()} }
2705 *
2706 * @return a vector where each lane elements is set to a randomly
2707 * generated primitive value
2708 */
2709 #if[intOrLong]
2710 public $abstractvectortype$ random() {
2711 ThreadLocalRandom r = ThreadLocalRandom.current();
2712 return op(i -> r.next$Type$());
2713 }
2714 #else[intOrLong]
2715 #if[FP]
2716 public $abstractvectortype$ random() {
2717 ThreadLocalRandom r = ThreadLocalRandom.current();
2718 return op(i -> r.next$Type$());
2719 }
2720 #else[FP]
2721 public $abstractvectortype$ random() {
2722 ThreadLocalRandom r = ThreadLocalRandom.current();
2723 return op(i -> ($type$) r.nextInt());
2724 }
|
90 }
91
92 abstract Mask<$Boxtype$> bTest(Vector<$Boxtype$> v, FBinTest f);
93
94 // Foreach
95
96 interface FUnCon {
97 void apply(int i, $type$ a);
98 }
99
100 abstract void forEach(FUnCon f);
101
102 abstract void forEach(Mask<$Boxtype$> m, FUnCon f);
103
104 // Static factories
105
106 /**
107 * Returns a vector where all lane elements are set to the default
108 * primitive value.
109 *
110 * @param species species of desired vector
111 * @return a zero vector of given species
112 */
113 @ForceInline
114 @SuppressWarnings("unchecked")
115 public static $abstractvectortype$ zero($Type$Species species) {
116 return species.zero();
117 }
118
119 /**
120 * Loads a vector from a byte array starting at an offset.
121 * <p>
122 * Bytes are composed into primitive lane elements according to the
123 * native byte order of the underlying platform
124 * <p>
125 * This method behaves as if it returns the result of calling the
126 * byte buffer, offset, and mask accepting
127 * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask) method} as follows:
128 * <pre>{@code
129 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
130 * }</pre>
131 *
132 * @param species species of desired vector
133 * @param a the byte array
134 * @param ix the offset into the array
135 * @return a vector loaded from a byte array
136 * @throws IndexOutOfBoundsException if {@code i < 0} or
137 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
138 */
139 @ForceInline
140 @SuppressWarnings("unchecked")
141 public static $abstractvectortype$ fromByteArray($Type$Species species, byte[] a, int ix) {
142 Objects.requireNonNull(a);
143 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
144 return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
145 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
146 a, ix, species,
147 (c, idx, s) -> {
148 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
149 $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
150 return (($Type$Species)s).op(i -> tb.get());
151 });
152 }
153
154 /**
155 * Loads a vector from a byte array starting at an offset and using a
156 * mask.
157 * <p>
158 * Bytes are composed into primitive lane elements according to the
159 * native byte order of the underlying platform.
160 * <p>
161 * This method behaves as if it returns the result of calling the
162 * byte buffer, offset, and mask accepting
163 * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask) method} as follows:
164 * <pre>{@code
165 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
166 * }</pre>
167 *
168 * @param species species of desired vector
169 * @param a the byte array
170 * @param ix the offset into the array
171 * @param m the mask
172 * @return a vector loaded from a byte array
173 * @throws IndexOutOfBoundsException if {@code i < 0} or
174 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
175 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
176 * or {@code > a.length},
177 * for any vector lane index {@code N} where the mask at lane {@code N}
178 * is set
179 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
180 */
181 @ForceInline
182 public static $abstractvectortype$ fromByteArray($Type$Species species, byte[] a, int ix, Mask<$Boxtype$> m) {
183 return zero(species).blend(fromByteArray(species, a, ix), m);
184 }
185
186 /**
187 * Loads a vector from an array starting at offset.
188 * <p>
189 * For each vector lane, where {@code N} is the vector lane index, the
190 * array element at index {@code i + N} is placed into the
191 * resulting vector at lane index {@code N}.
192 *
193 * @param species species of desired vector
194 * @param a the array
195 * @param i the offset into the array
196 * @return the vector loaded from an array
197 * @throws IndexOutOfBoundsException if {@code i < 0}, or
198 * {@code i > a.length - this.length()}
199 */
200 @ForceInline
201 @SuppressWarnings("unchecked")
202 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i){
203 Objects.requireNonNull(a);
204 i = VectorIntrinsics.checkIndex(i, a.length, species.length());
205 return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
206 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_$TYPE$_BASE_OFFSET,
207 a, i, species,
208 (c, idx, s) -> (($Type$Species)s).op(n -> c[idx + n]));
209 }
210
211
212 /**
213 * Loads a vector from an array starting at offset and using a mask.
214 * <p>
215 * For each vector lane, where {@code N} is the vector lane index,
216 * if the mask lane at index {@code N} is set then the array element at
217 * index {@code i + N} is placed into the resulting vector at lane index
218 * {@code N}, otherwise the default element value is placed into the
219 * resulting vector at lane index {@code N}.
220 *
221 * @param species species of desired vector
222 * @param a the array
223 * @param i the offset into the array
224 * @param m the mask
225 * @return the vector loaded from an array
226 * @throws IndexOutOfBoundsException if {@code i < 0}, or
227 * for any vector lane index {@code N} where the mask at lane {@code N}
228 * is set {@code i > a.length - N}
229 */
230 @ForceInline
231 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m) {
232 return zero(species).blend(fromArray(species, a, i), m);
233 }
234
235 /**
236 * Loads a vector from an array using indexes obtained from an index
237 * map.
238 * <p>
239 * For each vector lane, where {@code N} is the vector lane index, the
240 * array element at index {@code i + indexMap[j + N]} is placed into the
241 * resulting vector at lane index {@code N}.
242 *
243 * @param species species of desired vector
244 * @param a the array
245 * @param i the offset into the array, may be negative if relative
246 * indexes in the index map compensate to produce a value within the
247 * array bounds
248 * @param indexMap the index map
249 * @param j the offset into the index map
250 * @return the vector loaded from an array
251 * @throws IndexOutOfBoundsException if {@code j < 0}, or
252 * {@code j > indexMap.length - this.length()},
253 * or for any vector lane index {@code N} the result of
254 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
255 */
256 #if[byteOrShort]
257 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, int[] indexMap, int j) {
258 return species.op(n -> a[i + indexMap[j + n]]);
259 }
260 #else[byteOrShort]
261 @ForceInline
262 @SuppressWarnings("unchecked")
263 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, int[] indexMap, int j) {
274 IntVector vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
275
276 vix = VectorIntrinsics.checkIndex(vix, a.length);
277
278 return VectorIntrinsics.loadWithMap((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
279 species.indexSpecies().vectorType(), a, Unsafe.ARRAY_$TYPE$_BASE_OFFSET, vix,
280 a, i, indexMap, j, species,
281 (c, idx, iMap, idy, s) -> (($Type$Species)s).op(n -> c[idx + iMap[idy+n]]));
282 }
283
284 #end[byteOrShort]
285 /**
286 * Loads a vector from an array using indexes obtained from an index
287 * map and using a mask.
288 * <p>
289 * For each vector lane, where {@code N} is the vector lane index,
290 * if the mask lane at index {@code N} is set then the array element at
291 * index {@code i + indexMap[j + N]} is placed into the resulting vector
292 * at lane index {@code N}.
293 *
294 * @param species species of desired vector
295 * @param a the array
296 * @param i the offset into the array, may be negative if relative
297 * indexes in the index map compensate to produce a value within the
298 * array bounds
299 * @param m the mask
300 * @param indexMap the index map
301 * @param j the offset into the index map
302 * @return the vector loaded from an array
303 * @throws IndexOutOfBoundsException if {@code j < 0}, or
304 * {@code j > indexMap.length - this.length()},
305 * or for any vector lane index {@code N} where the mask at lane
306 * {@code N} is set the result of {@code i + indexMap[j + N]} is
307 * {@code < 0} or {@code >= a.length}
308 */
309 #if[byteOrShort]
310 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
311 return species.op(m, n -> a[i + indexMap[j + n]]);
312 }
313 #else[byteOrShort]
314 @ForceInline
315 @SuppressWarnings("unchecked")
316 public static $abstractvectortype$ fromArray($Type$Species species, $type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
317 // @@@ This can result in out of bounds errors for unset mask lanes
318 return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
319 }
320
321 #end[byteOrShort]
322
323 /**
324 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
325 * offset into the byte buffer.
326 * <p>
327 * Bytes are composed into primitive lane elements according to the
328 * native byte order of the underlying platform.
329 * <p>
330 * This method behaves as if it returns the result of calling the
331 * byte buffer, offset, and mask accepting
332 * {@link #fromByteBuffer($Type$Species, ByteBuffer, int, Mask)} method} as follows:
333 * <pre>{@code
334 * return this.fromByteBuffer(b, i, this.maskAllTrue())
335 * }</pre>
336 *
337 * @param species species of desired vector
338 * @param bb the byte buffer
339 * @param ix the offset into the byte buffer
340 * @return a vector loaded from a byte buffer
341 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
342 * or {@code > b.limit()},
343 * or if there are fewer than
344 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
345 * remaining in the byte buffer from the given offset
346 */
347 @ForceInline
348 @SuppressWarnings("unchecked")
349 public static $abstractvectortype$ fromByteBuffer($Type$Species species, ByteBuffer bb, int ix) {
350 if (bb.order() != ByteOrder.nativeOrder()) {
351 throw new IllegalArgumentException();
352 }
353 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
354 return VectorIntrinsics.load((Class<$abstractvectortype$>) species.boxType(), $type$.class, species.length(),
355 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
356 bb, ix, species,
357 (c, idx, s) -> {
369 * {@link java.nio.Buffer buffer} for the primitive element type,
370 * according to the native byte order of the underlying platform, and
371 * the returned vector is loaded with a mask from a primitive array
372 * obtained from the primitive buffer.
373 * The following pseudocode expresses the behaviour, where
374 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
375 * primitive element type, and {@code ESpecies<S>} is the primitive
376 * species for {@code e}:
377 * <pre>{@code
378 * EBuffer eb = b.duplicate().
379 * order(ByteOrder.nativeOrder()).position(i).
380 * asEBuffer();
381 * e[] es = new e[this.length()];
382 * for (int n = 0; n < t.length; n++) {
383 * if (m.isSet(n))
384 * es[n] = eb.get(n);
385 * }
386 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
387 * }</pre>
388 *
389 * @param species species of desired vector
390 * @param bb the byte buffer
391 * @param ix the offset into the byte buffer
392 * @param m the mask
393 * @return a vector loaded from a byte buffer
394 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
395 * or {@code > b.limit()},
396 * for any vector lane index {@code N} where the mask at lane {@code N}
397 * is set
398 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
399 */
400 @ForceInline
401 public static $abstractvectortype$ fromByteBuffer($Type$Species species, ByteBuffer bb, int ix, Mask<$Boxtype$> m) {
402 return zero(species).blend(fromByteBuffer(species, bb, ix), m);
403 }
404
405 /**
406 * Returns a mask where each lane is set or unset according to given
407 * {@code boolean} values
408 * <p>
409 * For each mask lane, where {@code N} is the mask lane index,
410 * if the given {@code boolean} value at index {@code N} is {@code true}
411 * then the mask lane at index {@code N} is set, otherwise it is unset.
412 *
413 * @param species mask species
414 * @param bits the given {@code boolean} values
415 * @return a mask where each lane is set or unset according to the given {@code boolean} value
416 * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
417 */
418 @ForceInline
419 public static Mask<$Boxtype$> maskFromValues($Type$Species species, boolean... bits) {
420 if (species.boxType() == $Type$MaxVector.class)
421 return new $Type$MaxVector.$Type$MaxMask(bits);
422 switch (species.bitSize()) {
423 case 64: return new $Type$64Vector.$Type$64Mask(bits);
424 case 128: return new $Type$128Vector.$Type$128Mask(bits);
425 case 256: return new $Type$256Vector.$Type$256Mask(bits);
426 case 512: return new $Type$512Vector.$Type$512Mask(bits);
427 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
428 }
429 }
430
431 // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
432 static Mask<$Boxtype$> trueMask($Type$Species species) {
433 if (species.boxType() == $Type$MaxVector.class)
434 return $Type$MaxVector.$Type$MaxMask.TRUE_MASK;
435 switch (species.bitSize()) {
436 case 64: return $Type$64Vector.$Type$64Mask.TRUE_MASK;
437 case 128: return $Type$128Vector.$Type$128Mask.TRUE_MASK;
438 case 256: return $Type$256Vector.$Type$256Mask.TRUE_MASK;
439 case 512: return $Type$512Vector.$Type$512Mask.TRUE_MASK;
440 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
441 }
442 }
443
444 static Mask<$Boxtype$> falseMask($Type$Species species) {
445 if (species.boxType() == $Type$MaxVector.class)
446 return $Type$MaxVector.$Type$MaxMask.FALSE_MASK;
447 switch (species.bitSize()) {
448 case 64: return $Type$64Vector.$Type$64Mask.FALSE_MASK;
449 case 128: return $Type$128Vector.$Type$128Mask.FALSE_MASK;
450 case 256: return $Type$256Vector.$Type$256Mask.FALSE_MASK;
451 case 512: return $Type$512Vector.$Type$512Mask.FALSE_MASK;
452 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
453 }
454 }
455
456 /**
457 * Loads a mask from a {@code boolean} array starting at an offset.
458 * <p>
459 * For each mask lane, where {@code N} is the mask lane index,
460 * if the array element at index {@code ix + N} is {@code true} then the
461 * mask lane at index {@code N} is set, otherwise it is unset.
462 *
463 * @param species mask species
464 * @param bits the {@code boolean} array
465 * @param ix the offset into the array
466 * @return the mask loaded from a {@code boolean} array
467 * @throws IndexOutOfBoundsException if {@code ix < 0}, or
468 * {@code ix > bits.length - species.length()}
469 */
470 @ForceInline
471 @SuppressWarnings("unchecked")
472 public static Mask<$Boxtype$> maskFromArray($Type$Species species, boolean[] bits, int ix) {
473 Objects.requireNonNull(bits);
474 ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
475 return VectorIntrinsics.load((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
476 bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
477 bits, ix, species,
478 (c, idx, s) -> (Mask<$Boxtype$>) (($Type$Species)s).opm(n -> c[idx + n]));
479 }
480
481 /**
482 * Returns a mask where all lanes are set.
483 *
484 * @param species mask species
485 * @return a mask where all lanes are set
486 */
487 @ForceInline
488 @SuppressWarnings("unchecked")
489 public static Mask<$Boxtype$> maskAllTrue($Type$Species species) {
490 return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
491 ($bitstype$)-1, species,
492 ((z, s) -> trueMask(($Type$Species)s)));
493 }
494
495 /**
496 * Returns a mask where all lanes are unset.
497 *
498 * @param species mask species
499 * @return a mask where all lanes are unset
500 */
501 @ForceInline
502 @SuppressWarnings("unchecked")
503 public static Mask<$Boxtype$> maskAllFalse($Type$Species species) {
504 return VectorIntrinsics.broadcastCoerced((Class<Mask<$Boxtype$>>) species.maskType(), $bitstype$.class, species.length(),
505 0, species,
506 ((z, s) -> falseMask(($Type$Species)s)));
507 }
508
509 /**
510 * Returns a shuffle of mapped indexes where each lane element is
511 * the result of applying a mapping function to the corresponding lane
512 * index.
513 * <p>
514 * Care should be taken to ensure Shuffle values produced from this
515 * method are consumed as constants to ensure optimal generation of
516 * code. For example, values held in static final fields or values
517 * held in loop constant local variables.
518 * <p>
519 * This method behaves as if a shuffle is created from an array of
520 * mapped indexes as follows:
521 * <pre>{@code
522 * int[] a = new int[species.length()];
523 * for (int i = 0; i < a.length; i++) {
524 * a[i] = f.applyAsInt(i);
525 * }
526 * return this.shuffleFromValues(a);
527 * }</pre>
528 *
529 * @param species shuffle species
530 * @param f the lane index mapping function
531 * @return a shuffle of mapped indexes
532 */
533 @ForceInline
534 public static Shuffle<$Boxtype$> shuffle($Type$Species species, IntUnaryOperator f) {
535 if (species.boxType() == $Type$MaxVector.class)
536 return new $Type$MaxVector.$Type$MaxShuffle(f);
537 switch (species.bitSize()) {
538 case 64: return new $Type$64Vector.$Type$64Shuffle(f);
539 case 128: return new $Type$128Vector.$Type$128Shuffle(f);
540 case 256: return new $Type$256Vector.$Type$256Shuffle(f);
541 case 512: return new $Type$512Vector.$Type$512Shuffle(f);
542 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
543 }
544 }
545
546 /**
547 * Returns a shuffle where each lane element is the value of its
548 * corresponding lane index.
549 * <p>
550 * This method behaves as if a shuffle is created from an identity
551 * index mapping function as follows:
552 * <pre>{@code
553 * return this.shuffle(i -> i);
554 * }</pre>
555 *
556 * @param species shuffle species
557 * @return a shuffle of lane indexes
558 */
559 @ForceInline
560 public static Shuffle<$Boxtype$> shuffleIota($Type$Species species) {
561 if (species.boxType() == $Type$MaxVector.class)
562 return new $Type$MaxVector.$Type$MaxShuffle(AbstractShuffle.IDENTITY);
563 switch (species.bitSize()) {
564 case 64: return new $Type$64Vector.$Type$64Shuffle(AbstractShuffle.IDENTITY);
565 case 128: return new $Type$128Vector.$Type$128Shuffle(AbstractShuffle.IDENTITY);
566 case 256: return new $Type$256Vector.$Type$256Shuffle(AbstractShuffle.IDENTITY);
567 case 512: return new $Type$512Vector.$Type$512Shuffle(AbstractShuffle.IDENTITY);
568 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
569 }
570 }
571
572 /**
573 * Returns a shuffle where each lane element is set to a given
574 * {@code int} value logically AND'ed by the species length minus one.
575 * <p>
576 * For each shuffle lane, where {@code N} is the shuffle lane index, the
577 * the {@code int} value at index {@code N} logically AND'ed by
578 * {@code species.length() - 1} is placed into the resulting shuffle at
579 * lane index {@code N}.
580 *
581 * @param species shuffle species
582 * @param ixs the given {@code int} values
583 * @return a shuffle where each lane element is set to a given
584 * {@code int} value
585 * @throws IndexOutOfBoundsException if the number of int values is
586 * {@code < species.length()}
587 */
588 @ForceInline
589 public static Shuffle<$Boxtype$> shuffleFromValues($Type$Species species, int... ixs) {
590 if (species.boxType() == $Type$MaxVector.class)
591 return new $Type$MaxVector.$Type$MaxShuffle(ixs);
592 switch (species.bitSize()) {
593 case 64: return new $Type$64Vector.$Type$64Shuffle(ixs);
594 case 128: return new $Type$128Vector.$Type$128Shuffle(ixs);
595 case 256: return new $Type$256Vector.$Type$256Shuffle(ixs);
596 case 512: return new $Type$512Vector.$Type$512Shuffle(ixs);
597 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
598 }
599 }
600
601 /**
602 * Loads a shuffle from an {@code int} array starting at an offset.
603 * <p>
604 * For each shuffle lane, where {@code N} is the shuffle lane index, the
605 * array element at index {@code i + N} logically AND'ed by
606 * {@code species.length() - 1} is placed into the resulting shuffle at lane
607 * index {@code N}.
608 *
609 * @param species shuffle species
610 * @param ixs the {@code int} array
611 * @param i the offset into the array
612 * @return a shuffle loaded from the {@code int} array
613 * @throws IndexOutOfBoundsException if {@code i < 0}, or
614 * {@code i > a.length - species.length()}
615 */
616 @ForceInline
617 public static Shuffle<$Boxtype$> shuffleFromArray($Type$Species species, int[] ixs, int i) {
618 if (species.boxType() == $Type$MaxVector.class)
619 return new $Type$MaxVector.$Type$MaxShuffle(ixs, i);
620 switch (species.bitSize()) {
621 case 64: return new $Type$64Vector.$Type$64Shuffle(ixs, i);
622 case 128: return new $Type$128Vector.$Type$128Shuffle(ixs, i);
623 case 256: return new $Type$256Vector.$Type$256Shuffle(ixs, i);
624 case 512: return new $Type$512Vector.$Type$512Shuffle(ixs, i);
625 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
626 }
627 }
628
629
630 // Ops
631
632 @Override
633 public abstract $abstractvectortype$ add(Vector<$Boxtype$> v);
634
635 /**
1925
1926 /**
1927 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1928 * <p>
1929 * This is a vector unary operation where the primitive bitwise NOT
1930 * operation ({@code ~}) is applied to lane elements.
1931 *
1932 * @param m the mask controlling lane selection
1933 * @return the bitwise NOT of this vector
1934 */
1935 public abstract $abstractvectortype$ not(Mask<$Boxtype$> m);
1936
1937 #if[byte]
1938 /**
1939 * Logically left shifts this vector by the broadcast of an input scalar.
1940 * <p>
1941 * This is a vector binary operation where the primitive logical left shift
1942 * operation ({@code <<}) is applied to lane elements to left shift the
1943 * element by shift value as specified by the input scalar. Only the 3
1944 * lowest-order bits of shift value are used. It is as if the shift value
1945 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1946 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1947 *
1948 * @param s the input scalar; the number of the bits to left shift
1949 * @return the result of logically left shifting left this vector by the
1950 * broadcast of an input scalar
1951 */
1952 #end[byte]
1953 #if[short]
1954 /**
1955 * Logically left shifts this vector by the broadcast of an input scalar.
1956 * <p>
1957 * This is a vector binary operation where the primitive logical left shift
1958 * operation ({@code <<}) is applied to lane elements to left shift the
1959 * element by shift value as specified by the input scalar. Only the 4
1960 * lowest-order bits of shift value are used. It is as if the shift value
1961 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
1962 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
1963 *
1964 * @param s the input scalar; the number of the bits to left shift
1965 * @return the result of logically left shifting left this vector by the
1966 * broadcast of an input scalar
1967 */
1968 #end[short]
1969 #if[intOrLong]
1970 /**
1971 * Logically left shifts this vector by the broadcast of an input scalar.
1972 * <p>
1973 * This is a vector binary operation where the primitive logical left shift
1974 * operation ({@code <<}) is applied to lane elements.
1975 *
1976 * @param s the input scalar; the number of the bits to left shift
1977 * @return the result of logically left shifting left this vector by the
1978 * broadcast of an input scalar
1979 */
1980 #end[intOrLong]
1981 public abstract $abstractvectortype$ shiftL(int s);
1982
1983 #if[byte]
1984 /**
1985 * Logically left shifts this vector by the broadcast of an input scalar,
1986 * selecting lane elements controlled by a mask.
1987 * <p>
1988 * This is a vector binary operation where the primitive logical left shift
1989 * operation ({@code <<}) is applied to lane elements to left shift the
1990 * element by shift value as specified by the input scalar. Only the 3
1991 * lowest-order bits of shift value are used. It is as if the shift value
1992 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1993 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1994 *
1995 * @param s the input scalar; the number of the bits to left shift
1996 * @param m the mask controlling lane selection
1997 * @return the result of logically left shifting left this vector by the
1998 * broadcast of an input scalar
1999 */
2000 #end[byte]
2001 #if[short]
2002 /**
2003 * Logically left shifts this vector by the broadcast of an input scalar,
2004 * selecting lane elements controlled by a mask.
2005 * <p>
2006 * This is a vector binary operation where the primitive logical left shift
2007 * operation ({@code <<}) is applied to lane elements to left shift the
2008 * element by shift value as specified by the input scalar. Only the 4
2009 * lowest-order bits of shift value are used. It is as if the shift value
2010 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
2011 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2012 *
2013 * @param s the input scalar; the number of the bits to left shift
2014 * @param m the mask controlling lane selection
2015 * @return the result of logically left shifting left this vector by the
2016 * broadcast of an input scalar
2017 */
2018 #end[short]
2019 #if[intOrLong]
2020 /**
2021 * Logically left shifts this vector by the broadcast of an input scalar,
2022 * selecting lane elements controlled by a mask.
2023 * <p>
2024 * This is a vector binary operation where the primitive logical left shift
2025 * operation ({@code <<}) is applied to lane elements.
2026 *
2027 * @param s the input scalar; the number of the bits to left shift
2028 * @param m the mask controlling lane selection
2029 * @return the result of logically left shifting this vector by the
2030 * broadcast of an input scalar
2056 * @param m the mask controlling lane selection
2057 * @return the result of logically left shifting this vector by the input
2058 * vector
2059 */
2060 public $abstractvectortype$ shiftL(Vector<$Boxtype$> v, Mask<$Boxtype$> m) {
2061 return bOp(v, m, (i, a, b) -> ($type$) (a << b));
2062 }
2063 #end[intOrLong]
2064
2065 // logical, or unsigned, shift right
2066
2067 #if[byte]
2068 /**
2069 * Logically right shifts (or unsigned right shifts) this vector by the
2070 * broadcast of an input scalar.
2071 * <p>
2072 * This is a vector binary operation where the primitive logical right shift
2073 * operation ({@code >>>}) is applied to lane elements to logically right shift the
2074 * element by shift value as specified by the input scalar. Only the 3
2075 * lowest-order bits of shift value are used. It is as if the shift value
2076 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
2077 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2078 *
2079 * @param s the input scalar; the number of the bits to right shift
2080 * @return the result of logically right shifting this vector by the
2081 * broadcast of an input scalar
2082 */
2083 #end[byte]
2084 #if[short]
2085 /**
2086 * Logically right shifts (or unsigned right shifts) this vector by the
2087 * broadcast of an input scalar.
2088 * <p>
2089 * This is a vector binary operation where the primitive logical right shift
2090 * operation ({@code >>>}) is applied to lane elements to logically right shift the
2091 * element by shift value as specified by the input scalar. Only the 4
2092 * lowest-order bits of shift value are used. It is as if the shift value
2093 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
2094 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2095 *
2096 * @param s the input scalar; the number of the bits to right shift
2097 * @return the result of logically right shifting this vector by the
2098 * broadcast of an input scalar
2099 */
2100 #end[short]
2101 #if[intOrLong]
2102 /**
2103 * Logically right shifts (or unsigned right shifts) this vector by the
2104 * broadcast of an input scalar.
2105 * <p>
2106 * This is a vector binary operation where the primitive logical right shift
2107 * operation ({@code >>>}) is applied to lane elements.
2108 *
2109 * @param s the input scalar; the number of the bits to right shift
2110 * @return the result of logically right shifting this vector by the
2111 * broadcast of an input scalar
2112 */
2113 #end[intOrLong]
2114 public abstract $abstractvectortype$ shiftR(int s);
2115
2116 #if[byte]
2117 /**
2118 * Logically right shifts (or unsigned right shifts) this vector by the
2119 * broadcast of an input scalar, selecting lane elements controlled by a
2120 * mask.
2121 * <p>
2122 * This is a vector binary operation where the primitive logical right shift
2123 * operation ({@code >>>}) is applied to lane elements to logically right shift the
2124 * element by shift value as specified by the input scalar. Only the 3
2125 * lowest-order bits of shift value are used. It is as if the shift value
2126 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
2127 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2128 *
2129 * @param s the input scalar; the number of the bits to right shift
2130 * @param m the mask controlling lane selection
2131 * @return the result of logically right shifting this vector by the
2132 * broadcast of an input scalar
2133 */
2134 #end[byte]
2135 #if[short]
2136 /**
2137 * Logically right shifts (or unsigned right shifts) this vector by the
2138 * broadcast of an input scalar, selecting lane elements controlled by a
2139 * mask.
2140 * <p>
2141 * This is a vector binary operation where the primitive logical right shift
2142 * operation ({@code >>>}) is applied to lane elements to logically right shift the
2143 * element by shift value as specified by the input scalar. Only the 4
2144 * lowest-order bits of shift value are used. It is as if the shift value
2145 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
2146 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2147 *
2148 * @param s the input scalar; the number of the bits to right shift
2149 * @param m the mask controlling lane selection
2150 * @return the result of logically right shifting this vector by the
2151 * broadcast of an input scalar
2152 */
2153 #end[short]
2154 #if[intOrLong]
2155 /**
2156 * Logically right shifts (or unsigned right shifts) this vector by the
2157 * broadcast of an input scalar, selecting lane elements controlled by a
2158 * mask.
2159 * <p>
2160 * This is a vector binary operation where the primitive logical right shift
2161 * operation ({@code >>>}) is applied to lane elements.
2162 *
2163 * @param s the input scalar; the number of the bits to right shift
2164 * @param m the mask controlling lane selection
2165 * @return the result of logically right shifting this vector by the
2166 * broadcast of an input scalar
2167 */
2168 #end[intOrLong]
2169 public abstract $abstractvectortype$ shiftR(int s, Mask<$Boxtype$> m);
2170
2171 #if[intOrLong]
2172 /**
2173 * Logically right shifts (or unsigned right shifts) this vector by an
2174 * input vector.
2175 * <p>
2176 * This is a vector binary operation where the primitive logical right shift
2177 * operation ({@code >>>}) is applied to lane elements.
2178 *
2179 * @param v the input vector
2180 * @return the result of logically right shifting this vector by the
2181 * input vector
2182 */
2183 public abstract $abstractvectortype$ shiftR(Vector<$Boxtype$> v);
2184
2191 *
2192 * @param v the input vector
2193 * @param m the mask controlling lane selection
2194 * @return the result of logically right shifting this vector by the
2195 * input vector
2196 */
2197 public $abstractvectortype$ shiftR(Vector<$Boxtype$> v, Mask<$Boxtype$> m) {
2198 return bOp(v, m, (i, a, b) -> ($type$) (a >>> b));
2199 }
2200 #end[intOrLong]
2201
2202 #if[byte]
2203 /**
2204 * Arithmetically right shifts (or signed right shifts) this vector by the
2205 * broadcast of an input scalar.
2206 * <p>
2207 * This is a vector binary operation where the primitive arithmetic right
2208 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2209 * right shift the element by shift value as specified by the input scalar.
2210 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
2211 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
2212 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2213 *
2214 * @param s the input scalar; the number of the bits to right shift
2215 * @return the result of arithmetically right shifting this vector by the
2216 * broadcast of an input scalar
2217 */
2218 #end[byte]
2219 #if[short]
2220 /**
2221 * Arithmetically right shifts (or signed right shifts) this vector by the
2222 * broadcast of an input scalar.
2223 * <p>
2224 * This is a vector binary operation where the primitive arithmetic right
2225 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2226 * right shift the element by shift value as specified by the input scalar.
2227 * Only the 4 lowest-order bits of shift value are used. It is as if the shift
2228 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
2229 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2230 *
2231 * @param s the input scalar; the number of the bits to right shift
2232 * @return the result of arithmetically right shifting this vector by the
2233 * broadcast of an input scalar
2234 */
2235 #end[short]
2236 #if[intOrLong]
2237 /**
2238 * Arithmetically right shifts (or signed right shifts) this vector by the
2239 * broadcast of an input scalar.
2240 * <p>
2241 * This is a vector binary operation where the primitive arithmetic right
2242 * shift operation ({@code >>}) is applied to lane elements.
2243 *
2244 * @param s the input scalar; the number of the bits to right shift
2245 * @return the result of arithmetically right shifting this vector by the
2246 * broadcast of an input scalar
2247 */
2248 #end[intOrLong]
2249 public abstract $abstractvectortype$ aShiftR(int s);
2250
2251 #if[byte]
2252 /**
2253 * Arithmetically right shifts (or signed right shifts) this vector by the
2254 * broadcast of an input scalar, selecting lane elements controlled by a
2255 * mask.
2256 * <p>
2257 * This is a vector binary operation where the primitive arithmetic right
2258 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2259 * right shift the element by shift value as specified by the input scalar.
2260 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
2261 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
2262 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
2263 *
2264 * @param s the input scalar; the number of the bits to right shift
2265 * @param m the mask controlling lane selection
2266 * @return the result of arithmetically right shifting this vector by the
2267 * broadcast of an input scalar
2268 */
2269 #end[byte]
2270 #if[short]
2271 /**
2272 * Arithmetically right shifts (or signed right shifts) this vector by the
2273 * broadcast of an input scalar, selecting lane elements controlled by a
2274 * mask.
2275 * <p>
2276 * This is a vector binary operation where the primitive arithmetic right
2277 * shift operation ({@code >>}) is applied to lane elements to arithmetically
2278 * right shift the element by shift value as specified by the input scalar.
2279 * Only the 4 lowest-order bits of shift value are used. It is as if the shift
2280 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF.
2281 * The shift distance actually used is therefore always in the range 0 to 15, inclusive.
2282 *
2283 * @param s the input scalar; the number of the bits to right shift
2284 * @param m the mask controlling lane selection
2285 * @return the result of arithmetically right shifting this vector by the
2286 * broadcast of an input scalar
2287 */
2288 #end[short]
2289 #if[intOrLong]
2290 /**
2291 * Arithmetically right shifts (or signed right shifts) this vector by the
2292 * broadcast of an input scalar, selecting lane elements controlled by a
2293 * mask.
2294 * <p>
2295 * This is a vector binary operation where the primitive arithmetic right
2296 * shift operation ({@code >>}) is applied to lane elements.
2297 *
2298 * @param s the input scalar; the number of the bits to right shift
2299 * @param m the mask controlling lane selection
2300 * @return the result of arithmetically right shifting this vector by the
2408 public final $abstractvectortype$ rotateR(int s, Mask<$Boxtype$> m) {
2409 return shiftR(s, m).or(shiftL(-s, m), m);
2410 }
2411 #end[intOrLong]
2412 #end[BITWISE]
2413
2414 @Override
2415 public abstract void intoByteArray(byte[] a, int ix);
2416
2417 @Override
2418 public abstract void intoByteArray(byte[] a, int ix, Mask<$Boxtype$> m);
2419
2420 @Override
2421 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
2422
2423 @Override
2424 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<$Boxtype$> m);
2425
2426
2427 // Type specific horizontal reductions
2428 /**
2429 * Adds all lane elements of this vector.
2430 * <p>
2431 #if[FP]
2432 * This is a vector reduction operation where the addition
2433 * operation ({@code +}) is applied to lane elements,
2434 * and the identity value is {@code 0.0}.
2435 *
2436 * <p>The value of a floating-point sum is a function both of the input values as well
2437 * as the order of addition operations. The order of addition operations of this method
2438 * is intentionally not defined to allow for JVM to generate optimal machine
2439 * code for the underlying platform at runtime. If the platform supports a vector
2440 * instruction to add all values in the vector, or if there is some other efficient machine
2441 * code sequence, then the JVM has the option of generating this machine code. Otherwise,
2442 * the default implementation of adding vectors sequentially from left to right is used.
2443 * For this reason, the output of this method may vary for the same input values.
2444 #else[FP]
2445 * This is an associative vector reduction operation where the addition
2446 * operation ({@code +}) is applied to lane elements,
2447 * and the identity value is {@code 0}.
2448 #end[FP]
2449 *
2450 * @return the addition of all the lane elements of this vector
2451 */
2452 public abstract $type$ addAll();
2453
2454 /**
2455 * Adds all lane elements of this vector, selecting lane elements
2456 * controlled by a mask.
2457 * <p>
2458 #if[FP]
2459 * This is a vector reduction operation where the addition
2460 * operation ({@code +}) is applied to lane elements,
2461 * and the identity value is {@code 0.0}.
2462 *
2463 * <p>The value of a floating-point sum is a function both of the input values as well
2464 * as the order of addition operations. The order of addition operations of this method
2465 * is intentionally not defined to allow for JVM to generate optimal machine
2466 * code for the underlying platform at runtime. If the platform supports a vector
2467 * instruction to add all values in the vector, or if there is some other efficient machine
2468 * code sequence, then the JVM has the option of generating this machine code. Otherwise,
2469 * the default implementation of adding vectors sequentially from left to right is used.
2470 * For this reason, the output of this method may vary on the same input values.
2471 #else[FP]
2472 * This is an associative vector reduction operation where the addition
2473 * operation ({@code +}) is applied to lane elements,
2474 * and the identity value is {@code 0}.
2475 #end[FP]
2476 *
2477 * @param m the mask controlling lane selection
2478 * @return the addition of the selected lane elements of this vector
2479 */
2480 public abstract $type$ addAll(Mask<$Boxtype$> m);
2481
2482 /**
2483 * Multiplies all lane elements of this vector.
2484 * <p>
2485 #if[FP]
2486 * This is a vector reduction operation where the
2487 * multiplication operation ({@code *}) is applied to lane elements,
2488 * and the identity value is {@code 1.0}.
2489 *
2490 * <p>The order of multiplication operations of this method
2491 * is intentionally not defined to allow for JVM to generate optimal machine
2492 * code for the underlying platform at runtime. If the platform supports a vector
2493 * instruction to multiply all values in the vector, or if there is some other efficient machine
2494 * code sequence, then the JVM has the option of generating this machine code. Otherwise,
2495 * the default implementation of multiplying vectors sequentially from left to right is used.
2496 * For this reason, the output of this method may vary on the same input values.
2497 #else[FP]
2498 * This is an associative vector reduction operation where the
2499 * multiplication operation ({@code *}) is applied to lane elements,
2500 * and the identity value is {@code 1}.
2501 #end[FP]
2502 *
2503 * @return the multiplication of all the lane elements of this vector
2504 */
2505 public abstract $type$ mulAll();
2506
2507 /**
2508 * Multiplies all lane elements of this vector, selecting lane elements
2509 * controlled by a mask.
2510 * <p>
2511 #if[FP]
2512 * This is a vector reduction operation where the
2513 * multiplication operation ({@code *}) is applied to lane elements,
2514 * and the identity value is {@code 1.0}.
2515 *
2516 * <p>The order of multiplication operations of this method
2517 * is intentionally not defined to allow for JVM to generate optimal machine
2518 * code for the underlying platform at runtime. If the platform supports a vector
2519 * instruction to multiply all values in the vector, or if there is some other efficient machine
2520 * code sequence, then the JVM has the option of generating this machine code. Otherwise,
2521 * the default implementation of multiplying vectors sequentially from left to right is used.
2522 * For this reason, the output of this method may vary on the same input values.
2523 #else[FP]
2524 * This is an associative vector reduction operation where the
2525 * multiplication operation ({@code *}) is applied to lane elements,
2526 * and the identity value is {@code 1}.
2527 #end[FP]
2528 *
2529 * @param m the mask controlling lane selection
2530 * @return the multiplication of all the lane elements of this vector
2531 */
2532 public abstract $type$ mulAll(Mask<$Boxtype$> m);
2533
2534 /**
2535 * Returns the minimum lane element of this vector.
2536 * <p>
2537 * This is an associative vector reduction operation where the operation
2538 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
2539 * and the identity value is
2540 #if[FP]
2541 * {@link $Boxtype$#POSITIVE_INFINITY}.
2542 #else[FP]
2543 * {@link $Boxtype$#MAX_VALUE}.
2544 #end[FP]
2545 *
2546 * @return the minimum lane element of this vector
2547 */
2548 public abstract $type$ minAll();
2549
2550 /**
2551 * Returns the minimum lane element of this vector, selecting lane elements
2552 * controlled by a mask.
2553 * <p>
2554 * This is an associative vector reduction operation where the operation
2555 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
2556 * and the identity value is
2557 #if[FP]
2558 * {@link $Boxtype$#POSITIVE_INFINITY}.
2559 #else[FP]
2560 * {@link $Boxtype$#MAX_VALUE}.
2561 #end[FP]
2562 *
2563 * @param m the mask controlling lane selection
2564 * @return the minimum lane element of this vector
2565 */
2566 public abstract $type$ minAll(Mask<$Boxtype$> m);
2567
2568 /**
2569 * Returns the maximum lane element of this vector.
2570 * <p>
2571 * This is an associative vector reduction operation where the operation
2572 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
2573 * and the identity value is
2574 #if[FP]
2575 * {@link $Boxtype$#NEGATIVE_INFINITY}.
2576 #else[FP]
2577 * {@link $Boxtype$#MIN_VALUE}.
2578 #end[FP]
2579 *
2580 * @return the maximum lane element of this vector
2581 */
2582 public abstract $type$ maxAll();
2583
2584 /**
2585 * Returns the maximum lane element of this vector, selecting lane elements
2586 * controlled by a mask.
2587 * <p>
2588 * This is an associative vector reduction operation where the operation
2589 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
2590 * and the identity value is
2591 #if[FP]
2592 * {@link $Boxtype$#NEGATIVE_INFINITY}.
2593 #else[FP]
2594 * {@link $Boxtype$#MIN_VALUE}.
2595 #end[FP]
2596 *
2597 * @param m the mask controlling lane selection
2598 * @return the maximum lane element of this vector
2599 */
2600 public abstract $type$ maxAll(Mask<$Boxtype$> m);
2601
2602 #if[BITWISE]
2603 /**
2604 * Logically ORs all lane elements of this vector.
2605 * <p>
2606 * This is an associative vector reduction operation where the logical OR
2607 * operation ({@code |}) is applied to lane elements,
2608 * and the identity value is {@code 0}.
2609 *
2610 * @return the logical OR all the lane elements of this vector
2611 */
2612 public abstract $type$ orAll();
2613
2614 /**
2615 * Logically ORs all lane elements of this vector, selecting lane elements
2800 * @param j the offset into the index map
2801 * @throws IndexOutOfBoundsException if {@code j < 0}, or
2802 * {@code j > indexMap.length - this.length()},
2803 * or for any vector lane index {@code N} where the mask at lane
2804 * {@code N} is set the result of {@code i + indexMap[j + N]} is
2805 * {@code < 0} or {@code >= a.length}
2806 */
2807 #if[byteOrShort]
2808 public void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j) {
2809 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
2810 }
2811 #else[byteOrShort]
2812 public abstract void intoArray($type$[] a, int i, Mask<$Boxtype$> m, int[] indexMap, int j);
2813 #end[byteOrShort]
2814 // Species
2815
2816 @Override
2817 public abstract $Type$Species species();
2818
2819 /**
2820 * Class representing {@link $abstractvectortype$}'s of the same {@link Vector.Shape Shape}.
2821 */
2822 public static abstract class $Type$Species extends Vector.Species<$Boxtype$> {
2823 interface FOp {
2824 $type$ apply(int i);
2825 }
2826
2827 abstract $abstractvectortype$ op(FOp f);
2828
2829 abstract $abstractvectortype$ op(Mask<$Boxtype$> m, FOp f);
2830
2831 interface FOpm {
2832 boolean apply(int i);
2833 }
2834
2835 abstract Mask<$Boxtype$> opm(FOpm f);
2836
2837 #if[!byteOrShort]
2838 abstract IntVector.IntSpecies indexSpecies();
2839 #end[!byteOrShort]
2840
2856
2857 /**
2858 * Returns a vector where the first lane element is set to the primtive
2859 * value {@code e}, all other lane elements are set to the default
2860 * value.
2861 *
2862 * @param e the value
2863 * @return a vector where the first lane element is set to the primitive
2864 * value {@code e}
2865 */
2866 @ForceInline
2867 public final $abstractvectortype$ single($type$ e) {
2868 return zero().with(0, e);
2869 }
2870
2871 /**
2872 * Returns a vector where each lane element is set to a randomly
2873 * generated primitive value.
2874 *
2875 * The semantics are equivalent to calling
2876 #if[FP]
2877 * {@code ThreadLocalRandom#next$Type$}.
2878 #else[FP]
2879 * {@code ($type$)ThreadLocalRandom#nextInt()}.
2880 #end[FP]
2881 *
2882 * @return a vector where each lane elements is set to a randomly
2883 * generated primitive value
2884 */
2885 #if[intOrLong]
2886 public $abstractvectortype$ random() {
2887 ThreadLocalRandom r = ThreadLocalRandom.current();
2888 return op(i -> r.next$Type$());
2889 }
2890 #else[intOrLong]
2891 #if[FP]
2892 public $abstractvectortype$ random() {
2893 ThreadLocalRandom r = ThreadLocalRandom.current();
2894 return op(i -> r.next$Type$());
2895 }
2896 #else[FP]
2897 public $abstractvectortype$ random() {
2898 ThreadLocalRandom r = ThreadLocalRandom.current();
2899 return op(i -> ($type$) r.nextInt());
2900 }
|