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