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.function.Function; 32 import java.util.concurrent.ThreadLocalRandom; 33 34 import jdk.internal.misc.Unsafe; 35 import jdk.internal.vm.annotation.ForceInline; 36 import static jdk.incubator.vector.VectorIntrinsics.*; 37 38 39 /** 40 * A specialized {@link Vector} representing an ordered immutable sequence of 41 * {@code byte} values. 42 */ 43 @SuppressWarnings("cast") 44 public abstract class ByteVector extends Vector<Byte> { 45 46 ByteVector() {} 47 48 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE); 49 50 // Unary operator 51 52 interface FUnOp { 53 byte apply(int i, byte a); 54 } 55 56 abstract ByteVector uOp(FUnOp f); 57 58 abstract ByteVector uOp(VectorMask<Byte> m, FUnOp f); 59 60 // Binary operator 61 62 interface FBinOp { 63 byte apply(int i, byte a, byte b); 64 } 65 66 abstract ByteVector bOp(Vector<Byte> v, FBinOp f); 67 68 abstract ByteVector bOp(Vector<Byte> v, VectorMask<Byte> m, FBinOp f); 69 70 // Trinary operator 71 72 interface FTriOp { 73 byte apply(int i, byte a, byte b, byte c); 74 } 75 76 abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, FTriOp f); 77 78 abstract ByteVector tOp(Vector<Byte> v1, Vector<Byte> v2, VectorMask<Byte> m, FTriOp f); 79 80 // Reduction operator 81 82 abstract byte rOp(byte v, FBinOp f); 83 84 // Binary test 85 86 interface FBinTest { 87 boolean apply(int i, byte a, byte b); 88 } 89 90 abstract VectorMask<Byte> bTest(Vector<Byte> v, FBinTest f); 91 92 // Foreach 93 94 interface FUnCon { 95 void apply(int i, byte a); 96 } 97 98 abstract void forEach(FUnCon f); 99 100 abstract void forEach(VectorMask<Byte> m, FUnCon f); 101 102 // Static factories 103 104 /** 105 * Returns a vector where all lane elements are set to the default 106 * primitive value. 107 * 108 * @param species species of desired vector 109 * @return a zero vector of given species 110 */ 111 @ForceInline 112 @SuppressWarnings("unchecked") 113 public static ByteVector zero(VectorSpecies<Byte> species) { 114 return VectorIntrinsics.broadcastCoerced((Class<ByteVector>) species.boxType(), byte.class, species.length(), 115 0, species, 116 ((bits, s) -> ((ByteSpecies)s).op(i -> (byte)bits))); 117 } 118 119 /** 120 * Loads a vector from a byte array starting at an offset. 121 * <p> 122 * Bytes are composed into primitive lane elements according to the 123 * native byte order of the underlying platform 124 * <p> 125 * This method behaves as if it returns the result of calling the 126 * byte buffer, offset, and mask accepting 127 * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask) method} as follows: 128 * <pre>{@code 129 * return fromByteBuffer(species, ByteBuffer.wrap(a), offset, VectorMask.allTrue()); 130 * }</pre> 131 * 132 * @param species species of desired vector 133 * @param a the byte array 134 * @param offset the offset into the array 135 * @return a vector loaded from a byte array 136 * @throws IndexOutOfBoundsException if {@code i < 0} or 137 * {@code offset > a.length - (species.length() * species.elementSize() / Byte.SIZE)} 138 */ 139 @ForceInline 140 @SuppressWarnings("unchecked") 141 public static ByteVector fromByteArray(VectorSpecies<Byte> species, byte[] a, int offset) { 142 Objects.requireNonNull(a); 143 offset = VectorIntrinsics.checkIndex(offset, a.length, species.bitSize() / Byte.SIZE); 144 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(), 145 a, ((long) offset) + Unsafe.ARRAY_BYTE_BASE_OFFSET, 146 a, offset, species, 147 (c, idx, s) -> { 148 ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder()); 149 ByteBuffer tb = bbc; 150 return ((ByteSpecies)s).op(i -> tb.get()); 151 }); 152 } 153 154 /** 155 * Loads a vector from a byte array starting at an offset and using a 156 * mask. 157 * <p> 158 * Bytes are composed into primitive lane elements according to the 159 * native byte order of the underlying platform. 160 * <p> 161 * This method behaves as if it returns the result of calling the 162 * byte buffer, offset, and mask accepting 163 * {@link #fromByteBuffer(VectorSpecies, ByteBuffer, int, VectorMask) method} as follows: 164 * <pre>{@code 165 * return fromByteBuffer(species, ByteBuffer.wrap(a), offset, m); 166 * }</pre> 167 * 168 * @param species species of desired vector 169 * @param a the byte array 170 * @param offset the offset into the array 171 * @param m the mask 172 * @return a vector loaded from a byte array 173 * @throws IndexOutOfBoundsException if {@code offset < 0} or 174 * for any vector lane index {@code N} where the mask at lane {@code N} 175 * is set 176 * {@code offset >= a.length - (N * species.elementSize() / Byte.SIZE)} 177 */ 178 @ForceInline 179 public static ByteVector fromByteArray(VectorSpecies<Byte> species, byte[] a, int offset, VectorMask<Byte> m) { 180 return zero(species).blend(fromByteArray(species, a, offset), 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 offset + 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 offset the offset into the array 193 * @return the vector loaded from an array 194 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 195 * {@code offset > a.length - species.length()} 196 */ 197 @ForceInline 198 @SuppressWarnings("unchecked") 199 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int offset){ 200 Objects.requireNonNull(a); 201 offset = VectorIntrinsics.checkIndex(offset, a.length, species.length()); 202 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(), 203 a, (((long) offset) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET, 204 a, offset, 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 offset + 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 offset the offset into the array 221 * @param m the mask 222 * @return the vector loaded from an array 223 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 224 * for any vector lane index {@code N} where the mask at lane {@code N} 225 * is set {@code offset > a.length - N} 226 */ 227 @ForceInline 228 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int offset, VectorMask<Byte> m) { 229 return zero(species).blend(fromArray(species, a, offset), 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 a_offset + indexMap[i_offset + 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 a_offset 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 i_offset the offset into the index map 247 * @return the vector loaded from an array 248 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 249 * {@code i_offset > indexMap.length - species.length()}, 250 * or for any vector lane index {@code N} the result of 251 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length} 252 */ 253 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int a_offset, int[] indexMap, int i_offset) { 254 return ((ByteSpecies)species).op(n -> a[a_offset + indexMap[i_offset + 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 a_offset + indexMap[i_offset + 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 a_offset 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 i_offset the offset into the index map 273 * @return the vector loaded from an array 274 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 275 * {@code i_offset > indexMap.length - species.length()}, 276 * or for any vector lane index {@code N} where the mask at lane 277 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is 278 * {@code < 0} or {@code >= a.length} 279 */ 280 public static ByteVector fromArray(VectorSpecies<Byte> species, byte[] a, int a_offset, VectorMask<Byte> m, int[] indexMap, int i_offset) { 281 return ((ByteSpecies)species).op(m, n -> a[a_offset + indexMap[i_offset + 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(VectorSpecies, ByteBuffer, int, VectorMask)} method} as follows: 294 * <pre>{@code 295 * return fromByteBuffer(b, offset, VectorMask.allTrue()) 296 * }</pre> 297 * 298 * @param species species of desired vector 299 * @param bb the byte buffer 300 * @param offset 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 species.length() * species.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(VectorSpecies<Byte> species, ByteBuffer bb, int offset) { 311 if (bb.order() != ByteOrder.nativeOrder()) { 312 throw new IllegalArgumentException(); 313 } 314 offset = VectorIntrinsics.checkIndex(offset, 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) + offset, 317 bb, offset, species, 318 (c, idx, s) -> { 319 ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder()); 320 ByteBuffer tb = bbc; 321 return ((ByteSpecies)s).op(i -> tb.get()); 322 }); 323 } 324 325 /** 326 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an 327 * offset into the byte buffer and using a mask. 328 * <p> 329 * This method behaves as if the byte buffer is viewed as a primitive 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 * {@code EBuffer} is the primitive buffer type, {@code e} is the 336 * primitive element type, and {@code ESpecies} is the primitive 337 * species for {@code e}: 338 * <pre>{@code 339 * EBuffer eb = b.duplicate(). 340 * order(ByteOrder.nativeOrder()).position(offset). 341 * asEBuffer(); 342 * e[] es = new e[species.length()]; 343 * for (int n = 0; n < t.length; n++) { 344 * if (m.isSet(n)) 345 * es[n] = eb.get(n); 346 * } 347 * EVector r = EVector.fromArray(es, 0, m); 348 * }</pre> 349 * 350 * @param species species of desired vector 351 * @param bb the byte buffer 352 * @param offset 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 offset >= b.limit() - (N * species.elementSize() / Byte.SIZE)} 360 */ 361 @ForceInline 362 public static ByteVector fromByteBuffer(VectorSpecies<Byte> species, ByteBuffer bb, int offset, VectorMask<Byte> m) { 363 return zero(species).blend(fromByteBuffer(species, bb, offset), m); 364 } 365 366 /** 367 * Returns a vector where all lane elements are set to the primitive 368 * value {@code e}. 369 * 370 * @param species species of the desired vector 371 * @param e the value 372 * @return a vector of vector where all lane elements are set to 373 * the primitive value {@code e} 374 */ 375 @ForceInline 376 @SuppressWarnings("unchecked") 377 public static ByteVector broadcast(VectorSpecies<Byte> species, byte e) { 378 return VectorIntrinsics.broadcastCoerced( 379 (Class<ByteVector>) species.boxType(), byte.class, species.length(), 380 e, species, 381 ((bits, sp) -> ((ByteSpecies)sp).op(i -> (byte)bits))); 382 } 383 384 /** 385 * Returns a vector where each lane element is set to given 386 * primitive values. 387 * <p> 388 * For each vector lane, where {@code N} is the vector lane index, the 389 * the primitive value at index {@code N} is placed into the resulting 390 * vector at lane index {@code N}. 391 * 392 * @param species species of the desired vector 393 * @param es the given primitive values 394 * @return a vector where each lane element is set to given primitive 395 * values 396 * @throws IndexOutOfBoundsException if {@code es.length < species.length()} 397 */ 398 @ForceInline 399 @SuppressWarnings("unchecked") 400 public static ByteVector scalars(VectorSpecies<Byte> species, byte... es) { 401 Objects.requireNonNull(es); 402 int ix = VectorIntrinsics.checkIndex(0, es.length, species.length()); 403 return VectorIntrinsics.load((Class<ByteVector>) species.boxType(), byte.class, species.length(), 404 es, Unsafe.ARRAY_BYTE_BASE_OFFSET, 405 es, ix, species, 406 (c, idx, sp) -> ((ByteSpecies)sp).op(n -> c[idx + n])); 407 } 408 409 /** 410 * Returns a vector where the first lane element is set to the primtive 411 * value {@code e}, all other lane elements are set to the default 412 * value. 413 * 414 * @param species species of the desired vector 415 * @param e the value 416 * @return a vector where the first lane element is set to the primitive 417 * value {@code e} 418 */ 419 @ForceInline 420 public static final ByteVector single(VectorSpecies<Byte> species, byte e) { 421 return zero(species).with(0, e); 422 } 423 424 /** 425 * Returns a vector where each lane element is set to a randomly 426 * generated primitive value. 427 * 428 * The semantics are equivalent to calling 429 * (byte){@link ThreadLocalRandom#nextInt()} 430 * 431 * @param species species of the desired vector 432 * @return a vector where each lane elements is set to a randomly 433 * generated primitive value 434 */ 435 public static ByteVector random(VectorSpecies<Byte> species) { 436 ThreadLocalRandom r = ThreadLocalRandom.current(); 437 return ((ByteSpecies)species).op(i -> (byte) r.nextInt()); 438 } 439 440 // Ops 441 442 /** 443 * {@inheritDoc} 444 */ 445 @Override 446 public abstract ByteVector add(Vector<Byte> v); 447 448 /** 449 * Adds this vector to the broadcast of an input scalar. 450 * <p> 451 * This is a lane-wise binary operation which applies the primitive addition operation 452 * ({@code +}) to each lane. 453 * 454 * @param s the input scalar 455 * @return the result of adding this vector to the broadcast of an input 456 * scalar 457 */ 458 public abstract ByteVector add(byte s); 459 460 /** 461 * {@inheritDoc} 462 */ 463 @Override 464 public abstract ByteVector add(Vector<Byte> v, VectorMask<Byte> m); 465 466 /** 467 * Adds this vector to broadcast of an input scalar, 468 * selecting lane elements controlled by a mask. 469 * <p> 470 * This is a lane-wise binary operation which applies the primitive addition operation 471 * ({@code +}) to each lane. 472 * 473 * @param s the input scalar 474 * @param m the mask controlling lane selection 475 * @return the result of adding this vector to the broadcast of an input 476 * scalar 477 */ 478 public abstract ByteVector add(byte s, VectorMask<Byte> m); 479 480 /** 481 * {@inheritDoc} 482 */ 483 @Override 484 public abstract ByteVector sub(Vector<Byte> v); 485 486 /** 487 * Subtracts the broadcast of an input scalar from this vector. 488 * <p> 489 * This is a lane-wise binary operation which applies the primitive subtraction 490 * operation ({@code -}) to each lane. 491 * 492 * @param s the input scalar 493 * @return the result of subtracting the broadcast of an input 494 * scalar from this vector 495 */ 496 public abstract ByteVector sub(byte s); 497 498 /** 499 * {@inheritDoc} 500 */ 501 @Override 502 public abstract ByteVector sub(Vector<Byte> v, VectorMask<Byte> m); 503 504 /** 505 * Subtracts the broadcast of an input scalar from this vector, selecting 506 * lane elements controlled by a mask. 507 * <p> 508 * This is a lane-wise binary operation which applies the primitive subtraction 509 * operation ({@code -}) to each lane. 510 * 511 * @param s the input scalar 512 * @param m the mask controlling lane selection 513 * @return the result of subtracting the broadcast of an input 514 * scalar from this vector 515 */ 516 public abstract ByteVector sub(byte s, VectorMask<Byte> m); 517 518 /** 519 * {@inheritDoc} 520 */ 521 @Override 522 public abstract ByteVector mul(Vector<Byte> v); 523 524 /** 525 * Multiplies this vector with the broadcast of an input scalar. 526 * <p> 527 * This is a lane-wise binary operation which applies the primitive multiplication 528 * operation ({@code *}) to each lane. 529 * 530 * @param s the input scalar 531 * @return the result of multiplying this vector with the broadcast of an 532 * input scalar 533 */ 534 public abstract ByteVector mul(byte s); 535 536 /** 537 * {@inheritDoc} 538 */ 539 @Override 540 public abstract ByteVector mul(Vector<Byte> v, VectorMask<Byte> m); 541 542 /** 543 * Multiplies this vector with the broadcast of an input scalar, selecting 544 * lane elements controlled by a mask. 545 * <p> 546 * This is a lane-wise binary operation which applies the primitive multiplication 547 * operation ({@code *}) to each lane. 548 * 549 * @param s the input scalar 550 * @param m the mask controlling lane selection 551 * @return the result of multiplying this vector with the broadcast of an 552 * input scalar 553 */ 554 public abstract ByteVector mul(byte s, VectorMask<Byte> m); 555 556 /** 557 * {@inheritDoc} 558 */ 559 @Override 560 public abstract ByteVector neg(); 561 562 /** 563 * {@inheritDoc} 564 */ 565 @Override 566 public abstract ByteVector neg(VectorMask<Byte> m); 567 568 /** 569 * {@inheritDoc} 570 */ 571 @Override 572 public abstract ByteVector abs(); 573 574 /** 575 * {@inheritDoc} 576 */ 577 @Override 578 public abstract ByteVector abs(VectorMask<Byte> m); 579 580 /** 581 * {@inheritDoc} 582 */ 583 @Override 584 public abstract ByteVector min(Vector<Byte> v); 585 586 /** 587 * {@inheritDoc} 588 */ 589 @Override 590 public abstract ByteVector min(Vector<Byte> v, VectorMask<Byte> m); 591 592 /** 593 * Returns the minimum of this vector and the broadcast of an input scalar. 594 * <p> 595 * This is a lane-wise binary operation which applies the operation 596 * {@code (a, b) -> Math.min(a, b)} to each lane. 597 * 598 * @param s the input scalar 599 * @return the minimum of this vector and the broadcast of an input scalar 600 */ 601 public abstract ByteVector min(byte s); 602 603 /** 604 * {@inheritDoc} 605 */ 606 @Override 607 public abstract ByteVector max(Vector<Byte> v); 608 609 /** 610 * {@inheritDoc} 611 */ 612 @Override 613 public abstract ByteVector max(Vector<Byte> v, VectorMask<Byte> m); 614 615 /** 616 * Returns the maximum of this vector and the broadcast of an input scalar. 617 * <p> 618 * This is a lane-wise binary operation which applies the operation 619 * {@code (a, b) -> Math.max(a, b)} to each lane. 620 * 621 * @param s the input scalar 622 * @return the maximum of this vector and the broadcast of an input scalar 623 */ 624 public abstract ByteVector max(byte s); 625 626 /** 627 * {@inheritDoc} 628 */ 629 @Override 630 public abstract VectorMask<Byte> equal(Vector<Byte> v); 631 632 /** 633 * Tests if this vector is equal to the broadcast of an input scalar. 634 * <p> 635 * This is a lane-wise binary test operation which applies the primitive equals 636 * operation ({@code ==}) each lane. 637 * 638 * @param s the input scalar 639 * @return the result mask of testing if this vector is equal to the 640 * broadcast of an input scalar 641 */ 642 public abstract VectorMask<Byte> equal(byte s); 643 644 /** 645 * {@inheritDoc} 646 */ 647 @Override 648 public abstract VectorMask<Byte> notEqual(Vector<Byte> v); 649 650 /** 651 * Tests if this vector is not equal to the broadcast of an input scalar. 652 * <p> 653 * This is a lane-wise binary test operation which applies the primitive not equals 654 * operation ({@code !=}) to each lane. 655 * 656 * @param s the input scalar 657 * @return the result mask of testing if this vector is not equal to the 658 * broadcast of an input scalar 659 */ 660 public abstract VectorMask<Byte> notEqual(byte s); 661 662 /** 663 * {@inheritDoc} 664 */ 665 @Override 666 public abstract VectorMask<Byte> lessThan(Vector<Byte> v); 667 668 /** 669 * Tests if this vector is less than the broadcast of an input scalar. 670 * <p> 671 * This is a lane-wise binary test operation which applies the primitive less than 672 * operation ({@code <}) to each lane. 673 * 674 * @param s the input scalar 675 * @return the mask result of testing if this vector is less than the 676 * broadcast of an input scalar 677 */ 678 public abstract VectorMask<Byte> lessThan(byte s); 679 680 /** 681 * {@inheritDoc} 682 */ 683 @Override 684 public abstract VectorMask<Byte> lessThanEq(Vector<Byte> v); 685 686 /** 687 * Tests if this vector is less or equal to the broadcast of an input scalar. 688 * <p> 689 * This is a lane-wise binary test operation which applies the primitive less than 690 * or equal to operation ({@code <=}) to each lane. 691 * 692 * @param s the input scalar 693 * @return the mask result of testing if this vector is less than or equal 694 * to the broadcast of an input scalar 695 */ 696 public abstract VectorMask<Byte> lessThanEq(byte s); 697 698 /** 699 * {@inheritDoc} 700 */ 701 @Override 702 public abstract VectorMask<Byte> greaterThan(Vector<Byte> v); 703 704 /** 705 * Tests if this vector is greater than the broadcast of an input scalar. 706 * <p> 707 * This is a lane-wise binary test operation which applies the primitive greater than 708 * operation ({@code >}) to each lane. 709 * 710 * @param s the input scalar 711 * @return the mask result of testing if this vector is greater than the 712 * broadcast of an input scalar 713 */ 714 public abstract VectorMask<Byte> greaterThan(byte s); 715 716 /** 717 * {@inheritDoc} 718 */ 719 @Override 720 public abstract VectorMask<Byte> greaterThanEq(Vector<Byte> v); 721 722 /** 723 * Tests if this vector is greater than or equal to the broadcast of an 724 * input scalar. 725 * <p> 726 * This is a lane-wise binary test operation which applies the primitive greater than 727 * or equal to operation ({@code >=}) to each lane. 728 * 729 * @param s the input scalar 730 * @return the mask result of testing if this vector is greater than or 731 * equal to the broadcast of an input scalar 732 */ 733 public abstract VectorMask<Byte> greaterThanEq(byte s); 734 735 /** 736 * {@inheritDoc} 737 */ 738 @Override 739 public abstract ByteVector blend(Vector<Byte> v, VectorMask<Byte> m); 740 741 /** 742 * Blends the lane elements of this vector with those of the broadcast of an 743 * input scalar, selecting lanes controlled by a mask. 744 * <p> 745 * For each lane of the mask, at lane index {@code N}, if the mask lane 746 * is set then the lane element at {@code N} from the input vector is 747 * selected and placed into the resulting vector at {@code N}, 748 * otherwise the the lane element at {@code N} from this input vector is 749 * selected and placed into the resulting vector at {@code N}. 750 * 751 * @param s the input scalar 752 * @param m the mask controlling lane selection 753 * @return the result of blending the lane elements of this vector with 754 * those of the broadcast of an input scalar 755 */ 756 public abstract ByteVector blend(byte s, VectorMask<Byte> m); 757 758 /** 759 * {@inheritDoc} 760 */ 761 @Override 762 public abstract ByteVector rearrange(Vector<Byte> v, 763 VectorShuffle<Byte> s, VectorMask<Byte> m); 764 765 /** 766 * {@inheritDoc} 767 */ 768 @Override 769 public abstract ByteVector rearrange(VectorShuffle<Byte> m); 770 771 /** 772 * {@inheritDoc} 773 */ 774 @Override 775 public abstract ByteVector reshape(VectorSpecies<Byte> s); 776 777 /** 778 * {@inheritDoc} 779 */ 780 @Override 781 public abstract ByteVector rotateEL(int i); 782 783 /** 784 * {@inheritDoc} 785 */ 786 @Override 787 public abstract ByteVector rotateER(int i); 788 789 /** 790 * {@inheritDoc} 791 */ 792 @Override 793 public abstract ByteVector shiftEL(int i); 794 795 /** 796 * {@inheritDoc} 797 */ 798 @Override 799 public abstract ByteVector shiftER(int i); 800 801 802 803 /** 804 * Bitwise ANDs this vector with an input vector. 805 * <p> 806 * This is a lane-wise binary operation which applies the primitive bitwise AND 807 * operation ({@code &}) to each lane. 808 * 809 * @param v the input vector 810 * @return the bitwise AND of this vector with the input vector 811 */ 812 public abstract ByteVector and(Vector<Byte> v); 813 814 /** 815 * Bitwise ANDs this vector with the broadcast of an input scalar. 816 * <p> 817 * This is a lane-wise binary operation which applies the primitive bitwise AND 818 * operation ({@code &}) to each lane. 819 * 820 * @param s the input scalar 821 * @return the bitwise AND of this vector with the broadcast of an input 822 * scalar 823 */ 824 public abstract ByteVector and(byte s); 825 826 /** 827 * Bitwise ANDs this vector with an input vector, selecting lane elements 828 * controlled by a mask. 829 * <p> 830 * This is a lane-wise binary operation which applies the primitive bitwise AND 831 * operation ({@code &}) to each lane. 832 * 833 * @param v the input vector 834 * @param m the mask controlling lane selection 835 * @return the bitwise AND of this vector with the input vector 836 */ 837 public abstract ByteVector and(Vector<Byte> v, VectorMask<Byte> m); 838 839 /** 840 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting 841 * lane elements controlled by a mask. 842 * <p> 843 * This is a lane-wise binary operation which applies the primitive bitwise AND 844 * operation ({@code &}) to each lane. 845 * 846 * @param s the input scalar 847 * @param m the mask controlling lane selection 848 * @return the bitwise AND of this vector with the broadcast of an input 849 * scalar 850 */ 851 public abstract ByteVector and(byte s, VectorMask<Byte> m); 852 853 /** 854 * Bitwise ORs this vector with an input vector. 855 * <p> 856 * This is a lane-wise binary operation which applies the primitive bitwise OR 857 * operation ({@code |}) to each lane. 858 * 859 * @param v the input vector 860 * @return the bitwise OR of this vector with the input vector 861 */ 862 public abstract ByteVector or(Vector<Byte> v); 863 864 /** 865 * Bitwise ORs this vector with the broadcast of an input scalar. 866 * <p> 867 * This is a lane-wise binary operation which applies the primitive bitwise OR 868 * operation ({@code |}) to each lane. 869 * 870 * @param s the input scalar 871 * @return the bitwise OR of this vector with the broadcast of an input 872 * scalar 873 */ 874 public abstract ByteVector or(byte s); 875 876 /** 877 * Bitwise ORs this vector with an input vector, selecting lane elements 878 * controlled by a mask. 879 * <p> 880 * This is a lane-wise binary operation which applies the primitive bitwise OR 881 * operation ({@code |}) to each lane. 882 * 883 * @param v the input vector 884 * @param m the mask controlling lane selection 885 * @return the bitwise OR of this vector with the input vector 886 */ 887 public abstract ByteVector or(Vector<Byte> v, VectorMask<Byte> m); 888 889 /** 890 * Bitwise ORs this vector with the broadcast of an input scalar, selecting 891 * lane elements controlled by a mask. 892 * <p> 893 * This is a lane-wise binary operation which applies the primitive bitwise OR 894 * operation ({@code |}) to each lane. 895 * 896 * @param s the input scalar 897 * @param m the mask controlling lane selection 898 * @return the bitwise OR of this vector with the broadcast of an input 899 * scalar 900 */ 901 public abstract ByteVector or(byte s, VectorMask<Byte> m); 902 903 /** 904 * Bitwise XORs this vector with an input vector. 905 * <p> 906 * This is a lane-wise binary operation which applies the primitive bitwise XOR 907 * operation ({@code ^}) to each lane. 908 * 909 * @param v the input vector 910 * @return the bitwise XOR of this vector with the input vector 911 */ 912 public abstract ByteVector xor(Vector<Byte> v); 913 914 /** 915 * Bitwise XORs this vector with the broadcast of an input scalar. 916 * <p> 917 * This is a lane-wise binary operation which applies the primitive bitwise XOR 918 * operation ({@code ^}) to each lane. 919 * 920 * @param s the input scalar 921 * @return the bitwise XOR of this vector with the broadcast of an input 922 * scalar 923 */ 924 public abstract ByteVector xor(byte s); 925 926 /** 927 * Bitwise XORs this vector with an input vector, selecting lane elements 928 * controlled by a mask. 929 * <p> 930 * This is a lane-wise binary operation which applies the primitive bitwise XOR 931 * operation ({@code ^}) to each lane. 932 * 933 * @param v the input vector 934 * @param m the mask controlling lane selection 935 * @return the bitwise XOR of this vector with the input vector 936 */ 937 public abstract ByteVector xor(Vector<Byte> v, VectorMask<Byte> m); 938 939 /** 940 * Bitwise XORs this vector with the broadcast of an input scalar, selecting 941 * lane elements controlled by a mask. 942 * <p> 943 * This is a lane-wise binary operation which applies the primitive bitwise XOR 944 * operation ({@code ^}) to each lane. 945 * 946 * @param s the input scalar 947 * @param m the mask controlling lane selection 948 * @return the bitwise XOR of this vector with the broadcast of an input 949 * scalar 950 */ 951 public abstract ByteVector xor(byte s, VectorMask<Byte> m); 952 953 /** 954 * Bitwise NOTs this vector. 955 * <p> 956 * This is a lane-wise unary operation which applies the primitive bitwise NOT 957 * operation ({@code ~}) to each lane. 958 * 959 * @return the bitwise NOT of this vector 960 */ 961 public abstract ByteVector not(); 962 963 /** 964 * Bitwise NOTs this vector, selecting lane elements controlled by a mask. 965 * <p> 966 * This is a lane-wise unary operation which applies the primitive bitwise NOT 967 * operation ({@code ~}) to each lane. 968 * 969 * @param m the mask controlling lane selection 970 * @return the bitwise NOT of this vector 971 */ 972 public abstract ByteVector not(VectorMask<Byte> m); 973 974 /** 975 * Logically left shifts this vector by the broadcast of an input scalar. 976 * <p> 977 * This is a lane-wise binary operation which applies the primitive logical left shift 978 * operation ({@code <<}) to each lane to left shift the 979 * element by shift value as specified by the input scalar. Only the 3 980 * lowest-order bits of shift value are used. It is as if the shift value 981 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7. 982 * The shift distance actually used is therefore always in the range 0 to 7, inclusive. 983 * 984 * @param s the input scalar; the number of the bits to left shift 985 * @return the result of logically left shifting left this vector by the 986 * broadcast of an input scalar 987 */ 988 public abstract ByteVector shiftL(int s); 989 990 /** 991 * Logically left shifts this vector by the broadcast of an input scalar, 992 * selecting lane elements controlled by a mask. 993 * <p> 994 * This is a lane-wise binary operation which applies the primitive logical left shift 995 * operation ({@code <<}) to each lane to left shift the 996 * element by shift value as specified by the input scalar. Only the 3 997 * lowest-order bits of shift value are used. It is as if the shift value 998 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7. 999 * The shift distance actually used is therefore always in the range 0 to 7, inclusive. 1000 * 1001 * @param s the input scalar; the number of the bits to left shift 1002 * @param m the mask controlling lane selection 1003 * @return the result of logically left shifting left this vector by the 1004 * broadcast of an input scalar 1005 */ 1006 public abstract ByteVector shiftL(int s, VectorMask<Byte> m); 1007 1008 1009 // logical, or unsigned, shift right 1010 1011 /** 1012 * Logically right shifts (or unsigned right shifts) this vector by the 1013 * broadcast of an input scalar. 1014 * <p> 1015 * This is a lane-wise binary operation which applies the primitive logical right shift 1016 * operation ({@code >>>}) to each lane to logically right shift the 1017 * element by shift value as specified by the input scalar. Only the 3 1018 * lowest-order bits of shift value are used. It is as if the shift value 1019 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7. 1020 * The shift distance actually used is therefore always in the range 0 to 7, inclusive. 1021 * 1022 * @param s the input scalar; the number of the bits to right shift 1023 * @return the result of logically right shifting this vector by the 1024 * broadcast of an input scalar 1025 */ 1026 public abstract ByteVector shiftR(int s); 1027 1028 /** 1029 * Logically right shifts (or unsigned right shifts) this vector by the 1030 * broadcast of an input scalar, selecting lane elements controlled by a 1031 * mask. 1032 * <p> 1033 * This is a lane-wise binary operation which applies the primitive logical right shift 1034 * operation ({@code >>}) to each lane to logically right shift the 1035 * element by shift value as specified by the input scalar. Only the 3 1036 * lowest-order bits of shift value are used. It is as if the shift value 1037 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7. 1038 * The shift distance actually used is therefore always in the range 0 to 7, inclusive. 1039 * 1040 * @param s the input scalar; the number of the bits to right shift 1041 * @param m the mask controlling lane selection 1042 * @return the result of logically right shifting this vector by the 1043 * broadcast of an input scalar 1044 */ 1045 public abstract ByteVector shiftR(int s, VectorMask<Byte> m); 1046 1047 1048 /** 1049 * Arithmetically right shifts (or signed right shifts) this vector by the 1050 * broadcast of an input scalar. 1051 * <p> 1052 * This is a lane-wise binary operation which applies the primitive arithmetic right 1053 * shift operation ({@code >>}) to each lane to arithmetically 1054 * right shift the element by shift value as specified by the input scalar. 1055 * Only the 3 lowest-order bits of shift value are used. It is as if the shift 1056 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7. 1057 * The shift distance actually used is therefore always in the range 0 to 7, inclusive. 1058 * 1059 * @param s the input scalar; the number of the bits to right shift 1060 * @return the result of arithmetically right shifting this vector by the 1061 * broadcast of an input scalar 1062 */ 1063 public abstract ByteVector aShiftR(int s); 1064 1065 /** 1066 * Arithmetically right shifts (or signed right shifts) this vector by the 1067 * broadcast of an input scalar, selecting lane elements controlled by a 1068 * mask. 1069 * <p> 1070 * This is a lane-wise binary operation which applies the primitive arithmetic right 1071 * shift operation ({@code >>}) to each lane to arithmetically 1072 * right shift the element by shift value as specified by the input scalar. 1073 * Only the 3 lowest-order bits of shift value are used. It is as if the shift 1074 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0x7. 1075 * The shift distance actually used is therefore always in the range 0 to 7, inclusive. 1076 * 1077 * @param s the input scalar; the number of the bits to right shift 1078 * @param m the mask controlling lane selection 1079 * @return the result of arithmetically right shifting this vector by the 1080 * broadcast of an input scalar 1081 */ 1082 public abstract ByteVector aShiftR(int s, VectorMask<Byte> m); 1083 1084 1085 /** 1086 * {@inheritDoc} 1087 */ 1088 @Override 1089 public abstract void intoByteArray(byte[] a, int ix); 1090 1091 /** 1092 * {@inheritDoc} 1093 */ 1094 @Override 1095 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Byte> m); 1096 1097 /** 1098 * {@inheritDoc} 1099 */ 1100 @Override 1101 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 1102 1103 /** 1104 * {@inheritDoc} 1105 */ 1106 @Override 1107 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Byte> m); 1108 1109 1110 // Type specific horizontal reductions 1111 /** 1112 * Adds all lane elements of this vector. 1113 * <p> 1114 * This is an associative cross-lane reduction operation which applies the addition 1115 * operation ({@code +}) to lane elements, 1116 * and the identity value is {@code 0}. 1117 * 1118 * @return the addition of all the lane elements of this vector 1119 */ 1120 public abstract byte addAll(); 1121 1122 /** 1123 * Adds all lane elements of this vector, selecting lane elements 1124 * controlled by a mask. 1125 * <p> 1126 * This is an associative cross-lane reduction operation which applies the addition 1127 * operation ({@code +}) to lane elements, 1128 * and the identity value is {@code 0}. 1129 * 1130 * @param m the mask controlling lane selection 1131 * @return the addition of the selected lane elements of this vector 1132 */ 1133 public abstract byte addAll(VectorMask<Byte> m); 1134 1135 /** 1136 * Multiplies all lane elements of this vector. 1137 * <p> 1138 * This is an associative cross-lane reduction operation which applies the 1139 * multiplication operation ({@code *}) to lane elements, 1140 * and the identity value is {@code 1}. 1141 * 1142 * @return the multiplication of all the lane elements of this vector 1143 */ 1144 public abstract byte mulAll(); 1145 1146 /** 1147 * Multiplies all lane elements of this vector, selecting lane elements 1148 * controlled by a mask. 1149 * <p> 1150 * This is an associative cross-lane reduction operation which applies the 1151 * multiplication operation ({@code *}) to lane elements, 1152 * and the identity value is {@code 1}. 1153 * 1154 * @param m the mask controlling lane selection 1155 * @return the multiplication of all the lane elements of this vector 1156 */ 1157 public abstract byte mulAll(VectorMask<Byte> m); 1158 1159 /** 1160 * Returns the minimum lane element of this vector. 1161 * <p> 1162 * This is an associative cross-lane reduction operation which applies the operation 1163 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1164 * and the identity value is 1165 * {@link Byte#MAX_VALUE}. 1166 * 1167 * @return the minimum lane element of this vector 1168 */ 1169 public abstract byte minAll(); 1170 1171 /** 1172 * Returns the minimum lane element of this vector, selecting lane elements 1173 * controlled by a mask. 1174 * <p> 1175 * This is an associative cross-lane reduction operation which applies the operation 1176 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1177 * and the identity value is 1178 * {@link Byte#MAX_VALUE}. 1179 * 1180 * @param m the mask controlling lane selection 1181 * @return the minimum lane element of this vector 1182 */ 1183 public abstract byte minAll(VectorMask<Byte> m); 1184 1185 /** 1186 * Returns the maximum lane element of this vector. 1187 * <p> 1188 * This is an associative cross-lane reduction operation which applies the operation 1189 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1190 * and the identity value is 1191 * {@link Byte#MIN_VALUE}. 1192 * 1193 * @return the maximum lane element of this vector 1194 */ 1195 public abstract byte maxAll(); 1196 1197 /** 1198 * Returns the maximum lane element of this vector, selecting lane elements 1199 * controlled by a mask. 1200 * <p> 1201 * This is an associative cross-lane reduction operation which applies the operation 1202 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1203 * and the identity value is 1204 * {@link Byte#MIN_VALUE}. 1205 * 1206 * @param m the mask controlling lane selection 1207 * @return the maximum lane element of this vector 1208 */ 1209 public abstract byte maxAll(VectorMask<Byte> m); 1210 1211 /** 1212 * Logically ORs all lane elements of this vector. 1213 * <p> 1214 * This is an associative cross-lane reduction operation which applies the logical OR 1215 * operation ({@code |}) to lane elements, 1216 * and the identity value is {@code 0}. 1217 * 1218 * @return the logical OR all the lane elements of this vector 1219 */ 1220 public abstract byte orAll(); 1221 1222 /** 1223 * Logically ORs all lane elements of this vector, selecting lane elements 1224 * controlled by a mask. 1225 * <p> 1226 * This is an associative cross-lane reduction operation which applies the logical OR 1227 * operation ({@code |}) to lane elements, 1228 * and the identity value is {@code 0}. 1229 * 1230 * @param m the mask controlling lane selection 1231 * @return the logical OR all the lane elements of this vector 1232 */ 1233 public abstract byte orAll(VectorMask<Byte> m); 1234 1235 /** 1236 * Logically ANDs all lane elements of this vector. 1237 * <p> 1238 * This is an associative cross-lane reduction operation which applies the logical AND 1239 * operation ({@code |}) to lane elements, 1240 * and the identity value is {@code -1}. 1241 * 1242 * @return the logical AND all the lane elements of this vector 1243 */ 1244 public abstract byte andAll(); 1245 1246 /** 1247 * Logically ANDs all lane elements of this vector, selecting lane elements 1248 * controlled by a mask. 1249 * <p> 1250 * This is an associative cross-lane reduction operation which applies the logical AND 1251 * operation ({@code |}) to lane elements, 1252 * and the identity value is {@code -1}. 1253 * 1254 * @param m the mask controlling lane selection 1255 * @return the logical AND all the lane elements of this vector 1256 */ 1257 public abstract byte andAll(VectorMask<Byte> m); 1258 1259 /** 1260 * Logically XORs all lane elements of this vector. 1261 * <p> 1262 * This is an associative cross-lane reduction operation which applies the logical XOR 1263 * operation ({@code ^}) to lane elements, 1264 * and the identity value is {@code 0}. 1265 * 1266 * @return the logical XOR all the lane elements of this vector 1267 */ 1268 public abstract byte xorAll(); 1269 1270 /** 1271 * Logically XORs all lane elements of this vector, selecting lane elements 1272 * controlled by a mask. 1273 * <p> 1274 * This is an associative cross-lane reduction operation which applies the logical XOR 1275 * operation ({@code ^}) to lane elements, 1276 * and the identity value is {@code 0}. 1277 * 1278 * @param m the mask controlling lane selection 1279 * @return the logical XOR all the lane elements of this vector 1280 */ 1281 public abstract byte xorAll(VectorMask<Byte> m); 1282 1283 // Type specific accessors 1284 1285 /** 1286 * Gets the lane element at lane index {@code i} 1287 * 1288 * @param i the lane index 1289 * @return the lane element at lane index {@code i} 1290 * @throws IllegalArgumentException if the index is is out of range 1291 * ({@code < 0 || >= length()}) 1292 */ 1293 public abstract byte lane(int i); 1294 1295 /** 1296 * Replaces the lane element of this vector at lane index {@code i} with 1297 * value {@code e}. 1298 * <p> 1299 * This is a cross-lane operation and behaves as if it returns the result 1300 * of blending this vector with an input vector that is the result of 1301 * broadcasting {@code e} and a mask that has only one lane set at lane 1302 * index {@code i}. 1303 * 1304 * @param i the lane index of the lane element to be replaced 1305 * @param e the value to be placed 1306 * @return the result of replacing the lane element of this vector at lane 1307 * index {@code i} with value {@code e}. 1308 * @throws IllegalArgumentException if the index is is out of range 1309 * ({@code < 0 || >= length()}) 1310 */ 1311 public abstract ByteVector with(int i, byte e); 1312 1313 // Type specific extractors 1314 1315 /** 1316 * Returns an array containing the lane elements of this vector. 1317 * <p> 1318 * This method behaves as if it {@link #intoArray(byte[], int)} stores} 1319 * this vector into an allocated array and returns the array as follows: 1320 * <pre>{@code 1321 * byte[] a = new byte[this.length()]; 1322 * this.intoArray(a, 0); 1323 * return a; 1324 * }</pre> 1325 * 1326 * @return an array containing the the lane elements of this vector 1327 */ 1328 @ForceInline 1329 public final byte[] toArray() { 1330 byte[] a = new byte[species().length()]; 1331 intoArray(a, 0); 1332 return a; 1333 } 1334 1335 /** 1336 * Stores this vector into an array starting at offset. 1337 * <p> 1338 * For each vector lane, where {@code N} is the vector lane index, 1339 * the lane element at index {@code N} is stored into the array at index 1340 * {@code offset + N}. 1341 * 1342 * @param a the array 1343 * @param offset the offset into the array 1344 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1345 * {@code offset > a.length - this.length()} 1346 */ 1347 public abstract void intoArray(byte[] a, int offset); 1348 1349 /** 1350 * Stores this vector into an array starting at offset and using a mask. 1351 * <p> 1352 * For each vector lane, where {@code N} is the vector lane index, 1353 * if the mask lane at index {@code N} is set then the lane element at 1354 * index {@code N} is stored into the array index {@code offset + N}. 1355 * 1356 * @param a the array 1357 * @param offset the offset into the array 1358 * @param m the mask 1359 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1360 * for any vector lane index {@code N} where the mask at lane {@code N} 1361 * is set {@code offset >= a.length - N} 1362 */ 1363 public abstract void intoArray(byte[] a, int offset, VectorMask<Byte> m); 1364 1365 /** 1366 * Stores this vector into an array using indexes obtained from an index 1367 * map. 1368 * <p> 1369 * For each vector lane, where {@code N} is the vector lane index, the 1370 * lane element at index {@code N} is stored into the array at index 1371 * {@code a_offset + indexMap[i_offset + N]}. 1372 * 1373 * @param a the array 1374 * @param a_offset the offset into the array, may be negative if relative 1375 * indexes in the index map compensate to produce a value within the 1376 * array bounds 1377 * @param indexMap the index map 1378 * @param i_offset the offset into the index map 1379 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 1380 * {@code i_offset > indexMap.length - this.length()}, 1381 * or for any vector lane index {@code N} the result of 1382 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length} 1383 */ 1384 public void intoArray(byte[] a, int a_offset, int[] indexMap, int i_offset) { 1385 forEach((n, e) -> a[a_offset + indexMap[i_offset + n]] = e); 1386 } 1387 1388 /** 1389 * Stores this vector into an array using indexes obtained from an index 1390 * map and using a mask. 1391 * <p> 1392 * For each vector lane, where {@code N} is the vector lane index, 1393 * if the mask lane at index {@code N} is set then the lane element at 1394 * index {@code N} is stored into the array at index 1395 * {@code a_offset + indexMap[i_offset + N]}. 1396 * 1397 * @param a the array 1398 * @param a_offset the offset into the array, may be negative if relative 1399 * indexes in the index map compensate to produce a value within the 1400 * array bounds 1401 * @param m the mask 1402 * @param indexMap the index map 1403 * @param i_offset the offset into the index map 1404 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1405 * {@code i_offset > indexMap.length - this.length()}, 1406 * or for any vector lane index {@code N} where the mask at lane 1407 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is 1408 * {@code < 0} or {@code >= a.length} 1409 */ 1410 public void intoArray(byte[] a, int a_offset, VectorMask<Byte> m, int[] indexMap, int i_offset) { 1411 forEach(m, (n, e) -> a[a_offset + indexMap[i_offset + n]] = e); 1412 } 1413 // Species 1414 1415 /** 1416 * {@inheritDoc} 1417 */ 1418 @Override 1419 public abstract VectorSpecies<Byte> species(); 1420 1421 /** 1422 * Class representing {@link ByteVector}'s of the same {@link VectorShape VectorShape}. 1423 */ 1424 static final class ByteSpecies extends AbstractSpecies<Byte> { 1425 final Function<byte[], ByteVector> vectorFactory; 1426 1427 private ByteSpecies(VectorShape shape, 1428 Class<?> boxType, 1429 Class<?> maskType, 1430 Function<byte[], ByteVector> vectorFactory, 1431 Function<boolean[], VectorMask<Byte>> maskFactory, 1432 Function<IntUnaryOperator, VectorShuffle<Byte>> shuffleFromArrayFactory, 1433 fShuffleFromArray<Byte> shuffleFromOpFactory) { 1434 super(shape, byte.class, Byte.SIZE, boxType, maskType, maskFactory, 1435 shuffleFromArrayFactory, shuffleFromOpFactory); 1436 this.vectorFactory = vectorFactory; 1437 } 1438 1439 interface FOp { 1440 byte apply(int i); 1441 } 1442 1443 ByteVector op(FOp f) { 1444 byte[] res = new byte[length()]; 1445 for (int i = 0; i < length(); i++) { 1446 res[i] = f.apply(i); 1447 } 1448 return vectorFactory.apply(res); 1449 } 1450 1451 ByteVector op(VectorMask<Byte> o, FOp f) { 1452 byte[] res = new byte[length()]; 1453 boolean[] mbits = ((AbstractMask<Byte>)o).getBits(); 1454 for (int i = 0; i < length(); i++) { 1455 if (mbits[i]) { 1456 res[i] = f.apply(i); 1457 } 1458 } 1459 return vectorFactory.apply(res); 1460 } 1461 } 1462 1463 /** 1464 * Finds the preferred species for an element type of {@code byte}. 1465 * <p> 1466 * A preferred species is a species chosen by the platform that has a 1467 * shape of maximal bit size. A preferred species for different element 1468 * types will have the same shape, and therefore vectors, masks, and 1469 * shuffles created from such species will be shape compatible. 1470 * 1471 * @return the preferred species for an element type of {@code byte} 1472 */ 1473 private static ByteSpecies preferredSpecies() { 1474 return (ByteSpecies) VectorSpecies.ofPreferred(byte.class); 1475 } 1476 1477 /** 1478 * Finds a species for an element type of {@code byte} and shape. 1479 * 1480 * @param s the shape 1481 * @return a species for an element type of {@code byte} and shape 1482 * @throws IllegalArgumentException if no such species exists for the shape 1483 */ 1484 static ByteSpecies species(VectorShape s) { 1485 Objects.requireNonNull(s); 1486 switch (s) { 1487 case S_64_BIT: return (ByteSpecies) SPECIES_64; 1488 case S_128_BIT: return (ByteSpecies) SPECIES_128; 1489 case S_256_BIT: return (ByteSpecies) SPECIES_256; 1490 case S_512_BIT: return (ByteSpecies) SPECIES_512; 1491 case S_Max_BIT: return (ByteSpecies) SPECIES_MAX; 1492 default: throw new IllegalArgumentException("Bad shape: " + s); 1493 } 1494 } 1495 1496 /** Species representing {@link ByteVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 1497 public static final VectorSpecies<Byte> SPECIES_64 = new ByteSpecies(VectorShape.S_64_BIT, Byte64Vector.class, Byte64Vector.Byte64Mask.class, 1498 Byte64Vector::new, Byte64Vector.Byte64Mask::new, 1499 Byte64Vector.Byte64Shuffle::new, Byte64Vector.Byte64Shuffle::new); 1500 1501 /** Species representing {@link ByteVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 1502 public static final VectorSpecies<Byte> SPECIES_128 = new ByteSpecies(VectorShape.S_128_BIT, Byte128Vector.class, Byte128Vector.Byte128Mask.class, 1503 Byte128Vector::new, Byte128Vector.Byte128Mask::new, 1504 Byte128Vector.Byte128Shuffle::new, Byte128Vector.Byte128Shuffle::new); 1505 1506 /** Species representing {@link ByteVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 1507 public static final VectorSpecies<Byte> SPECIES_256 = new ByteSpecies(VectorShape.S_256_BIT, Byte256Vector.class, Byte256Vector.Byte256Mask.class, 1508 Byte256Vector::new, Byte256Vector.Byte256Mask::new, 1509 Byte256Vector.Byte256Shuffle::new, Byte256Vector.Byte256Shuffle::new); 1510 1511 /** Species representing {@link ByteVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 1512 public static final VectorSpecies<Byte> SPECIES_512 = new ByteSpecies(VectorShape.S_512_BIT, Byte512Vector.class, Byte512Vector.Byte512Mask.class, 1513 Byte512Vector::new, Byte512Vector.Byte512Mask::new, 1514 Byte512Vector.Byte512Shuffle::new, Byte512Vector.Byte512Shuffle::new); 1515 1516 /** Species representing {@link ByteVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 1517 public static final VectorSpecies<Byte> SPECIES_MAX = new ByteSpecies(VectorShape.S_Max_BIT, ByteMaxVector.class, ByteMaxVector.ByteMaxMask.class, 1518 ByteMaxVector::new, ByteMaxVector.ByteMaxMask::new, 1519 ByteMaxVector.ByteMaxShuffle::new, ByteMaxVector.ByteMaxShuffle::new); 1520 1521 /** 1522 * Preferred species for {@link ByteVector}s. 1523 * A preferred species is a species of maximal bit size for the platform. 1524 */ 1525 public static final VectorSpecies<Byte> SPECIES_PREFERRED = (VectorSpecies<Byte>) preferredSpecies(); 1526 }