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