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