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 /** 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.vectorType(), 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.vectorType(), 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.vectorType(), long.class, species.length(), 270 IntVector.species(species.indexShape()).vectorType(), 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.vectorType(), 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 to be broadcasted 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.vectorType(), 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.vectorType(), 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 rotateLanesLeft(int i); 806 807 /** 808 * {@inheritDoc} 809 */ 810 @Override 811 public abstract LongVector rotateLanesRight(int i); 812 813 /** 814 * {@inheritDoc} 815 */ 816 @Override 817 public abstract LongVector shiftLanesLeft(int i); 818 819 /** 820 * {@inheritDoc} 821 */ 822 @Override 823 public abstract LongVector shiftLanesRight(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 to left shift the 1003 * element by shift value as specified by the input scalar. 1004 * 1005 * @param s the input scalar; the number of the bits to left shift 1006 * @return the result of logically left shifting this vector by the 1007 * broadcast of an input scalar 1008 */ 1009 public abstract LongVector shiftLeft(int s); 1010 1011 /** 1012 * Logically left shifts this vector by the broadcast of an input scalar, 1013 * selecting lane elements controlled by a mask. 1014 * <p> 1015 * This is a lane-wise binary operation which applies the primitive logical left shift 1016 * operation ({@code <<}) to each lane to left shift the 1017 * element by shift value as specified by the input scalar. 1018 * 1019 * @param s the input scalar; the number of the bits to left shift 1020 * @param m the mask controlling lane selection 1021 * @return the result of logically left shifting this vector by the 1022 * broadcast of an input scalar 1023 */ 1024 public abstract LongVector shiftLeft(int s, VectorMask<Long> m); 1025 1026 /** 1027 * Logically left shifts this vector by an input vector. 1028 * <p> 1029 * This is a lane-wise binary operation which applies the primitive logical left shift 1030 * operation ({@code <<}) to each lane. For each lane of this vector, the 1031 * shift value is the corresponding lane of input vector. 1032 * 1033 * @param v the input vector 1034 * @return the result of logically left shifting this vector by the input 1035 * vector 1036 */ 1037 public abstract LongVector shiftLeft(Vector<Long> v); 1038 1039 /** 1040 * Logically left shifts this vector by an input vector, selecting lane 1041 * elements controlled by a mask. 1042 * <p> 1043 * This is a lane-wise binary operation which applies the primitive logical left shift 1044 * operation ({@code <<}) to each lane. For each lane of this vector, the 1045 * shift value is the corresponding lane of input vector. 1046 * 1047 * @param v the input vector 1048 * @param m the mask controlling lane selection 1049 * @return the result of logically left shifting this vector by the input 1050 * vector 1051 */ 1052 public LongVector shiftLeft(Vector<Long> v, VectorMask<Long> m) { 1053 return blend(shiftLeft(v), m); 1054 } 1055 1056 // logical, or unsigned, shift right 1057 1058 /** 1059 * Logically right shifts (or unsigned right shifts) this vector by the 1060 * broadcast of an input scalar. 1061 * <p> 1062 * This is a lane-wise binary operation which applies the primitive logical right shift 1063 * operation ({@code >>>}) to each lane to logically right shift the 1064 * element by shift value as specified by the input scalar. 1065 * 1066 * @param s the input scalar; the number of the bits to right shift 1067 * @return the result of logically right shifting this vector by the 1068 * broadcast of an input scalar 1069 */ 1070 public abstract LongVector shiftRight(int s); 1071 1072 /** 1073 * Logically right shifts (or unsigned right shifts) this vector by the 1074 * broadcast of an input scalar, selecting lane elements controlled by a 1075 * mask. 1076 * <p> 1077 * This is a lane-wise binary operation which applies the primitive logical right shift 1078 * operation ({@code >>}) to each lane to logically right shift the 1079 * element by shift value as specified by the input scalar. 1080 * 1081 * @param s the input scalar; the number of the bits to right shift 1082 * @param m the mask controlling lane selection 1083 * @return the result of logically right shifting this vector by the 1084 * broadcast of an input scalar 1085 */ 1086 public abstract LongVector shiftRight(int s, VectorMask<Long> m); 1087 1088 /** 1089 * Logically right shifts (or unsigned right shifts) this vector by an 1090 * input vector. 1091 * <p> 1092 * This is a lane-wise binary operation which applies the primitive logical right shift 1093 * operation ({@code >>>}) to each lane. For each lane of this vector, the 1094 * shift value is the corresponding lane of input vector. 1095 * 1096 * @param v the input vector 1097 * @return the result of logically right shifting this vector by the 1098 * input vector 1099 */ 1100 public abstract LongVector shiftRight(Vector<Long> v); 1101 1102 /** 1103 * Logically right shifts (or unsigned right shifts) this vector by an 1104 * input vector, selecting lane elements controlled by a mask. 1105 * <p> 1106 * This is a lane-wise binary operation which applies the primitive logical right shift 1107 * operation ({@code >>>}) to each lane. For each lane of this vector, the 1108 * shift value is the corresponding lane of input vector. 1109 * 1110 * @param v the input vector 1111 * @param m the mask controlling lane selection 1112 * @return the result of logically right shifting this vector by the 1113 * input vector 1114 */ 1115 public LongVector shiftRight(Vector<Long> v, VectorMask<Long> m) { 1116 return blend(shiftRight(v), m); 1117 } 1118 1119 /** 1120 * Arithmetically right shifts (or signed right shifts) this vector by the 1121 * broadcast of an input scalar. 1122 * <p> 1123 * This is a lane-wise binary operation which applies the primitive arithmetic right 1124 * shift operation ({@code >>}) to each lane to arithmetically 1125 * right shift the element by shift value as specified by the input scalar. 1126 * 1127 * @param s the input scalar; the number of the bits to right shift 1128 * @return the result of arithmetically right shifting this vector by the 1129 * broadcast of an input scalar 1130 */ 1131 public abstract LongVector shiftArithmeticRight(int s); 1132 1133 /** 1134 * Arithmetically right shifts (or signed right shifts) this vector by the 1135 * broadcast of an input scalar, selecting lane elements controlled by a 1136 * mask. 1137 * <p> 1138 * This is a lane-wise binary operation which applies the primitive arithmetic right 1139 * shift operation ({@code >>}) to each lane to arithmetically 1140 * right shift the element by shift value as specified by the input scalar. 1141 * 1142 * @param s the input scalar; the number of the bits to right shift 1143 * @param m the mask controlling lane selection 1144 * @return the result of arithmetically right shifting this vector by the 1145 * broadcast of an input scalar 1146 */ 1147 public abstract LongVector shiftArithmeticRight(int s, VectorMask<Long> m); 1148 1149 /** 1150 * Arithmetically right shifts (or signed right shifts) this vector by an 1151 * input vector. 1152 * <p> 1153 * This is a lane-wise binary operation which applies the primitive arithmetic right 1154 * shift operation ({@code >>}) to each lane. For each lane of this vector, the 1155 * shift value is the corresponding lane of input vector. 1156 * 1157 * @param v the input vector 1158 * @return the result of arithmetically right shifting this vector by the 1159 * input vector 1160 */ 1161 public abstract LongVector shiftArithmeticRight(Vector<Long> v); 1162 1163 /** 1164 * Arithmetically right shifts (or signed right shifts) this vector by an 1165 * input vector, selecting lane elements controlled by a mask. 1166 * <p> 1167 * This is a lane-wise binary operation which applies the primitive arithmetic right 1168 * shift operation ({@code >>}) to each lane. For each lane of this vector, the 1169 * shift value is the corresponding lane of input vector. 1170 * 1171 * @param v the input vector 1172 * @param m the mask controlling lane selection 1173 * @return the result of arithmetically right shifting this vector by the 1174 * input vector 1175 */ 1176 public LongVector shiftArithmeticRight(Vector<Long> v, VectorMask<Long> m) { 1177 return blend(shiftArithmeticRight(v), m); 1178 } 1179 1180 /** 1181 * Rotates left this vector by the broadcast of an input scalar. 1182 * <p> 1183 * This is a lane-wise binary operation which applies the operation 1184 * {@link Long#rotateLeft} to each lane and where 1185 * lane elements of this vector apply to the first argument, and lane 1186 * elements of the broadcast vector apply to the second argument (the 1187 * rotation distance). 1188 * 1189 * @param s the input scalar; the number of the bits to rotate left 1190 * @return the result of rotating left this vector by the broadcast of an 1191 * input scalar 1192 */ 1193 @ForceInline 1194 public final LongVector rotateLeft(int s) { 1195 return shiftLeft(s).or(shiftRight(-s)); 1196 } 1197 1198 /** 1199 * Rotates left this vector by the broadcast of an input scalar, selecting 1200 * lane elements controlled by a mask. 1201 * <p> 1202 * This is a lane-wise binary operation which applies the operation 1203 * {@link Long#rotateLeft} to each lane and where 1204 * lane elements of this vector apply to the first argument, and lane 1205 * elements of the broadcast vector apply to the second argument (the 1206 * rotation distance). 1207 * 1208 * @param s the input scalar; the number of the bits to rotate left 1209 * @param m the mask controlling lane selection 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, VectorMask<Long> m) { 1215 return shiftLeft(s, m).or(shiftRight(-s, m), m); 1216 } 1217 1218 /** 1219 * Rotates right this vector by the broadcast of an input scalar. 1220 * <p> 1221 * This is a lane-wise binary operation which applies the operation 1222 * {@link Long#rotateRight} to each lane and where 1223 * lane elements of this vector apply to the first argument, and lane 1224 * elements of the broadcast vector apply to the second argument (the 1225 * rotation distance). 1226 * 1227 * @param s the input scalar; the number of the bits to rotate right 1228 * @return the result of rotating right this vector by the broadcast of an 1229 * input scalar 1230 */ 1231 @ForceInline 1232 public final LongVector rotateRight(int s) { 1233 return shiftRight(s).or(shiftLeft(-s)); 1234 } 1235 1236 /** 1237 * Rotates right this vector by the broadcast of an input scalar, selecting 1238 * lane elements controlled by a mask. 1239 * <p> 1240 * This is a lane-wise binary operation which applies the operation 1241 * {@link Long#rotateRight} to each lane and where 1242 * lane elements of this vector apply to the first argument, and lane 1243 * elements of the broadcast vector apply to the second argument (the 1244 * rotation distance). 1245 * 1246 * @param s the input scalar; the number of the bits to rotate right 1247 * @param m the mask controlling lane selection 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, VectorMask<Long> m) { 1253 return shiftRight(s, m).or(shiftLeft(-s, m), m); 1254 } 1255 1256 /** 1257 * {@inheritDoc} 1258 */ 1259 @Override 1260 public abstract void intoByteArray(byte[] a, int ix); 1261 1262 /** 1263 * {@inheritDoc} 1264 */ 1265 @Override 1266 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Long> m); 1267 1268 /** 1269 * {@inheritDoc} 1270 */ 1271 @Override 1272 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 1273 1274 /** 1275 * {@inheritDoc} 1276 */ 1277 @Override 1278 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Long> m); 1279 1280 1281 // Type specific horizontal reductions 1282 /** 1283 * Adds all lane elements of this vector. 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 * @return the addition of all the lane elements of this vector 1290 */ 1291 public abstract long addLanes(); 1292 1293 /** 1294 * Adds all lane elements of this vector, selecting lane elements 1295 * controlled by a mask. 1296 * <p> 1297 * This is an associative cross-lane reduction operation which applies the addition 1298 * operation ({@code +}) to lane elements, 1299 * and the identity value is {@code 0}. 1300 * 1301 * @param m the mask controlling lane selection 1302 * @return the addition of the selected lane elements of this vector 1303 */ 1304 public abstract long addLanes(VectorMask<Long> m); 1305 1306 /** 1307 * Multiplies all lane elements of this vector. 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 * @return the multiplication of all the lane elements of this vector 1314 */ 1315 public abstract long mulLanes(); 1316 1317 /** 1318 * Multiplies all lane elements of this vector, selecting lane elements 1319 * controlled by a mask. 1320 * <p> 1321 * This is an associative cross-lane reduction operation which applies the 1322 * multiplication operation ({@code *}) to lane elements, 1323 * and the identity value is {@code 1}. 1324 * 1325 * @param m the mask controlling lane selection 1326 * @return the multiplication of all the lane elements of this vector 1327 */ 1328 public abstract long mulLanes(VectorMask<Long> m); 1329 1330 /** 1331 * Returns the minimum lane element of this vector. 1332 * <p> 1333 * This is an associative cross-lane reduction operation which applies the operation 1334 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1335 * and the identity value is 1336 * {@link Long#MAX_VALUE}. 1337 * 1338 * @return the minimum lane element of this vector 1339 */ 1340 public abstract long minLanes(); 1341 1342 /** 1343 * Returns the minimum lane element of this vector, selecting lane elements 1344 * controlled by a mask. 1345 * <p> 1346 * This is an associative cross-lane reduction operation which applies the operation 1347 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1348 * and the identity value is 1349 * {@link Long#MAX_VALUE}. 1350 * 1351 * @param m the mask controlling lane selection 1352 * @return the minimum lane element of this vector 1353 */ 1354 public abstract long minLanes(VectorMask<Long> m); 1355 1356 /** 1357 * Returns the maximum lane element of this vector. 1358 * <p> 1359 * This is an associative cross-lane reduction operation which applies the operation 1360 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1361 * and the identity value is 1362 * {@link Long#MIN_VALUE}. 1363 * 1364 * @return the maximum lane element of this vector 1365 */ 1366 public abstract long maxLanes(); 1367 1368 /** 1369 * Returns the maximum lane element of this vector, selecting lane elements 1370 * controlled by a mask. 1371 * <p> 1372 * This is an associative cross-lane reduction operation which applies the operation 1373 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1374 * and the identity value is 1375 * {@link Long#MIN_VALUE}. 1376 * 1377 * @param m the mask controlling lane selection 1378 * @return the maximum lane element of this vector 1379 */ 1380 public abstract long maxLanes(VectorMask<Long> m); 1381 1382 /** 1383 * Logically ORs all lane elements of this vector. 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 * @return the logical OR all the lane elements of this vector 1390 */ 1391 public abstract long orLanes(); 1392 1393 /** 1394 * Logically ORs all lane elements of this vector, selecting lane elements 1395 * controlled by a mask. 1396 * <p> 1397 * This is an associative cross-lane reduction operation which applies the logical OR 1398 * operation ({@code |}) to lane elements, 1399 * and the identity value is {@code 0}. 1400 * 1401 * @param m the mask controlling lane selection 1402 * @return the logical OR all the lane elements of this vector 1403 */ 1404 public abstract long orLanes(VectorMask<Long> m); 1405 1406 /** 1407 * Logically ANDs all lane elements of this vector. 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 * @return the logical AND all the lane elements of this vector 1414 */ 1415 public abstract long andLanes(); 1416 1417 /** 1418 * Logically ANDs all lane elements of this vector, selecting lane elements 1419 * controlled by a mask. 1420 * <p> 1421 * This is an associative cross-lane reduction operation which applies the logical AND 1422 * operation ({@code |}) to lane elements, 1423 * and the identity value is {@code -1}. 1424 * 1425 * @param m the mask controlling lane selection 1426 * @return the logical AND all the lane elements of this vector 1427 */ 1428 public abstract long andLanes(VectorMask<Long> m); 1429 1430 /** 1431 * Logically XORs all lane elements of this vector. 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 * @return the logical XOR all the lane elements of this vector 1438 */ 1439 public abstract long xorLanes(); 1440 1441 /** 1442 * Logically XORs all lane elements of this vector, selecting lane elements 1443 * controlled by a mask. 1444 * <p> 1445 * This is an associative cross-lane reduction operation which applies the logical XOR 1446 * operation ({@code ^}) to lane elements, 1447 * and the identity value is {@code 0}. 1448 * 1449 * @param m the mask controlling lane selection 1450 * @return the logical XOR all the lane elements of this vector 1451 */ 1452 public abstract long xorLanes(VectorMask<Long> m); 1453 1454 // Type specific accessors 1455 1456 /** 1457 * Gets the lane element at lane index {@code i} 1458 * 1459 * @param i the lane index 1460 * @return the lane element at lane index {@code i} 1461 * @throws IllegalArgumentException if the index is is out of range 1462 * ({@code < 0 || >= length()}) 1463 */ 1464 public abstract long lane(int i); 1465 1466 /** 1467 * Replaces the lane element of this vector at lane index {@code i} with 1468 * value {@code e}. 1469 * <p> 1470 * This is a cross-lane operation and behaves as if it returns the result 1471 * of blending this vector with an input vector that is the result of 1472 * broadcasting {@code e} and a mask that has only one lane set at lane 1473 * index {@code i}. 1474 * 1475 * @param i the lane index of the lane element to be replaced 1476 * @param e the value to be placed 1477 * @return the result of replacing the lane element of this vector at lane 1478 * index {@code i} with value {@code e}. 1479 * @throws IllegalArgumentException if the index is is out of range 1480 * ({@code < 0 || >= length()}) 1481 */ 1482 public abstract LongVector with(int i, long e); 1483 1484 // Type specific extractors 1485 1486 /** 1487 * Returns an array containing the lane elements of this vector. 1488 * <p> 1489 * This method behaves as if it {@link #intoArray(long[], int)} stores} 1490 * this vector into an allocated array and returns the array as follows: 1491 * <pre>{@code 1492 * long[] a = new long[this.length()]; 1493 * this.intoArray(a, 0); 1494 * return a; 1495 * }</pre> 1496 * 1497 * @return an array containing the the lane elements of this vector 1498 */ 1499 @ForceInline 1500 public final long[] toArray() { 1501 long[] a = new long[species().length()]; 1502 intoArray(a, 0); 1503 return a; 1504 } 1505 1506 /** 1507 * Stores this vector into an array starting at offset. 1508 * <p> 1509 * For each vector lane, where {@code N} is the vector lane index, 1510 * the lane element at index {@code N} is stored into the array at index 1511 * {@code offset + N}. 1512 * 1513 * @param a the array 1514 * @param offset the offset into the array 1515 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1516 * {@code offset > a.length - this.length()} 1517 */ 1518 public abstract void intoArray(long[] a, int offset); 1519 1520 /** 1521 * Stores this vector into an array starting at offset and using a mask. 1522 * <p> 1523 * For each vector lane, where {@code N} is the vector lane index, 1524 * if the mask lane at index {@code N} is set then the lane element at 1525 * index {@code N} is stored into the array index {@code offset + N}. 1526 * 1527 * @param a the array 1528 * @param offset the offset into the array 1529 * @param m the mask 1530 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1531 * for any vector lane index {@code N} where the mask at lane {@code N} 1532 * is set {@code offset >= a.length - N} 1533 */ 1534 public abstract void intoArray(long[] a, int offset, VectorMask<Long> m); 1535 1536 /** 1537 * Stores this vector into an array using indexes obtained from an index 1538 * map. 1539 * <p> 1540 * For each vector lane, where {@code N} is the vector lane index, the 1541 * lane element at index {@code N} is stored into the array at index 1542 * {@code a_offset + indexMap[i_offset + N]}. 1543 * 1544 * @param a the array 1545 * @param a_offset the offset into the array, may be negative if relative 1546 * indexes in the index map compensate to produce a value within the 1547 * array bounds 1548 * @param indexMap the index map 1549 * @param i_offset the offset into the index map 1550 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 1551 * {@code i_offset > indexMap.length - this.length()}, 1552 * or for any vector lane index {@code N} the result of 1553 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length} 1554 */ 1555 public abstract void intoArray(long[] a, int a_offset, int[] indexMap, int i_offset); 1556 1557 /** 1558 * Stores this vector into an array using indexes obtained from an index 1559 * map and using a mask. 1560 * <p> 1561 * For each vector lane, where {@code N} is the vector lane index, 1562 * if the mask lane at index {@code N} is set then the lane element at 1563 * index {@code N} is stored into the array at index 1564 * {@code a_offset + indexMap[i_offset + N]}. 1565 * 1566 * @param a the array 1567 * @param a_offset the offset into the array, may be negative if relative 1568 * indexes in the index map compensate to produce a value within the 1569 * array bounds 1570 * @param m the mask 1571 * @param indexMap the index map 1572 * @param i_offset the offset into the index map 1573 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1574 * {@code i_offset > indexMap.length - this.length()}, 1575 * or for any vector lane index {@code N} where the mask at lane 1576 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is 1577 * {@code < 0} or {@code >= a.length} 1578 */ 1579 public abstract void intoArray(long[] a, int a_offset, VectorMask<Long> m, int[] indexMap, int i_offset); 1580 // Species 1581 1582 /** 1583 * {@inheritDoc} 1584 */ 1585 @Override 1586 public abstract VectorSpecies<Long> species(); 1587 1588 /** 1589 * Class representing {@link LongVector}'s of the same {@link VectorShape VectorShape}. 1590 */ 1591 static final class LongSpecies extends AbstractSpecies<Long> { 1592 final Function<long[], LongVector> vectorFactory; 1593 1594 private LongSpecies(VectorShape shape, 1595 Class<?> vectorType, 1596 Class<?> maskType, 1597 Function<long[], LongVector> vectorFactory, 1598 Function<boolean[], VectorMask<Long>> maskFactory, 1599 Function<IntUnaryOperator, VectorShuffle<Long>> shuffleFromArrayFactory, 1600 fShuffleFromArray<Long> shuffleFromOpFactory) { 1601 super(shape, long.class, Long.SIZE, vectorType, maskType, maskFactory, 1602 shuffleFromArrayFactory, shuffleFromOpFactory); 1603 this.vectorFactory = vectorFactory; 1604 } 1605 1606 interface FOp { 1607 long apply(int i); 1608 } 1609 1610 LongVector op(FOp f) { 1611 long[] res = new long[length()]; 1612 for (int i = 0; i < length(); i++) { 1613 res[i] = f.apply(i); 1614 } 1615 return vectorFactory.apply(res); 1616 } 1617 1618 LongVector op(VectorMask<Long> o, FOp f) { 1619 long[] res = new long[length()]; 1620 boolean[] mbits = ((AbstractMask<Long>)o).getBits(); 1621 for (int i = 0; i < length(); i++) { 1622 if (mbits[i]) { 1623 res[i] = f.apply(i); 1624 } 1625 } 1626 return vectorFactory.apply(res); 1627 } 1628 } 1629 1630 /** 1631 * Finds the preferred species for an element type of {@code long}. 1632 * <p> 1633 * A preferred species is a species chosen by the platform that has a 1634 * shape of maximal bit size. A preferred species for different element 1635 * types will have the same shape, and therefore vectors, masks, and 1636 * shuffles created from such species will be shape compatible. 1637 * 1638 * @return the preferred species for an element type of {@code long} 1639 */ 1640 private static LongSpecies preferredSpecies() { 1641 return (LongSpecies) VectorSpecies.ofPreferred(long.class); 1642 } 1643 1644 /** 1645 * Finds a species for an element type of {@code long} and shape. 1646 * 1647 * @param s the shape 1648 * @return a species for an element type of {@code long} and shape 1649 * @throws IllegalArgumentException if no such species exists for the shape 1650 */ 1651 static LongSpecies species(VectorShape s) { 1652 Objects.requireNonNull(s); 1653 switch (s) { 1654 case S_64_BIT: return (LongSpecies) SPECIES_64; 1655 case S_128_BIT: return (LongSpecies) SPECIES_128; 1656 case S_256_BIT: return (LongSpecies) SPECIES_256; 1657 case S_512_BIT: return (LongSpecies) SPECIES_512; 1658 case S_Max_BIT: return (LongSpecies) SPECIES_MAX; 1659 default: throw new IllegalArgumentException("Bad shape: " + s); 1660 } 1661 } 1662 1663 /** Species representing {@link LongVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 1664 public static final VectorSpecies<Long> SPECIES_64 = new LongSpecies(VectorShape.S_64_BIT, Long64Vector.class, Long64Vector.Long64Mask.class, 1665 Long64Vector::new, Long64Vector.Long64Mask::new, 1666 Long64Vector.Long64Shuffle::new, Long64Vector.Long64Shuffle::new); 1667 1668 /** Species representing {@link LongVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 1669 public static final VectorSpecies<Long> SPECIES_128 = new LongSpecies(VectorShape.S_128_BIT, Long128Vector.class, Long128Vector.Long128Mask.class, 1670 Long128Vector::new, Long128Vector.Long128Mask::new, 1671 Long128Vector.Long128Shuffle::new, Long128Vector.Long128Shuffle::new); 1672 1673 /** Species representing {@link LongVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 1674 public static final VectorSpecies<Long> SPECIES_256 = new LongSpecies(VectorShape.S_256_BIT, Long256Vector.class, Long256Vector.Long256Mask.class, 1675 Long256Vector::new, Long256Vector.Long256Mask::new, 1676 Long256Vector.Long256Shuffle::new, Long256Vector.Long256Shuffle::new); 1677 1678 /** Species representing {@link LongVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 1679 public static final VectorSpecies<Long> SPECIES_512 = new LongSpecies(VectorShape.S_512_BIT, Long512Vector.class, Long512Vector.Long512Mask.class, 1680 Long512Vector::new, Long512Vector.Long512Mask::new, 1681 Long512Vector.Long512Shuffle::new, Long512Vector.Long512Shuffle::new); 1682 1683 /** Species representing {@link LongVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 1684 public static final VectorSpecies<Long> SPECIES_MAX = new LongSpecies(VectorShape.S_Max_BIT, LongMaxVector.class, LongMaxVector.LongMaxMask.class, 1685 LongMaxVector::new, LongMaxVector.LongMaxMask::new, 1686 LongMaxVector.LongMaxShuffle::new, LongMaxVector.LongMaxShuffle::new); 1687 1688 /** 1689 * Preferred species for {@link LongVector}s. 1690 * A preferred species is a species of maximal bit size for the platform. 1691 */ 1692 public static final VectorSpecies<Long> SPECIES_PREFERRED = (VectorSpecies<Long>) preferredSpecies(); 1693 }