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