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