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