1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import java.nio.ByteBuffer; 28 import java.nio.ByteOrder; 29 import java.util.Objects; 30 import java.util.function.IntUnaryOperator; 31 import java.util.concurrent.ThreadLocalRandom; 32 33 import jdk.internal.misc.Unsafe; 34 import jdk.internal.vm.annotation.ForceInline; 35 import static jdk.incubator.vector.VectorIntrinsics.*; 36 37 38 /** 39 * A specialized {@link Vector} representing an ordered immutable sequence of 40 * {@code byte} values. 41 */ 42 @SuppressWarnings("cast") 43 public abstract class ByteVector extends Vector<Byte> { 44 45 ByteVector() {} 46 47 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE); 48 49 // Unary operator 50 51 interface FUnOp { 52 byte apply(int i, byte a); 53 } 54 55 abstract ByteVector uOp(FUnOp f); 56 57 abstract ByteVector uOp(Mask<Byte> m, FUnOp f); 58 59 // Binary operator 60 61 interface FBinOp { 62 byte apply(int i, byte a, byte b); 63 } 64 65 abstract ByteVector bOp(Vector<Byte> v, FBinOp f); 66 67 abstract ByteVector bOp(Vector<Byte> v, Mask<Byte> m, FBinOp f); 68 69 // Trinary operator 70 71 interface FTriOp { 72 byte apply(int i, byte a, byte b, byte c); 73 } 74 75 abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, FTriOp f); 76 77 abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, Mask<Byte> m, FTriOp f); 78 79 // Reduction operator 80 81 abstract byte rOp(byte v, FBinOp f); 82 83 // Binary test 84 85 interface FBinTest { 86 boolean apply(int i, byte a, byte b); 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) -> { 310 ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder()); 311 ByteBuffer tb = bbc; 312 return ((ByteSpecies)s).op(i -> tb.get()); 313 }); 314 } 315 316 /** 317 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an 318 * offset into the byte buffer and using a mask. 319 * <p> 320 * This method behaves as if the byte buffer is viewed as a primitive 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 /** 479 * Adds this vector to the broadcast of an input scalar. 480 * <p> 481 * This is a vector binary operation where the primitive addition operation 482 * ({@code +}) is applied to lane elements. 483 * 484 * @param s the input scalar 485 * @return the result of adding this vector to the broadcast of an input 486 * scalar 487 */ 488 public abstract ByteVector add(byte s); 489 490 @Override 491 public abstract ByteVector add(Vector<Byte> v, Mask<Byte> m); 492 493 /** 494 * Adds this vector to broadcast of an input scalar, 495 * selecting lane elements controlled by a mask. 496 * <p> 497 * This is a vector binary operation where the primitive addition operation 498 * ({@code +}) is applied to lane elements. 499 * 500 * @param s the input scalar 501 * @param m the mask controlling lane selection 502 * @return the result of adding this vector to the broadcast of an input 503 * scalar 504 */ 505 public abstract ByteVector add(byte s, Mask<Byte> m); 506 507 @Override 508 public abstract ByteVector sub(Vector<Byte> v); 509 510 /** 511 * Subtracts the broadcast of an input scalar from this vector. 512 * <p> 513 * This is a vector binary operation where the primitive subtraction 514 * operation ({@code -}) is applied to lane elements. 515 * 516 * @param s the input scalar 517 * @return the result of subtracting the broadcast of an input 518 * scalar from this vector 519 */ 520 public abstract ByteVector sub(byte s); 521 522 @Override 523 public abstract ByteVector sub(Vector<Byte> v, Mask<Byte> m); 524 525 /** 526 * Subtracts the broadcast of an input scalar from this vector, selecting 527 * lane elements controlled by a mask. 528 * <p> 529 * This is a vector binary operation where the primitive subtraction 530 * operation ({@code -}) is applied to lane elements. 531 * 532 * @param s the input scalar 533 * @param m the mask controlling lane selection 534 * @return the result of subtracting the broadcast of an input 535 * scalar from this vector 536 */ 537 public abstract ByteVector sub(byte s, Mask<Byte> m); 538 539 @Override 540 public abstract ByteVector mul(Vector<Byte> v); 541 542 /** 543 * Multiplies this vector with the broadcast of an input scalar. 544 * <p> 545 * This is a vector binary operation where the primitive multiplication 546 * operation ({@code *}) is applied to lane elements. 547 * 548 * @param s the input scalar 549 * @return the result of multiplying this vector with the broadcast of an 550 * input scalar 551 */ 552 public abstract ByteVector mul(byte s); 553 554 @Override 555 public abstract ByteVector mul(Vector<Byte> v, Mask<Byte> m); 556 557 /** 558 * Multiplies this vector with the broadcast of an input scalar, selecting 559 * lane elements controlled by a mask. 560 * <p> 561 * This is a vector binary operation where the primitive multiplication 562 * operation ({@code *}) is applied to lane elements. 563 * 564 * @param s the input scalar 565 * @param m the mask controlling lane selection 566 * @return the result of multiplying this vector with the broadcast of an 567 * input scalar 568 */ 569 public abstract ByteVector mul(byte s, Mask<Byte> m); 570 571 @Override 572 public abstract ByteVector neg(); 573 574 @Override 575 public abstract ByteVector neg(Mask<Byte> m); 576 577 @Override 578 public abstract ByteVector abs(); 579 580 @Override 581 public abstract ByteVector abs(Mask<Byte> m); 582 583 @Override 584 public abstract ByteVector min(Vector<Byte> v); 585 586 @Override 587 public abstract ByteVector min(Vector<Byte> v, Mask<Byte> m); 588 589 /** 590 * Returns the minimum of this vector and the broadcast of an input scalar. 591 * <p> 592 * This is a vector binary operation where the operation 593 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements. 594 * 595 * @param s the input scalar 596 * @return the minimum of this vector and the broadcast of an input scalar 597 */ 598 public abstract ByteVector min(byte s); 599 600 @Override 601 public abstract ByteVector max(Vector<Byte> v); 602 603 @Override 604 public abstract ByteVector max(Vector<Byte> v, Mask<Byte> m); 605 606 /** 607 * Returns the maximum of this vector and the broadcast of an input scalar. 608 * <p> 609 * This is a vector binary operation where the operation 610 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements. 611 * 612 * @param s the input scalar 613 * @return the maximum of this vector and the broadcast of an input scalar 614 */ 615 public abstract ByteVector max(byte s); 616 617 @Override 618 public abstract Mask<Byte> equal(Vector<Byte> v); 619 620 /** 621 * Tests if this vector is equal to the broadcast of an input scalar. 622 * <p> 623 * This is a vector binary test operation where the primitive equals 624 * operation ({@code ==}) is applied to lane elements. 625 * 626 * @param s the input scalar 627 * @return the result mask of testing if this vector is equal to the 628 * broadcast of an input scalar 629 */ 630 public abstract Mask<Byte> equal(byte s); 631 632 @Override 633 public abstract Mask<Byte> notEqual(Vector<Byte> v); 634 635 /** 636 * Tests if this vector is not equal to the broadcast of an input scalar. 637 * <p> 638 * This is a vector binary test operation where the primitive not equals 639 * operation ({@code !=}) is applied to lane elements. 640 * 641 * @param s the input scalar 642 * @return the result mask of testing if this vector is not equal to the 643 * broadcast of an input scalar 644 */ 645 public abstract Mask<Byte> notEqual(byte s); 646 647 @Override 648 public abstract Mask<Byte> lessThan(Vector<Byte> v); 649 650 /** 651 * Tests if this vector is less than the broadcast of an input scalar. 652 * <p> 653 * This is a vector binary test operation where the primitive less than 654 * operation ({@code <}) is applied to lane elements. 655 * 656 * @param s the input scalar 657 * @return the mask result of testing if this vector is less than the 658 * broadcast of an input scalar 659 */ 660 public abstract Mask<Byte> lessThan(byte s); 661 662 @Override 663 public abstract Mask<Byte> lessThanEq(Vector<Byte> v); 664 665 /** 666 * Tests if this vector is less or equal to the broadcast of an input scalar. 667 * <p> 668 * This is a vector binary test operation where the primitive less than 669 * or equal to operation ({@code <=}) is applied to lane elements. 670 * 671 * @param s the input scalar 672 * @return the mask result of testing if this vector is less than or equal 673 * to the broadcast of an input scalar 674 */ 675 public abstract Mask<Byte> lessThanEq(byte s); 676 677 @Override 678 public abstract Mask<Byte> greaterThan(Vector<Byte> v); 679 680 /** 681 * Tests if this vector is greater than the broadcast of an input scalar. 682 * <p> 683 * This is a vector binary test operation where the primitive greater than 684 * operation ({@code >}) is applied to lane elements. 685 * 686 * @param s the input scalar 687 * @return the mask result of testing if this vector is greater than the 688 * broadcast of an input scalar 689 */ 690 public abstract Mask<Byte> greaterThan(byte s); 691 692 @Override 693 public abstract Mask<Byte> greaterThanEq(Vector<Byte> v); 694 695 /** 696 * Tests if this vector is greater than or equal to the broadcast of an 697 * input scalar. 698 * <p> 699 * This is a vector binary test operation where the primitive greater than 700 * or equal to operation ({@code >=}) is applied to lane elements. 701 * 702 * @param s the input scalar 703 * @return the mask result of testing if this vector is greater than or 704 * equal to the broadcast of an input scalar 705 */ 706 public abstract Mask<Byte> greaterThanEq(byte s); 707 708 @Override 709 public abstract ByteVector blend(Vector<Byte> v, Mask<Byte> m); 710 711 /** 712 * Blends the lane elements of this vector with those of the broadcast of an 713 * input scalar, selecting lanes controlled by a mask. 714 * <p> 715 * For each lane of the mask, at lane index {@code N}, if the mask lane 716 * is set then the lane element at {@code N} from the input vector is 717 * selected and placed into the resulting vector at {@code N}, 718 * otherwise the the lane element at {@code N} from this input vector is 719 * selected and placed into the resulting vector at {@code N}. 720 * 721 * @param s the input scalar 722 * @param m the mask controlling lane selection 723 * @return the result of blending the lane elements of this vector with 724 * those of the broadcast of an input scalar 725 */ 726 public abstract ByteVector blend(byte s, Mask<Byte> m); 727 728 @Override 729 public abstract ByteVector rearrange(Vector<Byte> v, 730 Shuffle<Byte> s, Mask<Byte> m); 731 732 @Override 733 public abstract ByteVector rearrange(Shuffle<Byte> m); 734 735 @Override 736 public abstract ByteVector reshape(Species<Byte> s); 737 738 @Override 739 public abstract ByteVector rotateEL(int i); 740 741 @Override 742 public abstract ByteVector rotateER(int i); 743 744 @Override 745 public abstract ByteVector shiftEL(int i); 746 747 @Override 748 public abstract ByteVector shiftER(int i); 749 750 751 752 /** 753 * Bitwise ANDs this vector with an input vector. 754 * <p> 755 * This is a vector binary operation where the primitive bitwise AND 756 * operation ({@code &}) is applied to lane elements. 757 * 758 * @param v the input vector 759 * @return the bitwise AND of this vector with the input vector 760 */ 761 public abstract ByteVector and(Vector<Byte> v); 762 763 /** 764 * Bitwise ANDs this vector with the broadcast of an input scalar. 765 * <p> 766 * This is a vector binary operation where the primitive bitwise AND 767 * operation ({@code &}) is applied to lane elements. 768 * 769 * @param s the input scalar 770 * @return the bitwise AND of this vector with the broadcast of an input 771 * scalar 772 */ 773 public abstract ByteVector and(byte s); 774 775 /** 776 * Bitwise ANDs this vector with an input vector, selecting lane elements 777 * controlled by a mask. 778 * <p> 779 * This is a vector binary operation where the primitive bitwise AND 780 * operation ({@code &}) is applied to lane elements. 781 * 782 * @param v the input vector 783 * @param m the mask controlling lane selection 784 * @return the bitwise AND of this vector with the input vector 785 */ 786 public abstract ByteVector and(Vector<Byte> v, Mask<Byte> m); 787 788 /** 789 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting 790 * lane elements controlled by a mask. 791 * <p> 792 * This is a vector binary operation where the primitive bitwise AND 793 * operation ({@code &}) is applied to lane elements. 794 * 795 * @param s the input scalar 796 * @param m the mask controlling lane selection 797 * @return the bitwise AND of this vector with the broadcast of an input 798 * scalar 799 */ 800 public abstract ByteVector and(byte s, Mask<Byte> m); 801 802 /** 803 * Bitwise ORs this vector with an input vector. 804 * <p> 805 * This is a vector binary operation where the primitive bitwise OR 806 * operation ({@code |}) is applied to lane elements. 807 * 808 * @param v the input vector 809 * @return the bitwise OR of this vector with the input vector 810 */ 811 public abstract ByteVector or(Vector<Byte> v); 812 813 /** 814 * Bitwise ORs this vector with the broadcast of an input scalar. 815 * <p> 816 * This is a vector binary operation where the primitive bitwise OR 817 * operation ({@code |}) is applied to lane elements. 818 * 819 * @param s the input scalar 820 * @return the bitwise OR of this vector with the broadcast of an input 821 * scalar 822 */ 823 public abstract ByteVector or(byte s); 824 825 /** 826 * Bitwise ORs this vector with an input vector, selecting lane elements 827 * controlled by a mask. 828 * <p> 829 * This is a vector binary operation where the primitive bitwise OR 830 * operation ({@code |}) is applied to lane elements. 831 * 832 * @param v the input vector 833 * @param m the mask controlling lane selection 834 * @return the bitwise OR of this vector with the input vector 835 */ 836 public abstract ByteVector or(Vector<Byte> v, Mask<Byte> m); 837 838 /** 839 * Bitwise ORs this vector with the broadcast of an input scalar, selecting 840 * lane elements controlled by a mask. 841 * <p> 842 * This is a vector binary operation where the primitive bitwise OR 843 * operation ({@code |}) is applied to lane elements. 844 * 845 * @param s the input scalar 846 * @param m the mask controlling lane selection 847 * @return the bitwise OR of this vector with the broadcast of an input 848 * scalar 849 */ 850 public abstract ByteVector or(byte s, Mask<Byte> m); 851 852 /** 853 * Bitwise XORs this vector with an input vector. 854 * <p> 855 * This is a vector binary operation where the primitive bitwise XOR 856 * operation ({@code ^}) is applied to lane elements. 857 * 858 * @param v the input vector 859 * @return the bitwise XOR of this vector with the input vector 860 */ 861 public abstract ByteVector xor(Vector<Byte> v); 862 863 /** 864 * Bitwise XORs this vector with the broadcast of an input scalar. 865 * <p> 866 * This is a vector binary operation where the primitive bitwise XOR 867 * operation ({@code ^}) is applied to lane elements. 868 * 869 * @param s the input scalar 870 * @return the bitwise XOR of this vector with the broadcast of an input 871 * scalar 872 */ 873 public abstract ByteVector xor(byte s); 874 875 /** 876 * Bitwise XORs this vector with an input vector, selecting lane elements 877 * controlled by a mask. 878 * <p> 879 * This is a vector binary operation where the primitive bitwise XOR 880 * operation ({@code ^}) is applied to lane elements. 881 * 882 * @param v the input vector 883 * @param m the mask controlling lane selection 884 * @return the bitwise XOR of this vector with the input vector 885 */ 886 public abstract ByteVector xor(Vector<Byte> v, Mask<Byte> m); 887 888 /** 889 * Bitwise XORs this vector with the broadcast of an input scalar, selecting 890 * lane elements controlled by a mask. 891 * <p> 892 * This is a vector binary operation where the primitive bitwise XOR 893 * operation ({@code ^}) is applied to lane elements. 894 * 895 * @param s the input scalar 896 * @param m the mask controlling lane selection 897 * @return the bitwise XOR of this vector with the broadcast of an input 898 * scalar 899 */ 900 public abstract ByteVector xor(byte s, Mask<Byte> m); 901 902 /** 903 * Bitwise NOTs this vector. 904 * <p> 905 * This is a vector unary operation where the primitive bitwise NOT 906 * operation ({@code ~}) is applied to lane elements. 907 * 908 * @return the bitwise NOT of this vector 909 */ 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. 1182 * <p> 1183 * This is an associative vector reduction operation where the logical OR 1184 * operation ({@code |}) is applied to lane elements, 1185 * and the identity value is {@code 0}. 1186 * 1187 * @param m the mask controlling lane selection 1188 * @return the logical OR all the lane elements of this vector 1189 */ 1190 public abstract byte orAll(Mask<Byte> m); 1191 1192 /** 1193 * Logically ANDs all lane elements of this vector. 1194 * <p> 1195 * This is an associative vector reduction operation where the logical AND 1196 * operation ({@code |}) is applied to lane elements, 1197 * and the identity value is {@code -1}. 1198 * 1199 * @return the logical AND all the lane elements of this vector 1200 */ 1201 public abstract byte andAll(); 1202 1203 /** 1204 * Logically ANDs all lane elements of this vector, selecting lane elements 1205 * controlled by a mask. 1206 * <p> 1207 * This is an associative vector reduction operation where the logical AND 1208 * operation ({@code |}) is applied to lane elements, 1209 * and the identity value is {@code -1}. 1210 * 1211 * @param m the mask controlling lane selection 1212 * @return the logical AND all the lane elements of this vector 1213 */ 1214 public abstract byte andAll(Mask<Byte> m); 1215 1216 /** 1217 * Logically XORs all lane elements of this vector. 1218 * <p> 1219 * This is an associative vector reduction operation where the logical XOR 1220 * operation ({@code ^}) is applied to lane elements, 1221 * and the identity value is {@code 0}. 1222 * 1223 * @return the logical XOR all the lane elements of this vector 1224 */ 1225 public abstract byte xorAll(); 1226 1227 /** 1228 * Logically XORs all lane elements of this vector, selecting lane elements 1229 * controlled by a mask. 1230 * <p> 1231 * This is an associative vector reduction operation where the logical XOR 1232 * operation ({@code ^}) is applied to lane elements, 1233 * and the identity value is {@code 0}. 1234 * 1235 * @param m the mask controlling lane selection 1236 * @return the logical XOR all the lane elements of this vector 1237 */ 1238 public abstract byte xorAll(Mask<Byte> m); 1239 1240 // Type specific accessors 1241 1242 /** 1243 * Gets the lane element at lane index {@code i} 1244 * 1245 * @param i the lane index 1246 * @return the lane element at lane index {@code i} 1247 * @throws IllegalArgumentException if the index is is out of range 1248 * ({@code < 0 || >= length()}) 1249 */ 1250 public abstract byte get(int i); 1251 1252 /** 1253 * Replaces the lane element of this vector at lane index {@code i} with 1254 * value {@code e}. 1255 * <p> 1256 * This is a cross-lane operation and behaves as if it returns the result 1257 * of blending this vector with an input vector that is the result of 1258 * broadcasting {@code e} and a mask that has only one lane set at lane 1259 * index {@code i}. 1260 * 1261 * @param i the lane index of the lane element to be replaced 1262 * @param e the value to be placed 1263 * @return the result of replacing the lane element of this vector at lane 1264 * index {@code i} with value {@code e}. 1265 * @throws IllegalArgumentException if the index is is out of range 1266 * ({@code < 0 || >= length()}) 1267 */ 1268 public abstract ByteVector with(int i, byte e); 1269 1270 // Type specific extractors 1271 1272 /** 1273 * Returns an array containing the lane elements of this vector. 1274 * <p> 1275 * This method behaves as if it {@link #intoArray(byte[], int)} stores} 1276 * this vector into an allocated array and returns the array as follows: 1277 * <pre>{@code 1278 * byte[] a = new byte[this.length()]; 1279 * this.intoArray(a, 0); 1280 * return a; 1281 * }</pre> 1282 * 1283 * @return an array containing the the lane elements of this vector 1284 */ 1285 @ForceInline 1286 public final byte[] toArray() { 1287 byte[] a = new byte[species().length()]; 1288 intoArray(a, 0); 1289 return a; 1290 } 1291 1292 /** 1293 * Stores this vector into an array starting at offset. 1294 * <p> 1295 * For each vector lane, where {@code N} is the vector lane index, 1296 * the lane element at index {@code N} is stored into the array at index 1297 * {@code i + N}. 1298 * 1299 * @param a the array 1300 * @param i the offset into the array 1301 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1302 * {@code i > a.length - this.length()} 1303 */ 1304 public abstract void intoArray(byte[] a, int i); 1305 1306 /** 1307 * Stores this vector into an array starting at offset and using a mask. 1308 * <p> 1309 * For each vector lane, where {@code N} is the vector lane index, 1310 * if the mask lane at index {@code N} is set then the lane element at 1311 * index {@code N} is stored into the array index {@code i + N}. 1312 * 1313 * @param a the array 1314 * @param i the offset into the array 1315 * @param m the mask 1316 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1317 * for any vector lane index {@code N} where the mask at lane {@code N} 1318 * is set {@code i >= a.length - N} 1319 */ 1320 public abstract void intoArray(byte[] a, int i, Mask<Byte> m); 1321 1322 /** 1323 * Stores this vector into an array using indexes obtained from an index 1324 * map. 1325 * <p> 1326 * For each vector lane, where {@code N} is the vector lane index, the 1327 * lane element at index {@code N} is stored into the array at index 1328 * {@code i + indexMap[j + N]}. 1329 * 1330 * @param a the array 1331 * @param i the offset into the array, may be negative if relative 1332 * indexes in the index map compensate to produce a value within the 1333 * array bounds 1334 * @param indexMap the index map 1335 * @param j the offset into the index map 1336 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1337 * {@code j > indexMap.length - this.length()}, 1338 * or for any vector lane index {@code N} the result of 1339 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 1340 */ 1341 public void intoArray(byte[] a, int i, int[] indexMap, int j) { 1342 forEach((n, e) -> a[i + indexMap[j + n]] = e); 1343 } 1344 1345 /** 1346 * Stores this vector into an array using indexes obtained from an index 1347 * map and using a mask. 1348 * <p> 1349 * For each vector lane, where {@code N} is the vector lane index, 1350 * if the mask lane at index {@code N} is set then the lane element at 1351 * index {@code N} is stored into the array at index 1352 * {@code i + indexMap[j + N]}. 1353 * 1354 * @param a the array 1355 * @param i the offset into the array, may be negative if relative 1356 * indexes in the index map compensate to produce a value within the 1357 * array bounds 1358 * @param m the mask 1359 * @param indexMap the index map 1360 * @param j the offset into the index map 1361 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1362 * {@code j > indexMap.length - this.length()}, 1363 * or for any vector lane index {@code N} where the mask at lane 1364 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1365 * {@code < 0} or {@code >= a.length} 1366 */ 1367 public void intoArray(byte[] a, int i, Mask<Byte> m, int[] indexMap, int j) { 1368 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e); 1369 } 1370 // Species 1371 1372 @Override 1373 public abstract ByteSpecies species(); 1374 1375 /** 1376 * A specialized factory for creating {@link ByteVector} value of the same 1377 * shape, and a {@link Mask} and {@link Shuffle} values of the same shape 1378 * and {@code int} element type. 1379 */ 1380 public static abstract class ByteSpecies extends Vector.Species<Byte> { 1381 interface FOp { 1382 byte apply(int i); 1383 } 1384 1385 abstract ByteVector op(FOp f); 1386 1387 abstract ByteVector op(Mask<Byte> m, FOp f); 1388 1389 interface FOpm { 1390 boolean apply(int i); 1391 } 1392 1393 abstract Mask<Byte> opm(FOpm f); 1394 1395 1396 1397 // Factories 1398 1399 @Override 1400 public abstract ByteVector zero(); 1401 1402 /** 1403 * Returns a vector where all lane elements are set to the primitive 1404 * value {@code e}. 1405 * 1406 * @param e the value 1407 * @return a vector of vector where all lane elements are set to 1408 * the primitive value {@code e} 1409 */ 1410 public abstract ByteVector broadcast(byte e); 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 1452 * @throws IndexOutOfBoundsException if {@code es.length < this.length()} 1453 */ 1454 public abstract ByteVector scalars(byte... es); 1455 } 1456 1457 /** 1458 * Finds the preferred species for an element type of {@code byte}. 1459 * <p> 1460 * A preferred species is a species chosen by the platform that has a 1461 * shape of maximal bit size. A preferred species for different element 1462 * types will have the same shape, and therefore vectors, masks, and 1463 * shuffles created from such species will be shape compatible. 1464 * 1465 * @return the preferred species for an element type of {@code byte} 1466 */ 1467 @SuppressWarnings("unchecked") 1468 public static ByteSpecies preferredSpecies() { 1469 return (ByteSpecies) Species.ofPreferred(byte.class); 1470 } 1471 1472 /** 1473 * Finds a species for an element type of {@code byte} and shape. 1474 * 1475 * @param s the shape 1476 * @return a species for an element type of {@code byte} and shape 1477 * @throws IllegalArgumentException if no such species exists for the shape 1478 */ 1479 @SuppressWarnings("unchecked") 1480 public static ByteSpecies species(Vector.Shape s) { 1481 Objects.requireNonNull(s); 1482 switch (s) { 1483 case S_64_BIT: return Byte64Vector.SPECIES; 1484 case S_128_BIT: return Byte128Vector.SPECIES; 1485 case S_256_BIT: return Byte256Vector.SPECIES; 1486 case S_512_BIT: return Byte512Vector.SPECIES; 1487 case S_Max_BIT: return ByteMaxVector.SPECIES; 1488 default: throw new IllegalArgumentException("Bad shape: " + s); 1489 } 1490 } 1491 }