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