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.vectorType(), 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.vectorType(), 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.vectorType(), 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.vectorType(), int.class, species.length(), 267 IntVector.species(species.indexShape()).vectorType(), 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.vectorType(), 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 to be broadcasted 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.vectorType(), 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.vectorType(), 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 rotateLanesLeft(int i); 803 804 /** 805 * {@inheritDoc} 806 */ 807 @Override 808 public abstract IntVector rotateLanesRight(int i); 809 810 /** 811 * {@inheritDoc} 812 */ 813 @Override 814 public abstract IntVector shiftLanesLeft(int i); 815 816 /** 817 * {@inheritDoc} 818 */ 819 @Override 820 public abstract IntVector shiftLanesRight(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 to left shift the 1000 * element by shift value as specified by the input scalar. 1001 * 1002 * @param s the input scalar; the number of the bits to left shift 1003 * @return the result of logically left shifting this vector by the 1004 * broadcast of an input scalar 1005 */ 1006 public abstract IntVector shiftLeft(int s); 1007 1008 /** 1009 * Logically left shifts this vector by the broadcast of an input scalar, 1010 * selecting lane elements controlled by a mask. 1011 * <p> 1012 * This is a lane-wise binary operation which applies the primitive logical left shift 1013 * operation ({@code <<}) to each lane to left shift the 1014 * element by shift value as specified by the input scalar. 1015 * 1016 * @param s the input scalar; the number of the bits to left shift 1017 * @param m the mask controlling lane selection 1018 * @return the result of logically left shifting this vector by the 1019 * broadcast of an input scalar 1020 */ 1021 public abstract IntVector shiftLeft(int s, VectorMask<Integer> m); 1022 1023 /** 1024 * Logically left shifts this vector by an input vector. 1025 * <p> 1026 * This is a lane-wise binary operation which applies the primitive logical left shift 1027 * operation ({@code <<}) to each lane. For each lane of this vector, the 1028 * shift value is the corresponding lane of input vector. 1029 * 1030 * @param v the input vector 1031 * @return the result of logically left shifting this vector by the input 1032 * vector 1033 */ 1034 public abstract IntVector shiftLeft(Vector<Integer> v); 1035 1036 /** 1037 * Logically left shifts this vector by an input vector, selecting lane 1038 * elements controlled by a mask. 1039 * <p> 1040 * This is a lane-wise binary operation which applies the primitive logical left shift 1041 * operation ({@code <<}) to each lane. For each lane of this vector, the 1042 * shift value is the corresponding lane of input vector. 1043 * 1044 * @param v the input vector 1045 * @param m the mask controlling lane selection 1046 * @return the result of logically left shifting this vector by the input 1047 * vector 1048 */ 1049 public IntVector shiftLeft(Vector<Integer> v, VectorMask<Integer> m) { 1050 return blend(shiftLeft(v), m); 1051 } 1052 1053 // logical, or unsigned, shift right 1054 1055 /** 1056 * Logically right shifts (or unsigned right shifts) this vector by the 1057 * broadcast of an input scalar. 1058 * <p> 1059 * This is a lane-wise binary operation which applies the primitive logical right shift 1060 * operation ({@code >>>}) to each lane to logically right shift the 1061 * element by shift value as specified by the input scalar. 1062 * 1063 * @param s the input scalar; the number of the bits to right shift 1064 * @return the result of logically right shifting this vector by the 1065 * broadcast of an input scalar 1066 */ 1067 public abstract IntVector shiftRight(int s); 1068 1069 /** 1070 * Logically right shifts (or unsigned right shifts) this vector by the 1071 * broadcast of an input scalar, selecting lane elements controlled by a 1072 * mask. 1073 * <p> 1074 * This is a lane-wise binary operation which applies the primitive logical right shift 1075 * operation ({@code >>}) to each lane to logically right shift the 1076 * element by shift value as specified by the input scalar. 1077 * 1078 * @param s the input scalar; the number of the bits to right shift 1079 * @param m the mask controlling lane selection 1080 * @return the result of logically right shifting this vector by the 1081 * broadcast of an input scalar 1082 */ 1083 public abstract IntVector shiftRight(int s, VectorMask<Integer> m); 1084 1085 /** 1086 * Logically right shifts (or unsigned right shifts) this vector by an 1087 * input vector. 1088 * <p> 1089 * This is a lane-wise binary operation which applies the primitive logical right shift 1090 * operation ({@code >>>}) to each lane. For each lane of this vector, the 1091 * shift value is the corresponding lane of input vector. 1092 * 1093 * @param v the input vector 1094 * @return the result of logically right shifting this vector by the 1095 * input vector 1096 */ 1097 public abstract IntVector shiftRight(Vector<Integer> v); 1098 1099 /** 1100 * Logically right shifts (or unsigned right shifts) this vector by an 1101 * input vector, selecting lane elements controlled by a mask. 1102 * <p> 1103 * This is a lane-wise binary operation which applies the primitive logical right shift 1104 * operation ({@code >>>}) to each lane. For each lane of this vector, the 1105 * shift value is the corresponding lane of input vector. 1106 * 1107 * @param v the input vector 1108 * @param m the mask controlling lane selection 1109 * @return the result of logically right shifting this vector by the 1110 * input vector 1111 */ 1112 public IntVector shiftRight(Vector<Integer> v, VectorMask<Integer> m) { 1113 return blend(shiftRight(v), m); 1114 } 1115 1116 /** 1117 * Arithmetically right shifts (or signed right shifts) this vector by the 1118 * broadcast of an input scalar. 1119 * <p> 1120 * This is a lane-wise binary operation which applies the primitive arithmetic right 1121 * shift operation ({@code >>}) to each lane to arithmetically 1122 * right shift the element by shift value as specified by the input scalar. 1123 * 1124 * @param s the input scalar; the number of the bits to right shift 1125 * @return the result of arithmetically right shifting this vector by the 1126 * broadcast of an input scalar 1127 */ 1128 public abstract IntVector shiftArithmeticRight(int s); 1129 1130 /** 1131 * Arithmetically right shifts (or signed right shifts) this vector by the 1132 * broadcast of an input scalar, selecting lane elements controlled by a 1133 * mask. 1134 * <p> 1135 * This is a lane-wise binary operation which applies the primitive arithmetic right 1136 * shift operation ({@code >>}) to each lane to arithmetically 1137 * right shift the element by shift value as specified by the input scalar. 1138 * 1139 * @param s the input scalar; the number of the bits to right shift 1140 * @param m the mask controlling lane selection 1141 * @return the result of arithmetically right shifting this vector by the 1142 * broadcast of an input scalar 1143 */ 1144 public abstract IntVector shiftArithmeticRight(int s, VectorMask<Integer> m); 1145 1146 /** 1147 * Arithmetically right shifts (or signed right shifts) this vector by an 1148 * input vector. 1149 * <p> 1150 * This is a lane-wise binary operation which applies the primitive arithmetic right 1151 * shift operation ({@code >>}) to each lane. For each lane of this vector, the 1152 * shift value is the corresponding lane of input vector. 1153 * 1154 * @param v the input vector 1155 * @return the result of arithmetically right shifting this vector by the 1156 * input vector 1157 */ 1158 public abstract IntVector shiftArithmeticRight(Vector<Integer> v); 1159 1160 /** 1161 * Arithmetically right shifts (or signed right shifts) this vector by an 1162 * input vector, selecting lane elements controlled by a mask. 1163 * <p> 1164 * This is a lane-wise binary operation which applies the primitive arithmetic right 1165 * shift operation ({@code >>}) to each lane. For each lane of this vector, the 1166 * shift value is the corresponding lane of input vector. 1167 * 1168 * @param v the input vector 1169 * @param m the mask controlling lane selection 1170 * @return the result of arithmetically right shifting this vector by the 1171 * input vector 1172 */ 1173 public IntVector shiftArithmeticRight(Vector<Integer> v, VectorMask<Integer> m) { 1174 return blend(shiftArithmeticRight(v), m); 1175 } 1176 1177 /** 1178 * Rotates left this vector by the broadcast of an input scalar. 1179 * <p> 1180 * This is a lane-wise binary operation which applies the operation 1181 * {@link Integer#rotateLeft} to each lane and where 1182 * lane elements of this vector apply to the first argument, and lane 1183 * elements of the broadcast vector apply to the second argument (the 1184 * rotation distance). 1185 * 1186 * @param s the input scalar; the number of the bits to rotate left 1187 * @return the result of rotating left this vector by the broadcast of an 1188 * input scalar 1189 */ 1190 @ForceInline 1191 public final IntVector rotateLeft(int s) { 1192 return shiftLeft(s).or(shiftRight(-s)); 1193 } 1194 1195 /** 1196 * Rotates left this vector by the broadcast of an input scalar, selecting 1197 * lane elements controlled by a mask. 1198 * <p> 1199 * This is a lane-wise binary operation which applies the operation 1200 * {@link Integer#rotateLeft} to each lane and where 1201 * lane elements of this vector apply to the first argument, and lane 1202 * elements of the broadcast vector apply to the second argument (the 1203 * rotation distance). 1204 * 1205 * @param s the input scalar; the number of the bits to rotate left 1206 * @param m the mask controlling lane selection 1207 * @return the result of rotating left this vector by the broadcast of an 1208 * input scalar 1209 */ 1210 @ForceInline 1211 public final IntVector rotateLeft(int s, VectorMask<Integer> m) { 1212 return shiftLeft(s, m).or(shiftRight(-s, m), m); 1213 } 1214 1215 /** 1216 * Rotates right this vector by the broadcast of an input scalar. 1217 * <p> 1218 * This is a lane-wise binary operation which applies the operation 1219 * {@link Integer#rotateRight} to each lane and where 1220 * lane elements of this vector apply to the first argument, and lane 1221 * elements of the broadcast vector apply to the second argument (the 1222 * rotation distance). 1223 * 1224 * @param s the input scalar; the number of the bits to rotate right 1225 * @return the result of rotating right this vector by the broadcast of an 1226 * input scalar 1227 */ 1228 @ForceInline 1229 public final IntVector rotateRight(int s) { 1230 return shiftRight(s).or(shiftLeft(-s)); 1231 } 1232 1233 /** 1234 * Rotates right this vector by the broadcast of an input scalar, selecting 1235 * lane elements controlled by a mask. 1236 * <p> 1237 * This is a lane-wise binary operation which applies the operation 1238 * {@link Integer#rotateRight} to each lane and where 1239 * lane elements of this vector apply to the first argument, and lane 1240 * elements of the broadcast vector apply to the second argument (the 1241 * rotation distance). 1242 * 1243 * @param s the input scalar; the number of the bits to rotate right 1244 * @param m the mask controlling lane selection 1245 * @return the result of rotating right this vector by the broadcast of an 1246 * input scalar 1247 */ 1248 @ForceInline 1249 public final IntVector rotateRight(int s, VectorMask<Integer> m) { 1250 return shiftRight(s, m).or(shiftLeft(-s, m), m); 1251 } 1252 1253 /** 1254 * {@inheritDoc} 1255 */ 1256 @Override 1257 public abstract void intoByteArray(byte[] a, int ix); 1258 1259 /** 1260 * {@inheritDoc} 1261 */ 1262 @Override 1263 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Integer> m); 1264 1265 /** 1266 * {@inheritDoc} 1267 */ 1268 @Override 1269 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 1270 1271 /** 1272 * {@inheritDoc} 1273 */ 1274 @Override 1275 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Integer> m); 1276 1277 1278 // Type specific horizontal reductions 1279 /** 1280 * Adds all lane elements of this vector. 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 * @return the addition of all the lane elements of this vector 1287 */ 1288 public abstract int addLanes(); 1289 1290 /** 1291 * Adds all lane elements of this vector, selecting lane elements 1292 * controlled by a mask. 1293 * <p> 1294 * This is an associative cross-lane reduction operation which applies the addition 1295 * operation ({@code +}) to lane elements, 1296 * and the identity value is {@code 0}. 1297 * 1298 * @param m the mask controlling lane selection 1299 * @return the addition of the selected lane elements of this vector 1300 */ 1301 public abstract int addLanes(VectorMask<Integer> m); 1302 1303 /** 1304 * Multiplies all lane elements of this vector. 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 * @return the multiplication of all the lane elements of this vector 1311 */ 1312 public abstract int mulLanes(); 1313 1314 /** 1315 * Multiplies all lane elements of this vector, selecting lane elements 1316 * controlled by a mask. 1317 * <p> 1318 * This is an associative cross-lane reduction operation which applies the 1319 * multiplication operation ({@code *}) to lane elements, 1320 * and the identity value is {@code 1}. 1321 * 1322 * @param m the mask controlling lane selection 1323 * @return the multiplication of all the lane elements of this vector 1324 */ 1325 public abstract int mulLanes(VectorMask<Integer> m); 1326 1327 /** 1328 * Returns the minimum lane element of this vector. 1329 * <p> 1330 * This is an associative cross-lane reduction operation which applies the operation 1331 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1332 * and the identity value is 1333 * {@link Integer#MAX_VALUE}. 1334 * 1335 * @return the minimum lane element of this vector 1336 */ 1337 public abstract int minLanes(); 1338 1339 /** 1340 * Returns the minimum lane element of this vector, selecting lane elements 1341 * controlled by a mask. 1342 * <p> 1343 * This is an associative cross-lane reduction operation which applies the operation 1344 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1345 * and the identity value is 1346 * {@link Integer#MAX_VALUE}. 1347 * 1348 * @param m the mask controlling lane selection 1349 * @return the minimum lane element of this vector 1350 */ 1351 public abstract int minLanes(VectorMask<Integer> m); 1352 1353 /** 1354 * Returns the maximum lane element of this vector. 1355 * <p> 1356 * This is an associative cross-lane reduction operation which applies the operation 1357 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1358 * and the identity value is 1359 * {@link Integer#MIN_VALUE}. 1360 * 1361 * @return the maximum lane element of this vector 1362 */ 1363 public abstract int maxLanes(); 1364 1365 /** 1366 * Returns the maximum lane element of this vector, selecting lane elements 1367 * controlled by a mask. 1368 * <p> 1369 * This is an associative cross-lane reduction operation which applies the operation 1370 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1371 * and the identity value is 1372 * {@link Integer#MIN_VALUE}. 1373 * 1374 * @param m the mask controlling lane selection 1375 * @return the maximum lane element of this vector 1376 */ 1377 public abstract int maxLanes(VectorMask<Integer> m); 1378 1379 /** 1380 * Logically ORs all lane elements of this vector. 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 * @return the logical OR all the lane elements of this vector 1387 */ 1388 public abstract int orLanes(); 1389 1390 /** 1391 * Logically ORs all lane elements of this vector, selecting lane elements 1392 * controlled by a mask. 1393 * <p> 1394 * This is an associative cross-lane reduction operation which applies the logical OR 1395 * operation ({@code |}) to lane elements, 1396 * and the identity value is {@code 0}. 1397 * 1398 * @param m the mask controlling lane selection 1399 * @return the logical OR all the lane elements of this vector 1400 */ 1401 public abstract int orLanes(VectorMask<Integer> m); 1402 1403 /** 1404 * Logically ANDs all lane elements of this vector. 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 * @return the logical AND all the lane elements of this vector 1411 */ 1412 public abstract int andLanes(); 1413 1414 /** 1415 * Logically ANDs all lane elements of this vector, selecting lane elements 1416 * controlled by a mask. 1417 * <p> 1418 * This is an associative cross-lane reduction operation which applies the logical AND 1419 * operation ({@code |}) to lane elements, 1420 * and the identity value is {@code -1}. 1421 * 1422 * @param m the mask controlling lane selection 1423 * @return the logical AND all the lane elements of this vector 1424 */ 1425 public abstract int andLanes(VectorMask<Integer> m); 1426 1427 /** 1428 * Logically XORs all lane elements of this vector. 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 * @return the logical XOR all the lane elements of this vector 1435 */ 1436 public abstract int xorLanes(); 1437 1438 /** 1439 * Logically XORs all lane elements of this vector, selecting lane elements 1440 * controlled by a mask. 1441 * <p> 1442 * This is an associative cross-lane reduction operation which applies the logical XOR 1443 * operation ({@code ^}) to lane elements, 1444 * and the identity value is {@code 0}. 1445 * 1446 * @param m the mask controlling lane selection 1447 * @return the logical XOR all the lane elements of this vector 1448 */ 1449 public abstract int xorLanes(VectorMask<Integer> m); 1450 1451 // Type specific accessors 1452 1453 /** 1454 * Gets the lane element at lane index {@code i} 1455 * 1456 * @param i the lane index 1457 * @return the lane element at lane index {@code i} 1458 * @throws IllegalArgumentException if the index is is out of range 1459 * ({@code < 0 || >= length()}) 1460 */ 1461 public abstract int lane(int i); 1462 1463 /** 1464 * Replaces the lane element of this vector at lane index {@code i} with 1465 * value {@code e}. 1466 * <p> 1467 * This is a cross-lane operation and behaves as if it returns the result 1468 * of blending this vector with an input vector that is the result of 1469 * broadcasting {@code e} and a mask that has only one lane set at lane 1470 * index {@code i}. 1471 * 1472 * @param i the lane index of the lane element to be replaced 1473 * @param e the value to be placed 1474 * @return the result of replacing the lane element of this vector at lane 1475 * index {@code i} with value {@code e}. 1476 * @throws IllegalArgumentException if the index is is out of range 1477 * ({@code < 0 || >= length()}) 1478 */ 1479 public abstract IntVector with(int i, int e); 1480 1481 // Type specific extractors 1482 1483 /** 1484 * Returns an array containing the lane elements of this vector. 1485 * <p> 1486 * This method behaves as if it {@link #intoArray(int[], int)} stores} 1487 * this vector into an allocated array and returns the array as follows: 1488 * <pre>{@code 1489 * int[] a = new int[this.length()]; 1490 * this.intoArray(a, 0); 1491 * return a; 1492 * }</pre> 1493 * 1494 * @return an array containing the the lane elements of this vector 1495 */ 1496 @ForceInline 1497 public final int[] toArray() { 1498 int[] a = new int[species().length()]; 1499 intoArray(a, 0); 1500 return a; 1501 } 1502 1503 /** 1504 * Stores this vector into an array starting at offset. 1505 * <p> 1506 * For each vector lane, where {@code N} is the vector lane index, 1507 * the lane element at index {@code N} is stored into the array at index 1508 * {@code offset + N}. 1509 * 1510 * @param a the array 1511 * @param offset the offset into the array 1512 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1513 * {@code offset > a.length - this.length()} 1514 */ 1515 public abstract void intoArray(int[] a, int offset); 1516 1517 /** 1518 * Stores this vector into an array starting at offset and using a mask. 1519 * <p> 1520 * For each vector lane, where {@code N} is the vector lane index, 1521 * if the mask lane at index {@code N} is set then the lane element at 1522 * index {@code N} is stored into the array index {@code offset + N}. 1523 * 1524 * @param a the array 1525 * @param offset the offset into the array 1526 * @param m the mask 1527 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1528 * for any vector lane index {@code N} where the mask at lane {@code N} 1529 * is set {@code offset >= a.length - N} 1530 */ 1531 public abstract void intoArray(int[] a, int offset, VectorMask<Integer> m); 1532 1533 /** 1534 * Stores this vector into an array using indexes obtained from an index 1535 * map. 1536 * <p> 1537 * For each vector lane, where {@code N} is the vector lane index, the 1538 * lane element at index {@code N} is stored into the array at index 1539 * {@code a_offset + indexMap[i_offset + N]}. 1540 * 1541 * @param a the array 1542 * @param a_offset the offset into the array, may be negative if relative 1543 * indexes in the index map compensate to produce a value within the 1544 * array bounds 1545 * @param indexMap the index map 1546 * @param i_offset the offset into the index map 1547 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 1548 * {@code i_offset > indexMap.length - this.length()}, 1549 * or for any vector lane index {@code N} the result of 1550 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length} 1551 */ 1552 public abstract void intoArray(int[] a, int a_offset, int[] indexMap, int i_offset); 1553 1554 /** 1555 * Stores this vector into an array using indexes obtained from an index 1556 * map and using a mask. 1557 * <p> 1558 * For each vector lane, where {@code N} is the vector lane index, 1559 * if the mask lane at index {@code N} is set then the lane element at 1560 * index {@code N} is stored into the array at index 1561 * {@code a_offset + indexMap[i_offset + N]}. 1562 * 1563 * @param a the array 1564 * @param a_offset the offset into the array, may be negative if relative 1565 * indexes in the index map compensate to produce a value within the 1566 * array bounds 1567 * @param m the mask 1568 * @param indexMap the index map 1569 * @param i_offset the offset into the index map 1570 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1571 * {@code i_offset > indexMap.length - this.length()}, 1572 * or for any vector lane index {@code N} where the mask at lane 1573 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is 1574 * {@code < 0} or {@code >= a.length} 1575 */ 1576 public abstract void intoArray(int[] a, int a_offset, VectorMask<Integer> m, int[] indexMap, int i_offset); 1577 // Species 1578 1579 /** 1580 * {@inheritDoc} 1581 */ 1582 @Override 1583 public abstract VectorSpecies<Integer> species(); 1584 1585 /** 1586 * Class representing {@link IntVector}'s of the same {@link VectorShape VectorShape}. 1587 */ 1588 static final class IntSpecies extends AbstractSpecies<Integer> { 1589 final Function<int[], IntVector> vectorFactory; 1590 1591 private IntSpecies(VectorShape shape, 1592 Class<?> vectorType, 1593 Class<?> maskType, 1594 Function<int[], IntVector> vectorFactory, 1595 Function<boolean[], VectorMask<Integer>> maskFactory, 1596 Function<IntUnaryOperator, VectorShuffle<Integer>> shuffleFromArrayFactory, 1597 fShuffleFromArray<Integer> shuffleFromOpFactory) { 1598 super(shape, int.class, Integer.SIZE, vectorType, maskType, maskFactory, 1599 shuffleFromArrayFactory, shuffleFromOpFactory); 1600 this.vectorFactory = vectorFactory; 1601 } 1602 1603 interface FOp { 1604 int apply(int i); 1605 } 1606 1607 IntVector op(FOp f) { 1608 int[] res = new int[length()]; 1609 for (int i = 0; i < length(); i++) { 1610 res[i] = f.apply(i); 1611 } 1612 return vectorFactory.apply(res); 1613 } 1614 1615 IntVector op(VectorMask<Integer> o, FOp f) { 1616 int[] res = new int[length()]; 1617 boolean[] mbits = ((AbstractMask<Integer>)o).getBits(); 1618 for (int i = 0; i < length(); i++) { 1619 if (mbits[i]) { 1620 res[i] = f.apply(i); 1621 } 1622 } 1623 return vectorFactory.apply(res); 1624 } 1625 } 1626 1627 /** 1628 * Finds the preferred species for an element type of {@code int}. 1629 * <p> 1630 * A preferred species is a species chosen by the platform that has a 1631 * shape of maximal bit size. A preferred species for different element 1632 * types will have the same shape, and therefore vectors, masks, and 1633 * shuffles created from such species will be shape compatible. 1634 * 1635 * @return the preferred species for an element type of {@code int} 1636 */ 1637 private static IntSpecies preferredSpecies() { 1638 return (IntSpecies) VectorSpecies.ofPreferred(int.class); 1639 } 1640 1641 /** 1642 * Finds a species for an element type of {@code int} and shape. 1643 * 1644 * @param s the shape 1645 * @return a species for an element type of {@code int} and shape 1646 * @throws IllegalArgumentException if no such species exists for the shape 1647 */ 1648 static IntSpecies species(VectorShape s) { 1649 Objects.requireNonNull(s); 1650 switch (s) { 1651 case S_64_BIT: return (IntSpecies) SPECIES_64; 1652 case S_128_BIT: return (IntSpecies) SPECIES_128; 1653 case S_256_BIT: return (IntSpecies) SPECIES_256; 1654 case S_512_BIT: return (IntSpecies) SPECIES_512; 1655 case S_Max_BIT: return (IntSpecies) SPECIES_MAX; 1656 default: throw new IllegalArgumentException("Bad shape: " + s); 1657 } 1658 } 1659 1660 /** Species representing {@link IntVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 1661 public static final VectorSpecies<Integer> SPECIES_64 = new IntSpecies(VectorShape.S_64_BIT, Int64Vector.class, Int64Vector.Int64Mask.class, 1662 Int64Vector::new, Int64Vector.Int64Mask::new, 1663 Int64Vector.Int64Shuffle::new, Int64Vector.Int64Shuffle::new); 1664 1665 /** Species representing {@link IntVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 1666 public static final VectorSpecies<Integer> SPECIES_128 = new IntSpecies(VectorShape.S_128_BIT, Int128Vector.class, Int128Vector.Int128Mask.class, 1667 Int128Vector::new, Int128Vector.Int128Mask::new, 1668 Int128Vector.Int128Shuffle::new, Int128Vector.Int128Shuffle::new); 1669 1670 /** Species representing {@link IntVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 1671 public static final VectorSpecies<Integer> SPECIES_256 = new IntSpecies(VectorShape.S_256_BIT, Int256Vector.class, Int256Vector.Int256Mask.class, 1672 Int256Vector::new, Int256Vector.Int256Mask::new, 1673 Int256Vector.Int256Shuffle::new, Int256Vector.Int256Shuffle::new); 1674 1675 /** Species representing {@link IntVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 1676 public static final VectorSpecies<Integer> SPECIES_512 = new IntSpecies(VectorShape.S_512_BIT, Int512Vector.class, Int512Vector.Int512Mask.class, 1677 Int512Vector::new, Int512Vector.Int512Mask::new, 1678 Int512Vector.Int512Shuffle::new, Int512Vector.Int512Shuffle::new); 1679 1680 /** Species representing {@link IntVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 1681 public static final VectorSpecies<Integer> SPECIES_MAX = new IntSpecies(VectorShape.S_Max_BIT, IntMaxVector.class, IntMaxVector.IntMaxMask.class, 1682 IntMaxVector::new, IntMaxVector.IntMaxMask::new, 1683 IntMaxVector.IntMaxShuffle::new, IntMaxVector.IntMaxShuffle::new); 1684 1685 /** 1686 * Preferred species for {@link IntVector}s. 1687 * A preferred species is a species of maximal bit size for the platform. 1688 */ 1689 public static final VectorSpecies<Integer> SPECIES_PREFERRED = (VectorSpecies<Integer>) preferredSpecies(); 1690 }