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 }