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