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