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