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