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