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