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