1 /* 2 * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have 23 * questions. 24 */ 25 package jdk.incubator.vector; 26 27 import java.nio.ByteBuffer; 28 import java.nio.ByteOrder; 29 #if[!byte] 30 import java.nio.$Type$Buffer; 31 #end[!byte] 32 import java.nio.ReadOnlyBufferException; 33 import java.util.Arrays; 34 import java.util.Objects; 35 import java.util.function.IntUnaryOperator; 36 37 import jdk.internal.misc.Unsafe; 38 import jdk.internal.vm.annotation.ForceInline; 39 import jdk.internal.vm.annotation.Stable; 40 41 import static jdk.incubator.vector.VectorIntrinsics.*; 42 import static jdk.incubator.vector.VectorOperators.*; 43 44 #warn This file is preprocessed before being compiled 45 46 @SuppressWarnings("cast") // warning: redundant cast 47 final class $vectortype$ extends $abstractvectortype$ { 48 static final $Type$Species VSPECIES = 49 ($Type$Species) $Type$Vector.SPECIES_$BITS$; 50 51 static final VectorShape VSHAPE = 52 VSPECIES.vectorShape(); 53 54 static final Class<$vectortype$> VCLASS = $vectortype$.class; 55 56 static final int VSIZE = VSPECIES.vectorBitSize(); 57 58 static final int VLENGTH = VSPECIES.laneCount(); 59 60 static final Class<$Boxtype$> ETYPE = $type$.class; 61 62 // The JVM expects to find the state here. 63 private final $type$[] vec; // Don't access directly, use getElements() instead. 64 65 $vectortype$($type$[] v) { 66 vec = v; 67 } 68 69 // For compatibility as $vectortype$::new, 70 // stored into species.vectorFactory. 71 $vectortype$(Object v) { 72 this(($type$[]) v); 73 } 74 75 static final $vectortype$ ZERO = new $vectortype$(new $type$[VLENGTH]); 76 static final $vectortype$ IOTA = new $vectortype$(VSPECIES.iotaArray()); 77 78 static { 79 // Warm up a few species caches. 80 // If we do this too much we will 81 // get NPEs from bootstrap circularity. 82 VSPECIES.dummyVector(); 83 VSPECIES.withLanes(LaneType.BYTE); 84 } 85 86 // Specialized extractors 87 88 @ForceInline 89 final @Override 90 public $Type$Species vspecies() { 91 // ISSUE: This should probably be a @Stable 92 // field inside AbstractVector, rather than 93 // a megamorphic method. 94 return VSPECIES; 95 } 96 97 @ForceInline 98 @Override 99 public final Class<$Boxtype$> elementType() { return $type$.class; } 100 101 @ForceInline 102 @Override 103 public final int elementSize() { return $Boxtype$.SIZE; } 104 105 @ForceInline 106 @Override 107 public final VectorShape shape() { return VSHAPE; } 108 109 @ForceInline 110 @Override 111 public final int length() { return VLENGTH; } 112 113 @ForceInline 114 @Override 115 public final int bitSize() { return VSIZE; } 116 117 @ForceInline 118 @Override 119 public final int byteSize() { return VSIZE / Byte.SIZE; } 120 121 /*package-private*/ 122 @ForceInline 123 final @Override 124 $type$[] getElements() { 125 return VectorIntrinsics.maybeRebox(this).vec; 126 } 127 128 // Virtualized constructors 129 130 @Override 131 @ForceInline 132 public final $vectortype$ broadcast($type$ e) { 133 return ($vectortype$) super.broadcastTemplate(e); // specialize 134 } 135 136 #if[!long] 137 @Override 138 @ForceInline 139 public final $vectortype$ broadcast(long e) { 140 return ($vectortype$) super.broadcastTemplate(e); // specialize 141 } 142 #end[!long] 143 144 @Override 145 @ForceInline 146 $masktype$ maskFromArray(boolean[] bits) { 147 return new $masktype$(bits); 148 } 149 150 @Override 151 @ForceInline 152 $shuffletype$ iotaShuffle() { return $shuffletype$.IOTA; } 153 154 @ForceInline 155 $shuffletype$ iotaShuffle(int start) { 156 return ($shuffletype$)VectorIntrinsics.shuffleIota(ETYPE, $shuffletype$.class, VSPECIES, VLENGTH, start, (val, l) -> new $shuffletype$(i -> (VectorIntrinsics.wrapToRange(i + val, l)))); 157 } 158 159 @Override 160 @ForceInline 161 $shuffletype$ shuffleFromBytes(byte[] reorder) { return new $shuffletype$(reorder); } 162 163 @Override 164 @ForceInline 165 $shuffletype$ shuffleFromArray(int[] indexes, int i) { return new $shuffletype$(indexes, i); } 166 167 @Override 168 @ForceInline 169 $shuffletype$ shuffleFromOp(IntUnaryOperator fn) { return new $shuffletype$(fn); } 170 171 // Make a vector of the same species but the given elements: 172 @ForceInline 173 final @Override 174 $vectortype$ vectorFactory($type$[] vec) { 175 return new $vectortype$(vec); 176 } 177 178 @ForceInline 179 final @Override 180 Byte$bits$Vector asByteVectorRaw() { 181 return (Byte$bits$Vector) super.asByteVectorRawTemplate(); // specialize 182 } 183 184 @ForceInline 185 final @Override 186 AbstractVector<?> asVectorRaw(LaneType laneType) { 187 return super.asVectorRawTemplate(laneType); // specialize 188 } 189 190 // Unary operator 191 192 final @Override 193 $vectortype$ uOp(FUnOp f) { 194 return ($vectortype$) super.uOpTemplate(f); // specialize 195 } 196 197 @ForceInline 198 final @Override 199 $vectortype$ uOp(VectorMask<$Boxtype$> m, FUnOp f) { 200 return ($vectortype$) 201 super.uOpTemplate(($masktype$)m, f); // specialize 202 } 203 204 // Binary operator 205 206 @ForceInline 207 final @Override 208 $vectortype$ bOp(Vector<$Boxtype$> v, FBinOp f) { 209 return ($vectortype$) super.bOpTemplate(($vectortype$)v, f); // specialize 210 } 211 212 @ForceInline 213 final @Override 214 $vectortype$ bOp(Vector<$Boxtype$> v, 215 VectorMask<$Boxtype$> m, FBinOp f) { 216 return ($vectortype$) 217 super.bOpTemplate(($vectortype$)v, ($masktype$)m, 218 f); // specialize 219 } 220 221 // Ternary operator 222 223 @ForceInline 224 final @Override 225 $vectortype$ tOp(Vector<$Boxtype$> v1, Vector<$Boxtype$> v2, FTriOp f) { 226 return ($vectortype$) 227 super.tOpTemplate(($vectortype$)v1, ($vectortype$)v2, 228 f); // specialize 229 } 230 231 @ForceInline 232 final @Override 233 $vectortype$ tOp(Vector<$Boxtype$> v1, Vector<$Boxtype$> v2, 234 VectorMask<$Boxtype$> m, FTriOp f) { 235 return ($vectortype$) 236 super.tOpTemplate(($vectortype$)v1, ($vectortype$)v2, 237 ($masktype$)m, f); // specialize 238 } 239 240 @ForceInline 241 final @Override 242 $type$ rOp($type$ v, FBinOp f) { 243 return super.rOpTemplate(v, f); // specialize 244 } 245 246 @Override 247 @ForceInline 248 public final <F> 249 Vector<F> convertShape(VectorOperators.Conversion<$Boxtype$,F> conv, 250 VectorSpecies<F> rsp, int part) { 251 return super.convertShapeTemplate(conv, rsp, part); // specialize 252 } 253 254 @Override 255 @ForceInline 256 public final <F> 257 Vector<F> reinterpretShape(VectorSpecies<F> toSpecies, int part) { 258 return super.reinterpretShapeTemplate(toSpecies, part); // specialize 259 } 260 261 // Specialized algebraic operations: 262 263 // The following definition forces a specialized version of this 264 // crucial method into the v-table of this class. A call to add() 265 // will inline to a call to lanewise(ADD,), at which point the JIT 266 // intrinsic will have the opcode of ADD, plus all the metadata 267 // for this particular class, enabling it to generate precise 268 // code. 269 // 270 // There is probably no benefit to the JIT to specialize the 271 // masked or broadcast versions of the lanewise method. 272 273 @Override 274 @ForceInline 275 public $vectortype$ lanewise(Unary op) { 276 return ($vectortype$) super.lanewiseTemplate(op); // specialize 277 } 278 279 @Override 280 @ForceInline 281 public $vectortype$ lanewise(Binary op, Vector<$Boxtype$> v) { 282 return ($vectortype$) super.lanewiseTemplate(op, v); // specialize 283 } 284 285 #if[!FP] 286 /*package-private*/ 287 @Override 288 @ForceInline $vectortype$ 289 lanewiseShift(VectorOperators.Binary op, int e) { 290 return ($vectortype$) super.lanewiseShiftTemplate(op, e); // specialize 291 } 292 #end[!FP] 293 294 /*package-private*/ 295 @Override 296 @ForceInline 297 public final 298 $vectortype$ 299 lanewise(VectorOperators.Ternary op, Vector<$Boxtype$> v1, Vector<$Boxtype$> v2) { 300 return ($vectortype$) super.lanewiseTemplate(op, v1, v2); // specialize 301 } 302 303 @Override 304 @ForceInline 305 public final 306 $vectortype$ addIndex(int scale) { 307 return ($vectortype$) super.addIndexTemplate(scale); // specialize 308 } 309 310 // Type specific horizontal reductions 311 312 @Override 313 @ForceInline 314 public final $type$ reduceLanes(VectorOperators.Associative op) { 315 return super.reduceLanesTemplate(op); // specialized 316 } 317 318 @Override 319 @ForceInline 320 public final $type$ reduceLanes(VectorOperators.Associative op, 321 VectorMask<$Boxtype$> m) { 322 return super.reduceLanesTemplate(op, m); // specialized 323 } 324 325 @Override 326 @ForceInline 327 public final long reduceLanesToLong(VectorOperators.Associative op) { 328 return (long) super.reduceLanesTemplate(op); // specialized 329 } 330 331 @Override 332 @ForceInline 333 public final long reduceLanesToLong(VectorOperators.Associative op, 334 VectorMask<$Boxtype$> m) { 335 return (long) super.reduceLanesTemplate(op, m); // specialized 336 } 337 338 @Override 339 @ForceInline 340 public VectorShuffle<$Boxtype$> toShuffle() { 341 $type$[] a = toArray(); 342 int[] sa = new int[a.length]; 343 for (int i = 0; i < a.length; i++) { 344 sa[i] = (int) a[i]; 345 } 346 return VectorShuffle.fromArray(VSPECIES, sa, 0); 347 } 348 349 // Specialized unary testing 350 351 @Override 352 @ForceInline 353 public final $masktype$ test(Test op) { 354 return super.testTemplate($masktype$.class, op); // specialize 355 } 356 357 // Specialized comparisons 358 359 @Override 360 @ForceInline 361 public final $masktype$ compare(Comparison op, Vector<$Boxtype$> v) { 362 return super.compareTemplate($masktype$.class, op, v); // specialize 363 } 364 365 @Override 366 @ForceInline 367 public final $masktype$ compare(Comparison op, $type$ s) { 368 return super.compareTemplate($masktype$.class, op, s); // specialize 369 } 370 371 #if[!long] 372 @Override 373 @ForceInline 374 public final $masktype$ compare(Comparison op, long s) { 375 return super.compareTemplate($masktype$.class, op, s); // specialize 376 } 377 #end[!long] 378 379 @Override 380 @ForceInline 381 public $vectortype$ blend(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) { 382 return ($vectortype$) 383 super.blendTemplate($masktype$.class, 384 ($vectortype$) v, 385 ($masktype$) m); // specialize 386 } 387 388 @Override 389 @ForceInline 390 public $vectortype$ slice(int origin, Vector<$Boxtype$> v) { 391 return ($vectortype$) super.sliceTemplate(origin, v); // specialize 392 } 393 394 @Override 395 @ForceInline 396 public $vectortype$ slice(int origin) { 397 if ((origin < 0) || (origin >= VLENGTH)) { 398 throw new ArrayIndexOutOfBoundsException("Index " + origin + " out of bounds for vector length " + VLENGTH); 399 } else { 400 $shuffletype$ Iota = ($shuffletype$)VectorShuffle.iota(VSPECIES, 0, 1, true); 401 VectorMask<$Boxtype$> BlendMask = Iota.toVector().compare(VectorOperators.LT, (broadcast(($type$)(VLENGTH-origin)))); 402 Iota = ($shuffletype$)VectorShuffle.iota(VSPECIES, origin, 1, true); 403 return ZERO.blend(this.rearrange(Iota), BlendMask); 404 } 405 } 406 407 @Override 408 @ForceInline 409 public $vectortype$ unslice(int origin, Vector<$Boxtype$> w, int part) { 410 return ($vectortype$) super.unsliceTemplate(origin, w, part); // specialize 411 } 412 413 @Override 414 @ForceInline 415 public $vectortype$ unslice(int origin, Vector<$Boxtype$> w, int part, VectorMask<$Boxtype$> m) { 416 return ($vectortype$) 417 super.unsliceTemplate($masktype$.class, 418 origin, w, part, 419 ($masktype$) m); // specialize 420 } 421 422 @Override 423 @ForceInline 424 public $vectortype$ unslice(int origin) { 425 if ((origin < 0) || (origin >= VLENGTH)) { 426 throw new ArrayIndexOutOfBoundsException("Index " + origin + " out of bounds for vector length " + VLENGTH); 427 } else { 428 $shuffletype$ Iota = ($shuffletype$)VectorShuffle.iota(VSPECIES, 0, 1, true); 429 VectorMask<$Boxtype$> BlendMask = Iota.toVector().compare(VectorOperators.GE, (broadcast(($type$)(origin)))); 430 Iota = ($shuffletype$)VectorShuffle.iota(VSPECIES, -origin, 1, true); 431 return ZERO.blend(this.rearrange(Iota), BlendMask); 432 } 433 } 434 435 @Override 436 @ForceInline 437 public $vectortype$ rearrange(VectorShuffle<$Boxtype$> s) { 438 return ($vectortype$) 439 super.rearrangeTemplate($shuffletype$.class, 440 ($shuffletype$) s); // specialize 441 } 442 443 @Override 444 @ForceInline 445 public $vectortype$ rearrange(VectorShuffle<$Boxtype$> shuffle, 446 VectorMask<$Boxtype$> m) { 447 return ($vectortype$) 448 super.rearrangeTemplate($shuffletype$.class, 449 ($shuffletype$) shuffle, 450 ($masktype$) m); // specialize 451 } 452 453 @Override 454 @ForceInline 455 public $vectortype$ rearrange(VectorShuffle<$Boxtype$> s, 456 Vector<$Boxtype$> v) { 457 return ($vectortype$) 458 super.rearrangeTemplate($shuffletype$.class, 459 ($shuffletype$) s, 460 ($vectortype$) v); // specialize 461 } 462 463 @Override 464 @ForceInline 465 public $vectortype$ selectFrom(Vector<$Boxtype$> v) { 466 return ($vectortype$) 467 super.selectFromTemplate(($vectortype$) v); // specialize 468 } 469 470 @Override 471 @ForceInline 472 public $vectortype$ selectFrom(Vector<$Boxtype$> v, 473 VectorMask<$Boxtype$> m) { 474 return ($vectortype$) 475 super.selectFromTemplate(($vectortype$) v, 476 ($masktype$) m); // specialize 477 } 478 479 480 #if[FP] 481 @Override 482 public $type$ lane(int i) { 483 if (i < 0 || i >= VLENGTH) { 484 throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + VLENGTH); 485 } 486 $bitstype$ bits = ($bitstype$) VectorIntrinsics.extract( 487 VCLASS, ETYPE, VLENGTH, 488 this, i, 489 (vec, ix) -> { 490 $type$[] vecarr = vec.getElements(); 491 return (long)$Type$.$type$To$Bitstype$Bits(vecarr[ix]); 492 }); 493 return $Type$.$bitstype$BitsTo$Fptype$(bits); 494 } 495 496 @Override 497 public $vectortype$ withLane(int i, $type$ e) { 498 if (i < 0 || i >= VLENGTH) { 499 throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + VLENGTH); 500 } 501 return VectorIntrinsics.insert( 502 VCLASS, ETYPE, VLENGTH, 503 this, i, (long)$Type$.$type$To$Bitstype$Bits(e), 504 (v, ix, bits) -> { 505 $type$[] res = v.getElements().clone(); 506 res[ix] = $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits); 507 return v.vectorFactory(res); 508 }); 509 } 510 #else[FP] 511 @Override 512 public $type$ lane(int i) { 513 if (i < 0 || i >= VLENGTH) { 514 throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + VLENGTH); 515 } 516 return ($type$) VectorIntrinsics.extract( 517 VCLASS, ETYPE, VLENGTH, 518 this, i, 519 (vec, ix) -> { 520 $type$[] vecarr = vec.getElements(); 521 return (long)vecarr[ix]; 522 }); 523 } 524 525 @Override 526 public $vectortype$ withLane(int i, $type$ e) { 527 if (i < 0 || i >= VLENGTH) { 528 throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + VLENGTH); 529 } 530 return VectorIntrinsics.insert( 531 VCLASS, ETYPE, VLENGTH, 532 this, i, (long)e, 533 (v, ix, bits) -> { 534 $type$[] res = v.getElements().clone(); 535 res[ix] = ($type$)bits; 536 return v.vectorFactory(res); 537 }); 538 } 539 #end[FP] 540 541 // Mask 542 543 static final class $masktype$ extends AbstractMask<$Boxtype$> { 544 545 private final boolean[] bits; // Don't access directly, use getBits() instead. 546 547 public $masktype$(boolean[] bits) { 548 this(bits, 0); 549 } 550 551 public $masktype$(boolean[] bits, int offset) { 552 boolean[] a = new boolean[vspecies().laneCount()]; 553 for (int i = 0; i < a.length; i++) { 554 a[i] = bits[offset + i]; 555 } 556 this.bits = a; 557 } 558 559 public $masktype$(boolean val) { 560 boolean[] bits = new boolean[vspecies().laneCount()]; 561 Arrays.fill(bits, val); 562 this.bits = bits; 563 } 564 565 @ForceInline 566 final @Override 567 public $Type$Species vspecies() { 568 // ISSUE: This should probably be a @Stable 569 // field inside AbstractMask, rather than 570 // a megamorphic method. 571 return VSPECIES; 572 } 573 574 boolean[] getBits() { 575 return VectorIntrinsics.maybeRebox(this).bits; 576 } 577 578 @Override 579 $masktype$ uOp(MUnOp f) { 580 boolean[] res = new boolean[vspecies().laneCount()]; 581 boolean[] bits = getBits(); 582 for (int i = 0; i < res.length; i++) { 583 res[i] = f.apply(i, bits[i]); 584 } 585 return new $masktype$(res); 586 } 587 588 @Override 589 $masktype$ bOp(VectorMask<$Boxtype$> m, MBinOp f) { 590 boolean[] res = new boolean[vspecies().laneCount()]; 591 boolean[] bits = getBits(); 592 boolean[] mbits = (($masktype$)m).getBits(); 593 for (int i = 0; i < res.length; i++) { 594 res[i] = f.apply(i, bits[i], mbits[i]); 595 } 596 return new $masktype$(res); 597 } 598 599 @ForceInline 600 @Override 601 public final 602 $vectortype$ toVector() { 603 return ($vectortype$) super.toVectorTemplate(); // specialize 604 } 605 606 @Override 607 @ForceInline 608 public <E> VectorMask<E> cast(VectorSpecies<E> s) { 609 AbstractSpecies<E> species = (AbstractSpecies<E>) s; 610 if (length() != species.laneCount()) 611 throw new IllegalArgumentException("VectorMask length and species length differ"); 612 boolean[] maskArray = toArray(); 613 // enum-switches don't optimize properly JDK-8161245 614 switch (species.laneType.switchKey) { 615 case LaneType.SK_BYTE: 616 return new Byte$bits$Vector.Byte$bits$Mask(maskArray).check(species); 617 case LaneType.SK_SHORT: 618 return new Short$bits$Vector.Short$bits$Mask(maskArray).check(species); 619 case LaneType.SK_INT: 620 return new Int$bits$Vector.Int$bits$Mask(maskArray).check(species); 621 case LaneType.SK_LONG: 622 return new Long$bits$Vector.Long$bits$Mask(maskArray).check(species); 623 case LaneType.SK_FLOAT: 624 return new Float$bits$Vector.Float$bits$Mask(maskArray).check(species); 625 case LaneType.SK_DOUBLE: 626 return new Double$bits$Vector.Double$bits$Mask(maskArray).check(species); 627 } 628 629 // Should not reach here. 630 throw new AssertionError(species); 631 } 632 633 // Unary operations 634 635 @Override 636 @ForceInline 637 public $masktype$ not() { 638 return ($masktype$) VectorIntrinsics.unaryOp( 639 VECTOR_OP_NOT, $masktype$.class, $bitstype$.class, VLENGTH, 640 this, 641 (m1) -> m1.uOp((i, a) -> !a)); 642 } 643 644 // Binary operations 645 646 @Override 647 @ForceInline 648 public $masktype$ and(VectorMask<$Boxtype$> mask) { 649 Objects.requireNonNull(mask); 650 $masktype$ m = ($masktype$)mask; 651 return VectorIntrinsics.binaryOp(VECTOR_OP_AND, $masktype$.class, $bitstype$.class, VLENGTH, 652 this, m, 653 (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b)); 654 } 655 656 @Override 657 @ForceInline 658 public $masktype$ or(VectorMask<$Boxtype$> mask) { 659 Objects.requireNonNull(mask); 660 $masktype$ m = ($masktype$)mask; 661 return VectorIntrinsics.binaryOp(VECTOR_OP_OR, $masktype$.class, $bitstype$.class, VLENGTH, 662 this, m, 663 (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b)); 664 } 665 666 // Reductions 667 668 @Override 669 @ForceInline 670 public boolean anyTrue() { 671 return VectorIntrinsics.test(BT_ne, $masktype$.class, $bitstype$.class, VLENGTH, 672 this, this, 673 (m, __) -> anyTrueHelper((($masktype$)m).getBits())); 674 } 675 676 @Override 677 @ForceInline 678 public boolean allTrue() { 679 return VectorIntrinsics.test(BT_overflow, $masktype$.class, $bitstype$.class, VLENGTH, 680 this, vspecies().maskAll(true), 681 (m, __) -> allTrueHelper((($masktype$)m).getBits())); 682 } 683 684 /*package-private*/ 685 static $masktype$ maskAll(boolean bit) { 686 return bit ? TRUE_MASK : FALSE_MASK; 687 } 688 static final $masktype$ TRUE_MASK = new $masktype$(true); 689 static final $masktype$ FALSE_MASK = new $masktype$(false); 690 } 691 692 // Shuffle 693 694 static final class $shuffletype$ extends AbstractShuffle<$Boxtype$> { 695 $shuffletype$(byte[] reorder) { 696 super(reorder); 697 } 698 699 public $shuffletype$(int[] reorder) { 700 super(reorder); 701 } 702 703 public $shuffletype$(int[] reorder, int i) { 704 super(reorder, i); 705 } 706 707 public $shuffletype$(IntUnaryOperator fn) { 708 super(fn); 709 } 710 711 @Override 712 public $Type$Species vspecies() { 713 return VSPECIES; 714 } 715 716 static { 717 // There must be enough bits in the shuffle lanes to encode 718 // VLENGTH valid indexes and VLENGTH exceptional ones. 719 assert(VLENGTH < Byte.MAX_VALUE); 720 assert(Byte.MIN_VALUE <= -VLENGTH); 721 } 722 static final $shuffletype$ IOTA = new $shuffletype$(IDENTITY); 723 724 @Override 725 @ForceInline 726 public $vectortype$ toVector() { 727 return VectorIntrinsics.shuffleToVector(VCLASS, ETYPE, $shuffletype$.class, this, VLENGTH, 728 (s) -> (($vectortype$)(((AbstractShuffle<$Boxtype$>)(s)).toVectorTemplate()))); 729 } 730 731 @Override 732 @ForceInline 733 public <F> VectorShuffle<F> cast(VectorSpecies<F> s) { 734 AbstractSpecies<F> species = (AbstractSpecies<F>) s; 735 if (length() != species.laneCount()) 736 throw new IllegalArgumentException("VectorShuffle length and species length differ"); 737 int[] shuffleArray = toArray(); 738 // enum-switches don't optimize properly JDK-8161245 739 switch (species.laneType.switchKey) { 740 case LaneType.SK_BYTE: 741 return new Byte$bits$Vector.Byte$bits$Shuffle(shuffleArray).check(species); 742 case LaneType.SK_SHORT: 743 return new Short$bits$Vector.Short$bits$Shuffle(shuffleArray).check(species); 744 case LaneType.SK_INT: 745 return new Int$bits$Vector.Int$bits$Shuffle(shuffleArray).check(species); 746 case LaneType.SK_LONG: 747 return new Long$bits$Vector.Long$bits$Shuffle(shuffleArray).check(species); 748 case LaneType.SK_FLOAT: 749 return new Float$bits$Vector.Float$bits$Shuffle(shuffleArray).check(species); 750 case LaneType.SK_DOUBLE: 751 return new Double$bits$Vector.Double$bits$Shuffle(shuffleArray).check(species); 752 } 753 754 // Should not reach here. 755 throw new AssertionError(species); 756 } 757 758 @Override 759 public $shuffletype$ rearrange(VectorShuffle<$Boxtype$> shuffle) { 760 $shuffletype$ s = ($shuffletype$) shuffle; 761 byte[] r = new byte[reorder.length]; 762 for (int i = 0; i < reorder.length; i++) { 763 int ssi = s.reorder[i]; 764 r[i] = this.reorder[ssi]; // throws on exceptional index 765 } 766 return new $shuffletype$(r); 767 } 768 } 769 770 // ================================================ 771 772 // Specialized low-level memory operations. 773 774 @ForceInline 775 @Override 776 final 777 $abstractvectortype$ fromArray0($type$[] a, int offset) { 778 return super.fromArray0Template(a, offset); // specialize 779 } 780 781 @ForceInline 782 @Override 783 final 784 $abstractvectortype$ fromByteArray0(byte[] a, int offset) { 785 return super.fromByteArray0Template(a, offset); // specialize 786 } 787 788 @ForceInline 789 @Override 790 final 791 $abstractvectortype$ fromByteBuffer0(ByteBuffer bb, int offset) { 792 return super.fromByteBuffer0Template(bb, offset); // specialize 793 } 794 795 @ForceInline 796 @Override 797 final 798 void intoArray0($type$[] a, int offset) { 799 super.intoArray0Template(a, offset); // specialize 800 } 801 802 @ForceInline 803 @Override 804 final 805 void intoByteArray0(byte[] a, int offset) { 806 super.intoByteArray0Template(a, offset); // specialize 807 } 808 809 // End of specialized low-level memory operations. 810 811 // ================================================ 812 813 }