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