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