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