87 }
88
89 abstract Mask<Byte> bTest(Vector<Byte> v, FBinTest f);
90
91 // Foreach
92
93 interface FUnCon {
94 void apply(int i, byte a);
95 }
96
97 abstract void forEach(FUnCon f);
98
99 abstract void forEach(Mask<Byte> m, FUnCon f);
100
101 // Static factories
102
103 /**
104 * Returns a vector where all lane elements are set to the default
105 * primitive value.
106 *
107 * @return a zero vector
108 */
109 @ForceInline
110 @SuppressWarnings("unchecked")
111 public static ByteVector zero(ByteSpecies species) {
112 return species.zero();
113 }
114
115 /**
116 * Loads a vector from a byte array starting at an offset.
117 * <p>
118 * Bytes are composed into primitive lane elements according to the
119 * native byte order of the underlying platform
120 * <p>
121 * This method behaves as if it returns the result of calling the
122 * byte buffer, offset, and mask accepting
123 * {@link #fromByteBuffer(ByteSpecies, ByteBuffer, int, Mask) method} as follows:
124 * <pre>{@code
125 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
126 * }</pre>
127 *
128 * @param a the byte array
129 * @param ix the offset into the array
130 * @return a vector loaded from a byte array
131 * @throws IndexOutOfBoundsException if {@code i < 0} or
132 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
133 */
134 @ForceInline
135 @SuppressWarnings("unchecked")
136 public static ByteVector fromByteArray(ByteSpecies species, byte[] a, int ix) {
137 Objects.requireNonNull(a);
138 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
139 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
140 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
141 a, ix, species,
142 (c, idx, s) -> {
143 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
144 ByteBuffer tb = bbc;
145 return ((ByteSpecies)s).op(i -> tb.get());
146 });
147 }
148
149 /**
150 * Loads a vector from a byte array starting at an offset and using a
151 * mask.
152 * <p>
153 * Bytes are composed into primitive lane elements according to the
154 * native byte order of the underlying platform.
155 * <p>
156 * This method behaves as if it returns the result of calling the
157 * byte buffer, offset, and mask accepting
158 * {@link #fromByteBuffer(ByteSpecies, ByteBuffer, int, Mask) method} as follows:
159 * <pre>{@code
160 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
161 * }</pre>
162 *
163 * @param a the byte array
164 * @param ix the offset into the array
165 * @param m the mask
166 * @return a vector loaded from a byte array
167 * @throws IndexOutOfBoundsException if {@code i < 0} or
168 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
169 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
170 * or {@code > a.length},
171 * for any vector lane index {@code N} where the mask at lane {@code N}
172 * is set
173 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
174 */
175 @ForceInline
176 public static ByteVector fromByteArray(ByteSpecies species, byte[] a, int ix, Mask<Byte> m) {
177 return zero(species).blend(fromByteArray(species, a, ix), m);
178 }
179
180 /**
181 * Loads a vector from an array starting at offset.
182 * <p>
183 * For each vector lane, where {@code N} is the vector lane index, the
184 * array element at index {@code i + N} is placed into the
185 * resulting vector at lane index {@code N}.
186 *
187 * @param a the array
188 * @param i the offset into the array
189 * @return the vector loaded from an array
190 * @throws IndexOutOfBoundsException if {@code i < 0}, or
191 * {@code i > a.length - this.length()}
192 */
193 @ForceInline
194 @SuppressWarnings("unchecked")
195 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i){
196 Objects.requireNonNull(a);
197 i = VectorIntrinsics.checkIndex(i, a.length, species.length());
198 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
199 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
200 a, i, species,
201 (c, idx, s) -> ((ByteSpecies)s).op(n -> c[idx + n]));
202 }
203
204
205 /**
206 * Loads a vector from an array starting at offset and using a mask.
207 * <p>
208 * For each vector lane, where {@code N} is the vector lane index,
209 * if the mask lane at index {@code N} is set then the array element at
210 * index {@code i + N} is placed into the resulting vector at lane index
211 * {@code N}, otherwise the default element value is placed into the
212 * resulting vector at lane index {@code N}.
213 *
214 * @param a the array
215 * @param i the offset into the array
216 * @param m the mask
217 * @return the vector loaded from an array
218 * @throws IndexOutOfBoundsException if {@code i < 0}, or
219 * for any vector lane index {@code N} where the mask at lane {@code N}
220 * is set {@code i > a.length - N}
221 */
222 @ForceInline
223 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i, Mask<Byte> m) {
224 return zero(species).blend(fromArray(species, a, i), m);
225 }
226
227 /**
228 * Loads a vector from an array using indexes obtained from an index
229 * map.
230 * <p>
231 * For each vector lane, where {@code N} is the vector lane index, the
232 * array element at index {@code i + indexMap[j + N]} is placed into the
233 * resulting vector at lane index {@code N}.
234 *
235 * @param a the array
236 * @param i the offset into the array, may be negative if relative
237 * indexes in the index map compensate to produce a value within the
238 * array bounds
239 * @param indexMap the index map
240 * @param j the offset into the index map
241 * @return the vector loaded from an array
242 * @throws IndexOutOfBoundsException if {@code j < 0}, or
243 * {@code j > indexMap.length - this.length()},
244 * or for any vector lane index {@code N} the result of
245 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
246 */
247 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i, int[] indexMap, int j) {
248 return species.op(n -> a[i + indexMap[j + n]]);
249 }
250 /**
251 * Loads a vector from an array using indexes obtained from an index
252 * map and using a mask.
253 * <p>
254 * For each vector lane, where {@code N} is the vector lane index,
255 * if the mask lane at index {@code N} is set then the array element at
256 * index {@code i + indexMap[j + N]} is placed into the resulting vector
257 * at lane index {@code N}.
258 *
259 * @param a the array
260 * @param i the offset into the array, may be negative if relative
261 * indexes in the index map compensate to produce a value within the
262 * array bounds
263 * @param indexMap the index map
264 * @param j the offset into the index map
265 * @return the vector loaded from an array
266 * @throws IndexOutOfBoundsException if {@code j < 0}, or
267 * {@code j > indexMap.length - this.length()},
268 * or for any vector lane index {@code N} where the mask at lane
269 * {@code N} is set the result of {@code i + indexMap[j + N]} is
270 * {@code < 0} or {@code >= a.length}
271 */
272 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i, Mask<Byte> m, int[] indexMap, int j) {
273 return species.op(m, n -> a[i + indexMap[j + n]]);
274 }
275
276 /**
277 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
278 * offset into the byte buffer.
279 * <p>
280 * Bytes are composed into primitive lane elements according to the
281 * native byte order of the underlying platform.
282 * <p>
283 * This method behaves as if it returns the result of calling the
284 * byte buffer, offset, and mask accepting
285 * {@link #fromByteBuffer(ByteSpecies, ByteBuffer, int, Mask)} method} as follows:
286 * <pre>{@code
287 * return this.fromByteBuffer(b, i, this.maskAllTrue())
288 * }</pre>
289 *
290 * @param bb the byte buffer
291 * @param ix the offset into the byte buffer
292 * @return a vector loaded from a byte buffer
293 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
294 * or {@code > b.limit()},
295 * or if there are fewer than
296 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
297 * remaining in the byte buffer from the given offset
298 */
299 @ForceInline
300 @SuppressWarnings("unchecked")
301 public static ByteVector fromByteBuffer(ByteSpecies species, ByteBuffer bb, int ix) {
302 if (bb.order() != ByteOrder.nativeOrder()) {
303 throw new IllegalArgumentException();
304 }
305 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
306 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
307 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
308 bb, ix, species,
309 (c, idx, s) -> {
321 * {@link java.nio.Buffer buffer} for the primitive element type,
322 * according to the native byte order of the underlying platform, and
323 * the returned vector is loaded with a mask from a primitive array
324 * obtained from the primitive buffer.
325 * The following pseudocode expresses the behaviour, where
326 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
327 * primitive element type, and {@code ESpecies<S>} is the primitive
328 * species for {@code e}:
329 * <pre>{@code
330 * EBuffer eb = b.duplicate().
331 * order(ByteOrder.nativeOrder()).position(i).
332 * asEBuffer();
333 * e[] es = new e[this.length()];
334 * for (int n = 0; n < t.length; n++) {
335 * if (m.isSet(n))
336 * es[n] = eb.get(n);
337 * }
338 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
339 * }</pre>
340 *
341 * @param bb the byte buffer
342 * @param ix the offset into the byte buffer
343 * @return a vector loaded from a byte buffer
344 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
345 * or {@code > b.limit()},
346 * for any vector lane index {@code N} where the mask at lane {@code N}
347 * is set
348 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
349 */
350 @ForceInline
351 public static ByteVector fromByteBuffer(ByteSpecies species, ByteBuffer bb, int ix, Mask<Byte> m) {
352 return zero(species).blend(fromByteBuffer(species, bb, ix), m);
353 }
354
355 @ForceInline
356 public static Mask<Byte> maskFromValues(ByteSpecies species, boolean... bits) {
357 if (species.boxType() == ByteMaxVector.class)
358 return new ByteMaxVector.ByteMaxMask(bits);
359 switch (species.bitSize()) {
360 case 64: return new Byte64Vector.Byte64Mask(bits);
361 case 128: return new Byte128Vector.Byte128Mask(bits);
362 case 256: return new Byte256Vector.Byte256Mask(bits);
363 case 512: return new Byte512Vector.Byte512Mask(bits);
364 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
365 }
366 }
367
368 // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
369 static Mask<Byte> trueMask(ByteSpecies species) {
370 if (species.boxType() == ByteMaxVector.class)
371 return ByteMaxVector.ByteMaxMask.TRUE_MASK;
372 switch (species.bitSize()) {
373 case 64: return Byte64Vector.Byte64Mask.TRUE_MASK;
374 case 128: return Byte128Vector.Byte128Mask.TRUE_MASK;
375 case 256: return Byte256Vector.Byte256Mask.TRUE_MASK;
376 case 512: return Byte512Vector.Byte512Mask.TRUE_MASK;
377 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
378 }
379 }
380
381 static Mask<Byte> falseMask(ByteSpecies species) {
382 if (species.boxType() == ByteMaxVector.class)
383 return ByteMaxVector.ByteMaxMask.FALSE_MASK;
384 switch (species.bitSize()) {
385 case 64: return Byte64Vector.Byte64Mask.FALSE_MASK;
386 case 128: return Byte128Vector.Byte128Mask.FALSE_MASK;
387 case 256: return Byte256Vector.Byte256Mask.FALSE_MASK;
388 case 512: return Byte512Vector.Byte512Mask.FALSE_MASK;
389 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
390 }
391 }
392
393 @ForceInline
394 @SuppressWarnings("unchecked")
395 public static Mask<Byte> maskFromArray(ByteSpecies species, boolean[] bits, int ix) {
396 Objects.requireNonNull(bits);
397 ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
398 return VectorIntrinsics.load((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
399 bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
400 bits, ix, species,
401 (c, idx, s) -> (Mask<Byte>) ((ByteSpecies)s).opm(n -> c[idx + n]));
402 }
403
404 @ForceInline
405 @SuppressWarnings("unchecked")
406 public static Mask<Byte> maskAllTrue(ByteSpecies species) {
407 return VectorIntrinsics.broadcastCoerced((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
408 (byte)-1, species,
409 ((z, s) -> trueMask((ByteSpecies)s)));
410 }
411
412 @ForceInline
413 @SuppressWarnings("unchecked")
414 public static Mask<Byte> maskAllFalse(ByteSpecies species) {
415 return VectorIntrinsics.broadcastCoerced((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
416 0, species,
417 ((z, s) -> falseMask((ByteSpecies)s)));
418 }
419
420 @ForceInline
421 public static Shuffle<Byte> shuffle(ByteSpecies species, IntUnaryOperator f) {
422 if (species.boxType() == ByteMaxVector.class)
423 return new ByteMaxVector.ByteMaxShuffle(f);
424 switch (species.bitSize()) {
425 case 64: return new Byte64Vector.Byte64Shuffle(f);
426 case 128: return new Byte128Vector.Byte128Shuffle(f);
427 case 256: return new Byte256Vector.Byte256Shuffle(f);
428 case 512: return new Byte512Vector.Byte512Shuffle(f);
429 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
430 }
431 }
432
433 @ForceInline
434 public static Shuffle<Byte> shuffleIota(ByteSpecies species) {
435 if (species.boxType() == ByteMaxVector.class)
436 return new ByteMaxVector.ByteMaxShuffle(AbstractShuffle.IDENTITY);
437 switch (species.bitSize()) {
438 case 64: return new Byte64Vector.Byte64Shuffle(AbstractShuffle.IDENTITY);
439 case 128: return new Byte128Vector.Byte128Shuffle(AbstractShuffle.IDENTITY);
440 case 256: return new Byte256Vector.Byte256Shuffle(AbstractShuffle.IDENTITY);
441 case 512: return new Byte512Vector.Byte512Shuffle(AbstractShuffle.IDENTITY);
442 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
443 }
444 }
445
446 @ForceInline
447 public static Shuffle<Byte> shuffleFromValues(ByteSpecies species, int... ixs) {
448 if (species.boxType() == ByteMaxVector.class)
449 return new ByteMaxVector.ByteMaxShuffle(ixs);
450 switch (species.bitSize()) {
451 case 64: return new Byte64Vector.Byte64Shuffle(ixs);
452 case 128: return new Byte128Vector.Byte128Shuffle(ixs);
453 case 256: return new Byte256Vector.Byte256Shuffle(ixs);
454 case 512: return new Byte512Vector.Byte512Shuffle(ixs);
455 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
456 }
457 }
458
459 @ForceInline
460 public static Shuffle<Byte> shuffleFromArray(ByteSpecies species, int[] ixs, int i) {
461 if (species.boxType() == ByteMaxVector.class)
462 return new ByteMaxVector.ByteMaxShuffle(ixs, i);
463 switch (species.bitSize()) {
464 case 64: return new Byte64Vector.Byte64Shuffle(ixs, i);
465 case 128: return new Byte128Vector.Byte128Shuffle(ixs, i);
466 case 256: return new Byte256Vector.Byte256Shuffle(ixs, i);
467 case 512: return new Byte512Vector.Byte512Shuffle(ixs, i);
468 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
469 }
470 }
471
472
473 // Ops
474
475 @Override
476 public abstract ByteVector add(Vector<Byte> v);
477
478 /**
910 public abstract ByteVector not();
911
912 /**
913 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
914 * <p>
915 * This is a vector unary operation where the primitive bitwise NOT
916 * operation ({@code ~}) is applied to lane elements.
917 *
918 * @param m the mask controlling lane selection
919 * @return the bitwise NOT of this vector
920 */
921 public abstract ByteVector not(Mask<Byte> m);
922
923 /**
924 * Logically left shifts this vector by the broadcast of an input scalar.
925 * <p>
926 * This is a vector binary operation where the primitive logical left shift
927 * operation ({@code <<}) is applied to lane elements to left shift the
928 * element by shift value as specified by the input scalar. Only the 3
929 * lowest-order bits of shift value are used. It is as if the shift value
930 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
931 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
932 *
933 * @param s the input scalar; the number of the bits to left shift
934 * @return the result of logically left shifting left this vector by the
935 * broadcast of an input scalar
936 */
937 public abstract ByteVector shiftL(int s);
938
939 /**
940 * Logically left shifts this vector by the broadcast of an input scalar,
941 * selecting lane elements controlled by a mask.
942 * <p>
943 * This is a vector binary operation where the primitive logical left shift
944 * operation ({@code <<}) is applied to lane elements to left shift the
945 * element by shift value as specified by the input scalar. Only the 3
946 * lowest-order bits of shift value are used. It is as if the shift value
947 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
948 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
949 *
950 * @param s the input scalar; the number of the bits to left shift
951 * @param m the mask controlling lane selection
952 * @return the result of logically left shifting left this vector by the
953 * broadcast of an input scalar
954 */
955 public abstract ByteVector shiftL(int s, Mask<Byte> m);
956
957
958 // logical, or unsigned, shift right
959
960 /**
961 * Logically right shifts (or unsigned right shifts) this vector by the
962 * broadcast of an input scalar.
963 * <p>
964 * This is a vector binary operation where the primitive logical right shift
965 * operation ({@code >>>}) is applied to lane elements to logically right shift the
966 * element by shift value as specified by the input scalar. Only the 3
967 * lowest-order bits of shift value are used. It is as if the shift value
968 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
969 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
970 *
971 * @param s the input scalar; the number of the bits to right shift
972 * @return the result of logically right shifting this vector by the
973 * broadcast of an input scalar
974 */
975 public abstract ByteVector shiftR(int s);
976
977 /**
978 * Logically right shifts (or unsigned right shifts) this vector by the
979 * broadcast of an input scalar, selecting lane elements controlled by a
980 * mask.
981 * <p>
982 * This is a vector binary operation where the primitive logical right shift
983 * operation ({@code >>>}) is applied to lane elements to logically right shift the
984 * element by shift value as specified by the input scalar. Only the 3
985 * lowest-order bits of shift value are used. It is as if the shift value
986 * were subjected to a bitwise logical AND operator & with the mask value 0x7.
987 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
988 *
989 * @param s the input scalar; the number of the bits to right shift
990 * @return the result of logically right shifting this vector by the
991 * broadcast of an input scalar
992 */
993 public abstract ByteVector shiftR(int s, Mask<Byte> m);
994
995
996 /**
997 * Arithmetically right shifts (or signed right shifts) this vector by the
998 * broadcast of an input scalar.
999 * <p>
1000 * This is a vector binary operation where the primitive arithmetic right
1001 * shift operation ({@code >>}) is applied to lane elements to arithmetically
1002 * right shift the element by shift value as specified by the input scalar.
1003 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
1004 * value were subjected to a bitwise logical AND operator & with the mask value 0x7.
1005 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1006 *
1007 * @param s the input scalar; the number of the bits to right shift
1008 * @return the result of arithmetically right shifting this vector by the
1009 * broadcast of an input scalar
1010 */
1011 public abstract ByteVector aShiftR(int s);
1012
1013 /**
1014 * Arithmetically right shifts (or signed right shifts) this vector by the
1015 * broadcast of an input scalar, selecting lane elements controlled by a
1016 * mask.
1017 * <p>
1018 * This is a vector binary operation where the primitive arithmetic right
1019 * shift operation ({@code >>}) is applied to lane elements to arithmetically
1020 * right shift the element by shift value as specified by the input scalar.
1021 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
1022 * value were subjected to a bitwise logical AND operator & with the mask value 0x7.
1023 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1024 *
1025 * @param s the input scalar; the number of the bits to right shift
1026 * @param m the mask controlling lane selection
1027 * @return the result of arithmetically right shifting this vector by the
1028 * broadcast of an input scalar
1029 */
1030 public abstract ByteVector aShiftR(int s, Mask<Byte> m);
1031
1032
1033 @Override
1034 public abstract void intoByteArray(byte[] a, int ix);
1035
1036 @Override
1037 public abstract void intoByteArray(byte[] a, int ix, Mask<Byte> m);
1038
1039 @Override
1040 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1041
1042 @Override
1043 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Byte> m);
1044
1045
1046 // Type specific horizontal reductions
1047
1048 /**
1049 * Adds all lane elements of this vector.
1050 * <p>
1051 * This is an associative vector reduction operation where the addition
1052 * operation ({@code +}) is applied to lane elements,
1053 * and the identity value is {@code 0}.
1054 *
1055 * @return the addition of all the lane elements of this vector
1056 */
1057 public abstract byte addAll();
1058
1059 /**
1060 * Adds all lane elements of this vector, selecting lane elements
1061 * controlled by a mask.
1062 * <p>
1063 * This is an associative vector reduction operation where the addition
1064 * operation ({@code +}) is applied to lane elements,
1065 * and the identity value is {@code 0}.
1066 *
1067 * @param m the mask controlling lane selection
1068 * @return the addition of all the lane elements of this vector
1069 */
1070 public abstract byte addAll(Mask<Byte> m);
1071
1072 /**
1073 * Subtracts all lane elements of this vector.
1074 * <p>
1075 * This is an associative vector reduction operation where the subtraction
1076 * operation ({@code -}) is applied to lane elements,
1077 * and the identity value is {@code 0}.
1078 *
1079 * @return the subtraction of all the lane elements of this vector
1080 */
1081 public abstract byte subAll();
1082
1083 /**
1084 * Subtracts all lane elements of this vector, selecting lane elements
1085 * controlled by a mask.
1086 * <p>
1087 * This is an associative vector reduction operation where the subtraction
1088 * operation ({@code -}) is applied to lane elements,
1089 * and the identity value is {@code 0}.
1090 *
1091 * @param m the mask controlling lane selection
1092 * @return the subtraction of all the lane elements of this vector
1093 */
1094 public abstract byte subAll(Mask<Byte> m);
1095
1096 /**
1097 * Multiplies all lane elements of this vector.
1098 * <p>
1099 * This is an associative vector reduction operation where the
1100 * multiplication operation ({@code *}) is applied to lane elements,
1101 * and the identity value is {@code 1}.
1102 *
1103 * @return the multiplication of all the lane elements of this vector
1104 */
1105 public abstract byte mulAll();
1106
1107 /**
1108 * Multiplies all lane elements of this vector, selecting lane elements
1109 * controlled by a mask.
1110 * <p>
1111 * This is an associative vector reduction operation where the
1112 * multiplication operation ({@code *}) is applied to lane elements,
1113 * and the identity value is {@code 1}.
1114 *
1115 * @param m the mask controlling lane selection
1116 * @return the multiplication of all the lane elements of this vector
1117 */
1118 public abstract byte mulAll(Mask<Byte> m);
1119
1120 /**
1121 * Returns the minimum lane element of this vector.
1122 * <p>
1123 * This is an associative vector reduction operation where the operation
1124 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1125 * and the identity value is {@link Byte#MAX_VALUE}.
1126 *
1127 * @return the minimum lane element of this vector
1128 */
1129 public abstract byte minAll();
1130
1131 /**
1132 * Returns the minimum lane element of this vector, selecting lane elements
1133 * controlled by a mask.
1134 * <p>
1135 * This is an associative vector reduction operation where the operation
1136 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1137 * and the identity value is {@link Byte#MAX_VALUE}.
1138 *
1139 * @param m the mask controlling lane selection
1140 * @return the minimum lane element of this vector
1141 */
1142 public abstract byte minAll(Mask<Byte> m);
1143
1144 /**
1145 * Returns the maximum lane element of this vector.
1146 * <p>
1147 * This is an associative vector reduction operation where the operation
1148 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1149 * and the identity value is {@link Byte#MIN_VALUE}.
1150 *
1151 * @return the maximum lane element of this vector
1152 */
1153 public abstract byte maxAll();
1154
1155 /**
1156 * Returns the maximum lane element of this vector, selecting lane elements
1157 * controlled by a mask.
1158 * <p>
1159 * This is an associative vector reduction operation where the operation
1160 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1161 * and the identity value is {@link Byte#MIN_VALUE}.
1162 *
1163 * @param m the mask controlling lane selection
1164 * @return the maximum lane element of this vector
1165 */
1166 public abstract byte maxAll(Mask<Byte> m);
1167
1168 /**
1169 * Logically ORs all lane elements of this vector.
1170 * <p>
1171 * This is an associative vector reduction operation where the logical OR
1172 * operation ({@code |}) is applied to lane elements,
1173 * and the identity value is {@code 0}.
1174 *
1175 * @return the logical OR all the lane elements of this vector
1176 */
1177 public abstract byte orAll();
1178
1179 /**
1180 * Logically ORs all lane elements of this vector, selecting lane elements
1181 * controlled by a mask.
1411
1412 /**
1413 * Returns a vector where the first lane element is set to the primtive
1414 * value {@code e}, all other lane elements are set to the default
1415 * value.
1416 *
1417 * @param e the value
1418 * @return a vector where the first lane element is set to the primitive
1419 * value {@code e}
1420 */
1421 @ForceInline
1422 public final ByteVector single(byte e) {
1423 return zero().with(0, e);
1424 }
1425
1426 /**
1427 * Returns a vector where each lane element is set to a randomly
1428 * generated primitive value.
1429 *
1430 * The semantics are equivalent to calling
1431 * {@link (byte)ThreadLocalRandom#nextInt() }
1432 *
1433 * @return a vector where each lane elements is set to a randomly
1434 * generated primitive value
1435 */
1436 public ByteVector random() {
1437 ThreadLocalRandom r = ThreadLocalRandom.current();
1438 return op(i -> (byte) r.nextInt());
1439 }
1440
1441 /**
1442 * Returns a vector where each lane element is set to a given
1443 * primitive value.
1444 * <p>
1445 * For each vector lane, where {@code N} is the vector lane index, the
1446 * the primitive value at index {@code N} is placed into the resulting
1447 * vector at lane index {@code N}.
1448 *
1449 * @param es the given primitive values
1450 * @return a vector where each lane element is set to a given primitive
1451 * value
|
87 }
88
89 abstract Mask<Byte> bTest(Vector<Byte> v, FBinTest f);
90
91 // Foreach
92
93 interface FUnCon {
94 void apply(int i, byte a);
95 }
96
97 abstract void forEach(FUnCon f);
98
99 abstract void forEach(Mask<Byte> m, FUnCon f);
100
101 // Static factories
102
103 /**
104 * Returns a vector where all lane elements are set to the default
105 * primitive value.
106 *
107 * @param species species of desired vector
108 * @return a zero vector of given species
109 */
110 @ForceInline
111 @SuppressWarnings("unchecked")
112 public static ByteVector zero(ByteSpecies species) {
113 return species.zero();
114 }
115
116 /**
117 * Loads a vector from a byte array starting at an offset.
118 * <p>
119 * Bytes are composed into primitive lane elements according to the
120 * native byte order of the underlying platform
121 * <p>
122 * This method behaves as if it returns the result of calling the
123 * byte buffer, offset, and mask accepting
124 * {@link #fromByteBuffer(ByteSpecies, ByteBuffer, int, Mask) method} as follows:
125 * <pre>{@code
126 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
127 * }</pre>
128 *
129 * @param species species of desired vector
130 * @param a the byte array
131 * @param ix the offset into the array
132 * @return a vector loaded from a byte array
133 * @throws IndexOutOfBoundsException if {@code i < 0} or
134 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
135 */
136 @ForceInline
137 @SuppressWarnings("unchecked")
138 public static ByteVector fromByteArray(ByteSpecies species, byte[] a, int ix) {
139 Objects.requireNonNull(a);
140 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
141 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
142 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
143 a, ix, species,
144 (c, idx, s) -> {
145 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
146 ByteBuffer tb = bbc;
147 return ((ByteSpecies)s).op(i -> tb.get());
148 });
149 }
150
151 /**
152 * Loads a vector from a byte array starting at an offset and using a
153 * mask.
154 * <p>
155 * Bytes are composed into primitive lane elements according to the
156 * native byte order of the underlying platform.
157 * <p>
158 * This method behaves as if it returns the result of calling the
159 * byte buffer, offset, and mask accepting
160 * {@link #fromByteBuffer(ByteSpecies, ByteBuffer, int, Mask) method} as follows:
161 * <pre>{@code
162 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
163 * }</pre>
164 *
165 * @param species species of desired vector
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 ByteVector fromByteArray(ByteSpecies species, byte[] a, int ix, Mask<Byte> 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 species species of desired vector
191 * @param a the array
192 * @param i the offset into the array
193 * @return the vector loaded from an array
194 * @throws IndexOutOfBoundsException if {@code i < 0}, or
195 * {@code i > a.length - this.length()}
196 */
197 @ForceInline
198 @SuppressWarnings("unchecked")
199 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i){
200 Objects.requireNonNull(a);
201 i = VectorIntrinsics.checkIndex(i, a.length, species.length());
202 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
203 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
204 a, i, species,
205 (c, idx, s) -> ((ByteSpecies)s).op(n -> c[idx + n]));
206 }
207
208
209 /**
210 * Loads a vector from an array starting at offset and using a mask.
211 * <p>
212 * For each vector lane, where {@code N} is the vector lane index,
213 * if the mask lane at index {@code N} is set then the array element at
214 * index {@code i + N} is placed into the resulting vector at lane index
215 * {@code N}, otherwise the default element value is placed into the
216 * resulting vector at lane index {@code N}.
217 *
218 * @param species species of desired vector
219 * @param a the array
220 * @param i the offset into the array
221 * @param m the mask
222 * @return the vector loaded from an array
223 * @throws IndexOutOfBoundsException if {@code i < 0}, or
224 * for any vector lane index {@code N} where the mask at lane {@code N}
225 * is set {@code i > a.length - N}
226 */
227 @ForceInline
228 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i, Mask<Byte> m) {
229 return zero(species).blend(fromArray(species, a, i), m);
230 }
231
232 /**
233 * Loads a vector from an array using indexes obtained from an index
234 * map.
235 * <p>
236 * For each vector lane, where {@code N} is the vector lane index, the
237 * array element at index {@code i + indexMap[j + N]} is placed into the
238 * resulting vector at lane index {@code N}.
239 *
240 * @param species species of desired vector
241 * @param a the array
242 * @param i the offset into the array, may be negative if relative
243 * indexes in the index map compensate to produce a value within the
244 * array bounds
245 * @param indexMap the index map
246 * @param j the offset into the index map
247 * @return the vector loaded from an array
248 * @throws IndexOutOfBoundsException if {@code j < 0}, or
249 * {@code j > indexMap.length - this.length()},
250 * or for any vector lane index {@code N} the result of
251 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
252 */
253 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i, int[] indexMap, int j) {
254 return species.op(n -> a[i + indexMap[j + n]]);
255 }
256 /**
257 * Loads a vector from an array using indexes obtained from an index
258 * map and using a mask.
259 * <p>
260 * For each vector lane, where {@code N} is the vector lane index,
261 * if the mask lane at index {@code N} is set then the array element at
262 * index {@code i + indexMap[j + N]} is placed into the resulting vector
263 * at lane index {@code N}.
264 *
265 * @param species species of desired vector
266 * @param a the array
267 * @param i the offset into the array, may be negative if relative
268 * indexes in the index map compensate to produce a value within the
269 * array bounds
270 * @param m the mask
271 * @param indexMap the index map
272 * @param j the offset into the index map
273 * @return the vector loaded from an array
274 * @throws IndexOutOfBoundsException if {@code j < 0}, or
275 * {@code j > indexMap.length - this.length()},
276 * or for any vector lane index {@code N} where the mask at lane
277 * {@code N} is set the result of {@code i + indexMap[j + N]} is
278 * {@code < 0} or {@code >= a.length}
279 */
280 public static ByteVector fromArray(ByteSpecies species, byte[] a, int i, Mask<Byte> m, int[] indexMap, int j) {
281 return species.op(m, n -> a[i + indexMap[j + n]]);
282 }
283
284 /**
285 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
286 * offset into the byte buffer.
287 * <p>
288 * Bytes are composed into primitive lane elements according to the
289 * native byte order of the underlying platform.
290 * <p>
291 * This method behaves as if it returns the result of calling the
292 * byte buffer, offset, and mask accepting
293 * {@link #fromByteBuffer(ByteSpecies, ByteBuffer, int, Mask)} method} as follows:
294 * <pre>{@code
295 * return this.fromByteBuffer(b, i, this.maskAllTrue())
296 * }</pre>
297 *
298 * @param species species of desired vector
299 * @param bb the byte buffer
300 * @param ix the offset into the byte buffer
301 * @return a vector loaded from a byte buffer
302 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
303 * or {@code > b.limit()},
304 * or if there are fewer than
305 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
306 * remaining in the byte buffer from the given offset
307 */
308 @ForceInline
309 @SuppressWarnings("unchecked")
310 public static ByteVector fromByteBuffer(ByteSpecies species, ByteBuffer bb, int ix) {
311 if (bb.order() != ByteOrder.nativeOrder()) {
312 throw new IllegalArgumentException();
313 }
314 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
315 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(),
316 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
317 bb, ix, species,
318 (c, idx, s) -> {
330 * {@link java.nio.Buffer buffer} for the primitive element type,
331 * according to the native byte order of the underlying platform, and
332 * the returned vector is loaded with a mask from a primitive array
333 * obtained from the primitive buffer.
334 * The following pseudocode expresses the behaviour, where
335 * {@coce EBuffer} is the primitive buffer type, {@code e} is the
336 * primitive element type, and {@code ESpecies<S>} is the primitive
337 * species for {@code e}:
338 * <pre>{@code
339 * EBuffer eb = b.duplicate().
340 * order(ByteOrder.nativeOrder()).position(i).
341 * asEBuffer();
342 * e[] es = new e[this.length()];
343 * for (int n = 0; n < t.length; n++) {
344 * if (m.isSet(n))
345 * es[n] = eb.get(n);
346 * }
347 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
348 * }</pre>
349 *
350 * @param species species of desired vector
351 * @param bb the byte buffer
352 * @param ix the offset into the byte buffer
353 * @param m the mask
354 * @return a vector loaded from a byte buffer
355 * @throws IndexOutOfBoundsException if the offset is {@code < 0},
356 * or {@code > b.limit()},
357 * for any vector lane index {@code N} where the mask at lane {@code N}
358 * is set
359 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
360 */
361 @ForceInline
362 public static ByteVector fromByteBuffer(ByteSpecies species, ByteBuffer bb, int ix, Mask<Byte> m) {
363 return zero(species).blend(fromByteBuffer(species, bb, ix), m);
364 }
365
366 /**
367 * Returns a mask where each lane is set or unset according to given
368 * {@code boolean} values
369 * <p>
370 * For each mask lane, where {@code N} is the mask lane index,
371 * if the given {@code boolean} value at index {@code N} is {@code true}
372 * then the mask lane at index {@code N} is set, otherwise it is unset.
373 *
374 * @param species mask species
375 * @param bits the given {@code boolean} values
376 * @return a mask where each lane is set or unset according to the given {@code boolean} value
377 * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
378 */
379 @ForceInline
380 public static Mask<Byte> maskFromValues(ByteSpecies species, boolean... bits) {
381 if (species.boxType() == ByteMaxVector.class)
382 return new ByteMaxVector.ByteMaxMask(bits);
383 switch (species.bitSize()) {
384 case 64: return new Byte64Vector.Byte64Mask(bits);
385 case 128: return new Byte128Vector.Byte128Mask(bits);
386 case 256: return new Byte256Vector.Byte256Mask(bits);
387 case 512: return new Byte512Vector.Byte512Mask(bits);
388 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
389 }
390 }
391
392 // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
393 static Mask<Byte> trueMask(ByteSpecies species) {
394 if (species.boxType() == ByteMaxVector.class)
395 return ByteMaxVector.ByteMaxMask.TRUE_MASK;
396 switch (species.bitSize()) {
397 case 64: return Byte64Vector.Byte64Mask.TRUE_MASK;
398 case 128: return Byte128Vector.Byte128Mask.TRUE_MASK;
399 case 256: return Byte256Vector.Byte256Mask.TRUE_MASK;
400 case 512: return Byte512Vector.Byte512Mask.TRUE_MASK;
401 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
402 }
403 }
404
405 static Mask<Byte> falseMask(ByteSpecies species) {
406 if (species.boxType() == ByteMaxVector.class)
407 return ByteMaxVector.ByteMaxMask.FALSE_MASK;
408 switch (species.bitSize()) {
409 case 64: return Byte64Vector.Byte64Mask.FALSE_MASK;
410 case 128: return Byte128Vector.Byte128Mask.FALSE_MASK;
411 case 256: return Byte256Vector.Byte256Mask.FALSE_MASK;
412 case 512: return Byte512Vector.Byte512Mask.FALSE_MASK;
413 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
414 }
415 }
416
417 /**
418 * Loads a mask from a {@code boolean} array starting at an offset.
419 * <p>
420 * For each mask lane, where {@code N} is the mask lane index,
421 * if the array element at index {@code i + N} is {@code true} then the
422 * mask lane at index {@code N} is set, otherwise it is unset.
423 *
424 * @param species mask species
425 * @param bits the {@code boolean} array
426 * @param ix the offset into the array
427 * @return the mask loaded from a {@code boolean} array
428 * @throws IndexOutOfBoundsException if {@code ix < 0}, or
429 * {@code ix > bits.length - species.length()}
430 */
431 @ForceInline
432 @SuppressWarnings("unchecked")
433 public static Mask<Byte> maskFromArray(ByteSpecies species, boolean[] bits, int ix) {
434 Objects.requireNonNull(bits);
435 ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
436 return VectorIntrinsics.load((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
437 bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
438 bits, ix, species,
439 (c, idx, s) -> (Mask<Byte>) ((ByteSpecies)s).opm(n -> c[idx + n]));
440 }
441
442 /**
443 * Returns a mask where all lanes are a set.
444 *
445 * @param species mask species
446 * @return a mask where all lanes are a set
447 */
448 @ForceInline
449 @SuppressWarnings("unchecked")
450 public static Mask<Byte> maskAllTrue(ByteSpecies species) {
451 return VectorIntrinsics.broadcastCoerced((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
452 (byte)-1, species,
453 ((z, s) -> trueMask((ByteSpecies)s)));
454 }
455
456 /**
457 * Returns a mask where all lanes are a unset.
458 *
459 * @param species mask species
460 * @return a mask where all lanes are a unset
461 */
462 @ForceInline
463 @SuppressWarnings("unchecked")
464 public static Mask<Byte> maskAllFalse(ByteSpecies species) {
465 return VectorIntrinsics.broadcastCoerced((Class<Mask<Byte>>) species.maskType(), byte.class, species.length(),
466 0, species,
467 ((z, s) -> falseMask((ByteSpecies)s)));
468 }
469
470 /**
471 * Returns a shuffle of mapped indexes where each lane element is
472 * the result of applying a mapping function to the corresponding lane
473 * index.
474 * <p>
475 * Care should be taken to ensure Shuffle values produced from this
476 * method are consumed as constants to ensure optimal generation of
477 * code. For example, values held in static final fields or values
478 * held in loop constant local variables.
479 * <p>
480 * This method behaves as if a shuffle is created from an array of
481 * mapped indexes as follows:
482 * <pre>{@code
483 * int[] a = new int[species.length()];
484 * for (int i = 0; i < a.length; i++) {
485 * a[i] = f.applyAsInt(i);
486 * }
487 * return this.shuffleFromValues(a);
488 * }</pre>
489 *
490 * @param species shuffle species
491 * @param f the lane index mapping function
492 * @return a shuffle of mapped indexes
493 */
494 @ForceInline
495 public static Shuffle<Byte> shuffle(ByteSpecies species, IntUnaryOperator f) {
496 if (species.boxType() == ByteMaxVector.class)
497 return new ByteMaxVector.ByteMaxShuffle(f);
498 switch (species.bitSize()) {
499 case 64: return new Byte64Vector.Byte64Shuffle(f);
500 case 128: return new Byte128Vector.Byte128Shuffle(f);
501 case 256: return new Byte256Vector.Byte256Shuffle(f);
502 case 512: return new Byte512Vector.Byte512Shuffle(f);
503 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
504 }
505 }
506
507 /**
508 * Returns a shuffle where each lane element is the value of its
509 * corresponding lane index.
510 * <p>
511 * This method behaves as if a shuffle is created from an identity
512 * index mapping function as follows:
513 * <pre>{@code
514 * return this.shuffle(i -> i);
515 * }</pre>
516 *
517 * @param species shuffle species
518 * @return a shuffle of lane indexes
519 */
520 @ForceInline
521 public static Shuffle<Byte> shuffleIota(ByteSpecies species) {
522 if (species.boxType() == ByteMaxVector.class)
523 return new ByteMaxVector.ByteMaxShuffle(AbstractShuffle.IDENTITY);
524 switch (species.bitSize()) {
525 case 64: return new Byte64Vector.Byte64Shuffle(AbstractShuffle.IDENTITY);
526 case 128: return new Byte128Vector.Byte128Shuffle(AbstractShuffle.IDENTITY);
527 case 256: return new Byte256Vector.Byte256Shuffle(AbstractShuffle.IDENTITY);
528 case 512: return new Byte512Vector.Byte512Shuffle(AbstractShuffle.IDENTITY);
529 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
530 }
531 }
532
533 /**
534 * Returns a shuffle where each lane element is set to a given
535 * {@code int} value logically AND'ed by the species length minus one.
536 * <p>
537 * For each shuffle lane, where {@code N} is the shuffle lane index, the
538 * the {@code int} value at index {@code N} logically AND'ed by
539 * {@code species.length() - 1} is placed into the resulting shuffle at
540 * lane index {@code N}.
541 *
542 * @param species shuffle species
543 * @param ixs the given {@code int} values
544 * @return a shuffle where each lane element is set to a given
545 * {@code int} value
546 * @throws IndexOutOfBoundsException if the number of int values is
547 * {@code < species.length()}
548 */
549 @ForceInline
550 public static Shuffle<Byte> shuffleFromValues(ByteSpecies species, int... ixs) {
551 if (species.boxType() == ByteMaxVector.class)
552 return new ByteMaxVector.ByteMaxShuffle(ixs);
553 switch (species.bitSize()) {
554 case 64: return new Byte64Vector.Byte64Shuffle(ixs);
555 case 128: return new Byte128Vector.Byte128Shuffle(ixs);
556 case 256: return new Byte256Vector.Byte256Shuffle(ixs);
557 case 512: return new Byte512Vector.Byte512Shuffle(ixs);
558 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
559 }
560 }
561
562 /**
563 * Loads a shuffle from an {@code int} array starting at an offset.
564 * <p>
565 * For each shuffle lane, where {@code N} is the shuffle lane index, the
566 * array element at index {@code i + N} logically AND'ed by
567 * {@code species.length() - 1} is placed into the resulting shuffle at lane
568 * index {@code N}.
569 *
570 * @param species shuffle species
571 * @param ixs the {@code int} array
572 * @param i the offset into the array
573 * @return a shuffle loaded from the {@code int} array
574 * @throws IndexOutOfBoundsException if {@code i < 0}, or
575 * {@code i > a.length - species.length()}
576 */
577 @ForceInline
578 public static Shuffle<Byte> shuffleFromArray(ByteSpecies species, int[] ixs, int i) {
579 if (species.boxType() == ByteMaxVector.class)
580 return new ByteMaxVector.ByteMaxShuffle(ixs, i);
581 switch (species.bitSize()) {
582 case 64: return new Byte64Vector.Byte64Shuffle(ixs, i);
583 case 128: return new Byte128Vector.Byte128Shuffle(ixs, i);
584 case 256: return new Byte256Vector.Byte256Shuffle(ixs, i);
585 case 512: return new Byte512Vector.Byte512Shuffle(ixs, i);
586 default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
587 }
588 }
589
590
591 // Ops
592
593 @Override
594 public abstract ByteVector add(Vector<Byte> v);
595
596 /**
1028 public abstract ByteVector not();
1029
1030 /**
1031 * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1032 * <p>
1033 * This is a vector unary operation where the primitive bitwise NOT
1034 * operation ({@code ~}) is applied to lane elements.
1035 *
1036 * @param m the mask controlling lane selection
1037 * @return the bitwise NOT of this vector
1038 */
1039 public abstract ByteVector not(Mask<Byte> m);
1040
1041 /**
1042 * Logically left shifts this vector by the broadcast of an input scalar.
1043 * <p>
1044 * This is a vector binary operation where the primitive logical left shift
1045 * operation ({@code <<}) is applied to lane elements to left shift the
1046 * element by shift value as specified by the input scalar. Only the 3
1047 * lowest-order bits of shift value are used. It is as if the shift value
1048 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1049 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1050 *
1051 * @param s the input scalar; the number of the bits to left shift
1052 * @return the result of logically left shifting left this vector by the
1053 * broadcast of an input scalar
1054 */
1055 public abstract ByteVector shiftL(int s);
1056
1057 /**
1058 * Logically left shifts this vector by the broadcast of an input scalar,
1059 * selecting lane elements controlled by a mask.
1060 * <p>
1061 * This is a vector binary operation where the primitive logical left shift
1062 * operation ({@code <<}) is applied to lane elements to left shift the
1063 * element by shift value as specified by the input scalar. Only the 3
1064 * lowest-order bits of shift value are used. It is as if the shift value
1065 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1066 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1067 *
1068 * @param s the input scalar; the number of the bits to left shift
1069 * @param m the mask controlling lane selection
1070 * @return the result of logically left shifting left this vector by the
1071 * broadcast of an input scalar
1072 */
1073 public abstract ByteVector shiftL(int s, Mask<Byte> m);
1074
1075
1076 // logical, or unsigned, shift right
1077
1078 /**
1079 * Logically right shifts (or unsigned right shifts) this vector by the
1080 * broadcast of an input scalar.
1081 * <p>
1082 * This is a vector binary operation where the primitive logical right shift
1083 * operation ({@code >>>}) is applied to lane elements to logically right shift the
1084 * element by shift value as specified by the input scalar. Only the 3
1085 * lowest-order bits of shift value are used. It is as if the shift value
1086 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1087 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1088 *
1089 * @param s the input scalar; the number of the bits to right shift
1090 * @return the result of logically right shifting this vector by the
1091 * broadcast of an input scalar
1092 */
1093 public abstract ByteVector shiftR(int s);
1094
1095 /**
1096 * Logically right shifts (or unsigned right shifts) this vector by the
1097 * broadcast of an input scalar, selecting lane elements controlled by a
1098 * mask.
1099 * <p>
1100 * This is a vector binary operation where the primitive logical right shift
1101 * operation ({@code >>>}) is applied to lane elements to logically right shift the
1102 * element by shift value as specified by the input scalar. Only the 3
1103 * lowest-order bits of shift value are used. It is as if the shift value
1104 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1105 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1106 *
1107 * @param s the input scalar; the number of the bits to right shift
1108 * @param m the mask controlling lane selection
1109 * @return the result of logically right shifting this vector by the
1110 * broadcast of an input scalar
1111 */
1112 public abstract ByteVector shiftR(int s, Mask<Byte> m);
1113
1114
1115 /**
1116 * Arithmetically right shifts (or signed right shifts) this vector by the
1117 * broadcast of an input scalar.
1118 * <p>
1119 * This is a vector binary operation where the primitive arithmetic right
1120 * shift operation ({@code >>}) is applied to lane elements to arithmetically
1121 * right shift the element by shift value as specified by the input scalar.
1122 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
1123 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1124 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1125 *
1126 * @param s the input scalar; the number of the bits to right shift
1127 * @return the result of arithmetically right shifting this vector by the
1128 * broadcast of an input scalar
1129 */
1130 public abstract ByteVector aShiftR(int s);
1131
1132 /**
1133 * Arithmetically right shifts (or signed right shifts) this vector by the
1134 * broadcast of an input scalar, selecting lane elements controlled by a
1135 * mask.
1136 * <p>
1137 * This is a vector binary operation where the primitive arithmetic right
1138 * shift operation ({@code >>}) is applied to lane elements to arithmetically
1139 * right shift the element by shift value as specified by the input scalar.
1140 * Only the 3 lowest-order bits of shift value are used. It is as if the shift
1141 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7.
1142 * The shift distance actually used is therefore always in the range 0 to 7, inclusive.
1143 *
1144 * @param s the input scalar; the number of the bits to right shift
1145 * @param m the mask controlling lane selection
1146 * @return the result of arithmetically right shifting this vector by the
1147 * broadcast of an input scalar
1148 */
1149 public abstract ByteVector aShiftR(int s, Mask<Byte> m);
1150
1151
1152 @Override
1153 public abstract void intoByteArray(byte[] a, int ix);
1154
1155 @Override
1156 public abstract void intoByteArray(byte[] a, int ix, Mask<Byte> m);
1157
1158 @Override
1159 public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1160
1161 @Override
1162 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Byte> m);
1163
1164
1165 // Type specific horizontal reductions
1166 /**
1167 * Adds all lane elements of this vector.
1168 * <p>
1169 * This is an associative vector reduction operation where the addition
1170 * operation ({@code +}) is applied to lane elements,
1171 * and the identity value is {@code 0}.
1172 *
1173 * @return the addition of all the lane elements of this vector
1174 */
1175 public abstract byte addAll();
1176
1177 /**
1178 * Adds all lane elements of this vector, selecting lane elements
1179 * controlled by a mask.
1180 * <p>
1181 * This is an associative vector reduction operation where the addition
1182 * operation ({@code +}) is applied to lane elements,
1183 * and the identity value is {@code 0}.
1184 *
1185 * @param m the mask controlling lane selection
1186 * @return the addition of the selected lane elements of this vector
1187 */
1188 public abstract byte addAll(Mask<Byte> m);
1189
1190 /**
1191 * Multiplies all lane elements of this vector.
1192 * <p>
1193 * This is an associative vector reduction operation where the
1194 * multiplication operation ({@code *}) is applied to lane elements,
1195 * and the identity value is {@code 1}.
1196 *
1197 * @return the multiplication of all the lane elements of this vector
1198 */
1199 public abstract byte mulAll();
1200
1201 /**
1202 * Multiplies all lane elements of this vector, selecting lane elements
1203 * controlled by a mask.
1204 * <p>
1205 * This is an associative vector reduction operation where the
1206 * multiplication operation ({@code *}) is applied to lane elements,
1207 * and the identity value is {@code 1}.
1208 *
1209 * @param m the mask controlling lane selection
1210 * @return the multiplication of all the lane elements of this vector
1211 */
1212 public abstract byte mulAll(Mask<Byte> m);
1213
1214 /**
1215 * Returns the minimum lane element of this vector.
1216 * <p>
1217 * This is an associative vector reduction operation where the operation
1218 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1219 * and the identity value is
1220 * {@link Byte#MAX_VALUE}.
1221 *
1222 * @return the minimum lane element of this vector
1223 */
1224 public abstract byte minAll();
1225
1226 /**
1227 * Returns the minimum lane element of this vector, selecting lane elements
1228 * controlled by a mask.
1229 * <p>
1230 * This is an associative vector reduction operation where the operation
1231 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1232 * and the identity value is
1233 * {@link Byte#MAX_VALUE}.
1234 *
1235 * @param m the mask controlling lane selection
1236 * @return the minimum lane element of this vector
1237 */
1238 public abstract byte minAll(Mask<Byte> m);
1239
1240 /**
1241 * Returns the maximum lane element of this vector.
1242 * <p>
1243 * This is an associative vector reduction operation where the operation
1244 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1245 * and the identity value is
1246 * {@link Byte#MIN_VALUE}.
1247 *
1248 * @return the maximum lane element of this vector
1249 */
1250 public abstract byte maxAll();
1251
1252 /**
1253 * Returns the maximum lane element of this vector, selecting lane elements
1254 * controlled by a mask.
1255 * <p>
1256 * This is an associative vector reduction operation where the operation
1257 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1258 * and the identity value is
1259 * {@link Byte#MIN_VALUE}.
1260 *
1261 * @param m the mask controlling lane selection
1262 * @return the maximum lane element of this vector
1263 */
1264 public abstract byte maxAll(Mask<Byte> m);
1265
1266 /**
1267 * Logically ORs all lane elements of this vector.
1268 * <p>
1269 * This is an associative vector reduction operation where the logical OR
1270 * operation ({@code |}) is applied to lane elements,
1271 * and the identity value is {@code 0}.
1272 *
1273 * @return the logical OR all the lane elements of this vector
1274 */
1275 public abstract byte orAll();
1276
1277 /**
1278 * Logically ORs all lane elements of this vector, selecting lane elements
1279 * controlled by a mask.
1509
1510 /**
1511 * Returns a vector where the first lane element is set to the primtive
1512 * value {@code e}, all other lane elements are set to the default
1513 * value.
1514 *
1515 * @param e the value
1516 * @return a vector where the first lane element is set to the primitive
1517 * value {@code e}
1518 */
1519 @ForceInline
1520 public final ByteVector single(byte e) {
1521 return zero().with(0, e);
1522 }
1523
1524 /**
1525 * Returns a vector where each lane element is set to a randomly
1526 * generated primitive value.
1527 *
1528 * The semantics are equivalent to calling
1529 * {@code (byte)ThreadLocalRandom#nextInt()}.
1530 *
1531 * @return a vector where each lane elements is set to a randomly
1532 * generated primitive value
1533 */
1534 public ByteVector random() {
1535 ThreadLocalRandom r = ThreadLocalRandom.current();
1536 return op(i -> (byte) r.nextInt());
1537 }
1538
1539 /**
1540 * Returns a vector where each lane element is set to a given
1541 * primitive value.
1542 * <p>
1543 * For each vector lane, where {@code N} is the vector lane index, the
1544 * the primitive value at index {@code N} is placed into the resulting
1545 * vector at lane index {@code N}.
1546 *
1547 * @param es the given primitive values
1548 * @return a vector where each lane element is set to a given primitive
1549 * value
|