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 jdk.internal.vm.annotation.ForceInline; 28 29 import java.nio.ByteBuffer; 30 import java.nio.ByteOrder; 31 import java.nio.LongBuffer; 32 import java.util.Objects; 33 import java.util.concurrent.ThreadLocalRandom; 34 35 36 /** 37 * A specialized {@link Vector} representing an ordered immutable sequence of 38 * {@code long} values. 39 * 40 * @param <S> the type of shape of this vector 41 */ 42 @SuppressWarnings("cast") 43 public abstract class LongVector<S extends Vector.Shape> extends Vector<Long,S> { 44 45 LongVector() {} 46 47 // Unary operator 48 49 interface FUnOp { 50 long apply(int i, long a); 51 } 52 53 abstract LongVector<S> uOp(FUnOp f); 54 55 abstract LongVector<S> uOp(Mask<Long, S> m, FUnOp f); 56 57 // Binary operator 58 59 interface FBinOp { 60 long apply(int i, long a, long b); 61 } 62 63 abstract LongVector<S> bOp(Vector<Long,S> v, FBinOp f); 64 65 abstract LongVector<S> bOp(Vector<Long,S> v, Mask<Long, S> m, FBinOp f); 66 67 // Trinary operator 68 69 interface FTriOp { 70 long apply(int i, long a, long b, long c); 71 } 72 73 abstract LongVector<S> tOp(Vector<Long,S> v1, Vector<Long,S> v2, FTriOp f); 74 75 abstract LongVector<S> tOp(Vector<Long,S> v1, Vector<Long,S> v2, Mask<Long, S> m, FTriOp f); 76 77 // Reduction operator 78 79 abstract long rOp(long v, FBinOp f); 80 81 // Binary test 82 83 interface FBinTest { 84 boolean apply(int i, long a, long b); 85 } 86 87 abstract Mask<Long, S> bTest(Vector<Long,S> v, FBinTest f); 88 89 // Foreach 90 91 interface FUnCon { 92 void apply(int i, long a); 93 } 94 95 abstract void forEach(FUnCon f); 96 97 abstract void forEach(Mask<Long, S> m, FUnCon f); 98 99 // 100 101 @Override 102 public abstract LongVector<S> add(Vector<Long,S> v); 103 104 /** 105 * Adds this vector to the broadcast of an input scalar. 106 * <p> 107 * This is a vector binary operation where the primitive addition operation 108 * ({@code +}) is applied to lane elements. 109 * 110 * @param s the input scalar 111 * @return the result of adding this vector to the broadcast of an input 112 * scalar 113 */ 114 public abstract LongVector<S> add(long s); 115 116 @Override 117 public abstract LongVector<S> add(Vector<Long,S> v, Mask<Long, S> m); 118 119 /** 120 * Adds this vector to broadcast of an input scalar, 121 * selecting lane elements controlled by a mask. 122 * <p> 123 * This is a vector binary operation where the primitive addition operation 124 * ({@code +}) is applied to lane elements. 125 * 126 * @param s the input scalar 127 * @param m the mask controlling lane selection 128 * @return the result of adding this vector to the broadcast of an input 129 * scalar 130 */ 131 public abstract LongVector<S> add(long s, Mask<Long, S> m); 132 133 @Override 134 public abstract LongVector<S> sub(Vector<Long,S> v); 135 136 /** 137 * Subtracts the broadcast of an input scalar from this vector. 138 * <p> 139 * This is a vector binary operation where the primitive subtraction 140 * operation ({@code -}) is applied to lane elements. 141 * 142 * @param s the input scalar 143 * @return the result of subtracting the broadcast of an input 144 * scalar from this vector 145 */ 146 public abstract LongVector<S> sub(long s); 147 148 @Override 149 public abstract LongVector<S> sub(Vector<Long,S> v, Mask<Long, S> m); 150 151 /** 152 * Subtracts the broadcast of an input scalar from this vector, selecting 153 * lane elements controlled by a mask. 154 * <p> 155 * This is a vector binary operation where the primitive subtraction 156 * operation ({@code -}) is applied to lane elements. 157 * 158 * @param s the input scalar 159 * @param m the mask controlling lane selection 160 * @return the result of subtracting the broadcast of an input 161 * scalar from this vector 162 */ 163 public abstract LongVector<S> sub(long s, Mask<Long, S> m); 164 165 @Override 166 public abstract LongVector<S> mul(Vector<Long,S> v); 167 168 /** 169 * Multiplies this vector with the broadcast of an input scalar. 170 * <p> 171 * This is a vector binary operation where the primitive multiplication 172 * operation ({@code *}) is applied to lane elements. 173 * 174 * @param s the input scalar 175 * @return the result of multiplying this vector with the broadcast of an 176 * input scalar 177 */ 178 public abstract LongVector<S> mul(long s); 179 180 @Override 181 public abstract LongVector<S> mul(Vector<Long,S> v, Mask<Long, S> m); 182 183 /** 184 * Multiplies this vector with the broadcast of an input scalar, selecting 185 * lane elements controlled by a mask. 186 * <p> 187 * This is a vector binary operation where the primitive multiplication 188 * operation ({@code *}) is applied to lane elements. 189 * 190 * @param s the input scalar 191 * @param m the mask controlling lane selection 192 * @return the result of multiplying this vector with the broadcast of an 193 * input scalar 194 */ 195 public abstract LongVector<S> mul(long s, Mask<Long, S> m); 196 197 @Override 198 public abstract LongVector<S> neg(); 199 200 @Override 201 public abstract LongVector<S> neg(Mask<Long, S> m); 202 203 @Override 204 public abstract LongVector<S> abs(); 205 206 @Override 207 public abstract LongVector<S> abs(Mask<Long, S> m); 208 209 @Override 210 public abstract LongVector<S> min(Vector<Long,S> v); 211 212 /** 213 * Returns the minimum of this vector and the broadcast of an input scalar. 214 * <p> 215 * This is a vector binary operation where the operation 216 * {@code (a, b) -> a < b ? a : b} is applied to lane elements. 217 * 218 * @param s the input scalar 219 * @return the minimum of this vector and the broadcast of an input scalar 220 */ 221 public abstract LongVector<S> min(long s); 222 223 @Override 224 public abstract LongVector<S> max(Vector<Long,S> v); 225 226 /** 227 * Returns the maximum of this vector and the broadcast of an input scalar. 228 * <p> 229 * This is a vector binary operation where the operation 230 * {@code (a, b) -> a > b ? a : b} is applied to lane elements. 231 * 232 * @param s the input scalar 233 * @return the maximum of this vector and the broadcast of an input scalar 234 */ 235 public abstract LongVector<S> max(long s); 236 237 @Override 238 public abstract Mask<Long, S> equal(Vector<Long,S> v); 239 240 /** 241 * Tests if this vector is equal to the broadcast of an input scalar. 242 * <p> 243 * This is a vector binary test operation where the primitive equals 244 * operation ({@code ==}) is applied to lane elements. 245 * 246 * @param s the input scalar 247 * @return the result mask of testing if this vector is equal to the 248 * broadcast of an input scalar 249 */ 250 public abstract Mask<Long, S> equal(long s); 251 252 @Override 253 public abstract Mask<Long, S> notEqual(Vector<Long,S> v); 254 255 /** 256 * Tests if this vector is not equal to the broadcast of an input scalar. 257 * <p> 258 * This is a vector binary test operation where the primitive not equals 259 * operation ({@code !=}) is applied to lane elements. 260 * 261 * @param s the input scalar 262 * @return the result mask of testing if this vector is not equal to the 263 * broadcast of an input scalar 264 */ 265 public abstract Mask<Long, S> notEqual(long s); 266 267 @Override 268 public abstract Mask<Long, S> lessThan(Vector<Long,S> v); 269 270 /** 271 * Tests if this vector is less than the broadcast of an input scalar. 272 * <p> 273 * This is a vector binary test operation where the primitive less than 274 * operation ({@code <}) is applied to lane elements. 275 * 276 * @param s the input scalar 277 * @return the mask result of testing if this vector is less than the 278 * broadcast of an input scalar 279 */ 280 public abstract Mask<Long, S> lessThan(long s); 281 282 @Override 283 public abstract Mask<Long, S> lessThanEq(Vector<Long,S> v); 284 285 /** 286 * Tests if this vector is less or equal to the broadcast of an input scalar. 287 * <p> 288 * This is a vector binary test operation where the primitive less than 289 * or equal to operation ({@code <=}) is applied to lane elements. 290 * 291 * @param s the input scalar 292 * @return the mask result of testing if this vector is less than or equal 293 * to the broadcast of an input scalar 294 */ 295 public abstract Mask<Long, S> lessThanEq(long s); 296 297 @Override 298 public abstract Mask<Long, S> greaterThan(Vector<Long,S> v); 299 300 /** 301 * Tests if this vector is greater than the broadcast of an input scalar. 302 * <p> 303 * This is a vector binary test operation where the primitive greater than 304 * operation ({@code >}) is applied to lane elements. 305 * 306 * @param s the input scalar 307 * @return the mask result of testing if this vector is greater than the 308 * broadcast of an input scalar 309 */ 310 public abstract Mask<Long, S> greaterThan(long s); 311 312 @Override 313 public abstract Mask<Long, S> greaterThanEq(Vector<Long,S> v); 314 315 /** 316 * Tests if this vector is greater than or equal to the broadcast of an 317 * input scalar. 318 * <p> 319 * This is a vector binary test operation where the primitive greater than 320 * or equal to operation ({@code >=}) is applied to lane elements. 321 * 322 * @param s the input scalar 323 * @return the mask result of testing if this vector is greater than or 324 * equal to the broadcast of an input scalar 325 */ 326 public abstract Mask<Long, S> greaterThanEq(long s); 327 328 @Override 329 public abstract LongVector<S> blend(Vector<Long,S> v, Mask<Long, S> m); 330 331 /** 332 * Blends the lane elements of this vector with those of the broadcast of an 333 * input scalar, selecting lanes controlled by a mask. 334 * <p> 335 * For each lane of the mask, at lane index {@code N}, if the mask lane 336 * is set then the lane element at {@code N} from the input vector is 337 * selected and placed into the resulting vector at {@code N}, 338 * otherwise the the lane element at {@code N} from this input vector is 339 * selected and placed into the resulting vector at {@code N}. 340 * 341 * @param s the input scalar 342 * @param m the mask controlling lane selection 343 * @return the result of blending the lane elements of this vector with 344 * those of the broadcast of an input scalar 345 */ 346 public abstract LongVector<S> blend(long s, Mask<Long, S> m); 347 348 @Override 349 public abstract LongVector<S> rearrange(Vector<Long, S> v, 350 Shuffle<Long, S> s, Mask<Long, S> m); 351 352 @Override 353 public abstract LongVector<S> rearrange(Shuffle<Long, S> m); 354 355 @Override 356 @ForceInline 357 public <T extends Shape> LongVector<T> resize(Species<Long, T> species) { 358 return (LongVector<T>) species.resize(this); 359 } 360 361 @Override 362 public abstract LongVector<S> rotateEL(int i); 363 364 @Override 365 public abstract LongVector<S> rotateER(int i); 366 367 @Override 368 public abstract LongVector<S> shiftEL(int i); 369 370 @Override 371 public abstract LongVector<S> shiftER(int i); 372 373 374 375 /** 376 * Bitwise ANDs this vector with an input vector. 377 * <p> 378 * This is a vector binary operation where the primitive bitwise AND 379 * operation ({@code &}) is applied to lane elements. 380 * 381 * @param v the input vector 382 * @return the bitwise AND of this vector with the input vector 383 */ 384 public abstract LongVector<S> and(Vector<Long,S> v); 385 386 /** 387 * Bitwise ANDs this vector with the broadcast of an input scalar. 388 * <p> 389 * This is a vector binary operation where the primitive bitwise AND 390 * operation ({@code &}) is applied to lane elements. 391 * 392 * @param s the input scalar 393 * @return the bitwise AND of this vector with the broadcast of an input 394 * scalar 395 */ 396 public abstract LongVector<S> and(long s); 397 398 /** 399 * Bitwise ANDs this vector with an input vector, selecting lane elements 400 * controlled by a mask. 401 * <p> 402 * This is a vector binary operation where the primitive bitwise AND 403 * operation ({@code &}) is applied to lane elements. 404 * 405 * @param v the input vector 406 * @param m the mask controlling lane selection 407 * @return the bitwise AND of this vector with the input vector 408 */ 409 public abstract LongVector<S> and(Vector<Long,S> v, Mask<Long, S> m); 410 411 /** 412 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting 413 * lane elements controlled by a mask. 414 * <p> 415 * This is a vector binary operation where the primitive bitwise AND 416 * operation ({@code &}) is applied to lane elements. 417 * 418 * @param s the input scalar 419 * @param m the mask controlling lane selection 420 * @return the bitwise AND of this vector with the broadcast of an input 421 * scalar 422 */ 423 public abstract LongVector<S> and(long s, Mask<Long, S> m); 424 425 /** 426 * Bitwise ORs this vector with an input vector. 427 * <p> 428 * This is a vector binary operation where the primitive bitwise OR 429 * operation ({@code |}) is applied to lane elements. 430 * 431 * @param v the input vector 432 * @return the bitwise OR of this vector with the input vector 433 */ 434 public abstract LongVector<S> or(Vector<Long,S> v); 435 436 /** 437 * Bitwise ORs this vector with the broadcast of an input scalar. 438 * <p> 439 * This is a vector binary operation where the primitive bitwise OR 440 * operation ({@code |}) is applied to lane elements. 441 * 442 * @param s the input scalar 443 * @return the bitwise OR of this vector with the broadcast of an input 444 * scalar 445 */ 446 public abstract LongVector<S> or(long s); 447 448 /** 449 * Bitwise ORs this vector with an input vector, selecting lane elements 450 * controlled by a mask. 451 * <p> 452 * This is a vector binary operation where the primitive bitwise OR 453 * operation ({@code |}) is applied to lane elements. 454 * 455 * @param v the input vector 456 * @param m the mask controlling lane selection 457 * @return the bitwise OR of this vector with the input vector 458 */ 459 public abstract LongVector<S> or(Vector<Long,S> v, Mask<Long, S> m); 460 461 /** 462 * Bitwise ORs this vector with the broadcast of an input scalar, selecting 463 * lane elements controlled by a mask. 464 * <p> 465 * This is a vector binary operation where the primitive bitwise OR 466 * operation ({@code |}) is applied to lane elements. 467 * 468 * @param s the input scalar 469 * @param m the mask controlling lane selection 470 * @return the bitwise OR of this vector with the broadcast of an input 471 * scalar 472 */ 473 public abstract LongVector<S> or(long s, Mask<Long, S> m); 474 475 /** 476 * Bitwise XORs this vector with an input vector. 477 * <p> 478 * This is a vector binary operation where the primitive bitwise XOR 479 * operation ({@code ^}) is applied to lane elements. 480 * 481 * @param v the input vector 482 * @return the bitwise XOR of this vector with the input vector 483 */ 484 public abstract LongVector<S> xor(Vector<Long,S> v); 485 486 /** 487 * Bitwise XORs this vector with the broadcast of an input scalar. 488 * <p> 489 * This is a vector binary operation where the primitive bitwise XOR 490 * operation ({@code ^}) is applied to lane elements. 491 * 492 * @param s the input scalar 493 * @return the bitwise XOR of this vector with the broadcast of an input 494 * scalar 495 */ 496 public abstract LongVector<S> xor(long s); 497 498 /** 499 * Bitwise XORs this vector with an input vector, selecting lane elements 500 * controlled by a mask. 501 * <p> 502 * This is a vector binary operation where the primitive bitwise XOR 503 * operation ({@code ^}) is applied to lane elements. 504 * 505 * @param v the input vector 506 * @param m the mask controlling lane selection 507 * @return the bitwise XOR of this vector with the input vector 508 */ 509 public abstract LongVector<S> xor(Vector<Long,S> v, Mask<Long, S> m); 510 511 /** 512 * Bitwise XORs this vector with the broadcast of an input scalar, selecting 513 * lane elements controlled by a mask. 514 * <p> 515 * This is a vector binary operation where the primitive bitwise XOR 516 * operation ({@code ^}) is applied to lane elements. 517 * 518 * @param s the input scalar 519 * @param m the mask controlling lane selection 520 * @return the bitwise XOR of this vector with the broadcast of an input 521 * scalar 522 */ 523 public abstract LongVector<S> xor(long s, Mask<Long, S> m); 524 525 /** 526 * Bitwise NOTs this vector. 527 * <p> 528 * This is a vector unary operation where the primitive bitwise NOT 529 * operation ({@code ~}) is applied to lane elements. 530 * 531 * @return the bitwise NOT of this vector 532 */ 533 public abstract LongVector<S> not(); 534 535 /** 536 * Bitwise NOTs this vector, selecting lane elements controlled by a mask. 537 * <p> 538 * This is a vector unary operation where the primitive bitwise NOT 539 * operation ({@code ~}) is applied to lane elements. 540 * 541 * @param m the mask controlling lane selection 542 * @return the bitwise NOT of this vector 543 */ 544 public abstract LongVector<S> not(Mask<Long, S> m); 545 546 /* 547 @@@ Check the shift operations against the JLS definition and vector 548 instructions. 549 550 For int values the low 5 bits of s are used. 551 For long values the low 6 bits of s are used. 552 */ 553 554 /** 555 * Logically left shifts this vector by the broadcast of an input scalar. 556 * <p> 557 * This is a vector binary operation where the primitive logical left shift 558 * operation ({@code <<}) is applied to lane elements. 559 * 560 * @param s the input scalar; the number of the bits to left shift 561 * @return the result of logically left shifting left this vector by the 562 * broadcast of an input scalar 563 */ 564 public abstract LongVector<S> shiftL(int s); 565 566 /** 567 * Logically left shifts this vector by the broadcast of an input scalar, 568 * selecting lane elements controlled by a mask. 569 * <p> 570 * This is a vector binary operation where the primitive logical left shift 571 * operation ({@code <<}) is applied to lane elements. 572 * 573 * @param s the input scalar; the number of the bits to left shift 574 * @param m the mask controlling lane selection 575 * @return the result of logically left shifting this vector by the 576 * broadcast of an input scalar 577 */ 578 public LongVector<S> shiftL(int s, Mask<Long, S> m) { 579 return uOp(m, (i, a) -> (long) (a << s)); 580 } 581 582 /** 583 * Logically left shifts this vector by an input vector. 584 * <p> 585 * This is a vector binary operation where the primitive logical left shift 586 * operation ({@code <<}) is applied to lane elements. 587 * 588 * @param v the input vector 589 * @return the result of logically left shifting this vector by the input 590 * vector 591 */ 592 public abstract LongVector<S> shiftL(Vector<Long,S> v); 593 594 /** 595 * Logically left shifts this vector by an input vector, selecting lane 596 * elements controlled by a mask. 597 * <p> 598 * This is a vector binary operation where the primitive logical left shift 599 * operation ({@code <<}) is applied to lane elements. 600 * 601 * @param v the input vector 602 * @param m the mask controlling lane selection 603 * @return the result of logically left shifting this vector by the input 604 * vector 605 */ 606 public LongVector<S> shiftL(Vector<Long,S> v, Mask<Long, S> m) { 607 return bOp(v, m, (i, a, b) -> (long) (a << b)); 608 } 609 610 // logical, or unsigned, shift right 611 612 /** 613 * Logically right shifts (or unsigned right shifts) this vector by the 614 * broadcast of an input scalar. 615 * <p> 616 * This is a vector binary operation where the primitive logical right shift 617 * operation ({@code >>>}) is applied to lane elements. 618 * 619 * @param s the input scalar; the number of the bits to right shift 620 * @return the result of logically right shifting this vector by the 621 * broadcast of an input scalar 622 */ 623 public abstract LongVector<S> shiftR(int s); 624 625 /** 626 * Logically right shifts (or unsigned right shifts) this vector by the 627 * broadcast of an input scalar, selecting lane elements controlled by a 628 * mask. 629 * <p> 630 * This is a vector binary operation where the primitive logical right shift 631 * operation ({@code >>>}) is applied to lane elements. 632 * 633 * @param s the input scalar; the number of the bits to right shift 634 * @return the result of logically right shifting this vector by the 635 * broadcast of an input scalar 636 */ 637 public LongVector<S> shiftR(int s, Mask<Long, S> m) { 638 return uOp(m, (i, a) -> (long) (a >>> s)); 639 } 640 641 /** 642 * Logically right shifts (or unsigned right shifts) this vector by an 643 * input vector. 644 * <p> 645 * This is a vector binary operation where the primitive logical right shift 646 * operation ({@code >>>}) is applied to lane elements. 647 * 648 * @param v the input vector 649 * @return the result of logically right shifting this vector by the 650 * input vector 651 */ 652 public abstract LongVector<S> shiftR(Vector<Long,S> v); 653 654 /** 655 * Logically right shifts (or unsigned right shifts) this vector by an 656 * input vector, selecting lane elements controlled by a mask. 657 * <p> 658 * This is a vector binary operation where the primitive logical right shift 659 * operation ({@code >>>}) is applied to lane elements. 660 * 661 * @param v the input vector 662 * @param m the mask controlling lane selection 663 * @return the result of logically right shifting this vector by the 664 * input vector 665 */ 666 public LongVector<S> shiftR(Vector<Long,S> v, Mask<Long, S> m) { 667 return bOp(v, m, (i, a, b) -> (long) (a >>> b)); 668 } 669 670 /** 671 * Arithmetically right shifts (or signed right shifts) this vector by the 672 * broadcast of an input scalar. 673 * <p> 674 * This is a vector binary operation where the primitive arithmetic right 675 * shift operation ({@code >>}) is applied to lane elements. 676 * 677 * @param s the input scalar; the number of the bits to right shift 678 * @return the result of arithmetically right shifting this vector by the 679 * broadcast of an input scalar 680 */ 681 public abstract LongVector<S> aShiftR(int s); 682 683 /** 684 * Arithmetically right shifts (or signed right shifts) this vector by the 685 * broadcast of an input scalar, selecting lane elements controlled by a 686 * mask. 687 * <p> 688 * This is a vector binary operation where the primitive arithmetic right 689 * shift operation ({@code >>}) is applied to lane elements. 690 * 691 * @param s the input scalar; the number of the bits to right shift 692 * @param m the mask controlling lane selection 693 * @return the result of arithmetically right shifting this vector by the 694 * broadcast of an input scalar 695 */ 696 public LongVector<S> aShiftR(int s, Mask<Long, S> m) { 697 return uOp(m, (i, a) -> (long) (a >> s)); 698 } 699 700 /** 701 * Arithmetically right shifts (or signed right shifts) this vector by an 702 * input vector. 703 * <p> 704 * This is a vector binary operation where the primitive arithmetic right 705 * shift operation ({@code >>}) is applied to lane elements. 706 * 707 * @param v the input vector 708 * @return the result of arithmetically right shifting this vector by the 709 * input vector 710 */ 711 public abstract LongVector<S> aShiftR(Vector<Long,S> v); 712 713 /** 714 * Arithmetically right shifts (or signed right shifts) this vector by an 715 * input vector, selecting lane elements controlled by a mask. 716 * <p> 717 * This is a vector binary operation where the primitive arithmetic right 718 * shift operation ({@code >>}) is applied to lane elements. 719 * 720 * @param v the input vector 721 * @param m the mask controlling lane selection 722 * @return the result of arithmetically right shifting this vector by the 723 * input vector 724 */ 725 public LongVector<S> aShiftR(Vector<Long,S> v, Mask<Long, S> m) { 726 return bOp(v, m, (i, a, b) -> (long) (a >> b)); 727 } 728 729 /** 730 * Rotates left this vector by the broadcast of an input scalar. 731 * <p> 732 * This is a vector binary operation where the operation 733 * {@link Long#rotateLeft} is applied to lane elements and where 734 * lane elements of this vector apply to the first argument, and lane 735 * elements of the broadcast vector apply to the second argument (the 736 * rotation distance). 737 * 738 * @param s the input scalar; the number of the bits to rotate left 739 * @return the result of rotating left this vector by the broadcast of an 740 * input scalar 741 */ 742 @ForceInline 743 public final LongVector<S> rotateL(int s) { 744 return shiftL(s).or(shiftR(-s)); 745 } 746 747 /** 748 * Rotates left this vector by the broadcast of an input scalar, selecting 749 * lane elements controlled by a mask. 750 * <p> 751 * This is a vector binary operation where the operation 752 * {@link Long#rotateLeft} is applied to lane elements and where 753 * lane elements of this vector apply to the first argument, and lane 754 * elements of the broadcast vector apply to the second argument (the 755 * rotation distance). 756 * 757 * @param s the input scalar; the number of the bits to rotate left 758 * @param m the mask controlling lane selection 759 * @return the result of rotating left this vector by the broadcast of an 760 * input scalar 761 */ 762 @ForceInline 763 public final LongVector<S> rotateL(int s, Mask<Long, S> m) { 764 return shiftL(s, m).or(shiftR(-s, m), m); 765 } 766 767 /** 768 * Rotates right this vector by the broadcast of an input scalar. 769 * <p> 770 * This is a vector binary operation where the operation 771 * {@link Long#rotateRight} is applied to lane elements and where 772 * lane elements of this vector apply to the first argument, and lane 773 * elements of the broadcast vector apply to the second argument (the 774 * rotation distance). 775 * 776 * @param s the input scalar; the number of the bits to rotate right 777 * @return the result of rotating right this vector by the broadcast of an 778 * input scalar 779 */ 780 @ForceInline 781 public final LongVector<S> rotateR(int s) { 782 return shiftR(s).or(shiftL(-s)); 783 } 784 785 /** 786 * Rotates right this vector by the broadcast of an input scalar, selecting 787 * lane elements controlled by a mask. 788 * <p> 789 * This is a vector binary operation where the operation 790 * {@link Long#rotateRight} is applied to lane elements and where 791 * lane elements of this vector apply to the first argument, and lane 792 * elements of the broadcast vector apply to the second argument (the 793 * rotation distance). 794 * 795 * @param s the input scalar; the number of the bits to rotate right 796 * @param m the mask controlling lane selection 797 * @return the result of rotating right this vector by the broadcast of an 798 * input scalar 799 */ 800 @ForceInline 801 public final LongVector<S> rotateR(int s, Mask<Long, S> m) { 802 return shiftR(s, m).or(shiftL(-s, m), m); 803 } 804 805 @Override 806 public abstract void intoByteArray(byte[] a, int ix); 807 808 @Override 809 public abstract void intoByteArray(byte[] a, int ix, Mask<Long, S> m); 810 811 @Override 812 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 813 814 @Override 815 public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Long, S> m); 816 817 818 // Type specific horizontal reductions 819 820 // @@@ For floating point vectors order matters for reproducibility 821 // with equivalent sequential reduction. Some order needs to be specified 822 // by default. If that default is sequential encounter order then there 823 // could be a "go faster" option that is unspecified, essentially giving 824 // implementation flexibility at the expense of reproducibility and/or 825 // accuracy. 826 // @@@ Mask versions? 827 828 /** 829 * Adds all lane elements of this vector. 830 * <p> 831 * This is an associative vector reduction operation where the addition 832 * operation ({@code +}) is applied to lane elements, 833 * and the identity value is {@code 0}. 834 * 835 * @return the addition of all the lane elements of this vector 836 */ 837 public abstract long addAll(); 838 839 /** 840 * Adds all lane elements of this vector, selecting lane elements 841 * controlled by a mask. 842 * <p> 843 * This is an associative vector reduction operation where the addition 844 * operation ({@code +}) is applied to lane elements, 845 * and the identity value is {@code 0}. 846 * 847 * @param m the mask controlling lane selection 848 * @return the addition of all the lane elements of this vector 849 */ 850 public abstract long addAll(Mask<Long, S> m); 851 852 /** 853 * Subtracts all lane elements of this vector. 854 * <p> 855 * This is an associative vector reduction operation where the subtraction 856 * operation ({@code -}) is applied to lane elements, 857 * and the identity value is {@code 0}. 858 * 859 * @return the subtraction of all the lane elements of this vector 860 */ 861 public abstract long subAll(); 862 863 /** 864 * Subtracts all lane elements of this vector, selecting lane elements 865 * controlled by a mask. 866 * <p> 867 * This is an associative vector reduction operation where the subtraction 868 * operation ({@code -}) is applied to lane elements, 869 * and the identity value is {@code 0}. 870 * 871 * @param m the mask controlling lane selection 872 * @return the subtraction of all the lane elements of this vector 873 */ 874 public abstract long subAll(Mask<Long, S> m); 875 876 /** 877 * Multiplies all lane elements of this vector. 878 * <p> 879 * This is an associative vector reduction operation where the 880 * multiplication operation ({@code *}) is applied to lane elements, 881 * and the identity value is {@code 1}. 882 * 883 * @return the multiplication of all the lane elements of this vector 884 */ 885 public abstract long mulAll(); 886 887 /** 888 * Multiplies all lane elements of this vector, selecting lane elements 889 * controlled by a mask. 890 * <p> 891 * This is an associative vector reduction operation where the 892 * multiplication operation ({@code *}) is applied to lane elements, 893 * and the identity value is {@code 1}. 894 * 895 * @param m the mask controlling lane selection 896 * @return the multiplication of all the lane elements of this vector 897 */ 898 public abstract long mulAll(Mask<Long, S> m); 899 900 /** 901 * Returns the minimum lane element of this vector. 902 * <p> 903 * This is an associative vector reduction operation where the operation 904 * {@code (a, b) -> a > b ? b : a} is applied to lane elements, 905 * and the identity value is {@link Long.MAX_VALUE}. 906 * 907 * @return the minimum lane element of this vector 908 */ 909 public abstract long minAll(); 910 911 /** 912 * Returns the minimum lane element of this vector, selecting lane elements 913 * controlled by a mask. 914 * <p> 915 * This is an associative vector reduction operation where the operation 916 * {@code (a, b) -> a > b ? b : a} is applied to lane elements, 917 * and the identity value is {@link Long.MAX_VALUE}. 918 * 919 * @param m the mask controlling lane selection 920 * @return the minimum lane element of this vector 921 */ 922 public abstract long minAll(Mask<Long, S> m); 923 924 /** 925 * Returns the maximum lane element of this vector. 926 * <p> 927 * This is an associative vector reduction operation where the operation 928 * {@code (a, b) -> a < b ? b : a} is applied to lane elements, 929 * and the identity value is {@link Long.MIN_VALUE}. 930 * 931 * @return the maximum lane element of this vector 932 */ 933 public abstract long maxAll(); 934 935 /** 936 * Returns the maximum lane element of this vector, selecting lane elements 937 * controlled by a mask. 938 * <p> 939 * This is an associative vector reduction operation where the operation 940 * {@code (a, b) -> a < b ? b : a} is applied to lane elements, 941 * and the identity value is {@link Long.MIN_VALUE}. 942 * 943 * @param m the mask controlling lane selection 944 * @return the maximum lane element of this vector 945 */ 946 public abstract long maxAll(Mask<Long, S> m); 947 948 /** 949 * Logically ORs all lane elements of this vector. 950 * <p> 951 * This is an associative vector reduction operation where the logical OR 952 * operation ({@code |}) is applied to lane elements, 953 * and the identity value is {@code 0}. 954 * 955 * @return the logical OR all the lane elements of this vector 956 */ 957 public abstract long orAll(); 958 959 /** 960 * Logically ORs all lane elements of this vector, selecting lane elements 961 * controlled by a mask. 962 * <p> 963 * This is an associative vector reduction operation where the logical OR 964 * operation ({@code |}) is applied to lane elements, 965 * and the identity value is {@code 0}. 966 * 967 * @param m the mask controlling lane selection 968 * @return the logical OR all the lane elements of this vector 969 */ 970 public abstract long orAll(Mask<Long, S> m); 971 972 /** 973 * Logically ANDs all lane elements of this vector. 974 * <p> 975 * This is an associative vector reduction operation where the logical AND 976 * operation ({@code |}) is applied to lane elements, 977 * and the identity value is {@code -1}. 978 * 979 * @return the logical AND all the lane elements of this vector 980 */ 981 public abstract long andAll(); 982 983 /** 984 * Logically ANDs all lane elements of this vector, selecting lane elements 985 * controlled by a mask. 986 * <p> 987 * This is an associative vector reduction operation where the logical AND 988 * operation ({@code |}) is applied to lane elements, 989 * and the identity value is {@code -1}. 990 * 991 * @param m the mask controlling lane selection 992 * @return the logical AND all the lane elements of this vector 993 */ 994 public abstract long andAll(Mask<Long, S> m); 995 996 /** 997 * Logically XORs all lane elements of this vector. 998 * <p> 999 * This is an associative vector reduction operation where the logical XOR 1000 * operation ({@code ^}) is applied to lane elements, 1001 * and the identity value is {@code 0}. 1002 * 1003 * @return the logical XOR all the lane elements of this vector 1004 */ 1005 public abstract long xorAll(); 1006 1007 /** 1008 * Logically XORs all lane elements of this vector, selecting lane elements 1009 * controlled by a mask. 1010 * <p> 1011 * This is an associative vector reduction operation where the logical XOR 1012 * operation ({@code ^}) is applied to lane elements, 1013 * and the identity value is {@code 0}. 1014 * 1015 * @param m the mask controlling lane selection 1016 * @return the logical XOR all the lane elements of this vector 1017 */ 1018 public abstract long xorAll(Mask<Long, S> m); 1019 1020 // Type specific accessors 1021 1022 /** 1023 * Gets the lane element at lane index {@code i} 1024 * 1025 * @param i the lane index 1026 * @return the lane element at lane index {@code i} 1027 * @throws IllegalArgumentException if the index is is out of range 1028 * ({@code < 0 || >= length()}) 1029 */ 1030 public abstract long get(int i); 1031 1032 /** 1033 * Replaces the lane element of this vector at lane index {@code i} with 1034 * value {@code e}. 1035 * <p> 1036 * This is a cross-lane operation and behaves as if it returns the result 1037 * of blending this vector with an input vector that is the result of 1038 * broadcasting {@code e} and a mask that has only one lane set at lane 1039 * index {@code i}. 1040 * 1041 * @param i the lane index of the lane element to be replaced 1042 * @param e the value to be placed 1043 * @return the result of replacing the lane element of this vector at lane 1044 * index {@code i} with value {@code e}. 1045 * @throws IllegalArgumentException if the index is is out of range 1046 * ({@code < 0 || >= length()}) 1047 */ 1048 public abstract LongVector<S> with(int i, long e); 1049 1050 // Type specific extractors 1051 1052 /** 1053 * Returns an array containing the lane elements of this vector. 1054 * <p> 1055 * This method behaves as if it {@link #intoArray(long[], int)} stores} 1056 * this vector into an allocated array and returns the array as follows: 1057 * <pre>{@code 1058 * long[] a = new long[this.length()]; 1059 * this.intoArray(a, 0); 1060 * return a; 1061 * }</pre> 1062 * 1063 * @return an array containing the the lane elements of this vector 1064 */ 1065 @ForceInline 1066 public final long[] toArray() { 1067 // @@@ could allocate without zeroing, see Unsafe.allocateUninitializedArray 1068 long[] a = new long[species().length()]; 1069 intoArray(a, 0); 1070 return a; 1071 } 1072 1073 /** 1074 * Stores this vector into an array starting at offset. 1075 * <p> 1076 * For each vector lane, where {@code N} is the vector lane index, 1077 * the lane element at index {@code N} is stored into the array at index 1078 * {@code i + N}. 1079 * 1080 * @param a the array 1081 * @param i the offset into the array 1082 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1083 * {@code i > a.length - this.length()} 1084 */ 1085 public abstract void intoArray(long[] a, int i); 1086 1087 /** 1088 * Stores this vector into an array starting at offset and using a mask. 1089 * <p> 1090 * For each vector lane, where {@code N} is the vector lane index, 1091 * if the mask lane at index {@code N} is set then the lane element at 1092 * index {@code N} is stored into the array index {@code i + N}. 1093 * 1094 * @param a the array 1095 * @param i the offset into the array 1096 * @param m the mask 1097 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1098 * for any vector lane index {@code N} where the mask at lane {@code N} 1099 * is set {@code i >= a.length - N} 1100 */ 1101 public abstract void intoArray(long[] a, int i, Mask<Long, S> m); 1102 1103 /** 1104 * Stores this vector into an array using indexes obtained from an index 1105 * map. 1106 * <p> 1107 * For each vector lane, where {@code N} is the vector lane index, the 1108 * lane element at index {@code N} is stored into the array at index 1109 * {@code i + indexMap[j + N]}. 1110 * 1111 * @param a the array 1112 * @param i the offset into the array, may be negative if relative 1113 * indexes in the index map compensate to produce a value within the 1114 * array bounds 1115 * @param indexMap the index map 1116 * @param j the offset into the index map 1117 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1118 * {@code j > indexMap.length - this.length()}, 1119 * or for any vector lane index {@code N} the result of 1120 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 1121 */ 1122 public void intoArray(long[] a, int i, int[] indexMap, int j) { 1123 forEach((n, e) -> a[i + indexMap[j + n]] = e); 1124 } 1125 1126 /** 1127 * Stores this vector into an array using indexes obtained from an index 1128 * map and using a mask. 1129 * <p> 1130 * For each vector lane, where {@code N} is the vector lane index, 1131 * if the mask lane at index {@code N} is set then the lane element at 1132 * index {@code N} is stored into the array at index 1133 * {@code i + indexMap[j + N]}. 1134 * 1135 * @param a the array 1136 * @param i the offset into the array, may be negative if relative 1137 * indexes in the index map compensate to produce a value within the 1138 * array bounds 1139 * @param m the mask 1140 * @param indexMap the index map 1141 * @param j the offset into the index map 1142 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1143 * {@code j > indexMap.length - this.length()}, 1144 * or for any vector lane index {@code N} where the mask at lane 1145 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1146 * {@code < 0} or {@code >= a.length} 1147 */ 1148 public void intoArray(long[] a, int i, Mask<Long, S> m, int[] indexMap, int j) { 1149 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e); 1150 } 1151 1152 // Species 1153 1154 @Override 1155 public abstract LongSpecies<S> species(); 1156 1157 /** 1158 * A specialized factory for creating {@link LongVector} value of the same 1159 * shape, and a {@link Mask} and {@link Shuffle} values of the same shape 1160 * and {@code int} element type. 1161 * 1162 * @param <S> the type of shape of this species 1163 */ 1164 public static abstract class LongSpecies<S extends Vector.Shape> extends Vector.Species<Long, S> { 1165 interface FOp { 1166 long apply(int i); 1167 } 1168 1169 abstract LongVector<S> op(FOp f); 1170 1171 abstract LongVector<S> op(Mask<Long, S> m, FOp f); 1172 1173 // Factories 1174 1175 @Override 1176 public abstract LongVector<S> zero(); 1177 1178 /** 1179 * Returns a vector where all lane elements are set to the primitive 1180 * value {@code e}. 1181 * 1182 * @param e the value 1183 * @return a vector of vector where all lane elements are set to 1184 * the primitive value {@code e} 1185 */ 1186 public abstract LongVector<S> broadcast(long e); 1187 1188 /** 1189 * Returns a vector where the first lane element is set to the primtive 1190 * value {@code e}, all other lane elements are set to the default 1191 * value. 1192 * 1193 * @param e the value 1194 * @return a vector where the first lane element is set to the primitive 1195 * value {@code e} 1196 */ 1197 @ForceInline 1198 public final LongVector<S> single(long e) { 1199 return zero().with(0, e); 1200 } 1201 1202 /** 1203 * Returns a vector where each lane element is set to a randomly 1204 * generated primitive value. 1205 * @@@ what are the properties of the random number generator? 1206 * 1207 * @return a vector where each lane elements is set to a randomly 1208 * generated primitive value 1209 */ 1210 public LongVector<S> random() { 1211 ThreadLocalRandom r = ThreadLocalRandom.current(); 1212 return op(i -> r.nextLong()); 1213 } 1214 1215 /** 1216 * Returns a vector where each lane element is set to a given 1217 * primitive value. 1218 * <p> 1219 * For each vector lane, where {@code N} is the vector lane index, the 1220 * the primitive value at index {@code N} is placed into the resulting 1221 * vector at lane index {@code N}. 1222 * 1223 * @@@ What should happen if es.length < this.length() ? use the default 1224 * value or throw IndexOutOfBoundsException 1225 * 1226 * @param es the given primitive values 1227 * @return a vector where each lane element is set to a given primitive 1228 * value 1229 */ 1230 public abstract LongVector<S> scalars(long... es); 1231 1232 /** 1233 * Loads a vector from an array starting at offset. 1234 * <p> 1235 * For each vector lane, where {@code N} is the vector lane index, the 1236 * array element at index {@code i + N} is placed into the 1237 * resulting vector at lane index {@code N}. 1238 * 1239 * @param a the array 1240 * @param i the offset into the array 1241 * @return the vector loaded from an array 1242 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1243 * {@code i > a.length - this.length()} 1244 */ 1245 public abstract LongVector<S> fromArray(long[] a, int i); 1246 1247 /** 1248 * Loads a vector from an array starting at offset and using a mask. 1249 * <p> 1250 * For each vector lane, where {@code N} is the vector lane index, 1251 * if the mask lane at index {@code N} is set then the array element at 1252 * index {@code i + N} is placed into the resulting vector at lane index 1253 * {@code N}, otherwise the default element value is placed into the 1254 * resulting vector at lane index {@code N}. 1255 * 1256 * @param a the array 1257 * @param i the offset into the array 1258 * @param m the mask 1259 * @return the vector loaded from an array 1260 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1261 * for any vector lane index {@code N} where the mask at lane {@code N} 1262 * is set {@code i > a.length - N} 1263 */ 1264 public abstract LongVector<S> fromArray(long[] a, int i, Mask<Long, S> m); 1265 1266 /** 1267 * Loads a vector from an array using indexes obtained from an index 1268 * map. 1269 * <p> 1270 * For each vector lane, where {@code N} is the vector lane index, the 1271 * array element at index {@code i + indexMap[j + N]} is placed into the 1272 * resulting vector at lane index {@code N}. 1273 * 1274 * @param a the array 1275 * @param i the offset into the array, may be negative if relative 1276 * indexes in the index map compensate to produce a value within the 1277 * array bounds 1278 * @param indexMap the index map 1279 * @param j the offset into the index map 1280 * @return the vector loaded from an array 1281 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1282 * {@code j > indexMap.length - this.length()}, 1283 * or for any vector lane index {@code N} the result of 1284 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 1285 */ 1286 public LongVector<S> fromArray(long[] a, int i, int[] indexMap, int j) { 1287 return op(n -> a[i + indexMap[j + n]]); 1288 } 1289 1290 /** 1291 * Loads a vector from an array using indexes obtained from an index 1292 * map and using a mask. 1293 * <p> 1294 * For each vector lane, where {@code N} is the vector lane index, 1295 * if the mask lane at index {@code N} is set then the array element at 1296 * index {@code i + indexMap[j + N]} is placed into the resulting vector 1297 * at lane index {@code N}. 1298 * 1299 * @param a the array 1300 * @param i the offset into the array, may be negative if relative 1301 * indexes in the index map compensate to produce a value within the 1302 * array bounds 1303 * @param indexMap the index map 1304 * @param j the offset into the index map 1305 * @return the vector loaded from an array 1306 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1307 * {@code j > indexMap.length - this.length()}, 1308 * or for any vector lane index {@code N} where the mask at lane 1309 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1310 * {@code < 0} or {@code >= a.length} 1311 */ 1312 public LongVector<S> fromArray(long[] a, int i, Mask<Long, S> m, int[] indexMap, int j) { 1313 return op(m, n -> a[i + indexMap[j + n]]); 1314 } 1315 1316 @Override 1317 public abstract LongVector<S> fromByteArray(byte[] a, int ix); 1318 1319 @Override 1320 public abstract LongVector<S> fromByteArray(byte[] a, int ix, Mask<Long, S> m); 1321 1322 @Override 1323 public abstract LongVector<S> fromByteBuffer(ByteBuffer bb, int ix); 1324 1325 @Override 1326 public abstract LongVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Long, S> m); 1327 1328 @Override 1329 public <F, T extends Shape> LongVector<S> reshape(Vector<F, T> o) { 1330 int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE; 1331 ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder()); 1332 o.intoByteBuffer(bb, 0); 1333 return fromByteBuffer(bb, 0); 1334 } 1335 1336 @Override 1337 public abstract <F> LongVector<S> rebracket(Vector<F, S> o); 1338 1339 @Override 1340 public abstract <T extends Shape> LongVector<S> resize(Vector<Long, T> o); 1341 1342 @Override 1343 public abstract <F, T extends Shape> LongVector<S> cast(Vector<F, T> v); 1344 1345 } 1346 1347 /** 1348 * Finds the preferred species for an element type of {@code long}. 1349 * <p> 1350 * A preferred species is a species chosen by the platform that has a 1351 * shape of maximal bit size. A preferred species for different element 1352 * types will have the same shape, and therefore vectors, masks, and 1353 * shuffles created from such species will be shape compatible. 1354 * 1355 * @return the preferred species for an element type of {@code long} 1356 */ 1357 @SuppressWarnings("unchecked") 1358 public static LongSpecies<?> preferredSpecies() { 1359 return (LongSpecies<?>) Vector.preferredSpecies(long.class); 1360 } 1361 1362 /** 1363 * Finds a species for an element type of {@code long} and shape. 1364 * 1365 * @param s the shape 1366 * @param <S> the type of shape 1367 * @return a species for an element type of {@code long} and shape 1368 * @throws IllegalArgumentException if no such species exists for the shape 1369 */ 1370 @SuppressWarnings("unchecked") 1371 public static <S extends Shape> LongSpecies<S> species(S s) { 1372 Objects.requireNonNull(s); 1373 if (s == Shapes.S_64_BIT) { 1374 return (LongSpecies<S>) Long64Vector.SPECIES; 1375 } else if (s == Shapes.S_128_BIT) { 1376 return (LongSpecies<S>) Long128Vector.SPECIES; 1377 } else if (s == Shapes.S_256_BIT) { 1378 return (LongSpecies<S>) Long256Vector.SPECIES; 1379 } else if (s == Shapes.S_512_BIT) { 1380 return (LongSpecies<S>) Long512Vector.SPECIES; 1381 } else { 1382 throw new IllegalArgumentException("Bad shape: " + s); 1383 } 1384 } 1385 }