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