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