1 /* 2 * Copyright (c) 2017, 2022, 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 any 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import java.nio.ByteBuffer; 28 import java.nio.ByteOrder; 29 import java.nio.ReadOnlyBufferException; 30 import java.util.Arrays; 31 import java.util.Objects; 32 import java.util.function.Function; 33 import java.util.function.UnaryOperator; 34 35 import jdk.internal.misc.ScopedMemoryAccess; 36 import jdk.internal.misc.Unsafe; 37 import jdk.internal.vm.annotation.ForceInline; 38 import jdk.internal.vm.vector.VectorSupport; 39 40 import static jdk.internal.vm.vector.VectorSupport.*; 41 import static jdk.incubator.vector.VectorIntrinsics.*; 42 43 import static jdk.incubator.vector.VectorOperators.*; 44 45 // -- This file was mechanically generated: Do not edit! -- // 46 47 /** 48 * A specialized {@link Vector} representing an ordered immutable sequence of 49 * {@code long} values. 50 */ 51 @SuppressWarnings("cast") // warning: redundant cast 52 public abstract class LongVector extends AbstractVector<Long> { 53 54 LongVector(long[] vec) { 55 super(vec); 56 } 57 58 static final int FORBID_OPCODE_KIND = VO_ONLYFP; 59 60 @ForceInline 61 static int opCode(Operator op) { 62 return VectorOperators.opCode(op, VO_OPCODE_VALID, FORBID_OPCODE_KIND); 63 } 64 @ForceInline 65 static int opCode(Operator op, int requireKind) { 66 requireKind |= VO_OPCODE_VALID; 67 return VectorOperators.opCode(op, requireKind, FORBID_OPCODE_KIND); 68 } 69 @ForceInline 70 static boolean opKind(Operator op, int bit) { 71 return VectorOperators.opKind(op, bit); 72 } 73 74 // Virtualized factories and operators, 75 // coded with portable definitions. 76 // These are all @ForceInline in case 77 // they need to be used performantly. 78 // The various shape-specific subclasses 79 // also specialize them by wrapping 80 // them in a call like this: 81 // return (Byte128Vector) 82 // super.bOp((Byte128Vector) o); 83 // The purpose of that is to forcibly inline 84 // the generic definition from this file 85 // into a sharply type- and size-specific 86 // wrapper in the subclass file, so that 87 // the JIT can specialize the code. 88 // The code is only inlined and expanded 89 // if it gets hot. Think of it as a cheap 90 // and lazy version of C++ templates. 91 92 // Virtualized getter 93 94 /*package-private*/ 95 abstract long[] vec(); 96 97 // Virtualized constructors 98 99 /** 100 * Build a vector directly using my own constructor. 101 * It is an error if the array is aliased elsewhere. 102 */ 103 /*package-private*/ 104 abstract LongVector vectorFactory(long[] vec); 105 106 /** 107 * Build a mask directly using my species. 108 * It is an error if the array is aliased elsewhere. 109 */ 110 /*package-private*/ 111 @ForceInline 112 final 113 AbstractMask<Long> maskFactory(boolean[] bits) { 114 return vspecies().maskFactory(bits); 115 } 116 117 // Constant loader (takes dummy as vector arg) 118 interface FVOp { 119 long apply(int i); 120 } 121 122 /*package-private*/ 123 @ForceInline 124 final 125 LongVector vOp(FVOp f) { 126 long[] res = new long[length()]; 127 for (int i = 0; i < res.length; i++) { 128 res[i] = f.apply(i); 129 } 130 return vectorFactory(res); 131 } 132 133 @ForceInline 134 final 135 LongVector vOp(VectorMask<Long> m, FVOp f) { 136 long[] res = new long[length()]; 137 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 138 for (int i = 0; i < res.length; i++) { 139 if (mbits[i]) { 140 res[i] = f.apply(i); 141 } 142 } 143 return vectorFactory(res); 144 } 145 146 // Unary operator 147 148 /*package-private*/ 149 interface FUnOp { 150 long apply(int i, long a); 151 } 152 153 /*package-private*/ 154 abstract 155 LongVector uOp(FUnOp f); 156 @ForceInline 157 final 158 LongVector uOpTemplate(FUnOp f) { 159 long[] vec = vec(); 160 long[] res = new long[length()]; 161 for (int i = 0; i < res.length; i++) { 162 res[i] = f.apply(i, vec[i]); 163 } 164 return vectorFactory(res); 165 } 166 167 /*package-private*/ 168 abstract 169 LongVector uOp(VectorMask<Long> m, 170 FUnOp f); 171 @ForceInline 172 final 173 LongVector uOpTemplate(VectorMask<Long> m, 174 FUnOp f) { 175 if (m == null) { 176 return uOpTemplate(f); 177 } 178 long[] vec = vec(); 179 long[] res = new long[length()]; 180 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 181 for (int i = 0; i < res.length; i++) { 182 res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i]; 183 } 184 return vectorFactory(res); 185 } 186 187 // Binary operator 188 189 /*package-private*/ 190 interface FBinOp { 191 long apply(int i, long a, long b); 192 } 193 194 /*package-private*/ 195 abstract 196 LongVector bOp(Vector<Long> o, 197 FBinOp f); 198 @ForceInline 199 final 200 LongVector bOpTemplate(Vector<Long> o, 201 FBinOp f) { 202 long[] res = new long[length()]; 203 long[] vec1 = this.vec(); 204 long[] vec2 = ((LongVector)o).vec(); 205 for (int i = 0; i < res.length; i++) { 206 res[i] = f.apply(i, vec1[i], vec2[i]); 207 } 208 return vectorFactory(res); 209 } 210 211 /*package-private*/ 212 abstract 213 LongVector bOp(Vector<Long> o, 214 VectorMask<Long> m, 215 FBinOp f); 216 @ForceInline 217 final 218 LongVector bOpTemplate(Vector<Long> o, 219 VectorMask<Long> m, 220 FBinOp f) { 221 if (m == null) { 222 return bOpTemplate(o, f); 223 } 224 long[] res = new long[length()]; 225 long[] vec1 = this.vec(); 226 long[] vec2 = ((LongVector)o).vec(); 227 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 228 for (int i = 0; i < res.length; i++) { 229 res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i]; 230 } 231 return vectorFactory(res); 232 } 233 234 // Ternary operator 235 236 /*package-private*/ 237 interface FTriOp { 238 long apply(int i, long a, long b, long c); 239 } 240 241 /*package-private*/ 242 abstract 243 LongVector tOp(Vector<Long> o1, 244 Vector<Long> o2, 245 FTriOp f); 246 @ForceInline 247 final 248 LongVector tOpTemplate(Vector<Long> o1, 249 Vector<Long> o2, 250 FTriOp f) { 251 long[] res = new long[length()]; 252 long[] vec1 = this.vec(); 253 long[] vec2 = ((LongVector)o1).vec(); 254 long[] vec3 = ((LongVector)o2).vec(); 255 for (int i = 0; i < res.length; i++) { 256 res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]); 257 } 258 return vectorFactory(res); 259 } 260 261 /*package-private*/ 262 abstract 263 LongVector tOp(Vector<Long> o1, 264 Vector<Long> o2, 265 VectorMask<Long> m, 266 FTriOp f); 267 @ForceInline 268 final 269 LongVector tOpTemplate(Vector<Long> o1, 270 Vector<Long> o2, 271 VectorMask<Long> m, 272 FTriOp f) { 273 if (m == null) { 274 return tOpTemplate(o1, o2, f); 275 } 276 long[] res = new long[length()]; 277 long[] vec1 = this.vec(); 278 long[] vec2 = ((LongVector)o1).vec(); 279 long[] vec3 = ((LongVector)o2).vec(); 280 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 281 for (int i = 0; i < res.length; i++) { 282 res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i]; 283 } 284 return vectorFactory(res); 285 } 286 287 // Reduction operator 288 289 /*package-private*/ 290 abstract 291 long rOp(long v, VectorMask<Long> m, FBinOp f); 292 293 @ForceInline 294 final 295 long rOpTemplate(long v, VectorMask<Long> m, FBinOp f) { 296 if (m == null) { 297 return rOpTemplate(v, f); 298 } 299 long[] vec = vec(); 300 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 301 for (int i = 0; i < vec.length; i++) { 302 v = mbits[i] ? f.apply(i, v, vec[i]) : v; 303 } 304 return v; 305 } 306 307 @ForceInline 308 final 309 long rOpTemplate(long v, FBinOp f) { 310 long[] vec = vec(); 311 for (int i = 0; i < vec.length; i++) { 312 v = f.apply(i, v, vec[i]); 313 } 314 return v; 315 } 316 317 // Memory reference 318 319 /*package-private*/ 320 interface FLdOp<M> { 321 long apply(M memory, int offset, int i); 322 } 323 324 /*package-private*/ 325 @ForceInline 326 final 327 <M> LongVector ldOp(M memory, int offset, 328 FLdOp<M> f) { 329 //dummy; no vec = vec(); 330 long[] res = new long[length()]; 331 for (int i = 0; i < res.length; i++) { 332 res[i] = f.apply(memory, offset, i); 333 } 334 return vectorFactory(res); 335 } 336 337 /*package-private*/ 338 @ForceInline 339 final 340 <M> LongVector ldOp(M memory, int offset, 341 VectorMask<Long> m, 342 FLdOp<M> f) { 343 //long[] vec = vec(); 344 long[] res = new long[length()]; 345 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 346 for (int i = 0; i < res.length; i++) { 347 if (mbits[i]) { 348 res[i] = f.apply(memory, offset, i); 349 } 350 } 351 return vectorFactory(res); 352 } 353 354 interface FStOp<M> { 355 void apply(M memory, int offset, int i, long a); 356 } 357 358 /*package-private*/ 359 @ForceInline 360 final 361 <M> void stOp(M memory, int offset, 362 FStOp<M> f) { 363 long[] vec = vec(); 364 for (int i = 0; i < vec.length; i++) { 365 f.apply(memory, offset, i, vec[i]); 366 } 367 } 368 369 /*package-private*/ 370 @ForceInline 371 final 372 <M> void stOp(M memory, int offset, 373 VectorMask<Long> m, 374 FStOp<M> f) { 375 long[] vec = vec(); 376 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 377 for (int i = 0; i < vec.length; i++) { 378 if (mbits[i]) { 379 f.apply(memory, offset, i, vec[i]); 380 } 381 } 382 } 383 384 // Binary test 385 386 /*package-private*/ 387 interface FBinTest { 388 boolean apply(int cond, int i, long a, long b); 389 } 390 391 /*package-private*/ 392 @ForceInline 393 final 394 AbstractMask<Long> bTest(int cond, 395 Vector<Long> o, 396 FBinTest f) { 397 long[] vec1 = vec(); 398 long[] vec2 = ((LongVector)o).vec(); 399 boolean[] bits = new boolean[length()]; 400 for (int i = 0; i < length(); i++){ 401 bits[i] = f.apply(cond, i, vec1[i], vec2[i]); 402 } 403 return maskFactory(bits); 404 } 405 406 /*package-private*/ 407 @ForceInline 408 static long rotateLeft(long a, int n) { 409 return Long.rotateLeft(a, n); 410 } 411 412 /*package-private*/ 413 @ForceInline 414 static long rotateRight(long a, int n) { 415 return Long.rotateRight(a, n); 416 } 417 418 /*package-private*/ 419 @Override 420 abstract LongSpecies vspecies(); 421 422 /*package-private*/ 423 @ForceInline 424 static long toBits(long e) { 425 return e; 426 } 427 428 /*package-private*/ 429 @ForceInline 430 static long fromBits(long bits) { 431 return ((long)bits); 432 } 433 434 // Static factories (other than memory operations) 435 436 // Note: A surprising behavior in javadoc 437 // sometimes makes a lone /** {@inheritDoc} */ 438 // comment drop the method altogether, 439 // apparently if the method mentions an 440 // parameter or return type of Vector<Long> 441 // instead of Vector<E> as originally specified. 442 // Adding an empty HTML fragment appears to 443 // nudge javadoc into providing the desired 444 // inherited documentation. We use the HTML 445 // comment <!--workaround--> for this. 446 447 /** 448 * Returns a vector of the given species 449 * where all lane elements are set to 450 * zero, the default primitive value. 451 * 452 * @param species species of the desired zero vector 453 * @return a zero vector 454 */ 455 @ForceInline 456 public static LongVector zero(VectorSpecies<Long> species) { 457 LongSpecies vsp = (LongSpecies) species; 458 return VectorSupport.fromBitsCoerced(vsp.vectorType(), long.class, species.length(), 459 0, MODE_BROADCAST, vsp, 460 ((bits_, s_) -> s_.rvOp(i -> bits_))); 461 } 462 463 /** 464 * Returns a vector of the same species as this one 465 * where all lane elements are set to 466 * the primitive value {@code e}. 467 * 468 * The contents of the current vector are discarded; 469 * only the species is relevant to this operation. 470 * 471 * <p> This method returns the value of this expression: 472 * {@code LongVector.broadcast(this.species(), e)}. 473 * 474 * @apiNote 475 * Unlike the similar method named {@code broadcast()} 476 * in the supertype {@code Vector}, this method does not 477 * need to validate its argument, and cannot throw 478 * {@code IllegalArgumentException}. This method is 479 * therefore preferable to the supertype method. 480 * 481 * @param e the value to broadcast 482 * @return a vector where all lane elements are set to 483 * the primitive value {@code e} 484 * @see #broadcast(VectorSpecies,long) 485 * @see Vector#broadcast(long) 486 * @see VectorSpecies#broadcast(long) 487 */ 488 public abstract LongVector broadcast(long e); 489 490 /** 491 * Returns a vector of the given species 492 * where all lane elements are set to 493 * the primitive value {@code e}. 494 * 495 * @param species species of the desired vector 496 * @param e the value to broadcast 497 * @return a vector where all lane elements are set to 498 * the primitive value {@code e} 499 * @see #broadcast(long) 500 * @see Vector#broadcast(long) 501 * @see VectorSpecies#broadcast(long) 502 */ 503 @ForceInline 504 public static LongVector broadcast(VectorSpecies<Long> species, long e) { 505 LongSpecies vsp = (LongSpecies) species; 506 return vsp.broadcast(e); 507 } 508 509 /*package-private*/ 510 @ForceInline 511 final LongVector broadcastTemplate(long e) { 512 LongSpecies vsp = vspecies(); 513 return vsp.broadcast(e); 514 } 515 516 517 // Unary lanewise support 518 519 /** 520 * {@inheritDoc} <!--workaround--> 521 */ 522 public abstract 523 LongVector lanewise(VectorOperators.Unary op); 524 525 @ForceInline 526 final 527 LongVector lanewiseTemplate(VectorOperators.Unary op) { 528 if (opKind(op, VO_SPECIAL)) { 529 if (op == ZOMO) { 530 return blend(broadcast(-1), compare(NE, 0)); 531 } 532 if (op == NOT) { 533 return broadcast(-1).lanewise(XOR, this); 534 } 535 } 536 int opc = opCode(op); 537 return VectorSupport.unaryOp( 538 opc, getClass(), null, long.class, length(), 539 this, null, 540 UN_IMPL.find(op, opc, LongVector::unaryOperations)); 541 } 542 543 /** 544 * {@inheritDoc} <!--workaround--> 545 */ 546 @Override 547 public abstract 548 LongVector lanewise(VectorOperators.Unary op, 549 VectorMask<Long> m); 550 @ForceInline 551 final 552 LongVector lanewiseTemplate(VectorOperators.Unary op, 553 Class<? extends VectorMask<Long>> maskClass, 554 VectorMask<Long> m) { 555 m.check(maskClass, this); 556 if (opKind(op, VO_SPECIAL)) { 557 if (op == ZOMO) { 558 return blend(broadcast(-1), compare(NE, 0, m)); 559 } 560 if (op == NOT) { 561 return lanewise(XOR, broadcast(-1), m); 562 } 563 } 564 int opc = opCode(op); 565 return VectorSupport.unaryOp( 566 opc, getClass(), maskClass, long.class, length(), 567 this, m, 568 UN_IMPL.find(op, opc, LongVector::unaryOperations)); 569 } 570 571 private static final 572 ImplCache<Unary, UnaryOperation<LongVector, VectorMask<Long>>> 573 UN_IMPL = new ImplCache<>(Unary.class, LongVector.class); 574 575 private static UnaryOperation<LongVector, VectorMask<Long>> unaryOperations(int opc_) { 576 switch (opc_) { 577 case VECTOR_OP_NEG: return (v0, m) -> 578 v0.uOp(m, (i, a) -> (long) -a); 579 case VECTOR_OP_ABS: return (v0, m) -> 580 v0.uOp(m, (i, a) -> (long) Math.abs(a)); 581 default: return null; 582 } 583 } 584 585 // Binary lanewise support 586 587 /** 588 * {@inheritDoc} <!--workaround--> 589 * @see #lanewise(VectorOperators.Binary,long) 590 * @see #lanewise(VectorOperators.Binary,long,VectorMask) 591 */ 592 @Override 593 public abstract 594 LongVector lanewise(VectorOperators.Binary op, 595 Vector<Long> v); 596 @ForceInline 597 final 598 LongVector lanewiseTemplate(VectorOperators.Binary op, 599 Vector<Long> v) { 600 LongVector that = (LongVector) v; 601 that.check(this); 602 603 if (opKind(op, VO_SPECIAL | VO_SHIFT)) { 604 if (op == FIRST_NONZERO) { 605 // FIXME: Support this in the JIT. 606 VectorMask<Long> thisNZ 607 = this.viewAsIntegralLanes().compare(NE, (long) 0); 608 that = that.blend((long) 0, thisNZ.cast(vspecies())); 609 op = OR_UNCHECKED; 610 } 611 if (opKind(op, VO_SHIFT)) { 612 // As per shift specification for Java, mask the shift count. 613 // This allows the JIT to ignore some ISA details. 614 that = that.lanewise(AND, SHIFT_MASK); 615 } 616 if (op == AND_NOT) { 617 // FIXME: Support this in the JIT. 618 that = that.lanewise(NOT); 619 op = AND; 620 } else if (op == DIV) { 621 VectorMask<Long> eqz = that.eq((long) 0); 622 if (eqz.anyTrue()) { 623 throw that.divZeroException(); 624 } 625 } 626 } 627 628 int opc = opCode(op); 629 return VectorSupport.binaryOp( 630 opc, getClass(), null, long.class, length(), 631 this, that, null, 632 BIN_IMPL.find(op, opc, LongVector::binaryOperations)); 633 } 634 635 /** 636 * {@inheritDoc} <!--workaround--> 637 * @see #lanewise(VectorOperators.Binary,long,VectorMask) 638 */ 639 @Override 640 public abstract 641 LongVector lanewise(VectorOperators.Binary op, 642 Vector<Long> v, 643 VectorMask<Long> m); 644 @ForceInline 645 final 646 LongVector lanewiseTemplate(VectorOperators.Binary op, 647 Class<? extends VectorMask<Long>> maskClass, 648 Vector<Long> v, VectorMask<Long> m) { 649 LongVector that = (LongVector) v; 650 that.check(this); 651 m.check(maskClass, this); 652 653 if (opKind(op, VO_SPECIAL | VO_SHIFT)) { 654 if (op == FIRST_NONZERO) { 655 // FIXME: Support this in the JIT. 656 VectorMask<Long> thisNZ 657 = this.viewAsIntegralLanes().compare(NE, (long) 0); 658 that = that.blend((long) 0, thisNZ.cast(vspecies())); 659 op = OR_UNCHECKED; 660 } 661 if (opKind(op, VO_SHIFT)) { 662 // As per shift specification for Java, mask the shift count. 663 // This allows the JIT to ignore some ISA details. 664 that = that.lanewise(AND, SHIFT_MASK); 665 } 666 if (op == AND_NOT) { 667 // FIXME: Support this in the JIT. 668 that = that.lanewise(NOT); 669 op = AND; 670 } else if (op == DIV) { 671 VectorMask<Long> eqz = that.eq((long)0); 672 if (eqz.and(m).anyTrue()) { 673 throw that.divZeroException(); 674 } 675 // suppress div/0 exceptions in unset lanes 676 that = that.lanewise(NOT, eqz); 677 } 678 } 679 680 int opc = opCode(op); 681 return VectorSupport.binaryOp( 682 opc, getClass(), maskClass, long.class, length(), 683 this, that, m, 684 BIN_IMPL.find(op, opc, LongVector::binaryOperations)); 685 } 686 687 private static final 688 ImplCache<Binary, BinaryOperation<LongVector, VectorMask<Long>>> 689 BIN_IMPL = new ImplCache<>(Binary.class, LongVector.class); 690 691 private static BinaryOperation<LongVector, VectorMask<Long>> binaryOperations(int opc_) { 692 switch (opc_) { 693 case VECTOR_OP_ADD: return (v0, v1, vm) -> 694 v0.bOp(v1, vm, (i, a, b) -> (long)(a + b)); 695 case VECTOR_OP_SUB: return (v0, v1, vm) -> 696 v0.bOp(v1, vm, (i, a, b) -> (long)(a - b)); 697 case VECTOR_OP_MUL: return (v0, v1, vm) -> 698 v0.bOp(v1, vm, (i, a, b) -> (long)(a * b)); 699 case VECTOR_OP_DIV: return (v0, v1, vm) -> 700 v0.bOp(v1, vm, (i, a, b) -> (long)(a / b)); 701 case VECTOR_OP_MAX: return (v0, v1, vm) -> 702 v0.bOp(v1, vm, (i, a, b) -> (long)Math.max(a, b)); 703 case VECTOR_OP_MIN: return (v0, v1, vm) -> 704 v0.bOp(v1, vm, (i, a, b) -> (long)Math.min(a, b)); 705 case VECTOR_OP_AND: return (v0, v1, vm) -> 706 v0.bOp(v1, vm, (i, a, b) -> (long)(a & b)); 707 case VECTOR_OP_OR: return (v0, v1, vm) -> 708 v0.bOp(v1, vm, (i, a, b) -> (long)(a | b)); 709 case VECTOR_OP_XOR: return (v0, v1, vm) -> 710 v0.bOp(v1, vm, (i, a, b) -> (long)(a ^ b)); 711 case VECTOR_OP_LSHIFT: return (v0, v1, vm) -> 712 v0.bOp(v1, vm, (i, a, n) -> (long)(a << n)); 713 case VECTOR_OP_RSHIFT: return (v0, v1, vm) -> 714 v0.bOp(v1, vm, (i, a, n) -> (long)(a >> n)); 715 case VECTOR_OP_URSHIFT: return (v0, v1, vm) -> 716 v0.bOp(v1, vm, (i, a, n) -> (long)((a & LSHR_SETUP_MASK) >>> n)); 717 case VECTOR_OP_LROTATE: return (v0, v1, vm) -> 718 v0.bOp(v1, vm, (i, a, n) -> rotateLeft(a, (int)n)); 719 case VECTOR_OP_RROTATE: return (v0, v1, vm) -> 720 v0.bOp(v1, vm, (i, a, n) -> rotateRight(a, (int)n)); 721 default: return null; 722 } 723 } 724 725 // FIXME: Maybe all of the public final methods in this file (the 726 // simple ones that just call lanewise) should be pushed down to 727 // the X-VectorBits template. They can't optimize properly at 728 // this level, and must rely on inlining. Does it work? 729 // (If it works, of course keep the code here.) 730 731 /** 732 * Combines the lane values of this vector 733 * with the value of a broadcast scalar. 734 * 735 * This is a lane-wise binary operation which applies 736 * the selected operation to each lane. 737 * The return value will be equal to this expression: 738 * {@code this.lanewise(op, this.broadcast(e))}. 739 * 740 * @param op the operation used to process lane values 741 * @param e the input scalar 742 * @return the result of applying the operation lane-wise 743 * to the two input vectors 744 * @throws UnsupportedOperationException if this vector does 745 * not support the requested operation 746 * @see #lanewise(VectorOperators.Binary,Vector) 747 * @see #lanewise(VectorOperators.Binary,long,VectorMask) 748 */ 749 @ForceInline 750 public final 751 LongVector lanewise(VectorOperators.Binary op, 752 long e) { 753 if (opKind(op, VO_SHIFT) && (long)(int)e == e) { 754 return lanewiseShift(op, (int) e); 755 } 756 if (op == AND_NOT) { 757 op = AND; e = (long) ~e; 758 } 759 return lanewise(op, broadcast(e)); 760 } 761 762 /** 763 * Combines the lane values of this vector 764 * with the value of a broadcast scalar, 765 * with selection of lane elements controlled by a mask. 766 * 767 * This is a masked lane-wise binary operation which applies 768 * the selected operation to each lane. 769 * The return value will be equal to this expression: 770 * {@code this.lanewise(op, this.broadcast(e), m)}. 771 * 772 * @param op the operation used to process lane values 773 * @param e the input scalar 774 * @param m the mask controlling lane selection 775 * @return the result of applying the operation lane-wise 776 * to the input vector and the scalar 777 * @throws UnsupportedOperationException if this vector does 778 * not support the requested operation 779 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 780 * @see #lanewise(VectorOperators.Binary,long) 781 */ 782 @ForceInline 783 public final 784 LongVector lanewise(VectorOperators.Binary op, 785 long e, 786 VectorMask<Long> m) { 787 if (opKind(op, VO_SHIFT) && (long)(int)e == e) { 788 return lanewiseShift(op, (int) e, m); 789 } 790 if (op == AND_NOT) { 791 op = AND; e = (long) ~e; 792 } 793 return lanewise(op, broadcast(e), m); 794 } 795 796 797 /*package-private*/ 798 abstract LongVector 799 lanewiseShift(VectorOperators.Binary op, int e); 800 801 /*package-private*/ 802 @ForceInline 803 final LongVector 804 lanewiseShiftTemplate(VectorOperators.Binary op, int e) { 805 // Special handling for these. FIXME: Refactor? 806 assert(opKind(op, VO_SHIFT)); 807 // As per shift specification for Java, mask the shift count. 808 e &= SHIFT_MASK; 809 int opc = opCode(op); 810 return VectorSupport.broadcastInt( 811 opc, getClass(), null, long.class, length(), 812 this, e, null, 813 BIN_INT_IMPL.find(op, opc, LongVector::broadcastIntOperations)); 814 } 815 816 /*package-private*/ 817 abstract LongVector 818 lanewiseShift(VectorOperators.Binary op, int e, VectorMask<Long> m); 819 820 /*package-private*/ 821 @ForceInline 822 final LongVector 823 lanewiseShiftTemplate(VectorOperators.Binary op, 824 Class<? extends VectorMask<Long>> maskClass, 825 int e, VectorMask<Long> m) { 826 m.check(maskClass, this); 827 assert(opKind(op, VO_SHIFT)); 828 // As per shift specification for Java, mask the shift count. 829 e &= SHIFT_MASK; 830 int opc = opCode(op); 831 return VectorSupport.broadcastInt( 832 opc, getClass(), maskClass, long.class, length(), 833 this, e, m, 834 BIN_INT_IMPL.find(op, opc, LongVector::broadcastIntOperations)); 835 } 836 837 private static final 838 ImplCache<Binary,VectorBroadcastIntOp<LongVector, VectorMask<Long>>> BIN_INT_IMPL 839 = new ImplCache<>(Binary.class, LongVector.class); 840 841 private static VectorBroadcastIntOp<LongVector, VectorMask<Long>> broadcastIntOperations(int opc_) { 842 switch (opc_) { 843 case VECTOR_OP_LSHIFT: return (v, n, m) -> 844 v.uOp(m, (i, a) -> (long)(a << n)); 845 case VECTOR_OP_RSHIFT: return (v, n, m) -> 846 v.uOp(m, (i, a) -> (long)(a >> n)); 847 case VECTOR_OP_URSHIFT: return (v, n, m) -> 848 v.uOp(m, (i, a) -> (long)((a & LSHR_SETUP_MASK) >>> n)); 849 case VECTOR_OP_LROTATE: return (v, n, m) -> 850 v.uOp(m, (i, a) -> rotateLeft(a, (int)n)); 851 case VECTOR_OP_RROTATE: return (v, n, m) -> 852 v.uOp(m, (i, a) -> rotateRight(a, (int)n)); 853 default: return null; 854 } 855 } 856 857 // As per shift specification for Java, mask the shift count. 858 // We mask 0X3F (long), 0X1F (int), 0x0F (short), 0x7 (byte). 859 // The latter two maskings go beyond the JLS, but seem reasonable 860 // since our lane types are first-class types, not just dressed 861 // up ints. 862 private static final int SHIFT_MASK = (Long.SIZE - 1); 863 private static final long LSHR_SETUP_MASK = -1; 864 865 // Ternary lanewise support 866 867 // Ternary operators come in eight variations: 868 // lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2]) 869 // lanewise(op, [broadcast(e1)|v1], [broadcast(e2)|v2], mask) 870 871 // It is annoying to support all of these variations of masking 872 // and broadcast, but it would be more surprising not to continue 873 // the obvious pattern started by unary and binary. 874 875 /** 876 * {@inheritDoc} <!--workaround--> 877 * @see #lanewise(VectorOperators.Ternary,long,long,VectorMask) 878 * @see #lanewise(VectorOperators.Ternary,Vector,long,VectorMask) 879 * @see #lanewise(VectorOperators.Ternary,long,Vector,VectorMask) 880 * @see #lanewise(VectorOperators.Ternary,long,long) 881 * @see #lanewise(VectorOperators.Ternary,Vector,long) 882 * @see #lanewise(VectorOperators.Ternary,long,Vector) 883 */ 884 @Override 885 public abstract 886 LongVector lanewise(VectorOperators.Ternary op, 887 Vector<Long> v1, 888 Vector<Long> v2); 889 @ForceInline 890 final 891 LongVector lanewiseTemplate(VectorOperators.Ternary op, 892 Vector<Long> v1, 893 Vector<Long> v2) { 894 LongVector that = (LongVector) v1; 895 LongVector tother = (LongVector) v2; 896 // It's a word: https://www.dictionary.com/browse/tother 897 // See also Chapter 11 of Dickens, Our Mutual Friend: 898 // "Totherest Governor," replied Mr Riderhood... 899 that.check(this); 900 tother.check(this); 901 if (op == BITWISE_BLEND) { 902 // FIXME: Support this in the JIT. 903 that = this.lanewise(XOR, that).lanewise(AND, tother); 904 return this.lanewise(XOR, that); 905 } 906 int opc = opCode(op); 907 return VectorSupport.ternaryOp( 908 opc, getClass(), null, long.class, length(), 909 this, that, tother, null, 910 TERN_IMPL.find(op, opc, LongVector::ternaryOperations)); 911 } 912 913 /** 914 * {@inheritDoc} <!--workaround--> 915 * @see #lanewise(VectorOperators.Ternary,long,long,VectorMask) 916 * @see #lanewise(VectorOperators.Ternary,Vector,long,VectorMask) 917 * @see #lanewise(VectorOperators.Ternary,long,Vector,VectorMask) 918 */ 919 @Override 920 public abstract 921 LongVector lanewise(VectorOperators.Ternary op, 922 Vector<Long> v1, 923 Vector<Long> v2, 924 VectorMask<Long> m); 925 @ForceInline 926 final 927 LongVector lanewiseTemplate(VectorOperators.Ternary op, 928 Class<? extends VectorMask<Long>> maskClass, 929 Vector<Long> v1, 930 Vector<Long> v2, 931 VectorMask<Long> m) { 932 LongVector that = (LongVector) v1; 933 LongVector tother = (LongVector) v2; 934 // It's a word: https://www.dictionary.com/browse/tother 935 // See also Chapter 11 of Dickens, Our Mutual Friend: 936 // "Totherest Governor," replied Mr Riderhood... 937 that.check(this); 938 tother.check(this); 939 m.check(maskClass, this); 940 941 if (op == BITWISE_BLEND) { 942 // FIXME: Support this in the JIT. 943 that = this.lanewise(XOR, that).lanewise(AND, tother); 944 return this.lanewise(XOR, that, m); 945 } 946 int opc = opCode(op); 947 return VectorSupport.ternaryOp( 948 opc, getClass(), maskClass, long.class, length(), 949 this, that, tother, m, 950 TERN_IMPL.find(op, opc, LongVector::ternaryOperations)); 951 } 952 953 private static final 954 ImplCache<Ternary, TernaryOperation<LongVector, VectorMask<Long>>> 955 TERN_IMPL = new ImplCache<>(Ternary.class, LongVector.class); 956 957 private static TernaryOperation<LongVector, VectorMask<Long>> ternaryOperations(int opc_) { 958 switch (opc_) { 959 default: return null; 960 } 961 } 962 963 /** 964 * Combines the lane values of this vector 965 * with the values of two broadcast scalars. 966 * 967 * This is a lane-wise ternary operation which applies 968 * the selected operation to each lane. 969 * The return value will be equal to this expression: 970 * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2))}. 971 * 972 * @param op the operation used to combine lane values 973 * @param e1 the first input scalar 974 * @param e2 the second input scalar 975 * @return the result of applying the operation lane-wise 976 * to the input vector and the scalars 977 * @throws UnsupportedOperationException if this vector does 978 * not support the requested operation 979 * @see #lanewise(VectorOperators.Ternary,Vector,Vector) 980 * @see #lanewise(VectorOperators.Ternary,long,long,VectorMask) 981 */ 982 @ForceInline 983 public final 984 LongVector lanewise(VectorOperators.Ternary op, //(op,e1,e2) 985 long e1, 986 long e2) { 987 return lanewise(op, broadcast(e1), broadcast(e2)); 988 } 989 990 /** 991 * Combines the lane values of this vector 992 * with the values of two broadcast scalars, 993 * with selection of lane elements controlled by a mask. 994 * 995 * This is a masked lane-wise ternary operation which applies 996 * the selected operation to each lane. 997 * The return value will be equal to this expression: 998 * {@code this.lanewise(op, this.broadcast(e1), this.broadcast(e2), m)}. 999 * 1000 * @param op the operation used to combine lane values 1001 * @param e1 the first input scalar 1002 * @param e2 the second input scalar 1003 * @param m the mask controlling lane selection 1004 * @return the result of applying the operation lane-wise 1005 * to the input vector and the scalars 1006 * @throws UnsupportedOperationException if this vector does 1007 * not support the requested operation 1008 * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask) 1009 * @see #lanewise(VectorOperators.Ternary,long,long) 1010 */ 1011 @ForceInline 1012 public final 1013 LongVector lanewise(VectorOperators.Ternary op, //(op,e1,e2,m) 1014 long e1, 1015 long e2, 1016 VectorMask<Long> m) { 1017 return lanewise(op, broadcast(e1), broadcast(e2), m); 1018 } 1019 1020 /** 1021 * Combines the lane values of this vector 1022 * with the values of another vector and a broadcast scalar. 1023 * 1024 * This is a lane-wise ternary operation which applies 1025 * the selected operation to each lane. 1026 * The return value will be equal to this expression: 1027 * {@code this.lanewise(op, v1, this.broadcast(e2))}. 1028 * 1029 * @param op the operation used to combine lane values 1030 * @param v1 the other input vector 1031 * @param e2 the input scalar 1032 * @return the result of applying the operation lane-wise 1033 * to the input vectors and the scalar 1034 * @throws UnsupportedOperationException if this vector does 1035 * not support the requested operation 1036 * @see #lanewise(VectorOperators.Ternary,long,long) 1037 * @see #lanewise(VectorOperators.Ternary,Vector,long,VectorMask) 1038 */ 1039 @ForceInline 1040 public final 1041 LongVector lanewise(VectorOperators.Ternary op, //(op,v1,e2) 1042 Vector<Long> v1, 1043 long e2) { 1044 return lanewise(op, v1, broadcast(e2)); 1045 } 1046 1047 /** 1048 * Combines the lane values of this vector 1049 * with the values of another vector and a broadcast scalar, 1050 * with selection of lane elements controlled by a mask. 1051 * 1052 * This is a masked lane-wise ternary operation which applies 1053 * the selected operation to each lane. 1054 * The return value will be equal to this expression: 1055 * {@code this.lanewise(op, v1, this.broadcast(e2), m)}. 1056 * 1057 * @param op the operation used to combine lane values 1058 * @param v1 the other input vector 1059 * @param e2 the input scalar 1060 * @param m the mask controlling lane selection 1061 * @return the result of applying the operation lane-wise 1062 * to the input vectors and the scalar 1063 * @throws UnsupportedOperationException if this vector does 1064 * not support the requested operation 1065 * @see #lanewise(VectorOperators.Ternary,Vector,Vector) 1066 * @see #lanewise(VectorOperators.Ternary,long,long,VectorMask) 1067 * @see #lanewise(VectorOperators.Ternary,Vector,long) 1068 */ 1069 @ForceInline 1070 public final 1071 LongVector lanewise(VectorOperators.Ternary op, //(op,v1,e2,m) 1072 Vector<Long> v1, 1073 long e2, 1074 VectorMask<Long> m) { 1075 return lanewise(op, v1, broadcast(e2), m); 1076 } 1077 1078 /** 1079 * Combines the lane values of this vector 1080 * with the values of another vector and a broadcast scalar. 1081 * 1082 * This is a lane-wise ternary operation which applies 1083 * the selected operation to each lane. 1084 * The return value will be equal to this expression: 1085 * {@code this.lanewise(op, this.broadcast(e1), v2)}. 1086 * 1087 * @param op the operation used to combine lane values 1088 * @param e1 the input scalar 1089 * @param v2 the other input vector 1090 * @return the result of applying the operation lane-wise 1091 * to the input vectors and the scalar 1092 * @throws UnsupportedOperationException if this vector does 1093 * not support the requested operation 1094 * @see #lanewise(VectorOperators.Ternary,Vector,Vector) 1095 * @see #lanewise(VectorOperators.Ternary,long,Vector,VectorMask) 1096 */ 1097 @ForceInline 1098 public final 1099 LongVector lanewise(VectorOperators.Ternary op, //(op,e1,v2) 1100 long e1, 1101 Vector<Long> v2) { 1102 return lanewise(op, broadcast(e1), v2); 1103 } 1104 1105 /** 1106 * Combines the lane values of this vector 1107 * with the values of another vector and a broadcast scalar, 1108 * with selection of lane elements controlled by a mask. 1109 * 1110 * This is a masked lane-wise ternary operation which applies 1111 * the selected operation to each lane. 1112 * The return value will be equal to this expression: 1113 * {@code this.lanewise(op, this.broadcast(e1), v2, m)}. 1114 * 1115 * @param op the operation used to combine lane values 1116 * @param e1 the input scalar 1117 * @param v2 the other input vector 1118 * @param m the mask controlling lane selection 1119 * @return the result of applying the operation lane-wise 1120 * to the input vectors and the scalar 1121 * @throws UnsupportedOperationException if this vector does 1122 * not support the requested operation 1123 * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask) 1124 * @see #lanewise(VectorOperators.Ternary,long,Vector) 1125 */ 1126 @ForceInline 1127 public final 1128 LongVector lanewise(VectorOperators.Ternary op, //(op,e1,v2,m) 1129 long e1, 1130 Vector<Long> v2, 1131 VectorMask<Long> m) { 1132 return lanewise(op, broadcast(e1), v2, m); 1133 } 1134 1135 // (Thus endeth the Great and Mighty Ternary Ogdoad.) 1136 // https://en.wikipedia.org/wiki/Ogdoad 1137 1138 /// FULL-SERVICE BINARY METHODS: ADD, SUB, MUL, DIV 1139 // 1140 // These include masked and non-masked versions. 1141 // This subclass adds broadcast (masked or not). 1142 1143 /** 1144 * {@inheritDoc} <!--workaround--> 1145 * @see #add(long) 1146 */ 1147 @Override 1148 @ForceInline 1149 public final LongVector add(Vector<Long> v) { 1150 return lanewise(ADD, v); 1151 } 1152 1153 /** 1154 * Adds this vector to the broadcast of an input scalar. 1155 * 1156 * This is a lane-wise binary operation which applies 1157 * the primitive addition operation ({@code +}) to each lane. 1158 * 1159 * This method is also equivalent to the expression 1160 * {@link #lanewise(VectorOperators.Binary,long) 1161 * lanewise}{@code (}{@link VectorOperators#ADD 1162 * ADD}{@code , e)}. 1163 * 1164 * @param e the input scalar 1165 * @return the result of adding each lane of this vector to the scalar 1166 * @see #add(Vector) 1167 * @see #broadcast(long) 1168 * @see #add(long,VectorMask) 1169 * @see VectorOperators#ADD 1170 * @see #lanewise(VectorOperators.Binary,Vector) 1171 * @see #lanewise(VectorOperators.Binary,long) 1172 */ 1173 @ForceInline 1174 public final 1175 LongVector add(long e) { 1176 return lanewise(ADD, e); 1177 } 1178 1179 /** 1180 * {@inheritDoc} <!--workaround--> 1181 * @see #add(long,VectorMask) 1182 */ 1183 @Override 1184 @ForceInline 1185 public final LongVector add(Vector<Long> v, 1186 VectorMask<Long> m) { 1187 return lanewise(ADD, v, m); 1188 } 1189 1190 /** 1191 * Adds this vector to the broadcast of an input scalar, 1192 * selecting lane elements controlled by a mask. 1193 * 1194 * This is a masked lane-wise binary operation which applies 1195 * the primitive addition operation ({@code +}) to each lane. 1196 * 1197 * This method is also equivalent to the expression 1198 * {@link #lanewise(VectorOperators.Binary,long,VectorMask) 1199 * lanewise}{@code (}{@link VectorOperators#ADD 1200 * ADD}{@code , s, m)}. 1201 * 1202 * @param e the input scalar 1203 * @param m the mask controlling lane selection 1204 * @return the result of adding each lane of this vector to the scalar 1205 * @see #add(Vector,VectorMask) 1206 * @see #broadcast(long) 1207 * @see #add(long) 1208 * @see VectorOperators#ADD 1209 * @see #lanewise(VectorOperators.Binary,Vector) 1210 * @see #lanewise(VectorOperators.Binary,long) 1211 */ 1212 @ForceInline 1213 public final LongVector add(long e, 1214 VectorMask<Long> m) { 1215 return lanewise(ADD, e, m); 1216 } 1217 1218 /** 1219 * {@inheritDoc} <!--workaround--> 1220 * @see #sub(long) 1221 */ 1222 @Override 1223 @ForceInline 1224 public final LongVector sub(Vector<Long> v) { 1225 return lanewise(SUB, v); 1226 } 1227 1228 /** 1229 * Subtracts an input scalar from this vector. 1230 * 1231 * This is a masked lane-wise binary operation which applies 1232 * the primitive subtraction operation ({@code -}) to each lane. 1233 * 1234 * This method is also equivalent to the expression 1235 * {@link #lanewise(VectorOperators.Binary,long) 1236 * lanewise}{@code (}{@link VectorOperators#SUB 1237 * SUB}{@code , e)}. 1238 * 1239 * @param e the input scalar 1240 * @return the result of subtracting the scalar from each lane of this vector 1241 * @see #sub(Vector) 1242 * @see #broadcast(long) 1243 * @see #sub(long,VectorMask) 1244 * @see VectorOperators#SUB 1245 * @see #lanewise(VectorOperators.Binary,Vector) 1246 * @see #lanewise(VectorOperators.Binary,long) 1247 */ 1248 @ForceInline 1249 public final LongVector sub(long e) { 1250 return lanewise(SUB, e); 1251 } 1252 1253 /** 1254 * {@inheritDoc} <!--workaround--> 1255 * @see #sub(long,VectorMask) 1256 */ 1257 @Override 1258 @ForceInline 1259 public final LongVector sub(Vector<Long> v, 1260 VectorMask<Long> m) { 1261 return lanewise(SUB, v, m); 1262 } 1263 1264 /** 1265 * Subtracts an input scalar from this vector 1266 * under the control of a mask. 1267 * 1268 * This is a masked lane-wise binary operation which applies 1269 * the primitive subtraction operation ({@code -}) to each lane. 1270 * 1271 * This method is also equivalent to the expression 1272 * {@link #lanewise(VectorOperators.Binary,long,VectorMask) 1273 * lanewise}{@code (}{@link VectorOperators#SUB 1274 * SUB}{@code , s, m)}. 1275 * 1276 * @param e the input scalar 1277 * @param m the mask controlling lane selection 1278 * @return the result of subtracting the scalar from each lane of this vector 1279 * @see #sub(Vector,VectorMask) 1280 * @see #broadcast(long) 1281 * @see #sub(long) 1282 * @see VectorOperators#SUB 1283 * @see #lanewise(VectorOperators.Binary,Vector) 1284 * @see #lanewise(VectorOperators.Binary,long) 1285 */ 1286 @ForceInline 1287 public final LongVector sub(long e, 1288 VectorMask<Long> m) { 1289 return lanewise(SUB, e, m); 1290 } 1291 1292 /** 1293 * {@inheritDoc} <!--workaround--> 1294 * @see #mul(long) 1295 */ 1296 @Override 1297 @ForceInline 1298 public final LongVector mul(Vector<Long> v) { 1299 return lanewise(MUL, v); 1300 } 1301 1302 /** 1303 * Multiplies this vector by the broadcast of an input scalar. 1304 * 1305 * This is a lane-wise binary operation which applies 1306 * the primitive multiplication operation ({@code *}) to each lane. 1307 * 1308 * This method is also equivalent to the expression 1309 * {@link #lanewise(VectorOperators.Binary,long) 1310 * lanewise}{@code (}{@link VectorOperators#MUL 1311 * MUL}{@code , e)}. 1312 * 1313 * @param e the input scalar 1314 * @return the result of multiplying this vector by the given scalar 1315 * @see #mul(Vector) 1316 * @see #broadcast(long) 1317 * @see #mul(long,VectorMask) 1318 * @see VectorOperators#MUL 1319 * @see #lanewise(VectorOperators.Binary,Vector) 1320 * @see #lanewise(VectorOperators.Binary,long) 1321 */ 1322 @ForceInline 1323 public final LongVector mul(long e) { 1324 return lanewise(MUL, e); 1325 } 1326 1327 /** 1328 * {@inheritDoc} <!--workaround--> 1329 * @see #mul(long,VectorMask) 1330 */ 1331 @Override 1332 @ForceInline 1333 public final LongVector mul(Vector<Long> v, 1334 VectorMask<Long> m) { 1335 return lanewise(MUL, v, m); 1336 } 1337 1338 /** 1339 * Multiplies this vector by the broadcast of an input scalar, 1340 * selecting lane elements controlled by a mask. 1341 * 1342 * This is a masked lane-wise binary operation which applies 1343 * the primitive multiplication operation ({@code *}) to each lane. 1344 * 1345 * This method is also equivalent to the expression 1346 * {@link #lanewise(VectorOperators.Binary,long,VectorMask) 1347 * lanewise}{@code (}{@link VectorOperators#MUL 1348 * MUL}{@code , s, m)}. 1349 * 1350 * @param e the input scalar 1351 * @param m the mask controlling lane selection 1352 * @return the result of muling each lane of this vector to the scalar 1353 * @see #mul(Vector,VectorMask) 1354 * @see #broadcast(long) 1355 * @see #mul(long) 1356 * @see VectorOperators#MUL 1357 * @see #lanewise(VectorOperators.Binary,Vector) 1358 * @see #lanewise(VectorOperators.Binary,long) 1359 */ 1360 @ForceInline 1361 public final LongVector mul(long e, 1362 VectorMask<Long> m) { 1363 return lanewise(MUL, e, m); 1364 } 1365 1366 /** 1367 * {@inheritDoc} <!--workaround--> 1368 * @apiNote If there is a zero divisor, {@code 1369 * ArithmeticException} will be thrown. 1370 */ 1371 @Override 1372 @ForceInline 1373 public final LongVector div(Vector<Long> v) { 1374 return lanewise(DIV, v); 1375 } 1376 1377 /** 1378 * Divides this vector by the broadcast of an input scalar. 1379 * 1380 * This is a lane-wise binary operation which applies 1381 * the primitive division operation ({@code /}) to each lane. 1382 * 1383 * This method is also equivalent to the expression 1384 * {@link #lanewise(VectorOperators.Binary,long) 1385 * lanewise}{@code (}{@link VectorOperators#DIV 1386 * DIV}{@code , e)}. 1387 * 1388 * @apiNote If there is a zero divisor, {@code 1389 * ArithmeticException} will be thrown. 1390 * 1391 * @param e the input scalar 1392 * @return the result of dividing each lane of this vector by the scalar 1393 * @see #div(Vector) 1394 * @see #broadcast(long) 1395 * @see #div(long,VectorMask) 1396 * @see VectorOperators#DIV 1397 * @see #lanewise(VectorOperators.Binary,Vector) 1398 * @see #lanewise(VectorOperators.Binary,long) 1399 */ 1400 @ForceInline 1401 public final LongVector div(long e) { 1402 return lanewise(DIV, e); 1403 } 1404 1405 /** 1406 * {@inheritDoc} <!--workaround--> 1407 * @see #div(long,VectorMask) 1408 * @apiNote If there is a zero divisor, {@code 1409 * ArithmeticException} will be thrown. 1410 */ 1411 @Override 1412 @ForceInline 1413 public final LongVector div(Vector<Long> v, 1414 VectorMask<Long> m) { 1415 return lanewise(DIV, v, m); 1416 } 1417 1418 /** 1419 * Divides this vector by the broadcast of an input scalar, 1420 * selecting lane elements controlled by a mask. 1421 * 1422 * This is a masked lane-wise binary operation which applies 1423 * the primitive division operation ({@code /}) to each lane. 1424 * 1425 * This method is also equivalent to the expression 1426 * {@link #lanewise(VectorOperators.Binary,long,VectorMask) 1427 * lanewise}{@code (}{@link VectorOperators#DIV 1428 * DIV}{@code , s, m)}. 1429 * 1430 * @apiNote If there is a zero divisor, {@code 1431 * ArithmeticException} will be thrown. 1432 * 1433 * @param e the input scalar 1434 * @param m the mask controlling lane selection 1435 * @return the result of dividing each lane of this vector by the scalar 1436 * @see #div(Vector,VectorMask) 1437 * @see #broadcast(long) 1438 * @see #div(long) 1439 * @see VectorOperators#DIV 1440 * @see #lanewise(VectorOperators.Binary,Vector) 1441 * @see #lanewise(VectorOperators.Binary,long) 1442 */ 1443 @ForceInline 1444 public final LongVector div(long e, 1445 VectorMask<Long> m) { 1446 return lanewise(DIV, e, m); 1447 } 1448 1449 /// END OF FULL-SERVICE BINARY METHODS 1450 1451 /// SECOND-TIER BINARY METHODS 1452 // 1453 // There are no masked versions. 1454 1455 /** 1456 * {@inheritDoc} <!--workaround--> 1457 */ 1458 @Override 1459 @ForceInline 1460 public final LongVector min(Vector<Long> v) { 1461 return lanewise(MIN, v); 1462 } 1463 1464 // FIXME: "broadcast of an input scalar" is really wordy. Reduce? 1465 /** 1466 * Computes the smaller of this vector and the broadcast of an input scalar. 1467 * 1468 * This is a lane-wise binary operation which applies the 1469 * operation {@code Math.min()} to each pair of 1470 * corresponding lane values. 1471 * 1472 * This method is also equivalent to the expression 1473 * {@link #lanewise(VectorOperators.Binary,long) 1474 * lanewise}{@code (}{@link VectorOperators#MIN 1475 * MIN}{@code , e)}. 1476 * 1477 * @param e the input scalar 1478 * @return the result of multiplying this vector by the given scalar 1479 * @see #min(Vector) 1480 * @see #broadcast(long) 1481 * @see VectorOperators#MIN 1482 * @see #lanewise(VectorOperators.Binary,long,VectorMask) 1483 */ 1484 @ForceInline 1485 public final LongVector min(long e) { 1486 return lanewise(MIN, e); 1487 } 1488 1489 /** 1490 * {@inheritDoc} <!--workaround--> 1491 */ 1492 @Override 1493 @ForceInline 1494 public final LongVector max(Vector<Long> v) { 1495 return lanewise(MAX, v); 1496 } 1497 1498 /** 1499 * Computes the larger of this vector and the broadcast of an input scalar. 1500 * 1501 * This is a lane-wise binary operation which applies the 1502 * operation {@code Math.max()} to each pair of 1503 * corresponding lane values. 1504 * 1505 * This method is also equivalent to the expression 1506 * {@link #lanewise(VectorOperators.Binary,long) 1507 * lanewise}{@code (}{@link VectorOperators#MAX 1508 * MAX}{@code , e)}. 1509 * 1510 * @param e the input scalar 1511 * @return the result of multiplying this vector by the given scalar 1512 * @see #max(Vector) 1513 * @see #broadcast(long) 1514 * @see VectorOperators#MAX 1515 * @see #lanewise(VectorOperators.Binary,long,VectorMask) 1516 */ 1517 @ForceInline 1518 public final LongVector max(long e) { 1519 return lanewise(MAX, e); 1520 } 1521 1522 // common bitwise operators: and, or, not (with scalar versions) 1523 /** 1524 * Computes the bitwise logical conjunction ({@code &}) 1525 * of this vector and a second input vector. 1526 * 1527 * This is a lane-wise binary operation which applies the 1528 * the primitive bitwise "and" operation ({@code &}) 1529 * to each pair of corresponding lane values. 1530 * 1531 * This method is also equivalent to the expression 1532 * {@link #lanewise(VectorOperators.Binary,Vector) 1533 * lanewise}{@code (}{@link VectorOperators#AND 1534 * AND}{@code , v)}. 1535 * 1536 * <p> 1537 * This is not a full-service named operation like 1538 * {@link #add(Vector) add}. A masked version of 1539 * this operation is not directly available 1540 * but may be obtained via the masked version of 1541 * {@code lanewise}. 1542 * 1543 * @param v a second input vector 1544 * @return the bitwise {@code &} of this vector and the second input vector 1545 * @see #and(long) 1546 * @see #or(Vector) 1547 * @see #not() 1548 * @see VectorOperators#AND 1549 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1550 */ 1551 @ForceInline 1552 public final LongVector and(Vector<Long> v) { 1553 return lanewise(AND, v); 1554 } 1555 1556 /** 1557 * Computes the bitwise logical conjunction ({@code &}) 1558 * of this vector and a scalar. 1559 * 1560 * This is a lane-wise binary operation which applies the 1561 * the primitive bitwise "and" operation ({@code &}) 1562 * to each pair of corresponding lane values. 1563 * 1564 * This method is also equivalent to the expression 1565 * {@link #lanewise(VectorOperators.Binary,Vector) 1566 * lanewise}{@code (}{@link VectorOperators#AND 1567 * AND}{@code , e)}. 1568 * 1569 * @param e an input scalar 1570 * @return the bitwise {@code &} of this vector and scalar 1571 * @see #and(Vector) 1572 * @see VectorOperators#AND 1573 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1574 */ 1575 @ForceInline 1576 public final LongVector and(long e) { 1577 return lanewise(AND, e); 1578 } 1579 1580 /** 1581 * Computes the bitwise logical disjunction ({@code |}) 1582 * of this vector and a second input vector. 1583 * 1584 * This is a lane-wise binary operation which applies the 1585 * the primitive bitwise "or" operation ({@code |}) 1586 * to each pair of corresponding lane values. 1587 * 1588 * This method is also equivalent to the expression 1589 * {@link #lanewise(VectorOperators.Binary,Vector) 1590 * lanewise}{@code (}{@link VectorOperators#OR 1591 * AND}{@code , v)}. 1592 * 1593 * <p> 1594 * This is not a full-service named operation like 1595 * {@link #add(Vector) add}. A masked version of 1596 * this operation is not directly available 1597 * but may be obtained via the masked version of 1598 * {@code lanewise}. 1599 * 1600 * @param v a second input vector 1601 * @return the bitwise {@code |} of this vector and the second input vector 1602 * @see #or(long) 1603 * @see #and(Vector) 1604 * @see #not() 1605 * @see VectorOperators#OR 1606 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1607 */ 1608 @ForceInline 1609 public final LongVector or(Vector<Long> v) { 1610 return lanewise(OR, v); 1611 } 1612 1613 /** 1614 * Computes the bitwise logical disjunction ({@code |}) 1615 * of this vector and a scalar. 1616 * 1617 * This is a lane-wise binary operation which applies the 1618 * the primitive bitwise "or" operation ({@code |}) 1619 * to each pair of corresponding lane values. 1620 * 1621 * This method is also equivalent to the expression 1622 * {@link #lanewise(VectorOperators.Binary,Vector) 1623 * lanewise}{@code (}{@link VectorOperators#OR 1624 * OR}{@code , e)}. 1625 * 1626 * @param e an input scalar 1627 * @return the bitwise {@code |} of this vector and scalar 1628 * @see #or(Vector) 1629 * @see VectorOperators#OR 1630 * @see #lanewise(VectorOperators.Binary,Vector,VectorMask) 1631 */ 1632 @ForceInline 1633 public final LongVector or(long e) { 1634 return lanewise(OR, e); 1635 } 1636 1637 1638 1639 /// UNARY METHODS 1640 1641 /** 1642 * {@inheritDoc} <!--workaround--> 1643 */ 1644 @Override 1645 @ForceInline 1646 public final 1647 LongVector neg() { 1648 return lanewise(NEG); 1649 } 1650 1651 /** 1652 * {@inheritDoc} <!--workaround--> 1653 */ 1654 @Override 1655 @ForceInline 1656 public final 1657 LongVector abs() { 1658 return lanewise(ABS); 1659 } 1660 1661 // not (~) 1662 /** 1663 * Computes the bitwise logical complement ({@code ~}) 1664 * of this vector. 1665 * 1666 * This is a lane-wise binary operation which applies the 1667 * the primitive bitwise "not" operation ({@code ~}) 1668 * to each lane value. 1669 * 1670 * This method is also equivalent to the expression 1671 * {@link #lanewise(VectorOperators.Unary) 1672 * lanewise}{@code (}{@link VectorOperators#NOT 1673 * NOT}{@code )}. 1674 * 1675 * <p> 1676 * This is not a full-service named operation like 1677 * {@link #add(Vector) add}. A masked version of 1678 * this operation is not directly available 1679 * but may be obtained via the masked version of 1680 * {@code lanewise}. 1681 * 1682 * @return the bitwise complement {@code ~} of this vector 1683 * @see #and(Vector) 1684 * @see VectorOperators#NOT 1685 * @see #lanewise(VectorOperators.Unary,VectorMask) 1686 */ 1687 @ForceInline 1688 public final LongVector not() { 1689 return lanewise(NOT); 1690 } 1691 1692 1693 /// COMPARISONS 1694 1695 /** 1696 * {@inheritDoc} <!--workaround--> 1697 */ 1698 @Override 1699 @ForceInline 1700 public final 1701 VectorMask<Long> eq(Vector<Long> v) { 1702 return compare(EQ, v); 1703 } 1704 1705 /** 1706 * Tests if this vector is equal to an input scalar. 1707 * 1708 * This is a lane-wise binary test operation which applies 1709 * the primitive equals operation ({@code ==}) to each lane. 1710 * The result is the same as {@code compare(VectorOperators.Comparison.EQ, e)}. 1711 * 1712 * @param e the input scalar 1713 * @return the result mask of testing if this vector 1714 * is equal to {@code e} 1715 * @see #compare(VectorOperators.Comparison,long) 1716 */ 1717 @ForceInline 1718 public final 1719 VectorMask<Long> eq(long e) { 1720 return compare(EQ, e); 1721 } 1722 1723 /** 1724 * {@inheritDoc} <!--workaround--> 1725 */ 1726 @Override 1727 @ForceInline 1728 public final 1729 VectorMask<Long> lt(Vector<Long> v) { 1730 return compare(LT, v); 1731 } 1732 1733 /** 1734 * Tests if this vector is less than an input scalar. 1735 * 1736 * This is a lane-wise binary test operation which applies 1737 * the primitive less than operation ({@code <}) to each lane. 1738 * The result is the same as {@code compare(VectorOperators.LT, e)}. 1739 * 1740 * @param e the input scalar 1741 * @return the mask result of testing if this vector 1742 * is less than the input scalar 1743 * @see #compare(VectorOperators.Comparison,long) 1744 */ 1745 @ForceInline 1746 public final 1747 VectorMask<Long> lt(long e) { 1748 return compare(LT, e); 1749 } 1750 1751 /** 1752 * {@inheritDoc} <!--workaround--> 1753 */ 1754 @Override 1755 public abstract 1756 VectorMask<Long> test(VectorOperators.Test op); 1757 1758 /*package-private*/ 1759 @ForceInline 1760 final 1761 <M extends VectorMask<Long>> 1762 M testTemplate(Class<M> maskType, Test op) { 1763 LongSpecies vsp = vspecies(); 1764 if (opKind(op, VO_SPECIAL)) { 1765 VectorMask<Long> m; 1766 if (op == IS_DEFAULT) { 1767 m = compare(EQ, (long) 0); 1768 } else if (op == IS_NEGATIVE) { 1769 m = compare(LT, (long) 0); 1770 } 1771 else { 1772 throw new AssertionError(op); 1773 } 1774 return maskType.cast(m); 1775 } 1776 int opc = opCode(op); 1777 throw new AssertionError(op); 1778 } 1779 1780 /** 1781 * {@inheritDoc} <!--workaround--> 1782 */ 1783 @Override 1784 public abstract 1785 VectorMask<Long> test(VectorOperators.Test op, 1786 VectorMask<Long> m); 1787 1788 /*package-private*/ 1789 @ForceInline 1790 final 1791 <M extends VectorMask<Long>> 1792 M testTemplate(Class<M> maskType, Test op, M mask) { 1793 LongSpecies vsp = vspecies(); 1794 mask.check(maskType, this); 1795 if (opKind(op, VO_SPECIAL)) { 1796 VectorMask<Long> m = mask; 1797 if (op == IS_DEFAULT) { 1798 m = compare(EQ, (long) 0, m); 1799 } else if (op == IS_NEGATIVE) { 1800 m = compare(LT, (long) 0, m); 1801 } 1802 else { 1803 throw new AssertionError(op); 1804 } 1805 return maskType.cast(m); 1806 } 1807 int opc = opCode(op); 1808 throw new AssertionError(op); 1809 } 1810 1811 /** 1812 * {@inheritDoc} <!--workaround--> 1813 */ 1814 @Override 1815 public abstract 1816 VectorMask<Long> compare(VectorOperators.Comparison op, Vector<Long> v); 1817 1818 /*package-private*/ 1819 @ForceInline 1820 final 1821 <M extends VectorMask<Long>> 1822 M compareTemplate(Class<M> maskType, Comparison op, Vector<Long> v) { 1823 LongVector that = (LongVector) v; 1824 that.check(this); 1825 int opc = opCode(op); 1826 return VectorSupport.compare( 1827 opc, getClass(), maskType, long.class, length(), 1828 this, that, null, 1829 (cond, v0, v1, m1) -> { 1830 AbstractMask<Long> m 1831 = v0.bTest(cond, v1, (cond_, i, a, b) 1832 -> compareWithOp(cond, a, b)); 1833 @SuppressWarnings("unchecked") 1834 M m2 = (M) m; 1835 return m2; 1836 }); 1837 } 1838 1839 /*package-private*/ 1840 @ForceInline 1841 final 1842 <M extends VectorMask<Long>> 1843 M compareTemplate(Class<M> maskType, Comparison op, Vector<Long> v, M m) { 1844 LongVector that = (LongVector) v; 1845 that.check(this); 1846 m.check(maskType, this); 1847 int opc = opCode(op); 1848 return VectorSupport.compare( 1849 opc, getClass(), maskType, long.class, length(), 1850 this, that, m, 1851 (cond, v0, v1, m1) -> { 1852 AbstractMask<Long> cmpM 1853 = v0.bTest(cond, v1, (cond_, i, a, b) 1854 -> compareWithOp(cond, a, b)); 1855 @SuppressWarnings("unchecked") 1856 M m2 = (M) cmpM.and(m1); 1857 return m2; 1858 }); 1859 } 1860 1861 @ForceInline 1862 private static boolean compareWithOp(int cond, long a, long b) { 1863 return switch (cond) { 1864 case BT_eq -> a == b; 1865 case BT_ne -> a != b; 1866 case BT_lt -> a < b; 1867 case BT_le -> a <= b; 1868 case BT_gt -> a > b; 1869 case BT_ge -> a >= b; 1870 case BT_ult -> Long.compareUnsigned(a, b) < 0; 1871 case BT_ule -> Long.compareUnsigned(a, b) <= 0; 1872 case BT_ugt -> Long.compareUnsigned(a, b) > 0; 1873 case BT_uge -> Long.compareUnsigned(a, b) >= 0; 1874 default -> throw new AssertionError(); 1875 }; 1876 } 1877 1878 /** 1879 * Tests this vector by comparing it with an input scalar, 1880 * according to the given comparison operation. 1881 * 1882 * This is a lane-wise binary test operation which applies 1883 * the comparison operation to each lane. 1884 * <p> 1885 * The result is the same as 1886 * {@code compare(op, broadcast(species(), e))}. 1887 * That is, the scalar may be regarded as broadcast to 1888 * a vector of the same species, and then compared 1889 * against the original vector, using the selected 1890 * comparison operation. 1891 * 1892 * @param op the operation used to compare lane values 1893 * @param e the input scalar 1894 * @return the mask result of testing lane-wise if this vector 1895 * compares to the input, according to the selected 1896 * comparison operator 1897 * @see LongVector#compare(VectorOperators.Comparison,Vector) 1898 * @see #eq(long) 1899 * @see #lt(long) 1900 */ 1901 public abstract 1902 VectorMask<Long> compare(Comparison op, long e); 1903 1904 /*package-private*/ 1905 @ForceInline 1906 final 1907 <M extends VectorMask<Long>> 1908 M compareTemplate(Class<M> maskType, Comparison op, long e) { 1909 return compareTemplate(maskType, op, broadcast(e)); 1910 } 1911 1912 /** 1913 * Tests this vector by comparing it with an input scalar, 1914 * according to the given comparison operation, 1915 * in lanes selected by a mask. 1916 * 1917 * This is a masked lane-wise binary test operation which applies 1918 * to each pair of corresponding lane values. 1919 * 1920 * The returned result is equal to the expression 1921 * {@code compare(op,s).and(m)}. 1922 * 1923 * @param op the operation used to compare lane values 1924 * @param e the input scalar 1925 * @param m the mask controlling lane selection 1926 * @return the mask result of testing lane-wise if this vector 1927 * compares to the input, according to the selected 1928 * comparison operator, 1929 * and only in the lanes selected by the mask 1930 * @see LongVector#compare(VectorOperators.Comparison,Vector,VectorMask) 1931 */ 1932 @ForceInline 1933 public final VectorMask<Long> compare(VectorOperators.Comparison op, 1934 long e, 1935 VectorMask<Long> m) { 1936 return compare(op, broadcast(e), m); 1937 } 1938 1939 1940 /** 1941 * {@inheritDoc} <!--workaround--> 1942 */ 1943 @Override public abstract 1944 LongVector blend(Vector<Long> v, VectorMask<Long> m); 1945 1946 /*package-private*/ 1947 @ForceInline 1948 final 1949 <M extends VectorMask<Long>> 1950 LongVector 1951 blendTemplate(Class<M> maskType, LongVector v, M m) { 1952 v.check(this); 1953 return VectorSupport.blend( 1954 getClass(), maskType, long.class, length(), 1955 this, v, m, 1956 (v0, v1, m_) -> v0.bOp(v1, m_, (i, a, b) -> b)); 1957 } 1958 1959 /** 1960 * {@inheritDoc} <!--workaround--> 1961 */ 1962 @Override public abstract LongVector addIndex(int scale); 1963 1964 /*package-private*/ 1965 @ForceInline 1966 final LongVector addIndexTemplate(int scale) { 1967 LongSpecies vsp = vspecies(); 1968 // make sure VLENGTH*scale doesn't overflow: 1969 vsp.checkScale(scale); 1970 return VectorSupport.indexVector( 1971 getClass(), long.class, length(), 1972 this, scale, vsp, 1973 (v, scale_, s) 1974 -> { 1975 // If the platform doesn't support an INDEX 1976 // instruction directly, load IOTA from memory 1977 // and multiply. 1978 LongVector iota = s.iota(); 1979 long sc = (long) scale_; 1980 return v.add(sc == 1 ? iota : iota.mul(sc)); 1981 }); 1982 } 1983 1984 /** 1985 * Replaces selected lanes of this vector with 1986 * a scalar value 1987 * under the control of a mask. 1988 * 1989 * This is a masked lane-wise binary operation which 1990 * selects each lane value from one or the other input. 1991 * 1992 * The returned result is equal to the expression 1993 * {@code blend(broadcast(e),m)}. 1994 * 1995 * @param e the input scalar, containing the replacement lane value 1996 * @param m the mask controlling lane selection of the scalar 1997 * @return the result of blending the lane elements of this vector with 1998 * the scalar value 1999 */ 2000 @ForceInline 2001 public final LongVector blend(long e, 2002 VectorMask<Long> m) { 2003 return blend(broadcast(e), m); 2004 } 2005 2006 2007 /** 2008 * {@inheritDoc} <!--workaround--> 2009 */ 2010 @Override 2011 public abstract 2012 LongVector slice(int origin, Vector<Long> v1); 2013 2014 /*package-private*/ 2015 final 2016 @ForceInline 2017 LongVector sliceTemplate(int origin, Vector<Long> v1) { 2018 LongVector that = (LongVector) v1; 2019 that.check(this); 2020 Objects.checkIndex(origin, length() + 1); 2021 VectorShuffle<Long> iota = iotaShuffle(); 2022 VectorMask<Long> blendMask = iota.toVector().compare(VectorOperators.LT, (broadcast((long)(length() - origin)))); 2023 iota = iotaShuffle(origin, 1, true); 2024 return that.rearrange(iota).blend(this.rearrange(iota), blendMask); 2025 } 2026 2027 /** 2028 * {@inheritDoc} <!--workaround--> 2029 */ 2030 @Override 2031 @ForceInline 2032 public final 2033 LongVector slice(int origin, 2034 Vector<Long> w, 2035 VectorMask<Long> m) { 2036 return broadcast(0).blend(slice(origin, w), m); 2037 } 2038 2039 /** 2040 * {@inheritDoc} <!--workaround--> 2041 */ 2042 @Override 2043 public abstract 2044 LongVector slice(int origin); 2045 2046 /*package-private*/ 2047 final 2048 @ForceInline 2049 LongVector sliceTemplate(int origin) { 2050 Objects.checkIndex(origin, length() + 1); 2051 VectorShuffle<Long> iota = iotaShuffle(); 2052 VectorMask<Long> blendMask = iota.toVector().compare(VectorOperators.LT, (broadcast((long)(length() - origin)))); 2053 iota = iotaShuffle(origin, 1, true); 2054 return vspecies().zero().blend(this.rearrange(iota), blendMask); 2055 } 2056 2057 /** 2058 * {@inheritDoc} <!--workaround--> 2059 */ 2060 @Override 2061 public abstract 2062 LongVector unslice(int origin, Vector<Long> w, int part); 2063 2064 /*package-private*/ 2065 final 2066 @ForceInline 2067 LongVector 2068 unsliceTemplate(int origin, Vector<Long> w, int part) { 2069 LongVector that = (LongVector) w; 2070 that.check(this); 2071 Objects.checkIndex(origin, length() + 1); 2072 VectorShuffle<Long> iota = iotaShuffle(); 2073 VectorMask<Long> blendMask = iota.toVector().compare((part == 0) ? VectorOperators.GE : VectorOperators.LT, 2074 (broadcast((long)(origin)))); 2075 iota = iotaShuffle(-origin, 1, true); 2076 return that.blend(this.rearrange(iota), blendMask); 2077 } 2078 2079 /*package-private*/ 2080 final 2081 @ForceInline 2082 <M extends VectorMask<Long>> 2083 LongVector 2084 unsliceTemplate(Class<M> maskType, int origin, Vector<Long> w, int part, M m) { 2085 LongVector that = (LongVector) w; 2086 that.check(this); 2087 LongVector slice = that.sliceTemplate(origin, that); 2088 slice = slice.blendTemplate(maskType, this, m); 2089 return slice.unsliceTemplate(origin, w, part); 2090 } 2091 2092 /** 2093 * {@inheritDoc} <!--workaround--> 2094 */ 2095 @Override 2096 public abstract 2097 LongVector unslice(int origin, Vector<Long> w, int part, VectorMask<Long> m); 2098 2099 /** 2100 * {@inheritDoc} <!--workaround--> 2101 */ 2102 @Override 2103 public abstract 2104 LongVector unslice(int origin); 2105 2106 /*package-private*/ 2107 final 2108 @ForceInline 2109 LongVector 2110 unsliceTemplate(int origin) { 2111 Objects.checkIndex(origin, length() + 1); 2112 VectorShuffle<Long> iota = iotaShuffle(); 2113 VectorMask<Long> blendMask = iota.toVector().compare(VectorOperators.GE, 2114 (broadcast((long)(origin)))); 2115 iota = iotaShuffle(-origin, 1, true); 2116 return vspecies().zero().blend(this.rearrange(iota), blendMask); 2117 } 2118 2119 private ArrayIndexOutOfBoundsException 2120 wrongPartForSlice(int part) { 2121 String msg = String.format("bad part number %d for slice operation", 2122 part); 2123 return new ArrayIndexOutOfBoundsException(msg); 2124 } 2125 2126 /** 2127 * {@inheritDoc} <!--workaround--> 2128 */ 2129 @Override 2130 public abstract 2131 LongVector rearrange(VectorShuffle<Long> m); 2132 2133 /*package-private*/ 2134 @ForceInline 2135 final 2136 <S extends VectorShuffle<Long>> 2137 LongVector rearrangeTemplate(Class<S> shuffletype, S shuffle) { 2138 shuffle.checkIndexes(); 2139 return VectorSupport.rearrangeOp( 2140 getClass(), shuffletype, null, long.class, length(), 2141 this, shuffle, null, 2142 (v1, s_, m_) -> v1.uOp((i, a) -> { 2143 int ei = s_.laneSource(i); 2144 return v1.lane(ei); 2145 })); 2146 } 2147 2148 /** 2149 * {@inheritDoc} <!--workaround--> 2150 */ 2151 @Override 2152 public abstract 2153 LongVector rearrange(VectorShuffle<Long> s, 2154 VectorMask<Long> m); 2155 2156 /*package-private*/ 2157 @ForceInline 2158 final 2159 <S extends VectorShuffle<Long>, M extends VectorMask<Long>> 2160 LongVector rearrangeTemplate(Class<S> shuffletype, 2161 Class<M> masktype, 2162 S shuffle, 2163 M m) { 2164 2165 m.check(masktype, this); 2166 VectorMask<Long> valid = shuffle.laneIsValid(); 2167 if (m.andNot(valid).anyTrue()) { 2168 shuffle.checkIndexes(); 2169 throw new AssertionError(); 2170 } 2171 return VectorSupport.rearrangeOp( 2172 getClass(), shuffletype, masktype, long.class, length(), 2173 this, shuffle, m, 2174 (v1, s_, m_) -> v1.uOp((i, a) -> { 2175 int ei = s_.laneSource(i); 2176 return ei < 0 || !m_.laneIsSet(i) ? 0 : v1.lane(ei); 2177 })); 2178 } 2179 2180 /** 2181 * {@inheritDoc} <!--workaround--> 2182 */ 2183 @Override 2184 public abstract 2185 LongVector rearrange(VectorShuffle<Long> s, 2186 Vector<Long> v); 2187 2188 /*package-private*/ 2189 @ForceInline 2190 final 2191 <S extends VectorShuffle<Long>> 2192 LongVector rearrangeTemplate(Class<S> shuffletype, 2193 S shuffle, 2194 LongVector v) { 2195 VectorMask<Long> valid = shuffle.laneIsValid(); 2196 @SuppressWarnings("unchecked") 2197 S ws = (S) shuffle.wrapIndexes(); 2198 LongVector r0 = 2199 VectorSupport.rearrangeOp( 2200 getClass(), shuffletype, null, long.class, length(), 2201 this, ws, null, 2202 (v0, s_, m_) -> v0.uOp((i, a) -> { 2203 int ei = s_.laneSource(i); 2204 return v0.lane(ei); 2205 })); 2206 LongVector r1 = 2207 VectorSupport.rearrangeOp( 2208 getClass(), shuffletype, null, long.class, length(), 2209 v, ws, null, 2210 (v1, s_, m_) -> v1.uOp((i, a) -> { 2211 int ei = s_.laneSource(i); 2212 return v1.lane(ei); 2213 })); 2214 return r1.blend(r0, valid); 2215 } 2216 2217 @ForceInline 2218 private final 2219 VectorShuffle<Long> toShuffle0(LongSpecies dsp) { 2220 long[] a = toArray(); 2221 int[] sa = new int[a.length]; 2222 for (int i = 0; i < a.length; i++) { 2223 sa[i] = (int) a[i]; 2224 } 2225 return VectorShuffle.fromArray(dsp, sa, 0); 2226 } 2227 2228 /*package-private*/ 2229 @ForceInline 2230 final 2231 VectorShuffle<Long> toShuffleTemplate(Class<?> shuffleType) { 2232 LongSpecies vsp = vspecies(); 2233 return VectorSupport.convert(VectorSupport.VECTOR_OP_CAST, 2234 getClass(), long.class, length(), 2235 shuffleType, byte.class, length(), 2236 this, vsp, 2237 LongVector::toShuffle0); 2238 } 2239 2240 /** 2241 * {@inheritDoc} <!--workaround--> 2242 */ 2243 @Override 2244 public abstract 2245 LongVector selectFrom(Vector<Long> v); 2246 2247 /*package-private*/ 2248 @ForceInline 2249 final LongVector selectFromTemplate(LongVector v) { 2250 return v.rearrange(this.toShuffle()); 2251 } 2252 2253 /** 2254 * {@inheritDoc} <!--workaround--> 2255 */ 2256 @Override 2257 public abstract 2258 LongVector selectFrom(Vector<Long> s, VectorMask<Long> m); 2259 2260 /*package-private*/ 2261 @ForceInline 2262 final LongVector selectFromTemplate(LongVector v, 2263 AbstractMask<Long> m) { 2264 return v.rearrange(this.toShuffle(), m); 2265 } 2266 2267 /// Ternary operations 2268 2269 /** 2270 * Blends together the bits of two vectors under 2271 * the control of a third, which supplies mask bits. 2272 * 2273 * This is a lane-wise ternary operation which performs 2274 * a bitwise blending operation {@code (a&~c)|(b&c)} 2275 * to each lane. 2276 * 2277 * This method is also equivalent to the expression 2278 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2279 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2280 * BITWISE_BLEND}{@code , bits, mask)}. 2281 * 2282 * @param bits input bits to blend into the current vector 2283 * @param mask a bitwise mask to enable blending of the input bits 2284 * @return the bitwise blend of the given bits into the current vector, 2285 * under control of the bitwise mask 2286 * @see #bitwiseBlend(long,long) 2287 * @see #bitwiseBlend(long,Vector) 2288 * @see #bitwiseBlend(Vector,long) 2289 * @see VectorOperators#BITWISE_BLEND 2290 * @see #lanewise(VectorOperators.Ternary,Vector,Vector,VectorMask) 2291 */ 2292 @ForceInline 2293 public final 2294 LongVector bitwiseBlend(Vector<Long> bits, Vector<Long> mask) { 2295 return lanewise(BITWISE_BLEND, bits, mask); 2296 } 2297 2298 /** 2299 * Blends together the bits of a vector and a scalar under 2300 * the control of another scalar, which supplies mask bits. 2301 * 2302 * This is a lane-wise ternary operation which performs 2303 * a bitwise blending operation {@code (a&~c)|(b&c)} 2304 * to each lane. 2305 * 2306 * This method is also equivalent to the expression 2307 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2308 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2309 * BITWISE_BLEND}{@code , bits, mask)}. 2310 * 2311 * @param bits input bits to blend into the current vector 2312 * @param mask a bitwise mask to enable blending of the input bits 2313 * @return the bitwise blend of the given bits into the current vector, 2314 * under control of the bitwise mask 2315 * @see #bitwiseBlend(Vector,Vector) 2316 * @see VectorOperators#BITWISE_BLEND 2317 * @see #lanewise(VectorOperators.Ternary,long,long,VectorMask) 2318 */ 2319 @ForceInline 2320 public final 2321 LongVector bitwiseBlend(long bits, long mask) { 2322 return lanewise(BITWISE_BLEND, bits, mask); 2323 } 2324 2325 /** 2326 * Blends together the bits of a vector and a scalar under 2327 * the control of another vector, which supplies mask bits. 2328 * 2329 * This is a lane-wise ternary operation which performs 2330 * a bitwise blending operation {@code (a&~c)|(b&c)} 2331 * to each lane. 2332 * 2333 * This method is also equivalent to the expression 2334 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2335 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2336 * BITWISE_BLEND}{@code , bits, mask)}. 2337 * 2338 * @param bits input bits to blend into the current vector 2339 * @param mask a bitwise mask to enable blending of the input bits 2340 * @return the bitwise blend of the given bits into the current vector, 2341 * under control of the bitwise mask 2342 * @see #bitwiseBlend(Vector,Vector) 2343 * @see VectorOperators#BITWISE_BLEND 2344 * @see #lanewise(VectorOperators.Ternary,long,Vector,VectorMask) 2345 */ 2346 @ForceInline 2347 public final 2348 LongVector bitwiseBlend(long bits, Vector<Long> mask) { 2349 return lanewise(BITWISE_BLEND, bits, mask); 2350 } 2351 2352 /** 2353 * Blends together the bits of two vectors under 2354 * the control of a scalar, which supplies mask bits. 2355 * 2356 * This is a lane-wise ternary operation which performs 2357 * a bitwise blending operation {@code (a&~c)|(b&c)} 2358 * to each lane. 2359 * 2360 * This method is also equivalent to the expression 2361 * {@link #lanewise(VectorOperators.Ternary,Vector,Vector) 2362 * lanewise}{@code (}{@link VectorOperators#BITWISE_BLEND 2363 * BITWISE_BLEND}{@code , bits, mask)}. 2364 * 2365 * @param bits input bits to blend into the current vector 2366 * @param mask a bitwise mask to enable blending of the input bits 2367 * @return the bitwise blend of the given bits into the current vector, 2368 * under control of the bitwise mask 2369 * @see #bitwiseBlend(Vector,Vector) 2370 * @see VectorOperators#BITWISE_BLEND 2371 * @see #lanewise(VectorOperators.Ternary,Vector,long,VectorMask) 2372 */ 2373 @ForceInline 2374 public final 2375 LongVector bitwiseBlend(Vector<Long> bits, long mask) { 2376 return lanewise(BITWISE_BLEND, bits, mask); 2377 } 2378 2379 2380 // Type specific horizontal reductions 2381 2382 /** 2383 * Returns a value accumulated from all the lanes of this vector. 2384 * 2385 * This is an associative cross-lane reduction operation which 2386 * applies the specified operation to all the lane elements. 2387 * <p> 2388 * A few reduction operations do not support arbitrary reordering 2389 * of their operands, yet are included here because of their 2390 * usefulness. 2391 * <ul> 2392 * <li> 2393 * In the case of {@code FIRST_NONZERO}, the reduction returns 2394 * the value from the lowest-numbered non-zero lane. 2395 * <li> 2396 * All other reduction operations are fully commutative and 2397 * associative. The implementation can choose any order of 2398 * processing, yet it will always produce the same result. 2399 * </ul> 2400 * 2401 * @param op the operation used to combine lane values 2402 * @return the accumulated result 2403 * @throws UnsupportedOperationException if this vector does 2404 * not support the requested operation 2405 * @see #reduceLanes(VectorOperators.Associative,VectorMask) 2406 * @see #add(Vector) 2407 * @see #mul(Vector) 2408 * @see #min(Vector) 2409 * @see #max(Vector) 2410 * @see #and(Vector) 2411 * @see #or(Vector) 2412 * @see VectorOperators#XOR 2413 * @see VectorOperators#FIRST_NONZERO 2414 */ 2415 public abstract long reduceLanes(VectorOperators.Associative op); 2416 2417 /** 2418 * Returns a value accumulated from selected lanes of this vector, 2419 * controlled by a mask. 2420 * 2421 * This is an associative cross-lane reduction operation which 2422 * applies the specified operation to the selected lane elements. 2423 * <p> 2424 * If no elements are selected, an operation-specific identity 2425 * value is returned. 2426 * <ul> 2427 * <li> 2428 * If the operation is 2429 * {@code ADD}, {@code XOR}, {@code OR}, 2430 * or {@code FIRST_NONZERO}, 2431 * then the identity value is zero, the default {@code long} value. 2432 * <li> 2433 * If the operation is {@code MUL}, 2434 * then the identity value is one. 2435 * <li> 2436 * If the operation is {@code AND}, 2437 * then the identity value is minus one (all bits set). 2438 * <li> 2439 * If the operation is {@code MAX}, 2440 * then the identity value is {@code Long.MIN_VALUE}. 2441 * <li> 2442 * If the operation is {@code MIN}, 2443 * then the identity value is {@code Long.MAX_VALUE}. 2444 * </ul> 2445 * <p> 2446 * A few reduction operations do not support arbitrary reordering 2447 * of their operands, yet are included here because of their 2448 * usefulness. 2449 * <ul> 2450 * <li> 2451 * In the case of {@code FIRST_NONZERO}, the reduction returns 2452 * the value from the lowest-numbered non-zero lane. 2453 * <li> 2454 * All other reduction operations are fully commutative and 2455 * associative. The implementation can choose any order of 2456 * processing, yet it will always produce the same result. 2457 * </ul> 2458 * 2459 * @param op the operation used to combine lane values 2460 * @param m the mask controlling lane selection 2461 * @return the reduced result accumulated from the selected lane values 2462 * @throws UnsupportedOperationException if this vector does 2463 * not support the requested operation 2464 * @see #reduceLanes(VectorOperators.Associative) 2465 */ 2466 public abstract long reduceLanes(VectorOperators.Associative op, 2467 VectorMask<Long> m); 2468 2469 /*package-private*/ 2470 @ForceInline 2471 final 2472 long reduceLanesTemplate(VectorOperators.Associative op, 2473 Class<? extends VectorMask<Long>> maskClass, 2474 VectorMask<Long> m) { 2475 m.check(maskClass, this); 2476 if (op == FIRST_NONZERO) { 2477 // FIXME: The JIT should handle this. 2478 LongVector v = broadcast((long) 0).blend(this, m); 2479 return v.reduceLanesTemplate(op); 2480 } 2481 int opc = opCode(op); 2482 return fromBits(VectorSupport.reductionCoerced( 2483 opc, getClass(), maskClass, long.class, length(), 2484 this, m, 2485 REDUCE_IMPL.find(op, opc, LongVector::reductionOperations))); 2486 } 2487 2488 /*package-private*/ 2489 @ForceInline 2490 final 2491 long reduceLanesTemplate(VectorOperators.Associative op) { 2492 if (op == FIRST_NONZERO) { 2493 // FIXME: The JIT should handle this. 2494 VectorMask<Long> thisNZ 2495 = this.viewAsIntegralLanes().compare(NE, (long) 0); 2496 int ft = thisNZ.firstTrue(); 2497 return ft < length() ? this.lane(ft) : (long) 0; 2498 } 2499 int opc = opCode(op); 2500 return fromBits(VectorSupport.reductionCoerced( 2501 opc, getClass(), null, long.class, length(), 2502 this, null, 2503 REDUCE_IMPL.find(op, opc, LongVector::reductionOperations))); 2504 } 2505 2506 private static final 2507 ImplCache<Associative, ReductionOperation<LongVector, VectorMask<Long>>> 2508 REDUCE_IMPL = new ImplCache<>(Associative.class, LongVector.class); 2509 2510 private static ReductionOperation<LongVector, VectorMask<Long>> reductionOperations(int opc_) { 2511 switch (opc_) { 2512 case VECTOR_OP_ADD: return (v, m) -> 2513 toBits(v.rOp((long)0, m, (i, a, b) -> (long)(a + b))); 2514 case VECTOR_OP_MUL: return (v, m) -> 2515 toBits(v.rOp((long)1, m, (i, a, b) -> (long)(a * b))); 2516 case VECTOR_OP_MIN: return (v, m) -> 2517 toBits(v.rOp(MAX_OR_INF, m, (i, a, b) -> (long) Math.min(a, b))); 2518 case VECTOR_OP_MAX: return (v, m) -> 2519 toBits(v.rOp(MIN_OR_INF, m, (i, a, b) -> (long) Math.max(a, b))); 2520 case VECTOR_OP_AND: return (v, m) -> 2521 toBits(v.rOp((long)-1, m, (i, a, b) -> (long)(a & b))); 2522 case VECTOR_OP_OR: return (v, m) -> 2523 toBits(v.rOp((long)0, m, (i, a, b) -> (long)(a | b))); 2524 case VECTOR_OP_XOR: return (v, m) -> 2525 toBits(v.rOp((long)0, m, (i, a, b) -> (long)(a ^ b))); 2526 default: return null; 2527 } 2528 } 2529 2530 private static final long MIN_OR_INF = Long.MIN_VALUE; 2531 private static final long MAX_OR_INF = Long.MAX_VALUE; 2532 2533 public @Override abstract long reduceLanesToLong(VectorOperators.Associative op); 2534 public @Override abstract long reduceLanesToLong(VectorOperators.Associative op, 2535 VectorMask<Long> m); 2536 2537 // Type specific accessors 2538 2539 /** 2540 * Gets the lane element at lane index {@code i} 2541 * 2542 * @param i the lane index 2543 * @return the lane element at lane index {@code i} 2544 * @throws IllegalArgumentException if the index is is out of range 2545 * ({@code < 0 || >= length()}) 2546 */ 2547 public abstract long lane(int i); 2548 2549 /** 2550 * Replaces the lane element of this vector at lane index {@code i} with 2551 * value {@code e}. 2552 * 2553 * This is a cross-lane operation and behaves as if it returns the result 2554 * of blending this vector with an input vector that is the result of 2555 * broadcasting {@code e} and a mask that has only one lane set at lane 2556 * index {@code i}. 2557 * 2558 * @param i the lane index of the lane element to be replaced 2559 * @param e the value to be placed 2560 * @return the result of replacing the lane element of this vector at lane 2561 * index {@code i} with value {@code e}. 2562 * @throws IllegalArgumentException if the index is is out of range 2563 * ({@code < 0 || >= length()}) 2564 */ 2565 public abstract LongVector withLane(int i, long e); 2566 2567 // Memory load operations 2568 2569 /** 2570 * Returns an array of type {@code long[]} 2571 * containing all the lane values. 2572 * The array length is the same as the vector length. 2573 * The array elements are stored in lane order. 2574 * <p> 2575 * This method behaves as if it stores 2576 * this vector into an allocated array 2577 * (using {@link #intoArray(long[], int) intoArray}) 2578 * and returns the array as follows: 2579 * <pre>{@code 2580 * long[] a = new long[this.length()]; 2581 * this.intoArray(a, 0); 2582 * return a; 2583 * }</pre> 2584 * 2585 * @return an array containing the lane values of this vector 2586 */ 2587 @ForceInline 2588 @Override 2589 public final long[] toArray() { 2590 long[] a = new long[vspecies().laneCount()]; 2591 intoArray(a, 0); 2592 return a; 2593 } 2594 2595 /** {@inheritDoc} <!--workaround--> 2596 */ 2597 @ForceInline 2598 @Override 2599 public final int[] toIntArray() { 2600 long[] a = toArray(); 2601 int[] res = new int[a.length]; 2602 for (int i = 0; i < a.length; i++) { 2603 long e = a[i]; 2604 res[i] = (int) LongSpecies.toIntegralChecked(e, true); 2605 } 2606 return res; 2607 } 2608 2609 /** 2610 * {@inheritDoc} <!--workaround--> 2611 * This is an alias for {@link #toArray()} 2612 * When this method is used on used on vectors 2613 * of type {@code LongVector}, 2614 * there will be no loss of range or precision. 2615 */ 2616 @ForceInline 2617 @Override 2618 public final long[] toLongArray() { 2619 return toArray(); 2620 } 2621 2622 /** {@inheritDoc} <!--workaround--> 2623 * @implNote 2624 * When this method is used on used on vectors 2625 * of type {@code LongVector}, 2626 * up to nine bits of precision may be lost 2627 * for lane values of large magnitude. 2628 */ 2629 @ForceInline 2630 @Override 2631 public final double[] toDoubleArray() { 2632 long[] a = toArray(); 2633 double[] res = new double[a.length]; 2634 for (int i = 0; i < a.length; i++) { 2635 res[i] = (double) a[i]; 2636 } 2637 return res; 2638 } 2639 2640 /** 2641 * Loads a vector from a byte array starting at an offset. 2642 * Bytes are composed into primitive lane elements according 2643 * to the specified byte order. 2644 * The vector is arranged into lanes according to 2645 * <a href="Vector.html#lane-order">memory ordering</a>. 2646 * <p> 2647 * This method behaves as if it returns the result of calling 2648 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2649 * fromByteBuffer()} as follows: 2650 * <pre>{@code 2651 * var bb = ByteBuffer.wrap(a); 2652 * var m = species.maskAll(true); 2653 * return fromByteBuffer(species, bb, offset, bo, m); 2654 * }</pre> 2655 * 2656 * @param species species of desired vector 2657 * @param a the byte array 2658 * @param offset the offset into the array 2659 * @param bo the intended byte order 2660 * @return a vector loaded from a byte array 2661 * @throws IndexOutOfBoundsException 2662 * if {@code offset+N*ESIZE < 0} 2663 * or {@code offset+(N+1)*ESIZE > a.length} 2664 * for any lane {@code N} in the vector 2665 */ 2666 @ForceInline 2667 public static 2668 LongVector fromByteArray(VectorSpecies<Long> species, 2669 byte[] a, int offset, 2670 ByteOrder bo) { 2671 offset = checkFromIndexSize(offset, species.vectorByteSize(), a.length); 2672 LongSpecies vsp = (LongSpecies) species; 2673 return vsp.dummyVector().fromByteArray0(a, offset).maybeSwap(bo); 2674 } 2675 2676 /** 2677 * Loads a vector from a byte array starting at an offset 2678 * and using a mask. 2679 * Lanes where the mask is unset are filled with the default 2680 * value of {@code long} (zero). 2681 * Bytes are composed into primitive lane elements according 2682 * to the specified byte order. 2683 * The vector is arranged into lanes according to 2684 * <a href="Vector.html#lane-order">memory ordering</a>. 2685 * <p> 2686 * This method behaves as if it returns the result of calling 2687 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2688 * fromByteBuffer()} as follows: 2689 * <pre>{@code 2690 * var bb = ByteBuffer.wrap(a); 2691 * return fromByteBuffer(species, bb, offset, bo, m); 2692 * }</pre> 2693 * 2694 * @param species species of desired vector 2695 * @param a the byte array 2696 * @param offset the offset into the array 2697 * @param bo the intended byte order 2698 * @param m the mask controlling lane selection 2699 * @return a vector loaded from a byte array 2700 * @throws IndexOutOfBoundsException 2701 * if {@code offset+N*ESIZE < 0} 2702 * or {@code offset+(N+1)*ESIZE > a.length} 2703 * for any lane {@code N} in the vector 2704 * where the mask is set 2705 */ 2706 @ForceInline 2707 public static 2708 LongVector fromByteArray(VectorSpecies<Long> species, 2709 byte[] a, int offset, 2710 ByteOrder bo, 2711 VectorMask<Long> m) { 2712 LongSpecies vsp = (LongSpecies) species; 2713 if (offset >= 0 && offset <= (a.length - species.vectorByteSize())) { 2714 return vsp.dummyVector().fromByteArray0(a, offset, m).maybeSwap(bo); 2715 } 2716 2717 // FIXME: optimize 2718 checkMaskFromIndexSize(offset, vsp, m, 8, a.length); 2719 ByteBuffer wb = wrapper(a, bo); 2720 return vsp.ldOp(wb, offset, (AbstractMask<Long>)m, 2721 (wb_, o, i) -> wb_.getLong(o + i * 8)); 2722 } 2723 2724 /** 2725 * Loads a vector from an array of type {@code long[]} 2726 * starting at an offset. 2727 * For each vector lane, where {@code N} is the vector lane index, the 2728 * array element at index {@code offset + N} is placed into the 2729 * resulting vector at lane index {@code N}. 2730 * 2731 * @param species species of desired vector 2732 * @param a the array 2733 * @param offset the offset into the array 2734 * @return the vector loaded from an array 2735 * @throws IndexOutOfBoundsException 2736 * if {@code offset+N < 0} or {@code offset+N >= a.length} 2737 * for any lane {@code N} in the vector 2738 */ 2739 @ForceInline 2740 public static 2741 LongVector fromArray(VectorSpecies<Long> species, 2742 long[] a, int offset) { 2743 offset = checkFromIndexSize(offset, species.length(), a.length); 2744 LongSpecies vsp = (LongSpecies) species; 2745 return vsp.dummyVector().fromArray0(a, offset); 2746 } 2747 2748 /** 2749 * Loads a vector from an array of type {@code long[]} 2750 * starting at an offset and using a mask. 2751 * Lanes where the mask is unset are filled with the default 2752 * value of {@code long} (zero). 2753 * For each vector lane, where {@code N} is the vector lane index, 2754 * if the mask lane at index {@code N} is set then the array element at 2755 * index {@code offset + N} is placed into the resulting vector at lane index 2756 * {@code N}, otherwise the default element value is placed into the 2757 * resulting vector at lane index {@code N}. 2758 * 2759 * @param species species of desired vector 2760 * @param a the array 2761 * @param offset the offset into the array 2762 * @param m the mask controlling lane selection 2763 * @return the vector loaded from an array 2764 * @throws IndexOutOfBoundsException 2765 * if {@code offset+N < 0} or {@code offset+N >= a.length} 2766 * for any lane {@code N} in the vector 2767 * where the mask is set 2768 */ 2769 @ForceInline 2770 public static 2771 LongVector fromArray(VectorSpecies<Long> species, 2772 long[] a, int offset, 2773 VectorMask<Long> m) { 2774 LongSpecies vsp = (LongSpecies) species; 2775 if (offset >= 0 && offset <= (a.length - species.length())) { 2776 return vsp.dummyVector().fromArray0(a, offset, m); 2777 } 2778 2779 // FIXME: optimize 2780 checkMaskFromIndexSize(offset, vsp, m, 1, a.length); 2781 return vsp.vOp(m, i -> a[offset + i]); 2782 } 2783 2784 /** 2785 * Gathers a new vector composed of elements from an array of type 2786 * {@code long[]}, 2787 * using indexes obtained by adding a fixed {@code offset} to a 2788 * series of secondary offsets from an <em>index map</em>. 2789 * The index map is a contiguous sequence of {@code VLENGTH} 2790 * elements in a second array of {@code int}s, starting at a given 2791 * {@code mapOffset}. 2792 * <p> 2793 * For each vector lane, where {@code N} is the vector lane index, 2794 * the lane is loaded from the array 2795 * element {@code a[f(N)]}, where {@code f(N)} is the 2796 * index mapping expression 2797 * {@code offset + indexMap[mapOffset + N]]}. 2798 * 2799 * @param species species of desired vector 2800 * @param a the array 2801 * @param offset the offset into the array, may be negative if relative 2802 * indexes in the index map compensate to produce a value within the 2803 * array bounds 2804 * @param indexMap the index map 2805 * @param mapOffset the offset into the index map 2806 * @return the vector loaded from the indexed elements of the array 2807 * @throws IndexOutOfBoundsException 2808 * if {@code mapOffset+N < 0} 2809 * or if {@code mapOffset+N >= indexMap.length}, 2810 * or if {@code f(N)=offset+indexMap[mapOffset+N]} 2811 * is an invalid index into {@code a}, 2812 * for any lane {@code N} in the vector 2813 * @see LongVector#toIntArray() 2814 */ 2815 @ForceInline 2816 public static 2817 LongVector fromArray(VectorSpecies<Long> species, 2818 long[] a, int offset, 2819 int[] indexMap, int mapOffset) { 2820 LongSpecies vsp = (LongSpecies) species; 2821 IntVector.IntSpecies isp = IntVector.species(vsp.indexShape()); 2822 Objects.requireNonNull(a); 2823 Objects.requireNonNull(indexMap); 2824 Class<? extends LongVector> vectorType = vsp.vectorType(); 2825 2826 if (vsp.laneCount() == 1) { 2827 return LongVector.fromArray(vsp, a, offset + indexMap[mapOffset]); 2828 } 2829 2830 // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k] 2831 IntVector vix; 2832 if (isp.laneCount() != vsp.laneCount()) { 2833 // For LongMaxVector, if vector length is non-power-of-two or 2834 // 2048 bits, indexShape of Long species is S_MAX_BIT. 2835 // Assume that vector length is 2048, then the lane count of Long 2836 // vector is 32. When converting Long species to int species, 2837 // indexShape is still S_MAX_BIT, but the lane count of int vector 2838 // is 64. So when loading index vector (IntVector), only lower half 2839 // of index data is needed. 2840 vix = IntVector 2841 .fromArray(isp, indexMap, mapOffset, IntMaxVector.IntMaxMask.LOWER_HALF_TRUE_MASK) 2842 .add(offset); 2843 } else { 2844 vix = IntVector 2845 .fromArray(isp, indexMap, mapOffset) 2846 .add(offset); 2847 } 2848 2849 vix = VectorIntrinsics.checkIndex(vix, a.length); 2850 2851 return VectorSupport.loadWithMap( 2852 vectorType, null, long.class, vsp.laneCount(), 2853 isp.vectorType(), 2854 a, ARRAY_BASE, vix, null, 2855 a, offset, indexMap, mapOffset, vsp, 2856 (c, idx, iMap, idy, s, vm) -> 2857 s.vOp(n -> c[idx + iMap[idy+n]])); 2858 } 2859 2860 /** 2861 * Gathers a new vector composed of elements from an array of type 2862 * {@code long[]}, 2863 * under the control of a mask, and 2864 * using indexes obtained by adding a fixed {@code offset} to a 2865 * series of secondary offsets from an <em>index map</em>. 2866 * The index map is a contiguous sequence of {@code VLENGTH} 2867 * elements in a second array of {@code int}s, starting at a given 2868 * {@code mapOffset}. 2869 * <p> 2870 * For each vector lane, where {@code N} is the vector lane index, 2871 * if the lane is set in the mask, 2872 * the lane is loaded from the array 2873 * element {@code a[f(N)]}, where {@code f(N)} is the 2874 * index mapping expression 2875 * {@code offset + indexMap[mapOffset + N]]}. 2876 * Unset lanes in the resulting vector are set to zero. 2877 * 2878 * @param species species of desired vector 2879 * @param a the array 2880 * @param offset the offset into the array, may be negative if relative 2881 * indexes in the index map compensate to produce a value within the 2882 * array bounds 2883 * @param indexMap the index map 2884 * @param mapOffset the offset into the index map 2885 * @param m the mask controlling lane selection 2886 * @return the vector loaded from the indexed elements of the array 2887 * @throws IndexOutOfBoundsException 2888 * if {@code mapOffset+N < 0} 2889 * or if {@code mapOffset+N >= indexMap.length}, 2890 * or if {@code f(N)=offset+indexMap[mapOffset+N]} 2891 * is an invalid index into {@code a}, 2892 * for any lane {@code N} in the vector 2893 * where the mask is set 2894 * @see LongVector#toIntArray() 2895 */ 2896 @ForceInline 2897 public static 2898 LongVector fromArray(VectorSpecies<Long> species, 2899 long[] a, int offset, 2900 int[] indexMap, int mapOffset, 2901 VectorMask<Long> m) { 2902 if (m.allTrue()) { 2903 return fromArray(species, a, offset, indexMap, mapOffset); 2904 } 2905 else { 2906 LongSpecies vsp = (LongSpecies) species; 2907 return vsp.dummyVector().fromArray0(a, offset, indexMap, mapOffset, m); 2908 } 2909 } 2910 2911 2912 2913 /** 2914 * Loads a vector from a {@linkplain ByteBuffer byte buffer} 2915 * starting at an offset into the byte buffer. 2916 * Bytes are composed into primitive lane elements according 2917 * to the specified byte order. 2918 * The vector is arranged into lanes according to 2919 * <a href="Vector.html#lane-order">memory ordering</a>. 2920 * <p> 2921 * This method behaves as if it returns the result of calling 2922 * {@link #fromByteBuffer(VectorSpecies,ByteBuffer,int,ByteOrder,VectorMask) 2923 * fromByteBuffer()} as follows: 2924 * <pre>{@code 2925 * var m = species.maskAll(true); 2926 * return fromByteBuffer(species, bb, offset, bo, m); 2927 * }</pre> 2928 * 2929 * @param species species of desired vector 2930 * @param bb the byte buffer 2931 * @param offset the offset into the byte buffer 2932 * @param bo the intended byte order 2933 * @return a vector loaded from a byte buffer 2934 * @throws IndexOutOfBoundsException 2935 * if {@code offset+N*8 < 0} 2936 * or {@code offset+N*8 >= bb.limit()} 2937 * for any lane {@code N} in the vector 2938 */ 2939 @ForceInline 2940 public static 2941 LongVector fromByteBuffer(VectorSpecies<Long> species, 2942 ByteBuffer bb, int offset, 2943 ByteOrder bo) { 2944 offset = checkFromIndexSize(offset, species.vectorByteSize(), bb.limit()); 2945 LongSpecies vsp = (LongSpecies) species; 2946 return vsp.dummyVector().fromByteBuffer0(bb, offset).maybeSwap(bo); 2947 } 2948 2949 /** 2950 * Loads a vector from a {@linkplain ByteBuffer byte buffer} 2951 * starting at an offset into the byte buffer 2952 * and using a mask. 2953 * Lanes where the mask is unset are filled with the default 2954 * value of {@code long} (zero). 2955 * Bytes are composed into primitive lane elements according 2956 * to the specified byte order. 2957 * The vector is arranged into lanes according to 2958 * <a href="Vector.html#lane-order">memory ordering</a>. 2959 * <p> 2960 * The following pseudocode illustrates the behavior: 2961 * <pre>{@code 2962 * LongBuffer eb = bb.duplicate() 2963 * .position(offset) 2964 * .order(bo).asLongBuffer(); 2965 * long[] ar = new long[species.length()]; 2966 * for (int n = 0; n < ar.length; n++) { 2967 * if (m.laneIsSet(n)) { 2968 * ar[n] = eb.get(n); 2969 * } 2970 * } 2971 * LongVector r = LongVector.fromArray(species, ar, 0); 2972 * }</pre> 2973 * @implNote 2974 * This operation is likely to be more efficient if 2975 * the specified byte order is the same as 2976 * {@linkplain ByteOrder#nativeOrder() 2977 * the platform native order}, 2978 * since this method will not need to reorder 2979 * the bytes of lane values. 2980 * 2981 * @param species species of desired vector 2982 * @param bb the byte buffer 2983 * @param offset the offset into the byte buffer 2984 * @param bo the intended byte order 2985 * @param m the mask controlling lane selection 2986 * @return a vector loaded from a byte buffer 2987 * @throws IndexOutOfBoundsException 2988 * if {@code offset+N*8 < 0} 2989 * or {@code offset+N*8 >= bb.limit()} 2990 * for any lane {@code N} in the vector 2991 * where the mask is set 2992 */ 2993 @ForceInline 2994 public static 2995 LongVector fromByteBuffer(VectorSpecies<Long> species, 2996 ByteBuffer bb, int offset, 2997 ByteOrder bo, 2998 VectorMask<Long> m) { 2999 LongSpecies vsp = (LongSpecies) species; 3000 if (offset >= 0 && offset <= (bb.limit() - species.vectorByteSize())) { 3001 return vsp.dummyVector().fromByteBuffer0(bb, offset, m).maybeSwap(bo); 3002 } 3003 3004 // FIXME: optimize 3005 checkMaskFromIndexSize(offset, vsp, m, 8, bb.limit()); 3006 ByteBuffer wb = wrapper(bb, bo); 3007 return vsp.ldOp(wb, offset, (AbstractMask<Long>)m, 3008 (wb_, o, i) -> wb_.getLong(o + i * 8)); 3009 } 3010 3011 // Memory store operations 3012 3013 /** 3014 * Stores this vector into an array of type {@code long[]} 3015 * starting at an offset. 3016 * <p> 3017 * For each vector lane, where {@code N} is the vector lane index, 3018 * the lane element at index {@code N} is stored into the array 3019 * element {@code a[offset+N]}. 3020 * 3021 * @param a the array, of type {@code long[]} 3022 * @param offset the offset into the array 3023 * @throws IndexOutOfBoundsException 3024 * if {@code offset+N < 0} or {@code offset+N >= a.length} 3025 * for any lane {@code N} in the vector 3026 */ 3027 @ForceInline 3028 public final 3029 void intoArray(long[] a, int offset) { 3030 offset = checkFromIndexSize(offset, length(), a.length); 3031 LongSpecies vsp = vspecies(); 3032 VectorSupport.store( 3033 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3034 a, arrayAddress(a, offset), 3035 this, 3036 a, offset, 3037 (arr, off, v) 3038 -> v.stOp(arr, off, 3039 (arr_, off_, i, e) -> arr_[off_ + i] = e)); 3040 } 3041 3042 /** 3043 * Stores this vector into an array of type {@code long[]} 3044 * starting at offset and using a mask. 3045 * <p> 3046 * For each vector lane, where {@code N} is the vector lane index, 3047 * the lane element at index {@code N} is stored into the array 3048 * element {@code a[offset+N]}. 3049 * If the mask lane at {@code N} is unset then the corresponding 3050 * array element {@code a[offset+N]} is left unchanged. 3051 * <p> 3052 * Array range checking is done for lanes where the mask is set. 3053 * Lanes where the mask is unset are not stored and do not need 3054 * to correspond to legitimate elements of {@code a}. 3055 * That is, unset lanes may correspond to array indexes less than 3056 * zero or beyond the end of the array. 3057 * 3058 * @param a the array, of type {@code long[]} 3059 * @param offset the offset into the array 3060 * @param m the mask controlling lane storage 3061 * @throws IndexOutOfBoundsException 3062 * if {@code offset+N < 0} or {@code offset+N >= a.length} 3063 * for any lane {@code N} in the vector 3064 * where the mask is set 3065 */ 3066 @ForceInline 3067 public final 3068 void intoArray(long[] a, int offset, 3069 VectorMask<Long> m) { 3070 if (m.allTrue()) { 3071 intoArray(a, offset); 3072 } else { 3073 LongSpecies vsp = vspecies(); 3074 checkMaskFromIndexSize(offset, vsp, m, 1, a.length); 3075 intoArray0(a, offset, m); 3076 } 3077 } 3078 3079 /** 3080 * Scatters this vector into an array of type {@code long[]} 3081 * using indexes obtained by adding a fixed {@code offset} to a 3082 * series of secondary offsets from an <em>index map</em>. 3083 * The index map is a contiguous sequence of {@code VLENGTH} 3084 * elements in a second array of {@code int}s, starting at a given 3085 * {@code mapOffset}. 3086 * <p> 3087 * For each vector lane, where {@code N} is the vector lane index, 3088 * the lane element at index {@code N} is stored into the array 3089 * element {@code a[f(N)]}, where {@code f(N)} is the 3090 * index mapping expression 3091 * {@code offset + indexMap[mapOffset + N]]}. 3092 * 3093 * @param a the array 3094 * @param offset an offset to combine with the index map offsets 3095 * @param indexMap the index map 3096 * @param mapOffset the offset into the index map 3097 * @throws IndexOutOfBoundsException 3098 * if {@code mapOffset+N < 0} 3099 * or if {@code mapOffset+N >= indexMap.length}, 3100 * or if {@code f(N)=offset+indexMap[mapOffset+N]} 3101 * is an invalid index into {@code a}, 3102 * for any lane {@code N} in the vector 3103 * @see LongVector#toIntArray() 3104 */ 3105 @ForceInline 3106 public final 3107 void intoArray(long[] a, int offset, 3108 int[] indexMap, int mapOffset) { 3109 LongSpecies vsp = vspecies(); 3110 IntVector.IntSpecies isp = IntVector.species(vsp.indexShape()); 3111 if (vsp.laneCount() == 1) { 3112 intoArray(a, offset + indexMap[mapOffset]); 3113 return; 3114 } 3115 3116 // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] 3117 IntVector vix; 3118 if (isp.laneCount() != vsp.laneCount()) { 3119 // For LongMaxVector, if vector length is 2048 bits, indexShape 3120 // of Long species is S_MAX_BIT. and the lane count of Long 3121 // vector is 32. When converting Long species to int species, 3122 // indexShape is still S_MAX_BIT, but the lane count of int vector 3123 // is 64. So when loading index vector (IntVector), only lower half 3124 // of index data is needed. 3125 vix = IntVector 3126 .fromArray(isp, indexMap, mapOffset, IntMaxVector.IntMaxMask.LOWER_HALF_TRUE_MASK) 3127 .add(offset); 3128 } else { 3129 vix = IntVector 3130 .fromArray(isp, indexMap, mapOffset) 3131 .add(offset); 3132 } 3133 3134 3135 vix = VectorIntrinsics.checkIndex(vix, a.length); 3136 3137 VectorSupport.storeWithMap( 3138 vsp.vectorType(), null, vsp.elementType(), vsp.laneCount(), 3139 isp.vectorType(), 3140 a, arrayAddress(a, 0), vix, 3141 this, null, 3142 a, offset, indexMap, mapOffset, 3143 (arr, off, v, map, mo, vm) 3144 -> v.stOp(arr, off, 3145 (arr_, off_, i, e) -> { 3146 int j = map[mo + i]; 3147 arr[off + j] = e; 3148 })); 3149 } 3150 3151 /** 3152 * Scatters this vector into an array of type {@code long[]}, 3153 * under the control of a mask, and 3154 * using indexes obtained by adding a fixed {@code offset} to a 3155 * series of secondary offsets from an <em>index map</em>. 3156 * The index map is a contiguous sequence of {@code VLENGTH} 3157 * elements in a second array of {@code int}s, starting at a given 3158 * {@code mapOffset}. 3159 * <p> 3160 * For each vector lane, where {@code N} is the vector lane index, 3161 * if the mask lane at index {@code N} is set then 3162 * the lane element at index {@code N} is stored into the array 3163 * element {@code a[f(N)]}, where {@code f(N)} is the 3164 * index mapping expression 3165 * {@code offset + indexMap[mapOffset + N]]}. 3166 * 3167 * @param a the array 3168 * @param offset an offset to combine with the index map offsets 3169 * @param indexMap the index map 3170 * @param mapOffset the offset into the index map 3171 * @param m the mask 3172 * @throws IndexOutOfBoundsException 3173 * if {@code mapOffset+N < 0} 3174 * or if {@code mapOffset+N >= indexMap.length}, 3175 * or if {@code f(N)=offset+indexMap[mapOffset+N]} 3176 * is an invalid index into {@code a}, 3177 * for any lane {@code N} in the vector 3178 * where the mask is set 3179 * @see LongVector#toIntArray() 3180 */ 3181 @ForceInline 3182 public final 3183 void intoArray(long[] a, int offset, 3184 int[] indexMap, int mapOffset, 3185 VectorMask<Long> m) { 3186 if (m.allTrue()) { 3187 intoArray(a, offset, indexMap, mapOffset); 3188 } 3189 else { 3190 intoArray0(a, offset, indexMap, mapOffset, m); 3191 } 3192 } 3193 3194 3195 3196 /** 3197 * {@inheritDoc} <!--workaround--> 3198 */ 3199 @Override 3200 @ForceInline 3201 public final 3202 void intoByteArray(byte[] a, int offset, 3203 ByteOrder bo) { 3204 offset = checkFromIndexSize(offset, byteSize(), a.length); 3205 maybeSwap(bo).intoByteArray0(a, offset); 3206 } 3207 3208 /** 3209 * {@inheritDoc} <!--workaround--> 3210 */ 3211 @Override 3212 @ForceInline 3213 public final 3214 void intoByteArray(byte[] a, int offset, 3215 ByteOrder bo, 3216 VectorMask<Long> m) { 3217 if (m.allTrue()) { 3218 intoByteArray(a, offset, bo); 3219 } else { 3220 LongSpecies vsp = vspecies(); 3221 checkMaskFromIndexSize(offset, vsp, m, 8, a.length); 3222 maybeSwap(bo).intoByteArray0(a, offset, m); 3223 } 3224 } 3225 3226 /** 3227 * {@inheritDoc} <!--workaround--> 3228 */ 3229 @Override 3230 @ForceInline 3231 public final 3232 void intoByteBuffer(ByteBuffer bb, int offset, 3233 ByteOrder bo) { 3234 if (ScopedMemoryAccess.isReadOnly(bb)) { 3235 throw new ReadOnlyBufferException(); 3236 } 3237 offset = checkFromIndexSize(offset, byteSize(), bb.limit()); 3238 maybeSwap(bo).intoByteBuffer0(bb, offset); 3239 } 3240 3241 /** 3242 * {@inheritDoc} <!--workaround--> 3243 */ 3244 @Override 3245 @ForceInline 3246 public final 3247 void intoByteBuffer(ByteBuffer bb, int offset, 3248 ByteOrder bo, 3249 VectorMask<Long> m) { 3250 if (m.allTrue()) { 3251 intoByteBuffer(bb, offset, bo); 3252 } else { 3253 if (bb.isReadOnly()) { 3254 throw new ReadOnlyBufferException(); 3255 } 3256 LongSpecies vsp = vspecies(); 3257 checkMaskFromIndexSize(offset, vsp, m, 8, bb.limit()); 3258 maybeSwap(bo).intoByteBuffer0(bb, offset, m); 3259 } 3260 } 3261 3262 // ================================================ 3263 3264 // Low-level memory operations. 3265 // 3266 // Note that all of these operations *must* inline into a context 3267 // where the exact species of the involved vector is a 3268 // compile-time constant. Otherwise, the intrinsic generation 3269 // will fail and performance will suffer. 3270 // 3271 // In many cases this is achieved by re-deriving a version of the 3272 // method in each concrete subclass (per species). The re-derived 3273 // method simply calls one of these generic methods, with exact 3274 // parameters for the controlling metadata, which is either a 3275 // typed vector or constant species instance. 3276 3277 // Unchecked loading operations in native byte order. 3278 // Caller is responsible for applying index checks, masking, and 3279 // byte swapping. 3280 3281 /*package-private*/ 3282 abstract 3283 LongVector fromArray0(long[] a, int offset); 3284 @ForceInline 3285 final 3286 LongVector fromArray0Template(long[] a, int offset) { 3287 LongSpecies vsp = vspecies(); 3288 return VectorSupport.load( 3289 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3290 a, arrayAddress(a, offset), 3291 a, offset, vsp, 3292 (arr, off, s) -> s.ldOp(arr, off, 3293 (arr_, off_, i) -> arr_[off_ + i])); 3294 } 3295 3296 /*package-private*/ 3297 abstract 3298 LongVector fromArray0(long[] a, int offset, VectorMask<Long> m); 3299 @ForceInline 3300 final 3301 <M extends VectorMask<Long>> 3302 LongVector fromArray0Template(Class<M> maskClass, long[] a, int offset, M m) { 3303 m.check(species()); 3304 LongSpecies vsp = vspecies(); 3305 return VectorSupport.loadMasked( 3306 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3307 a, arrayAddress(a, offset), m, 3308 a, offset, vsp, 3309 (arr, off, s, vm) -> s.ldOp(arr, off, vm, 3310 (arr_, off_, i) -> arr_[off_ + i])); 3311 } 3312 3313 /*package-private*/ 3314 abstract 3315 LongVector fromArray0(long[] a, int offset, 3316 int[] indexMap, int mapOffset, 3317 VectorMask<Long> m); 3318 @ForceInline 3319 final 3320 <M extends VectorMask<Long>> 3321 LongVector fromArray0Template(Class<M> maskClass, long[] a, int offset, 3322 int[] indexMap, int mapOffset, M m) { 3323 LongSpecies vsp = vspecies(); 3324 IntVector.IntSpecies isp = IntVector.species(vsp.indexShape()); 3325 Objects.requireNonNull(a); 3326 Objects.requireNonNull(indexMap); 3327 m.check(vsp); 3328 Class<? extends LongVector> vectorType = vsp.vectorType(); 3329 3330 if (vsp.laneCount() == 1) { 3331 return LongVector.fromArray(vsp, a, offset + indexMap[mapOffset], m); 3332 } 3333 3334 // Index vector: vix[0:n] = k -> offset + indexMap[mapOffset + k] 3335 IntVector vix; 3336 if (isp.laneCount() != vsp.laneCount()) { 3337 // For LongMaxVector, if vector length is non-power-of-two or 3338 // 2048 bits, indexShape of Long species is S_MAX_BIT. 3339 // Assume that vector length is 2048, then the lane count of Long 3340 // vector is 32. When converting Long species to int species, 3341 // indexShape is still S_MAX_BIT, but the lane count of int vector 3342 // is 64. So when loading index vector (IntVector), only lower half 3343 // of index data is needed. 3344 vix = IntVector 3345 .fromArray(isp, indexMap, mapOffset, IntMaxVector.IntMaxMask.LOWER_HALF_TRUE_MASK) 3346 .add(offset); 3347 } else { 3348 vix = IntVector 3349 .fromArray(isp, indexMap, mapOffset) 3350 .add(offset); 3351 } 3352 3353 // FIXME: Check index under mask controlling. 3354 vix = VectorIntrinsics.checkIndex(vix, a.length); 3355 3356 return VectorSupport.loadWithMap( 3357 vectorType, maskClass, long.class, vsp.laneCount(), 3358 isp.vectorType(), 3359 a, ARRAY_BASE, vix, m, 3360 a, offset, indexMap, mapOffset, vsp, 3361 (c, idx, iMap, idy, s, vm) -> 3362 s.vOp(vm, n -> c[idx + iMap[idy+n]])); 3363 } 3364 3365 3366 3367 @Override 3368 abstract 3369 LongVector fromByteArray0(byte[] a, int offset); 3370 @ForceInline 3371 final 3372 LongVector fromByteArray0Template(byte[] a, int offset) { 3373 LongSpecies vsp = vspecies(); 3374 return VectorSupport.load( 3375 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3376 a, byteArrayAddress(a, offset), 3377 a, offset, vsp, 3378 (arr, off, s) -> { 3379 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN); 3380 return s.ldOp(wb, off, 3381 (wb_, o, i) -> wb_.getLong(o + i * 8)); 3382 }); 3383 } 3384 3385 abstract 3386 LongVector fromByteArray0(byte[] a, int offset, VectorMask<Long> m); 3387 @ForceInline 3388 final 3389 <M extends VectorMask<Long>> 3390 LongVector fromByteArray0Template(Class<M> maskClass, byte[] a, int offset, M m) { 3391 LongSpecies vsp = vspecies(); 3392 m.check(vsp); 3393 return VectorSupport.loadMasked( 3394 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3395 a, byteArrayAddress(a, offset), m, 3396 a, offset, vsp, 3397 (arr, off, s, vm) -> { 3398 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN); 3399 return s.ldOp(wb, off, vm, 3400 (wb_, o, i) -> wb_.getLong(o + i * 8)); 3401 }); 3402 } 3403 3404 abstract 3405 LongVector fromByteBuffer0(ByteBuffer bb, int offset); 3406 @ForceInline 3407 final 3408 LongVector fromByteBuffer0Template(ByteBuffer bb, int offset) { 3409 LongSpecies vsp = vspecies(); 3410 return ScopedMemoryAccess.loadFromByteBuffer( 3411 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3412 bb, offset, vsp, 3413 (buf, off, s) -> { 3414 ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN); 3415 return s.ldOp(wb, off, 3416 (wb_, o, i) -> wb_.getLong(o + i * 8)); 3417 }); 3418 } 3419 3420 abstract 3421 LongVector fromByteBuffer0(ByteBuffer bb, int offset, VectorMask<Long> m); 3422 @ForceInline 3423 final 3424 <M extends VectorMask<Long>> 3425 LongVector fromByteBuffer0Template(Class<M> maskClass, ByteBuffer bb, int offset, M m) { 3426 LongSpecies vsp = vspecies(); 3427 m.check(vsp); 3428 return ScopedMemoryAccess.loadFromByteBufferMasked( 3429 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3430 bb, offset, m, vsp, 3431 (buf, off, s, vm) -> { 3432 ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN); 3433 return s.ldOp(wb, off, vm, 3434 (wb_, o, i) -> wb_.getLong(o + i * 8)); 3435 }); 3436 } 3437 3438 // Unchecked storing operations in native byte order. 3439 // Caller is responsible for applying index checks, masking, and 3440 // byte swapping. 3441 3442 abstract 3443 void intoArray0(long[] a, int offset); 3444 @ForceInline 3445 final 3446 void intoArray0Template(long[] a, int offset) { 3447 LongSpecies vsp = vspecies(); 3448 VectorSupport.store( 3449 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3450 a, arrayAddress(a, offset), 3451 this, a, offset, 3452 (arr, off, v) 3453 -> v.stOp(arr, off, 3454 (arr_, off_, i, e) -> arr_[off_+i] = e)); 3455 } 3456 3457 abstract 3458 void intoArray0(long[] a, int offset, VectorMask<Long> m); 3459 @ForceInline 3460 final 3461 <M extends VectorMask<Long>> 3462 void intoArray0Template(Class<M> maskClass, long[] a, int offset, M m) { 3463 m.check(species()); 3464 LongSpecies vsp = vspecies(); 3465 VectorSupport.storeMasked( 3466 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3467 a, arrayAddress(a, offset), 3468 this, m, a, offset, 3469 (arr, off, v, vm) 3470 -> v.stOp(arr, off, vm, 3471 (arr_, off_, i, e) -> arr_[off_ + i] = e)); 3472 } 3473 3474 abstract 3475 void intoArray0(long[] a, int offset, 3476 int[] indexMap, int mapOffset, 3477 VectorMask<Long> m); 3478 @ForceInline 3479 final 3480 <M extends VectorMask<Long>> 3481 void intoArray0Template(Class<M> maskClass, long[] a, int offset, 3482 int[] indexMap, int mapOffset, M m) { 3483 m.check(species()); 3484 LongSpecies vsp = vspecies(); 3485 IntVector.IntSpecies isp = IntVector.species(vsp.indexShape()); 3486 if (vsp.laneCount() == 1) { 3487 intoArray(a, offset + indexMap[mapOffset], m); 3488 return; 3489 } 3490 3491 // Index vector: vix[0:n] = i -> offset + indexMap[mo + i] 3492 IntVector vix; 3493 if (isp.laneCount() != vsp.laneCount()) { 3494 // For LongMaxVector, if vector length is 2048 bits, indexShape 3495 // of Long species is S_MAX_BIT. and the lane count of Long 3496 // vector is 32. When converting Long species to int species, 3497 // indexShape is still S_MAX_BIT, but the lane count of int vector 3498 // is 64. So when loading index vector (IntVector), only lower half 3499 // of index data is needed. 3500 vix = IntVector 3501 .fromArray(isp, indexMap, mapOffset, IntMaxVector.IntMaxMask.LOWER_HALF_TRUE_MASK) 3502 .add(offset); 3503 } else { 3504 vix = IntVector 3505 .fromArray(isp, indexMap, mapOffset) 3506 .add(offset); 3507 } 3508 3509 3510 // FIXME: Check index under mask controlling. 3511 vix = VectorIntrinsics.checkIndex(vix, a.length); 3512 3513 VectorSupport.storeWithMap( 3514 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3515 isp.vectorType(), 3516 a, arrayAddress(a, 0), vix, 3517 this, m, 3518 a, offset, indexMap, mapOffset, 3519 (arr, off, v, map, mo, vm) 3520 -> v.stOp(arr, off, vm, 3521 (arr_, off_, i, e) -> { 3522 int j = map[mo + i]; 3523 arr[off + j] = e; 3524 })); 3525 } 3526 3527 3528 abstract 3529 void intoByteArray0(byte[] a, int offset); 3530 @ForceInline 3531 final 3532 void intoByteArray0Template(byte[] a, int offset) { 3533 LongSpecies vsp = vspecies(); 3534 VectorSupport.store( 3535 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3536 a, byteArrayAddress(a, offset), 3537 this, a, offset, 3538 (arr, off, v) -> { 3539 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN); 3540 v.stOp(wb, off, 3541 (tb_, o, i, e) -> tb_.putLong(o + i * 8, e)); 3542 }); 3543 } 3544 3545 abstract 3546 void intoByteArray0(byte[] a, int offset, VectorMask<Long> m); 3547 @ForceInline 3548 final 3549 <M extends VectorMask<Long>> 3550 void intoByteArray0Template(Class<M> maskClass, byte[] a, int offset, M m) { 3551 LongSpecies vsp = vspecies(); 3552 m.check(vsp); 3553 VectorSupport.storeMasked( 3554 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3555 a, byteArrayAddress(a, offset), 3556 this, m, a, offset, 3557 (arr, off, v, vm) -> { 3558 ByteBuffer wb = wrapper(arr, NATIVE_ENDIAN); 3559 v.stOp(wb, off, vm, 3560 (tb_, o, i, e) -> tb_.putLong(o + i * 8, e)); 3561 }); 3562 } 3563 3564 @ForceInline 3565 final 3566 void intoByteBuffer0(ByteBuffer bb, int offset) { 3567 LongSpecies vsp = vspecies(); 3568 ScopedMemoryAccess.storeIntoByteBuffer( 3569 vsp.vectorType(), vsp.elementType(), vsp.laneCount(), 3570 this, bb, offset, 3571 (buf, off, v) -> { 3572 ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN); 3573 v.stOp(wb, off, 3574 (wb_, o, i, e) -> wb_.putLong(o + i * 8, e)); 3575 }); 3576 } 3577 3578 abstract 3579 void intoByteBuffer0(ByteBuffer bb, int offset, VectorMask<Long> m); 3580 @ForceInline 3581 final 3582 <M extends VectorMask<Long>> 3583 void intoByteBuffer0Template(Class<M> maskClass, ByteBuffer bb, int offset, M m) { 3584 LongSpecies vsp = vspecies(); 3585 m.check(vsp); 3586 ScopedMemoryAccess.storeIntoByteBufferMasked( 3587 vsp.vectorType(), maskClass, vsp.elementType(), vsp.laneCount(), 3588 this, m, bb, offset, 3589 (buf, off, v, vm) -> { 3590 ByteBuffer wb = wrapper(buf, NATIVE_ENDIAN); 3591 v.stOp(wb, off, vm, 3592 (wb_, o, i, e) -> wb_.putLong(o + i * 8, e)); 3593 }); 3594 } 3595 3596 3597 // End of low-level memory operations. 3598 3599 private static 3600 void checkMaskFromIndexSize(int offset, 3601 LongSpecies vsp, 3602 VectorMask<Long> m, 3603 int scale, 3604 int limit) { 3605 ((AbstractMask<Long>)m) 3606 .checkIndexByLane(offset, limit, vsp.iota(), scale); 3607 } 3608 3609 @ForceInline 3610 private void conditionalStoreNYI(int offset, 3611 LongSpecies vsp, 3612 VectorMask<Long> m, 3613 int scale, 3614 int limit) { 3615 if (offset < 0 || offset + vsp.laneCount() * scale > limit) { 3616 String msg = 3617 String.format("unimplemented: store @%d in [0..%d), %s in %s", 3618 offset, limit, m, vsp); 3619 throw new AssertionError(msg); 3620 } 3621 } 3622 3623 /*package-private*/ 3624 @Override 3625 @ForceInline 3626 final 3627 LongVector maybeSwap(ByteOrder bo) { 3628 if (bo != NATIVE_ENDIAN) { 3629 return this.reinterpretAsBytes() 3630 .rearrange(swapBytesShuffle()) 3631 .reinterpretAsLongs(); 3632 } 3633 return this; 3634 } 3635 3636 static final int ARRAY_SHIFT = 3637 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_LONG_INDEX_SCALE); 3638 static final long ARRAY_BASE = 3639 Unsafe.ARRAY_LONG_BASE_OFFSET; 3640 3641 @ForceInline 3642 static long arrayAddress(long[] a, int index) { 3643 return ARRAY_BASE + (((long)index) << ARRAY_SHIFT); 3644 } 3645 3646 3647 3648 @ForceInline 3649 static long byteArrayAddress(byte[] a, int index) { 3650 return Unsafe.ARRAY_BYTE_BASE_OFFSET + index; 3651 } 3652 3653 // ================================================ 3654 3655 /// Reinterpreting view methods: 3656 // lanewise reinterpret: viewAsXVector() 3657 // keep shape, redraw lanes: reinterpretAsEs() 3658 3659 /** 3660 * {@inheritDoc} <!--workaround--> 3661 */ 3662 @ForceInline 3663 @Override 3664 public final ByteVector reinterpretAsBytes() { 3665 // Going to ByteVector, pay close attention to byte order. 3666 assert(REGISTER_ENDIAN == ByteOrder.LITTLE_ENDIAN); 3667 return asByteVectorRaw(); 3668 //return asByteVectorRaw().rearrange(swapBytesShuffle()); 3669 } 3670 3671 /** 3672 * {@inheritDoc} <!--workaround--> 3673 */ 3674 @ForceInline 3675 @Override 3676 public final LongVector viewAsIntegralLanes() { 3677 return this; 3678 } 3679 3680 /** 3681 * {@inheritDoc} <!--workaround--> 3682 */ 3683 @ForceInline 3684 @Override 3685 public final 3686 DoubleVector 3687 viewAsFloatingLanes() { 3688 LaneType flt = LaneType.LONG.asFloating(); 3689 return (DoubleVector) asVectorRaw(flt); 3690 } 3691 3692 // ================================================ 3693 3694 /// Object methods: toString, equals, hashCode 3695 // 3696 // Object methods are defined as if via Arrays.toString, etc., 3697 // is applied to the array of elements. Two equal vectors 3698 // are required to have equal species and equal lane values. 3699 3700 /** 3701 * Returns a string representation of this vector, of the form 3702 * {@code "[0,1,2...]"}, reporting the lane values of this vector, 3703 * in lane order. 3704 * 3705 * The string is produced as if by a call to {@link 3706 * java.util.Arrays#toString(long[]) Arrays.toString()}, 3707 * as appropriate to the {@code long} array returned by 3708 * {@link #toArray this.toArray()}. 3709 * 3710 * @return a string of the form {@code "[0,1,2...]"} 3711 * reporting the lane values of this vector 3712 */ 3713 @Override 3714 @ForceInline 3715 public final 3716 String toString() { 3717 // now that toArray is strongly typed, we can define this 3718 return Arrays.toString(toArray()); 3719 } 3720 3721 /** 3722 * {@inheritDoc} <!--workaround--> 3723 */ 3724 @Override 3725 @ForceInline 3726 public final 3727 boolean equals(Object obj) { 3728 if (obj instanceof Vector) { 3729 Vector<?> that = (Vector<?>) obj; 3730 if (this.species().equals(that.species())) { 3731 return this.eq(that.check(this.species())).allTrue(); 3732 } 3733 } 3734 return false; 3735 } 3736 3737 /** 3738 * {@inheritDoc} <!--workaround--> 3739 */ 3740 @Override 3741 @ForceInline 3742 public final 3743 int hashCode() { 3744 // now that toArray is strongly typed, we can define this 3745 return Objects.hash(species(), Arrays.hashCode(toArray())); 3746 } 3747 3748 // ================================================ 3749 3750 // Species 3751 3752 /** 3753 * Class representing {@link LongVector}'s of the same {@link VectorShape VectorShape}. 3754 */ 3755 /*package-private*/ 3756 static final class LongSpecies extends AbstractSpecies<Long> { 3757 private LongSpecies(VectorShape shape, 3758 Class<? extends LongVector> vectorType, 3759 Class<? extends AbstractMask<Long>> maskType, 3760 Function<Object, LongVector> vectorFactory) { 3761 super(shape, LaneType.of(long.class), 3762 vectorType, maskType, 3763 vectorFactory); 3764 assert(this.elementSize() == Long.SIZE); 3765 } 3766 3767 // Specializing overrides: 3768 3769 @Override 3770 @ForceInline 3771 public final Class<Long> elementType() { 3772 return long.class; 3773 } 3774 3775 @Override 3776 @ForceInline 3777 final Class<Long> genericElementType() { 3778 return Long.class; 3779 } 3780 3781 @SuppressWarnings("unchecked") 3782 @Override 3783 @ForceInline 3784 public final Class<? extends LongVector> vectorType() { 3785 return (Class<? extends LongVector>) vectorType; 3786 } 3787 3788 @Override 3789 @ForceInline 3790 public final long checkValue(long e) { 3791 longToElementBits(e); // only for exception 3792 return e; 3793 } 3794 3795 /*package-private*/ 3796 @Override 3797 @ForceInline 3798 final LongVector broadcastBits(long bits) { 3799 return (LongVector) 3800 VectorSupport.fromBitsCoerced( 3801 vectorType, long.class, laneCount, 3802 bits, MODE_BROADCAST, this, 3803 (bits_, s_) -> s_.rvOp(i -> bits_)); 3804 } 3805 3806 /*package-private*/ 3807 @ForceInline 3808 public final LongVector broadcast(long e) { 3809 return broadcastBits(toBits(e)); 3810 } 3811 3812 3813 /*package-private*/ 3814 final @Override 3815 @ForceInline 3816 long longToElementBits(long value) { 3817 // In this case, the conversion can never fail. 3818 return value; 3819 } 3820 3821 /*package-private*/ 3822 @ForceInline 3823 static long toIntegralChecked(long e, boolean convertToInt) { 3824 long value = convertToInt ? (int) e : (long) e; 3825 if ((long) value != e) { 3826 throw badArrayBits(e, convertToInt, value); 3827 } 3828 return value; 3829 } 3830 3831 /* this non-public one is for internal conversions */ 3832 @Override 3833 @ForceInline 3834 final LongVector fromIntValues(int[] values) { 3835 VectorIntrinsics.requireLength(values.length, laneCount); 3836 long[] va = new long[laneCount()]; 3837 for (int i = 0; i < va.length; i++) { 3838 int lv = values[i]; 3839 long v = (long) lv; 3840 va[i] = v; 3841 if ((int)v != lv) { 3842 throw badElementBits(lv, v); 3843 } 3844 } 3845 return dummyVector().fromArray0(va, 0); 3846 } 3847 3848 // Virtual constructors 3849 3850 @ForceInline 3851 @Override final 3852 public LongVector fromArray(Object a, int offset) { 3853 // User entry point: Be careful with inputs. 3854 return LongVector 3855 .fromArray(this, (long[]) a, offset); 3856 } 3857 3858 @ForceInline 3859 @Override final 3860 LongVector dummyVector() { 3861 return (LongVector) super.dummyVector(); 3862 } 3863 3864 /*package-private*/ 3865 final @Override 3866 @ForceInline 3867 LongVector rvOp(RVOp f) { 3868 long[] res = new long[laneCount()]; 3869 for (int i = 0; i < res.length; i++) { 3870 long bits = f.apply(i); 3871 res[i] = fromBits(bits); 3872 } 3873 return dummyVector().vectorFactory(res); 3874 } 3875 3876 LongVector vOp(FVOp f) { 3877 long[] res = new long[laneCount()]; 3878 for (int i = 0; i < res.length; i++) { 3879 res[i] = f.apply(i); 3880 } 3881 return dummyVector().vectorFactory(res); 3882 } 3883 3884 LongVector vOp(VectorMask<Long> m, FVOp f) { 3885 long[] res = new long[laneCount()]; 3886 boolean[] mbits = ((AbstractMask<Long>)m).getBits(); 3887 for (int i = 0; i < res.length; i++) { 3888 if (mbits[i]) { 3889 res[i] = f.apply(i); 3890 } 3891 } 3892 return dummyVector().vectorFactory(res); 3893 } 3894 3895 /*package-private*/ 3896 @ForceInline 3897 <M> LongVector ldOp(M memory, int offset, 3898 FLdOp<M> f) { 3899 return dummyVector().ldOp(memory, offset, f); 3900 } 3901 3902 /*package-private*/ 3903 @ForceInline 3904 <M> LongVector ldOp(M memory, int offset, 3905 VectorMask<Long> m, 3906 FLdOp<M> f) { 3907 return dummyVector().ldOp(memory, offset, m, f); 3908 } 3909 3910 /*package-private*/ 3911 @ForceInline 3912 <M> void stOp(M memory, int offset, FStOp<M> f) { 3913 dummyVector().stOp(memory, offset, f); 3914 } 3915 3916 /*package-private*/ 3917 @ForceInline 3918 <M> void stOp(M memory, int offset, 3919 AbstractMask<Long> m, 3920 FStOp<M> f) { 3921 dummyVector().stOp(memory, offset, m, f); 3922 } 3923 3924 // N.B. Make sure these constant vectors and 3925 // masks load up correctly into registers. 3926 // 3927 // Also, see if we can avoid all that switching. 3928 // Could we cache both vectors and both masks in 3929 // this species object? 3930 3931 // Zero and iota vector access 3932 @Override 3933 @ForceInline 3934 public final LongVector zero() { 3935 if ((Class<?>) vectorType() == LongMaxVector.class) 3936 return LongMaxVector.ZERO; 3937 switch (vectorBitSize()) { 3938 case 64: return Long64Vector.ZERO; 3939 case 128: return Long128Vector.ZERO; 3940 case 256: return Long256Vector.ZERO; 3941 case 512: return Long512Vector.ZERO; 3942 } 3943 throw new AssertionError(); 3944 } 3945 3946 @Override 3947 @ForceInline 3948 public final LongVector iota() { 3949 if ((Class<?>) vectorType() == LongMaxVector.class) 3950 return LongMaxVector.IOTA; 3951 switch (vectorBitSize()) { 3952 case 64: return Long64Vector.IOTA; 3953 case 128: return Long128Vector.IOTA; 3954 case 256: return Long256Vector.IOTA; 3955 case 512: return Long512Vector.IOTA; 3956 } 3957 throw new AssertionError(); 3958 } 3959 3960 // Mask access 3961 @Override 3962 @ForceInline 3963 public final VectorMask<Long> maskAll(boolean bit) { 3964 if ((Class<?>) vectorType() == LongMaxVector.class) 3965 return LongMaxVector.LongMaxMask.maskAll(bit); 3966 switch (vectorBitSize()) { 3967 case 64: return Long64Vector.Long64Mask.maskAll(bit); 3968 case 128: return Long128Vector.Long128Mask.maskAll(bit); 3969 case 256: return Long256Vector.Long256Mask.maskAll(bit); 3970 case 512: return Long512Vector.Long512Mask.maskAll(bit); 3971 } 3972 throw new AssertionError(); 3973 } 3974 } 3975 3976 /** 3977 * Finds a species for an element type of {@code long} and shape. 3978 * 3979 * @param s the shape 3980 * @return a species for an element type of {@code long} and shape 3981 * @throws IllegalArgumentException if no such species exists for the shape 3982 */ 3983 static LongSpecies species(VectorShape s) { 3984 Objects.requireNonNull(s); 3985 switch (s.switchKey) { 3986 case VectorShape.SK_64_BIT: return (LongSpecies) SPECIES_64; 3987 case VectorShape.SK_128_BIT: return (LongSpecies) SPECIES_128; 3988 case VectorShape.SK_256_BIT: return (LongSpecies) SPECIES_256; 3989 case VectorShape.SK_512_BIT: return (LongSpecies) SPECIES_512; 3990 case VectorShape.SK_Max_BIT: return (LongSpecies) SPECIES_MAX; 3991 default: throw new IllegalArgumentException("Bad shape: " + s); 3992 } 3993 } 3994 3995 /** Species representing {@link LongVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 3996 public static final VectorSpecies<Long> SPECIES_64 3997 = new LongSpecies(VectorShape.S_64_BIT, 3998 Long64Vector.class, 3999 Long64Vector.Long64Mask.class, 4000 Long64Vector::new); 4001 4002 /** Species representing {@link LongVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 4003 public static final VectorSpecies<Long> SPECIES_128 4004 = new LongSpecies(VectorShape.S_128_BIT, 4005 Long128Vector.class, 4006 Long128Vector.Long128Mask.class, 4007 Long128Vector::new); 4008 4009 /** Species representing {@link LongVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 4010 public static final VectorSpecies<Long> SPECIES_256 4011 = new LongSpecies(VectorShape.S_256_BIT, 4012 Long256Vector.class, 4013 Long256Vector.Long256Mask.class, 4014 Long256Vector::new); 4015 4016 /** Species representing {@link LongVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 4017 public static final VectorSpecies<Long> SPECIES_512 4018 = new LongSpecies(VectorShape.S_512_BIT, 4019 Long512Vector.class, 4020 Long512Vector.Long512Mask.class, 4021 Long512Vector::new); 4022 4023 /** Species representing {@link LongVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 4024 public static final VectorSpecies<Long> SPECIES_MAX 4025 = new LongSpecies(VectorShape.S_Max_BIT, 4026 LongMaxVector.class, 4027 LongMaxVector.LongMaxMask.class, 4028 LongMaxVector::new); 4029 4030 /** 4031 * Preferred species for {@link LongVector}s. 4032 * A preferred species is a species of maximal bit-size for the platform. 4033 */ 4034 public static final VectorSpecies<Long> SPECIES_PREFERRED 4035 = (LongSpecies) VectorSpecies.ofPreferred(long.class); 4036 }