1 /*
   2  * Copyright (c) 2017, 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
  23  * questions.
  24  */
  25 package jdk.incubator.vector;
  26 
  27 import java.nio.ByteBuffer;
  28 import java.nio.LongBuffer;
  29 import java.nio.ByteOrder;
  30 import java.util.Objects;
  31 import java.util.function.IntUnaryOperator;
  32 import java.util.concurrent.ThreadLocalRandom;
  33 
  34 import jdk.internal.misc.Unsafe;
  35 import jdk.internal.vm.annotation.ForceInline;
  36 import static jdk.incubator.vector.VectorIntrinsics.*;
  37 
  38 
  39 /**
  40  * A specialized {@link Vector} representing an ordered immutable sequence of
  41  * {@code long} values.
  42  */
  43 @SuppressWarnings("cast")
  44 public abstract class LongVector extends Vector<Long> {
  45 
  46     LongVector() {}
  47 
  48     private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_LONG_INDEX_SCALE);
  49 
  50     // Unary operator
  51 
  52     interface FUnOp {
  53         long apply(int i, long a);
  54     }
  55 
  56     abstract LongVector uOp(FUnOp f);
  57 
  58     abstract LongVector uOp(Mask<Long> m, FUnOp f);
  59 
  60     // Binary operator
  61 
  62     interface FBinOp {
  63         long apply(int i, long a, long b);
  64     }
  65 
  66     abstract LongVector bOp(Vector<Long> v, FBinOp f);
  67 
  68     abstract LongVector bOp(Vector<Long> v, Mask<Long> m, FBinOp f);
  69 
  70     // Trinary operator
  71 
  72     interface FTriOp {
  73         long apply(int i, long a, long b, long c);
  74     }
  75 
  76     abstract LongVector tOp(Vector<Long> v1, Vector<Long> v2, FTriOp f);
  77 
  78     abstract LongVector tOp(Vector<Long> v1, Vector<Long> v2, Mask<Long> m, FTriOp f);
  79 
  80     // Reduction operator
  81 
  82     abstract long rOp(long v, FBinOp f);
  83 
  84     // Binary test
  85 
  86     interface FBinTest {
  87         boolean apply(int i, long a, long b);
  88     }
  89 
  90     abstract Mask<Long> bTest(Vector<Long> v, FBinTest f);
  91 
  92     // Foreach
  93 
  94     interface FUnCon {
  95         void apply(int i, long a);
  96     }
  97 
  98     abstract void forEach(FUnCon f);
  99 
 100     abstract void forEach(Mask<Long> m, FUnCon f);
 101 
 102     // Static factories
 103 
 104     /**
 105      * Returns a vector where all lane elements are set to the default
 106      * primitive value.
 107      *
 108      * @param species species of desired vector
 109      * @return a zero vector of given species
 110      */
 111     @ForceInline
 112     @SuppressWarnings("unchecked")
 113     public static LongVector zero(LongSpecies species) {
 114         return species.zero();
 115     }
 116 
 117     /**
 118      * Loads a vector from a byte array starting at an offset.
 119      * <p>
 120      * Bytes are composed into primitive lane elements according to the
 121      * native byte order of the underlying platform
 122      * <p>
 123      * This method behaves as if it returns the result of calling the
 124      * byte buffer, offset, and mask accepting
 125      * {@link #fromByteBuffer(LongSpecies, ByteBuffer, int, Mask) method} as follows:
 126      * <pre>{@code
 127      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue());
 128      * }</pre>
 129      *
 130      * @param species species of desired vector
 131      * @param a the byte array
 132      * @param ix the offset into the array
 133      * @return a vector loaded from a byte array
 134      * @throws IndexOutOfBoundsException if {@code i < 0} or
 135      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 136      */
 137     @ForceInline
 138     @SuppressWarnings("unchecked")
 139     public static LongVector fromByteArray(LongSpecies species, byte[] a, int ix) {
 140         Objects.requireNonNull(a);
 141         ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE);
 142         return VectorIntrinsics.load((Class<LongVector>) species.boxType(), long.class, species.length(),
 143                                      a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 144                                      a, ix, species,
 145                                      (c, idx, s) -> {
 146                                          ByteBuffer bbc = ByteBuffer.wrap(c, idx, a.length - idx).order(ByteOrder.nativeOrder());
 147                                          LongBuffer tb = bbc.asLongBuffer();
 148                                          return ((LongSpecies)s).op(i -> tb.get());
 149                                      });
 150     }
 151 
 152     /**
 153      * Loads a vector from a byte array starting at an offset and using a
 154      * mask.
 155      * <p>
 156      * Bytes are composed into primitive lane elements according to the
 157      * native byte order of the underlying platform.
 158      * <p>
 159      * This method behaves as if it returns the result of calling the
 160      * byte buffer, offset, and mask accepting
 161      * {@link #fromByteBuffer(LongSpecies, ByteBuffer, int, Mask) method} as follows:
 162      * <pre>{@code
 163      * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m);
 164      * }</pre>
 165      *
 166      * @param species species of desired vector
 167      * @param a the byte array
 168      * @param ix the offset into the array
 169      * @param m the mask
 170      * @return a vector loaded from a byte array
 171      * @throws IndexOutOfBoundsException if {@code i < 0} or
 172      * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)}
 173      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 174      * or {@code > a.length},
 175      * for any vector lane index {@code N} where the mask at lane {@code N}
 176      * is set
 177      * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)}
 178      */
 179     @ForceInline
 180     public static LongVector fromByteArray(LongSpecies species, byte[] a, int ix, Mask<Long> m) {
 181         return zero(species).blend(fromByteArray(species, a, ix), m);
 182     }
 183 
 184     /**
 185      * Loads a vector from an array starting at offset.
 186      * <p>
 187      * For each vector lane, where {@code N} is the vector lane index, the
 188      * array element at index {@code i + N} is placed into the
 189      * resulting vector at lane index {@code N}.
 190      *
 191      * @param species species of desired vector
 192      * @param a the array
 193      * @param i the offset into the array
 194      * @return the vector loaded from an array
 195      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 196      * {@code i > a.length - this.length()}
 197      */
 198     @ForceInline
 199     @SuppressWarnings("unchecked")
 200     public static LongVector fromArray(LongSpecies species, long[] a, int i){
 201         Objects.requireNonNull(a);
 202         i = VectorIntrinsics.checkIndex(i, a.length, species.length());
 203         return VectorIntrinsics.load((Class<LongVector>) species.boxType(), long.class, species.length(),
 204                                      a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_LONG_BASE_OFFSET,
 205                                      a, i, species,
 206                                      (c, idx, s) -> ((LongSpecies)s).op(n -> c[idx + n]));
 207     }
 208 
 209 
 210     /**
 211      * Loads a vector from an array starting at offset and using a mask.
 212      * <p>
 213      * For each vector lane, where {@code N} is the vector lane index,
 214      * if the mask lane at index {@code N} is set then the array element at
 215      * index {@code i + N} is placed into the resulting vector at lane index
 216      * {@code N}, otherwise the default element value is placed into the
 217      * resulting vector at lane index {@code N}.
 218      *
 219      * @param species species of desired vector
 220      * @param a the array
 221      * @param i the offset into the array
 222      * @param m the mask
 223      * @return the vector loaded from an array
 224      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 225      * for any vector lane index {@code N} where the mask at lane {@code N}
 226      * is set {@code i > a.length - N}
 227      */
 228     @ForceInline
 229     public static LongVector fromArray(LongSpecies species, long[] a, int i, Mask<Long> m) {
 230         return zero(species).blend(fromArray(species, a, i), m);
 231     }
 232 
 233     /**
 234      * Loads a vector from an array using indexes obtained from an index
 235      * map.
 236      * <p>
 237      * For each vector lane, where {@code N} is the vector lane index, the
 238      * array element at index {@code i + indexMap[j + N]} is placed into the
 239      * resulting vector at lane index {@code N}.
 240      *
 241      * @param species species of desired vector
 242      * @param a the array
 243      * @param i the offset into the array, may be negative if relative
 244      * indexes in the index map compensate to produce a value within the
 245      * array bounds
 246      * @param indexMap the index map
 247      * @param j the offset into the index map
 248      * @return the vector loaded from an array
 249      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 250      * {@code j > indexMap.length - this.length()},
 251      * or for any vector lane index {@code N} the result of
 252      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 253      */
 254     @ForceInline
 255     @SuppressWarnings("unchecked")
 256     public static LongVector fromArray(LongSpecies species, long[] a, int i, int[] indexMap, int j) {
 257         Objects.requireNonNull(a);
 258         Objects.requireNonNull(indexMap);
 259 
 260         if (species.length() == 1) {
 261           return LongVector.fromArray(species, a, i + indexMap[j]);
 262         }
 263 
 264         // Index vector: vix[0:n] = k -> i + indexMap[j + i]
 265         IntVector vix;
 266         if (species.indexMask() != null) {
 267             vix = IntVector.fromArray(species.indexSpecies(), indexMap, j, species.indexMask()).add(i);
 268         } else {
 269             vix = IntVector.fromArray(species.indexSpecies(), indexMap, j).add(i);
 270         }
 271 
 272         vix = VectorIntrinsics.checkIndex(vix, a.length);
 273 
 274         return VectorIntrinsics.loadWithMap((Class<LongVector>) species.boxType(), long.class, species.length(),
 275                                             species.indexSpecies().vectorType(), a, Unsafe.ARRAY_LONG_BASE_OFFSET, vix,
 276                                             a, i, indexMap, j, species,
 277                                            (c, idx, iMap, idy, s) -> ((LongSpecies)s).op(n -> c[idx + iMap[idy+n]]));
 278         }
 279 
 280     /**
 281      * Loads a vector from an array using indexes obtained from an index
 282      * map and using a mask.
 283      * <p>
 284      * For each vector lane, where {@code N} is the vector lane index,
 285      * if the mask lane at index {@code N} is set then the array element at
 286      * index {@code i + indexMap[j + N]} is placed into the resulting vector
 287      * at lane index {@code N}.
 288      *
 289      * @param species species of desired vector
 290      * @param a the array
 291      * @param i the offset into the array, may be negative if relative
 292      * indexes in the index map compensate to produce a value within the
 293      * array bounds
 294      * @param m the mask
 295      * @param indexMap the index map
 296      * @param j the offset into the index map
 297      * @return the vector loaded from an array
 298      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 299      * {@code j > indexMap.length - this.length()},
 300      * or for any vector lane index {@code N} where the mask at lane
 301      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 302      * {@code < 0} or {@code >= a.length}
 303      */
 304     @ForceInline
 305     @SuppressWarnings("unchecked")
 306     public static LongVector fromArray(LongSpecies species, long[] a, int i, Mask<Long> m, int[] indexMap, int j) {
 307         // @@@ This can result in out of bounds errors for unset mask lanes
 308         return zero(species).blend(fromArray(species, a, i, indexMap, j), m);
 309     }
 310 
 311 
 312     /**
 313      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 314      * offset into the byte buffer.
 315      * <p>
 316      * Bytes are composed into primitive lane elements according to the
 317      * native byte order of the underlying platform.
 318      * <p>
 319      * This method behaves as if it returns the result of calling the
 320      * byte buffer, offset, and mask accepting
 321      * {@link #fromByteBuffer(LongSpecies, ByteBuffer, int, Mask)} method} as follows:
 322      * <pre>{@code
 323      *   return this.fromByteBuffer(b, i, this.maskAllTrue())
 324      * }</pre>
 325      *
 326      * @param species species of desired vector
 327      * @param bb the byte buffer
 328      * @param ix the offset into the byte buffer
 329      * @return a vector loaded from a byte buffer
 330      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 331      * or {@code > b.limit()},
 332      * or if there are fewer than
 333      * {@code this.length() * this.elementSize() / Byte.SIZE} bytes
 334      * remaining in the byte buffer from the given offset
 335      */
 336     @ForceInline
 337     @SuppressWarnings("unchecked")
 338     public static LongVector fromByteBuffer(LongSpecies species, ByteBuffer bb, int ix) {
 339         if (bb.order() != ByteOrder.nativeOrder()) {
 340             throw new IllegalArgumentException();
 341         }
 342         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE);
 343         return VectorIntrinsics.load((Class<LongVector>) species.boxType(), long.class, species.length(),
 344                                      U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix,
 345                                      bb, ix, species,
 346                                      (c, idx, s) -> {
 347                                          ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 348                                          LongBuffer tb = bbc.asLongBuffer();
 349                                          return ((LongSpecies)s).op(i -> tb.get());
 350                                      });
 351     }
 352 
 353     /**
 354      * Loads a vector from a {@link ByteBuffer byte buffer} starting at an
 355      * offset into the byte buffer and using a mask.
 356      * <p>
 357      * This method behaves as if the byte buffer is viewed as a primitive
 358      * {@link java.nio.Buffer buffer} for the primitive element type,
 359      * according to the native byte order of the underlying platform, and
 360      * the returned vector is loaded with a mask from a primitive array
 361      * obtained from the primitive buffer.
 362      * The following pseudocode expresses the behaviour, where
 363      * {@coce EBuffer} is the primitive buffer type, {@code e} is the
 364      * primitive element type, and {@code ESpecies<S>} is the primitive
 365      * species for {@code e}:
 366      * <pre>{@code
 367      * EBuffer eb = b.duplicate().
 368      *     order(ByteOrder.nativeOrder()).position(i).
 369      *     asEBuffer();
 370      * e[] es = new e[this.length()];
 371      * for (int n = 0; n < t.length; n++) {
 372      *     if (m.isSet(n))
 373      *         es[n] = eb.get(n);
 374      * }
 375      * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m);
 376      * }</pre>
 377      *
 378      * @param species species of desired vector
 379      * @param bb the byte buffer
 380      * @param ix the offset into the byte buffer
 381      * @param m the mask
 382      * @return a vector loaded from a byte buffer
 383      * @throws IndexOutOfBoundsException if the offset is {@code < 0},
 384      * or {@code > b.limit()},
 385      * for any vector lane index {@code N} where the mask at lane {@code N}
 386      * is set
 387      * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)}
 388      */
 389     @ForceInline
 390     public static LongVector fromByteBuffer(LongSpecies species, ByteBuffer bb, int ix, Mask<Long> m) {
 391         return zero(species).blend(fromByteBuffer(species, bb, ix), m);
 392     }
 393 
 394     /**
 395      * Returns a mask where each lane is set or unset according to given
 396      * {@code boolean} values
 397      * <p>
 398      * For each mask lane, where {@code N} is the mask lane index,
 399      * if the given {@code boolean} value at index {@code N} is {@code true}
 400      * then the mask lane at index {@code N} is set, otherwise it is unset.
 401      *
 402      * @param species mask species
 403      * @param bits the given {@code boolean} values
 404      * @return a mask where each lane is set or unset according to the given {@code boolean} value
 405      * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
 406      */
 407     @ForceInline
 408     public static Mask<Long> maskFromValues(LongSpecies species, boolean... bits) {
 409         if (species.boxType() == LongMaxVector.class)
 410             return new LongMaxVector.LongMaxMask(bits);
 411         switch (species.bitSize()) {
 412             case 64: return new Long64Vector.Long64Mask(bits);
 413             case 128: return new Long128Vector.Long128Mask(bits);
 414             case 256: return new Long256Vector.Long256Mask(bits);
 415             case 512: return new Long512Vector.Long512Mask(bits);
 416             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 417         }
 418     }
 419 
 420     // @@@ This is a bad implementation -- makes lambdas capturing -- fix this
 421     static Mask<Long> trueMask(LongSpecies species) {
 422         if (species.boxType() == LongMaxVector.class)
 423             return LongMaxVector.LongMaxMask.TRUE_MASK;
 424         switch (species.bitSize()) {
 425             case 64: return Long64Vector.Long64Mask.TRUE_MASK;
 426             case 128: return Long128Vector.Long128Mask.TRUE_MASK;
 427             case 256: return Long256Vector.Long256Mask.TRUE_MASK;
 428             case 512: return Long512Vector.Long512Mask.TRUE_MASK;
 429             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 430         }
 431     }
 432 
 433     static Mask<Long> falseMask(LongSpecies species) {
 434         if (species.boxType() == LongMaxVector.class)
 435             return LongMaxVector.LongMaxMask.FALSE_MASK;
 436         switch (species.bitSize()) {
 437             case 64: return Long64Vector.Long64Mask.FALSE_MASK;
 438             case 128: return Long128Vector.Long128Mask.FALSE_MASK;
 439             case 256: return Long256Vector.Long256Mask.FALSE_MASK;
 440             case 512: return Long512Vector.Long512Mask.FALSE_MASK;
 441             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 442         }
 443     }
 444 
 445     /**
 446      * Loads a mask from a {@code boolean} array starting at an offset.
 447      * <p>
 448      * For each mask lane, where {@code N} is the mask lane index,
 449      * if the array element at index {@code ix + N} is {@code true} then the
 450      * mask lane at index {@code N} is set, otherwise it is unset.
 451      *
 452      * @param species mask species
 453      * @param bits the {@code boolean} array
 454      * @param ix the offset into the array
 455      * @return the mask loaded from a {@code boolean} array
 456      * @throws IndexOutOfBoundsException if {@code ix < 0}, or
 457      * {@code ix > bits.length - species.length()}
 458      */
 459     @ForceInline
 460     @SuppressWarnings("unchecked")
 461     public static Mask<Long> maskFromArray(LongSpecies species, boolean[] bits, int ix) {
 462         Objects.requireNonNull(bits);
 463         ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
 464         return VectorIntrinsics.load((Class<Mask<Long>>) species.maskType(), long.class, species.length(),
 465                                      bits, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
 466                                      bits, ix, species,
 467                                      (c, idx, s) -> (Mask<Long>) ((LongSpecies)s).opm(n -> c[idx + n]));
 468     }
 469 
 470     /**
 471      * Returns a mask where all lanes are set.
 472      *
 473      * @param species mask species
 474      * @return a mask where all lanes are set
 475      */
 476     @ForceInline
 477     @SuppressWarnings("unchecked")
 478     public static Mask<Long> maskAllTrue(LongSpecies species) {
 479         return VectorIntrinsics.broadcastCoerced((Class<Mask<Long>>) species.maskType(), long.class, species.length(),
 480                                                  (long)-1,  species,
 481                                                  ((z, s) -> trueMask((LongSpecies)s)));
 482     }
 483 
 484     /**
 485      * Returns a mask where all lanes are unset.
 486      *
 487      * @param species mask species
 488      * @return a mask where all lanes are unset
 489      */
 490     @ForceInline
 491     @SuppressWarnings("unchecked")
 492     public static Mask<Long> maskAllFalse(LongSpecies species) {
 493         return VectorIntrinsics.broadcastCoerced((Class<Mask<Long>>) species.maskType(), long.class, species.length(),
 494                                                  0, species, 
 495                                                  ((z, s) -> falseMask((LongSpecies)s)));
 496     }
 497 
 498     /**
 499      * Returns a shuffle of mapped indexes where each lane element is
 500      * the result of applying a mapping function to the corresponding lane
 501      * index.
 502      * <p>
 503      * Care should be taken to ensure Shuffle values produced from this
 504      * method are consumed as constants to ensure optimal generation of
 505      * code.  For example, values held in static final fields or values
 506      * held in loop constant local variables.
 507      * <p>
 508      * This method behaves as if a shuffle is created from an array of
 509      * mapped indexes as follows:
 510      * <pre>{@code
 511      *   int[] a = new int[species.length()];
 512      *   for (int i = 0; i < a.length; i++) {
 513      *       a[i] = f.applyAsInt(i);
 514      *   }
 515      *   return this.shuffleFromValues(a);
 516      * }</pre>
 517      *
 518      * @param species shuffle species
 519      * @param f the lane index mapping function
 520      * @return a shuffle of mapped indexes
 521      */
 522     @ForceInline
 523     public static Shuffle<Long> shuffle(LongSpecies species, IntUnaryOperator f) {
 524         if (species.boxType() == LongMaxVector.class)
 525             return new LongMaxVector.LongMaxShuffle(f);
 526         switch (species.bitSize()) {
 527             case 64: return new Long64Vector.Long64Shuffle(f);
 528             case 128: return new Long128Vector.Long128Shuffle(f);
 529             case 256: return new Long256Vector.Long256Shuffle(f);
 530             case 512: return new Long512Vector.Long512Shuffle(f);
 531             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 532         }
 533     }
 534 
 535     /**
 536      * Returns a shuffle where each lane element is the value of its
 537      * corresponding lane index.
 538      * <p>
 539      * This method behaves as if a shuffle is created from an identity
 540      * index mapping function as follows:
 541      * <pre>{@code
 542      *   return this.shuffle(i -> i);
 543      * }</pre>
 544      *
 545      * @param species shuffle species
 546      * @return a shuffle of lane indexes
 547      */
 548     @ForceInline
 549     public static Shuffle<Long> shuffleIota(LongSpecies species) {
 550         if (species.boxType() == LongMaxVector.class)
 551             return new LongMaxVector.LongMaxShuffle(AbstractShuffle.IDENTITY);
 552         switch (species.bitSize()) {
 553             case 64: return new Long64Vector.Long64Shuffle(AbstractShuffle.IDENTITY);
 554             case 128: return new Long128Vector.Long128Shuffle(AbstractShuffle.IDENTITY);
 555             case 256: return new Long256Vector.Long256Shuffle(AbstractShuffle.IDENTITY);
 556             case 512: return new Long512Vector.Long512Shuffle(AbstractShuffle.IDENTITY);
 557             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 558         }
 559     }
 560 
 561     /**
 562      * Returns a shuffle where each lane element is set to a given
 563      * {@code int} value logically AND'ed by the species length minus one.
 564      * <p>
 565      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 566      * the {@code int} value at index {@code N} logically AND'ed by
 567      * {@code species.length() - 1} is placed into the resulting shuffle at
 568      * lane index {@code N}.
 569      *
 570      * @param species shuffle species
 571      * @param ixs the given {@code int} values
 572      * @return a shuffle where each lane element is set to a given
 573      * {@code int} value
 574      * @throws IndexOutOfBoundsException if the number of int values is
 575      * {@code < species.length()}
 576      */
 577     @ForceInline
 578     public static Shuffle<Long> shuffleFromValues(LongSpecies species, int... ixs) {
 579         if (species.boxType() == LongMaxVector.class)
 580             return new LongMaxVector.LongMaxShuffle(ixs);
 581         switch (species.bitSize()) {
 582             case 64: return new Long64Vector.Long64Shuffle(ixs);
 583             case 128: return new Long128Vector.Long128Shuffle(ixs);
 584             case 256: return new Long256Vector.Long256Shuffle(ixs);
 585             case 512: return new Long512Vector.Long512Shuffle(ixs);
 586             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 587         }
 588     }
 589 
 590     /**
 591      * Loads a shuffle from an {@code int} array starting at an offset.
 592      * <p>
 593      * For each shuffle lane, where {@code N} is the shuffle lane index, the
 594      * array element at index {@code i + N} logically AND'ed by
 595      * {@code species.length() - 1} is placed into the resulting shuffle at lane
 596      * index {@code N}.
 597      *
 598      * @param species shuffle species
 599      * @param ixs the {@code int} array
 600      * @param i the offset into the array
 601      * @return a shuffle loaded from the {@code int} array
 602      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 603      * {@code i > a.length - species.length()}
 604      */
 605     @ForceInline
 606     public static Shuffle<Long> shuffleFromArray(LongSpecies species, int[] ixs, int i) {
 607         if (species.boxType() == LongMaxVector.class)
 608             return new LongMaxVector.LongMaxShuffle(ixs, i);
 609         switch (species.bitSize()) {
 610             case 64: return new Long64Vector.Long64Shuffle(ixs, i);
 611             case 128: return new Long128Vector.Long128Shuffle(ixs, i);
 612             case 256: return new Long256Vector.Long256Shuffle(ixs, i);
 613             case 512: return new Long512Vector.Long512Shuffle(ixs, i);
 614             default: throw new IllegalArgumentException(Integer.toString(species.bitSize()));
 615         }
 616     }
 617 
 618 
 619     // Ops
 620 
 621     @Override
 622     public abstract LongVector add(Vector<Long> v);
 623 
 624     /**
 625      * Adds this vector to the broadcast of an input scalar.
 626      * <p>
 627      * This is a vector binary operation where the primitive addition operation
 628      * ({@code +}) is applied to lane elements.
 629      *
 630      * @param s the input scalar
 631      * @return the result of adding this vector to the broadcast of an input
 632      * scalar
 633      */
 634     public abstract LongVector add(long s);
 635 
 636     @Override
 637     public abstract LongVector add(Vector<Long> v, Mask<Long> m);
 638 
 639     /**
 640      * Adds this vector to broadcast of an input scalar,
 641      * selecting lane elements controlled by a mask.
 642      * <p>
 643      * This is a vector binary operation where the primitive addition operation
 644      * ({@code +}) is applied to lane elements.
 645      *
 646      * @param s the input scalar
 647      * @param m the mask controlling lane selection
 648      * @return the result of adding this vector to the broadcast of an input
 649      * scalar
 650      */
 651     public abstract LongVector add(long s, Mask<Long> m);
 652 
 653     @Override
 654     public abstract LongVector sub(Vector<Long> v);
 655 
 656     /**
 657      * Subtracts the broadcast of an input scalar from this vector.
 658      * <p>
 659      * This is a vector binary operation where the primitive subtraction
 660      * operation ({@code -}) is applied to lane elements.
 661      *
 662      * @param s the input scalar
 663      * @return the result of subtracting the broadcast of an input
 664      * scalar from this vector
 665      */
 666     public abstract LongVector sub(long s);
 667 
 668     @Override
 669     public abstract LongVector sub(Vector<Long> v, Mask<Long> m);
 670 
 671     /**
 672      * Subtracts the broadcast of an input scalar from this vector, selecting
 673      * lane elements controlled by a mask.
 674      * <p>
 675      * This is a vector binary operation where the primitive subtraction
 676      * operation ({@code -}) is applied to lane elements.
 677      *
 678      * @param s the input scalar
 679      * @param m the mask controlling lane selection
 680      * @return the result of subtracting the broadcast of an input
 681      * scalar from this vector
 682      */
 683     public abstract LongVector sub(long s, Mask<Long> m);
 684 
 685     @Override
 686     public abstract LongVector mul(Vector<Long> v);
 687 
 688     /**
 689      * Multiplies this vector with the broadcast of an input scalar.
 690      * <p>
 691      * This is a vector binary operation where the primitive multiplication
 692      * operation ({@code *}) is applied to lane elements.
 693      *
 694      * @param s the input scalar
 695      * @return the result of multiplying this vector with the broadcast of an
 696      * input scalar
 697      */
 698     public abstract LongVector mul(long s);
 699 
 700     @Override
 701     public abstract LongVector mul(Vector<Long> v, Mask<Long> m);
 702 
 703     /**
 704      * Multiplies this vector with the broadcast of an input scalar, selecting
 705      * lane elements controlled by a mask.
 706      * <p>
 707      * This is a vector binary operation where the primitive multiplication
 708      * operation ({@code *}) is applied to lane elements.
 709      *
 710      * @param s the input scalar
 711      * @param m the mask controlling lane selection
 712      * @return the result of multiplying this vector with the broadcast of an
 713      * input scalar
 714      */
 715     public abstract LongVector mul(long s, Mask<Long> m);
 716 
 717     @Override
 718     public abstract LongVector neg();
 719 
 720     @Override
 721     public abstract LongVector neg(Mask<Long> m);
 722 
 723     @Override
 724     public abstract LongVector abs();
 725 
 726     @Override
 727     public abstract LongVector abs(Mask<Long> m);
 728 
 729     @Override
 730     public abstract LongVector min(Vector<Long> v);
 731 
 732     @Override
 733     public abstract LongVector min(Vector<Long> v, Mask<Long> m);
 734 
 735     /**
 736      * Returns the minimum of this vector and the broadcast of an input scalar.
 737      * <p>
 738      * This is a vector binary operation where the operation
 739      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements.
 740      *
 741      * @param s the input scalar
 742      * @return the minimum of this vector and the broadcast of an input scalar
 743      */
 744     public abstract LongVector min(long s);
 745 
 746     @Override
 747     public abstract LongVector max(Vector<Long> v);
 748 
 749     @Override
 750     public abstract LongVector max(Vector<Long> v, Mask<Long> m);
 751 
 752     /**
 753      * Returns the maximum of this vector and the broadcast of an input scalar.
 754      * <p>
 755      * This is a vector binary operation where the operation
 756      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements.
 757      *
 758      * @param s the input scalar
 759      * @return the maximum of this vector and the broadcast of an input scalar
 760      */
 761     public abstract LongVector max(long s);
 762 
 763     @Override
 764     public abstract Mask<Long> equal(Vector<Long> v);
 765 
 766     /**
 767      * Tests if this vector is equal to the broadcast of an input scalar.
 768      * <p>
 769      * This is a vector binary test operation where the primitive equals
 770      * operation ({@code ==}) is applied to lane elements.
 771      *
 772      * @param s the input scalar
 773      * @return the result mask of testing if this vector is equal to the
 774      * broadcast of an input scalar
 775      */
 776     public abstract Mask<Long> equal(long s);
 777 
 778     @Override
 779     public abstract Mask<Long> notEqual(Vector<Long> v);
 780 
 781     /**
 782      * Tests if this vector is not equal to the broadcast of an input scalar.
 783      * <p>
 784      * This is a vector binary test operation where the primitive not equals
 785      * operation ({@code !=}) is applied to lane elements.
 786      *
 787      * @param s the input scalar
 788      * @return the result mask of testing if this vector is not equal to the
 789      * broadcast of an input scalar
 790      */
 791     public abstract Mask<Long> notEqual(long s);
 792 
 793     @Override
 794     public abstract Mask<Long> lessThan(Vector<Long> v);
 795 
 796     /**
 797      * Tests if this vector is less than the broadcast of an input scalar.
 798      * <p>
 799      * This is a vector binary test operation where the primitive less than
 800      * operation ({@code <}) is applied to lane elements.
 801      *
 802      * @param s the input scalar
 803      * @return the mask result of testing if this vector is less than the
 804      * broadcast of an input scalar
 805      */
 806     public abstract Mask<Long> lessThan(long s);
 807 
 808     @Override
 809     public abstract Mask<Long> lessThanEq(Vector<Long> v);
 810 
 811     /**
 812      * Tests if this vector is less or equal to the broadcast of an input scalar.
 813      * <p>
 814      * This is a vector binary test operation where the primitive less than
 815      * or equal to operation ({@code <=}) is applied to lane elements.
 816      *
 817      * @param s the input scalar
 818      * @return the mask result of testing if this vector is less than or equal
 819      * to the broadcast of an input scalar
 820      */
 821     public abstract Mask<Long> lessThanEq(long s);
 822 
 823     @Override
 824     public abstract Mask<Long> greaterThan(Vector<Long> v);
 825 
 826     /**
 827      * Tests if this vector is greater than the broadcast of an input scalar.
 828      * <p>
 829      * This is a vector binary test operation where the primitive greater than
 830      * operation ({@code >}) is applied to lane elements.
 831      *
 832      * @param s the input scalar
 833      * @return the mask result of testing if this vector is greater than the
 834      * broadcast of an input scalar
 835      */
 836     public abstract Mask<Long> greaterThan(long s);
 837 
 838     @Override
 839     public abstract Mask<Long> greaterThanEq(Vector<Long> v);
 840 
 841     /**
 842      * Tests if this vector is greater than or equal to the broadcast of an
 843      * input scalar.
 844      * <p>
 845      * This is a vector binary test operation where the primitive greater than
 846      * or equal to operation ({@code >=}) is applied to lane elements.
 847      *
 848      * @param s the input scalar
 849      * @return the mask result of testing if this vector is greater than or
 850      * equal to the broadcast of an input scalar
 851      */
 852     public abstract Mask<Long> greaterThanEq(long s);
 853 
 854     @Override
 855     public abstract LongVector blend(Vector<Long> v, Mask<Long> m);
 856 
 857     /**
 858      * Blends the lane elements of this vector with those of the broadcast of an
 859      * input scalar, selecting lanes controlled by a mask.
 860      * <p>
 861      * For each lane of the mask, at lane index {@code N}, if the mask lane
 862      * is set then the lane element at {@code N} from the input vector is
 863      * selected and placed into the resulting vector at {@code N},
 864      * otherwise the the lane element at {@code N} from this input vector is
 865      * selected and placed into the resulting vector at {@code N}.
 866      *
 867      * @param s the input scalar
 868      * @param m the mask controlling lane selection
 869      * @return the result of blending the lane elements of this vector with
 870      * those of the broadcast of an input scalar
 871      */
 872     public abstract LongVector blend(long s, Mask<Long> m);
 873 
 874     @Override
 875     public abstract LongVector rearrange(Vector<Long> v,
 876                                                       Shuffle<Long> s, Mask<Long> m);
 877 
 878     @Override
 879     public abstract LongVector rearrange(Shuffle<Long> m);
 880 
 881     @Override
 882     public abstract LongVector reshape(Species<Long> s);
 883 
 884     @Override
 885     public abstract LongVector rotateEL(int i);
 886 
 887     @Override
 888     public abstract LongVector rotateER(int i);
 889 
 890     @Override
 891     public abstract LongVector shiftEL(int i);
 892 
 893     @Override
 894     public abstract LongVector shiftER(int i);
 895 
 896 
 897 
 898     /**
 899      * Bitwise ANDs this vector with an input vector.
 900      * <p>
 901      * This is a vector binary operation where the primitive bitwise AND
 902      * operation ({@code &}) is applied to lane elements.
 903      *
 904      * @param v the input vector
 905      * @return the bitwise AND of this vector with the input vector
 906      */
 907     public abstract LongVector and(Vector<Long> v);
 908 
 909     /**
 910      * Bitwise ANDs this vector with the broadcast of an input scalar.
 911      * <p>
 912      * This is a vector binary operation where the primitive bitwise AND
 913      * operation ({@code &}) is applied to lane elements.
 914      *
 915      * @param s the input scalar
 916      * @return the bitwise AND of this vector with the broadcast of an input
 917      * scalar
 918      */
 919     public abstract LongVector and(long s);
 920 
 921     /**
 922      * Bitwise ANDs this vector with an input vector, selecting lane elements
 923      * controlled by a mask.
 924      * <p>
 925      * This is a vector binary operation where the primitive bitwise AND
 926      * operation ({@code &}) is applied to lane elements.
 927      *
 928      * @param v the input vector
 929      * @param m the mask controlling lane selection
 930      * @return the bitwise AND of this vector with the input vector
 931      */
 932     public abstract LongVector and(Vector<Long> v, Mask<Long> m);
 933 
 934     /**
 935      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 936      * lane elements controlled by a mask.
 937      * <p>
 938      * This is a vector binary operation where the primitive bitwise AND
 939      * operation ({@code &}) is applied to lane elements.
 940      *
 941      * @param s the input scalar
 942      * @param m the mask controlling lane selection
 943      * @return the bitwise AND of this vector with the broadcast of an input
 944      * scalar
 945      */
 946     public abstract LongVector and(long s, Mask<Long> m);
 947 
 948     /**
 949      * Bitwise ORs this vector with an input vector.
 950      * <p>
 951      * This is a vector binary operation where the primitive bitwise OR
 952      * operation ({@code |}) is applied to lane elements.
 953      *
 954      * @param v the input vector
 955      * @return the bitwise OR of this vector with the input vector
 956      */
 957     public abstract LongVector or(Vector<Long> v);
 958 
 959     /**
 960      * Bitwise ORs this vector with the broadcast of an input scalar.
 961      * <p>
 962      * This is a vector binary operation where the primitive bitwise OR
 963      * operation ({@code |}) is applied to lane elements.
 964      *
 965      * @param s the input scalar
 966      * @return the bitwise OR of this vector with the broadcast of an input
 967      * scalar
 968      */
 969     public abstract LongVector or(long s);
 970 
 971     /**
 972      * Bitwise ORs this vector with an input vector, selecting lane elements
 973      * controlled by a mask.
 974      * <p>
 975      * This is a vector binary operation where the primitive bitwise OR
 976      * operation ({@code |}) is applied to lane elements.
 977      *
 978      * @param v the input vector
 979      * @param m the mask controlling lane selection
 980      * @return the bitwise OR of this vector with the input vector
 981      */
 982     public abstract LongVector or(Vector<Long> v, Mask<Long> m);
 983 
 984     /**
 985      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
 986      * lane elements controlled by a mask.
 987      * <p>
 988      * This is a vector binary operation where the primitive bitwise OR
 989      * operation ({@code |}) is applied to lane elements.
 990      *
 991      * @param s the input scalar
 992      * @param m the mask controlling lane selection
 993      * @return the bitwise OR of this vector with the broadcast of an input
 994      * scalar
 995      */
 996     public abstract LongVector or(long s, Mask<Long> m);
 997 
 998     /**
 999      * Bitwise XORs this vector with an input vector.
1000      * <p>
1001      * This is a vector binary operation where the primitive bitwise XOR
1002      * operation ({@code ^}) is applied to lane elements.
1003      *
1004      * @param v the input vector
1005      * @return the bitwise XOR of this vector with the input vector
1006      */
1007     public abstract LongVector xor(Vector<Long> v);
1008 
1009     /**
1010      * Bitwise XORs this vector with the broadcast of an input scalar.
1011      * <p>
1012      * This is a vector binary operation where the primitive bitwise XOR
1013      * operation ({@code ^}) is applied to lane elements.
1014      *
1015      * @param s the input scalar
1016      * @return the bitwise XOR of this vector with the broadcast of an input
1017      * scalar
1018      */
1019     public abstract LongVector xor(long s);
1020 
1021     /**
1022      * Bitwise XORs this vector with an input vector, selecting lane elements
1023      * controlled by a mask.
1024      * <p>
1025      * This is a vector binary operation where the primitive bitwise XOR
1026      * operation ({@code ^}) is applied to lane elements.
1027      *
1028      * @param v the input vector
1029      * @param m the mask controlling lane selection
1030      * @return the bitwise XOR of this vector with the input vector
1031      */
1032     public abstract LongVector xor(Vector<Long> v, Mask<Long> m);
1033 
1034     /**
1035      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
1036      * lane elements controlled by a mask.
1037      * <p>
1038      * This is a vector binary operation where the primitive bitwise XOR
1039      * operation ({@code ^}) is applied to lane elements.
1040      *
1041      * @param s the input scalar
1042      * @param m the mask controlling lane selection
1043      * @return the bitwise XOR of this vector with the broadcast of an input
1044      * scalar
1045      */
1046     public abstract LongVector xor(long s, Mask<Long> m);
1047 
1048     /**
1049      * Bitwise NOTs this vector.
1050      * <p>
1051      * This is a vector unary operation where the primitive bitwise NOT
1052      * operation ({@code ~}) is applied to lane elements.
1053      *
1054      * @return the bitwise NOT of this vector
1055      */
1056     public abstract LongVector not();
1057 
1058     /**
1059      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
1060      * <p>
1061      * This is a vector unary operation where the primitive bitwise NOT
1062      * operation ({@code ~}) is applied to lane elements.
1063      *
1064      * @param m the mask controlling lane selection
1065      * @return the bitwise NOT of this vector
1066      */
1067     public abstract LongVector not(Mask<Long> m);
1068 
1069     /**
1070      * Logically left shifts this vector by the broadcast of an input scalar.
1071      * <p>
1072      * This is a vector binary operation where the primitive logical left shift
1073      * operation ({@code <<}) is applied to lane elements.
1074      *
1075      * @param s the input scalar; the number of the bits to left shift
1076      * @return the result of logically left shifting left this vector by the
1077      * broadcast of an input scalar
1078      */
1079     public abstract LongVector shiftL(int s);
1080 
1081     /**
1082      * Logically left shifts this vector by the broadcast of an input scalar,
1083      * selecting lane elements controlled by a mask.
1084      * <p>
1085      * This is a vector binary operation where the primitive logical left shift
1086      * operation ({@code <<}) is applied to lane elements.
1087      *
1088      * @param s the input scalar; the number of the bits to left shift
1089      * @param m the mask controlling lane selection
1090      * @return the result of logically left shifting this vector by the
1091      * broadcast of an input scalar
1092      */
1093     public abstract LongVector shiftL(int s, Mask<Long> m);
1094 
1095     /**
1096      * Logically left shifts this vector by an input vector.
1097      * <p>
1098      * This is a vector binary operation where the primitive logical left shift
1099      * operation ({@code <<}) is applied to lane elements.
1100      *
1101      * @param v the input vector
1102      * @return the result of logically left shifting this vector by the input
1103      * vector
1104      */
1105     public abstract LongVector shiftL(Vector<Long> v);
1106 
1107     /**
1108      * Logically left shifts this vector by an input vector, selecting lane
1109      * elements controlled by a mask.
1110      * <p>
1111      * This is a vector binary operation where the primitive logical left shift
1112      * operation ({@code <<}) is applied to lane elements.
1113      *
1114      * @param v the input vector
1115      * @param m the mask controlling lane selection
1116      * @return the result of logically left shifting this vector by the input
1117      * vector
1118      */
1119     public LongVector shiftL(Vector<Long> v, Mask<Long> m) {
1120         return bOp(v, m, (i, a, b) -> (long) (a << b));
1121     }
1122 
1123     // logical, or unsigned, shift right
1124 
1125     /**
1126      * Logically right shifts (or unsigned right shifts) this vector by the
1127      * broadcast of an input scalar.
1128      * <p>
1129      * This is a vector binary operation where the primitive logical right shift
1130      * operation ({@code >>>}) is applied to lane elements.
1131      *
1132      * @param s the input scalar; the number of the bits to right shift
1133      * @return the result of logically right shifting this vector by the
1134      * broadcast of an input scalar
1135      */
1136     public abstract LongVector shiftR(int s);
1137 
1138     /**
1139      * Logically right shifts (or unsigned right shifts) this vector by the
1140      * broadcast of an input scalar, selecting lane elements controlled by a
1141      * mask.
1142      * <p>
1143      * This is a vector binary operation where the primitive logical right shift
1144      * operation ({@code >>>}) is applied to lane elements.
1145      *
1146      * @param s the input scalar; the number of the bits to right shift
1147      * @param m the mask controlling lane selection
1148      * @return the result of logically right shifting this vector by the
1149      * broadcast of an input scalar
1150      */
1151     public abstract LongVector shiftR(int s, Mask<Long> m);
1152 
1153     /**
1154      * Logically right shifts (or unsigned right shifts) this vector by an
1155      * input vector.
1156      * <p>
1157      * This is a vector binary operation where the primitive logical right shift
1158      * operation ({@code >>>}) is applied to lane elements.
1159      *
1160      * @param v the input vector
1161      * @return the result of logically right shifting this vector by the
1162      * input vector
1163      */
1164     public abstract LongVector shiftR(Vector<Long> v);
1165 
1166     /**
1167      * Logically right shifts (or unsigned right shifts) this vector by an
1168      * input vector, selecting lane elements controlled by a mask.
1169      * <p>
1170      * This is a vector binary operation where the primitive logical right shift
1171      * operation ({@code >>>}) is applied to lane elements.
1172      *
1173      * @param v the input vector
1174      * @param m the mask controlling lane selection
1175      * @return the result of logically right shifting this vector by the
1176      * input vector
1177      */
1178     public LongVector shiftR(Vector<Long> v, Mask<Long> m) {
1179         return bOp(v, m, (i, a, b) -> (long) (a >>> b));
1180     }
1181 
1182     /**
1183      * Arithmetically right shifts (or signed right shifts) this vector by the
1184      * broadcast of an input scalar.
1185      * <p>
1186      * This is a vector binary operation where the primitive arithmetic right
1187      * shift operation ({@code >>}) is applied to lane elements.
1188      *
1189      * @param s the input scalar; the number of the bits to right shift
1190      * @return the result of arithmetically right shifting this vector by the
1191      * broadcast of an input scalar
1192      */
1193     public abstract LongVector aShiftR(int s);
1194 
1195     /**
1196      * Arithmetically right shifts (or signed right shifts) this vector by the
1197      * broadcast of an input scalar, selecting lane elements controlled by a
1198      * mask.
1199      * <p>
1200      * This is a vector binary operation where the primitive arithmetic right
1201      * shift operation ({@code >>}) is applied to lane elements.
1202      *
1203      * @param s the input scalar; the number of the bits to right shift
1204      * @param m the mask controlling lane selection
1205      * @return the result of arithmetically right shifting this vector by the
1206      * broadcast of an input scalar
1207      */
1208     public abstract LongVector aShiftR(int s, Mask<Long> m);
1209 
1210     /**
1211      * Arithmetically right shifts (or signed right shifts) this vector by an
1212      * input vector.
1213      * <p>
1214      * This is a vector binary operation where the primitive arithmetic right
1215      * shift operation ({@code >>}) is applied to lane elements.
1216      *
1217      * @param v the input vector
1218      * @return the result of arithmetically right shifting this vector by the
1219      * input vector
1220      */
1221     public abstract LongVector aShiftR(Vector<Long> v);
1222 
1223     /**
1224      * Arithmetically right shifts (or signed right shifts) this vector by an
1225      * input vector, selecting lane elements controlled by a mask.
1226      * <p>
1227      * This is a vector binary operation where the primitive arithmetic right
1228      * shift operation ({@code >>}) is applied to lane elements.
1229      *
1230      * @param v the input vector
1231      * @param m the mask controlling lane selection
1232      * @return the result of arithmetically right shifting this vector by the
1233      * input vector
1234      */
1235     public LongVector aShiftR(Vector<Long> v, Mask<Long> m) {
1236         return bOp(v, m, (i, a, b) -> (long) (a >> b));
1237     }
1238 
1239     /**
1240      * Rotates left this vector by the broadcast of an input scalar.
1241      * <p>
1242      * This is a vector binary operation where the operation
1243      * {@link Long#rotateLeft} is applied to lane elements and where
1244      * lane elements of this vector apply to the first argument, and lane
1245      * elements of the broadcast vector apply to the second argument (the
1246      * rotation distance).
1247      *
1248      * @param s the input scalar; the number of the bits to rotate left
1249      * @return the result of rotating left this vector by the broadcast of an
1250      * input scalar
1251      */
1252     @ForceInline
1253     public final LongVector rotateL(int s) {
1254         return shiftL(s).or(shiftR(-s));
1255     }
1256 
1257     /**
1258      * Rotates left this vector by the broadcast of an input scalar, selecting
1259      * lane elements controlled by a mask.
1260      * <p>
1261      * This is a vector binary operation where the operation
1262      * {@link Long#rotateLeft} is applied to lane elements and where
1263      * lane elements of this vector apply to the first argument, and lane
1264      * elements of the broadcast vector apply to the second argument (the
1265      * rotation distance).
1266      *
1267      * @param s the input scalar; the number of the bits to rotate left
1268      * @param m the mask controlling lane selection
1269      * @return the result of rotating left this vector by the broadcast of an
1270      * input scalar
1271      */
1272     @ForceInline
1273     public final LongVector rotateL(int s, Mask<Long> m) {
1274         return shiftL(s, m).or(shiftR(-s, m), m);
1275     }
1276 
1277     /**
1278      * Rotates right this vector by the broadcast of an input scalar.
1279      * <p>
1280      * This is a vector binary operation where the operation
1281      * {@link Long#rotateRight} is applied to lane elements and where
1282      * lane elements of this vector apply to the first argument, and lane
1283      * elements of the broadcast vector apply to the second argument (the
1284      * rotation distance).
1285      *
1286      * @param s the input scalar; the number of the bits to rotate right
1287      * @return the result of rotating right this vector by the broadcast of an
1288      * input scalar
1289      */
1290     @ForceInline
1291     public final LongVector rotateR(int s) {
1292         return shiftR(s).or(shiftL(-s));
1293     }
1294 
1295     /**
1296      * Rotates right this vector by the broadcast of an input scalar, selecting
1297      * lane elements controlled by a mask.
1298      * <p>
1299      * This is a vector binary operation where the operation
1300      * {@link Long#rotateRight} is applied to lane elements and where
1301      * lane elements of this vector apply to the first argument, and lane
1302      * elements of the broadcast vector apply to the second argument (the
1303      * rotation distance).
1304      *
1305      * @param s the input scalar; the number of the bits to rotate right
1306      * @param m the mask controlling lane selection
1307      * @return the result of rotating right this vector by the broadcast of an
1308      * input scalar
1309      */
1310     @ForceInline
1311     public final LongVector rotateR(int s, Mask<Long> m) {
1312         return shiftR(s, m).or(shiftL(-s, m), m);
1313     }
1314 
1315     @Override
1316     public abstract void intoByteArray(byte[] a, int ix);
1317 
1318     @Override
1319     public abstract void intoByteArray(byte[] a, int ix, Mask<Long> m);
1320 
1321     @Override
1322     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1323 
1324     @Override
1325     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Long> m);
1326 
1327 
1328     // Type specific horizontal reductions
1329     /**
1330      * Adds all lane elements of this vector.
1331      * <p>
1332      * This is an associative vector reduction operation where the addition
1333      * operation ({@code +}) is applied to lane elements,
1334      * and the identity value is {@code 0}.
1335      *
1336      * @return the addition of all the lane elements of this vector
1337      */
1338     public abstract long addAll();
1339 
1340     /**
1341      * Adds all lane elements of this vector, selecting lane elements
1342      * controlled by a mask.
1343      * <p>
1344      * This is an associative vector reduction operation where the addition
1345      * operation ({@code +}) is applied to lane elements,
1346      * and the identity value is {@code 0}.
1347      *
1348      * @param m the mask controlling lane selection
1349      * @return the addition of the selected lane elements of this vector
1350      */
1351     public abstract long addAll(Mask<Long> m);
1352 
1353     /**
1354      * Multiplies all lane elements of this vector.
1355      * <p>
1356      * This is an associative vector reduction operation where the
1357      * multiplication operation ({@code *}) is applied to lane elements,
1358      * and the identity value is {@code 1}.
1359      *
1360      * @return the multiplication of all the lane elements of this vector
1361      */
1362     public abstract long mulAll();
1363 
1364     /**
1365      * Multiplies all lane elements of this vector, selecting lane elements
1366      * controlled by a mask.
1367      * <p>
1368      * This is an associative vector reduction operation where the
1369      * multiplication operation ({@code *}) is applied to lane elements,
1370      * and the identity value is {@code 1}.
1371      *
1372      * @param m the mask controlling lane selection
1373      * @return the multiplication of all the lane elements of this vector
1374      */
1375     public abstract long mulAll(Mask<Long> m);
1376 
1377     /**
1378      * Returns the minimum lane element of this vector.
1379      * <p>
1380      * This is an associative vector reduction operation where the operation
1381      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1382      * and the identity value is
1383      * {@link Long#MAX_VALUE}.
1384      *
1385      * @return the minimum lane element of this vector
1386      */
1387     public abstract long minAll();
1388 
1389     /**
1390      * Returns the minimum lane element of this vector, selecting lane elements
1391      * controlled by a mask.
1392      * <p>
1393      * This is an associative vector reduction operation where the operation
1394      * {@code (a, b) -> Math.min(a, b)} is applied to lane elements,
1395      * and the identity value is
1396      * {@link Long#MAX_VALUE}.
1397      *
1398      * @param m the mask controlling lane selection
1399      * @return the minimum lane element of this vector
1400      */
1401     public abstract long minAll(Mask<Long> m);
1402 
1403     /**
1404      * Returns the maximum lane element of this vector.
1405      * <p>
1406      * This is an associative vector reduction operation where the operation
1407      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1408      * and the identity value is
1409      * {@link Long#MIN_VALUE}.
1410      *
1411      * @return the maximum lane element of this vector
1412      */
1413     public abstract long maxAll();
1414 
1415     /**
1416      * Returns the maximum lane element of this vector, selecting lane elements
1417      * controlled by a mask.
1418      * <p>
1419      * This is an associative vector reduction operation where the operation
1420      * {@code (a, b) -> Math.max(a, b)} is applied to lane elements,
1421      * and the identity value is
1422      * {@link Long#MIN_VALUE}.
1423      *
1424      * @param m the mask controlling lane selection
1425      * @return the maximum lane element of this vector
1426      */
1427     public abstract long maxAll(Mask<Long> m);
1428 
1429     /**
1430      * Logically ORs all lane elements of this vector.
1431      * <p>
1432      * This is an associative vector reduction operation where the logical OR
1433      * operation ({@code |}) is applied to lane elements,
1434      * and the identity value is {@code 0}.
1435      *
1436      * @return the logical OR all the lane elements of this vector
1437      */
1438     public abstract long orAll();
1439 
1440     /**
1441      * Logically ORs all lane elements of this vector, selecting lane elements
1442      * controlled by a mask.
1443      * <p>
1444      * This is an associative vector reduction operation where the logical OR
1445      * operation ({@code |}) is applied to lane elements,
1446      * and the identity value is {@code 0}.
1447      *
1448      * @param m the mask controlling lane selection
1449      * @return the logical OR all the lane elements of this vector
1450      */
1451     public abstract long orAll(Mask<Long> m);
1452 
1453     /**
1454      * Logically ANDs all lane elements of this vector.
1455      * <p>
1456      * This is an associative vector reduction operation where the logical AND
1457      * operation ({@code |}) is applied to lane elements,
1458      * and the identity value is {@code -1}.
1459      *
1460      * @return the logical AND all the lane elements of this vector
1461      */
1462     public abstract long andAll();
1463 
1464     /**
1465      * Logically ANDs all lane elements of this vector, selecting lane elements
1466      * controlled by a mask.
1467      * <p>
1468      * This is an associative vector reduction operation where the logical AND
1469      * operation ({@code |}) is applied to lane elements,
1470      * and the identity value is {@code -1}.
1471      *
1472      * @param m the mask controlling lane selection
1473      * @return the logical AND all the lane elements of this vector
1474      */
1475     public abstract long andAll(Mask<Long> m);
1476 
1477     /**
1478      * Logically XORs all lane elements of this vector.
1479      * <p>
1480      * This is an associative vector reduction operation where the logical XOR
1481      * operation ({@code ^}) is applied to lane elements,
1482      * and the identity value is {@code 0}.
1483      *
1484      * @return the logical XOR all the lane elements of this vector
1485      */
1486     public abstract long xorAll();
1487 
1488     /**
1489      * Logically XORs all lane elements of this vector, selecting lane elements
1490      * controlled by a mask.
1491      * <p>
1492      * This is an associative vector reduction operation where the logical XOR
1493      * operation ({@code ^}) is applied to lane elements,
1494      * and the identity value is {@code 0}.
1495      *
1496      * @param m the mask controlling lane selection
1497      * @return the logical XOR all the lane elements of this vector
1498      */
1499     public abstract long xorAll(Mask<Long> m);
1500 
1501     // Type specific accessors
1502 
1503     /**
1504      * Gets the lane element at lane index {@code i}
1505      *
1506      * @param i the lane index
1507      * @return the lane element at lane index {@code i}
1508      * @throws IllegalArgumentException if the index is is out of range
1509      * ({@code < 0 || >= length()})
1510      */
1511     public abstract long get(int i);
1512 
1513     /**
1514      * Replaces the lane element of this vector at lane index {@code i} with
1515      * value {@code e}.
1516      * <p>
1517      * This is a cross-lane operation and behaves as if it returns the result
1518      * of blending this vector with an input vector that is the result of
1519      * broadcasting {@code e} and a mask that has only one lane set at lane
1520      * index {@code i}.
1521      *
1522      * @param i the lane index of the lane element to be replaced
1523      * @param e the value to be placed
1524      * @return the result of replacing the lane element of this vector at lane
1525      * index {@code i} with value {@code e}.
1526      * @throws IllegalArgumentException if the index is is out of range
1527      * ({@code < 0 || >= length()})
1528      */
1529     public abstract LongVector with(int i, long e);
1530 
1531     // Type specific extractors
1532 
1533     /**
1534      * Returns an array containing the lane elements of this vector.
1535      * <p>
1536      * This method behaves as if it {@link #intoArray(long[], int)} stores}
1537      * this vector into an allocated array and returns the array as follows:
1538      * <pre>{@code
1539      *   long[] a = new long[this.length()];
1540      *   this.intoArray(a, 0);
1541      *   return a;
1542      * }</pre>
1543      *
1544      * @return an array containing the the lane elements of this vector
1545      */
1546     @ForceInline
1547     public final long[] toArray() {
1548         long[] a = new long[species().length()];
1549         intoArray(a, 0);
1550         return a;
1551     }
1552 
1553     /**
1554      * Stores this vector into an array starting at offset.
1555      * <p>
1556      * For each vector lane, where {@code N} is the vector lane index,
1557      * the lane element at index {@code N} is stored into the array at index
1558      * {@code i + N}.
1559      *
1560      * @param a the array
1561      * @param i the offset into the array
1562      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1563      * {@code i > a.length - this.length()}
1564      */
1565     public abstract void intoArray(long[] a, int i);
1566 
1567     /**
1568      * Stores this vector into an array starting at offset and using a mask.
1569      * <p>
1570      * For each vector lane, where {@code N} is the vector lane index,
1571      * if the mask lane at index {@code N} is set then the lane element at
1572      * index {@code N} is stored into the array index {@code i + N}.
1573      *
1574      * @param a the array
1575      * @param i the offset into the array
1576      * @param m the mask
1577      * @throws IndexOutOfBoundsException if {@code i < 0}, or
1578      * for any vector lane index {@code N} where the mask at lane {@code N}
1579      * is set {@code i >= a.length - N}
1580      */
1581     public abstract void intoArray(long[] a, int i, Mask<Long> m);
1582 
1583     /**
1584      * Stores this vector into an array using indexes obtained from an index
1585      * map.
1586      * <p>
1587      * For each vector lane, where {@code N} is the vector lane index, the
1588      * lane element at index {@code N} is stored into the array at index
1589      * {@code i + indexMap[j + N]}.
1590      *
1591      * @param a the array
1592      * @param i the offset into the array, may be negative if relative
1593      * indexes in the index map compensate to produce a value within the
1594      * array bounds
1595      * @param indexMap the index map
1596      * @param j the offset into the index map
1597      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1598      * {@code j > indexMap.length - this.length()},
1599      * or for any vector lane index {@code N} the result of
1600      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1601      */
1602     public abstract void intoArray(long[] a, int i, int[] indexMap, int j);
1603 
1604     /**
1605      * Stores this vector into an array using indexes obtained from an index
1606      * map and using a mask.
1607      * <p>
1608      * For each vector lane, where {@code N} is the vector lane index,
1609      * if the mask lane at index {@code N} is set then the lane element at
1610      * index {@code N} is stored into the array at index
1611      * {@code i + indexMap[j + N]}.
1612      *
1613      * @param a the array
1614      * @param i the offset into the array, may be negative if relative
1615      * indexes in the index map compensate to produce a value within the
1616      * array bounds
1617      * @param m the mask
1618      * @param indexMap the index map
1619      * @param j the offset into the index map
1620      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1621      * {@code j > indexMap.length - this.length()},
1622      * or for any vector lane index {@code N} where the mask at lane
1623      * {@code N} is set the result of {@code i + indexMap[j + N]} is
1624      * {@code < 0} or {@code >= a.length}
1625      */
1626     public abstract void intoArray(long[] a, int i, Mask<Long> m, int[] indexMap, int j);
1627     // Species
1628 
1629     @Override
1630     public abstract LongSpecies species();
1631 
1632     /**
1633      * Class representing {@link LongVector}'s of the same {@link Vector.Shape Shape}.
1634      */
1635     public static abstract class LongSpecies extends Vector.Species<Long> {
1636         interface FOp {
1637             long apply(int i);
1638         }
1639 
1640         abstract LongVector op(FOp f);
1641 
1642         abstract LongVector op(Mask<Long> m, FOp f);
1643 
1644         interface FOpm {
1645             boolean apply(int i);
1646         }
1647 
1648         abstract Mask<Long> opm(FOpm f);
1649 
1650         abstract IntVector.IntSpecies indexSpecies();
1651 
1652         abstract Mask<Integer> indexMask();
1653 
1654         // Factories
1655 
1656         @Override
1657         public abstract LongVector zero();
1658 
1659         /**
1660          * Returns a vector where all lane elements are set to the primitive
1661          * value {@code e}.
1662          *
1663          * @param e the value
1664          * @return a vector of vector where all lane elements are set to
1665          * the primitive value {@code e}
1666          */
1667         public abstract LongVector broadcast(long e);
1668 
1669         /**
1670          * Returns a vector where the first lane element is set to the primtive
1671          * value {@code e}, all other lane elements are set to the default
1672          * value.
1673          *
1674          * @param e the value
1675          * @return a vector where the first lane element is set to the primitive
1676          * value {@code e}
1677          */
1678         @ForceInline
1679         public final LongVector single(long e) {
1680             return zero().with(0, e);
1681         }
1682 
1683         /**
1684          * Returns a vector where each lane element is set to a randomly
1685          * generated primitive value.
1686          *
1687          * The semantics are equivalent to calling
1688          * {@code (long)ThreadLocalRandom#nextInt()}.
1689          *
1690          * @return a vector where each lane elements is set to a randomly
1691          * generated primitive value
1692          */
1693         public LongVector random() {
1694             ThreadLocalRandom r = ThreadLocalRandom.current();
1695             return op(i -> r.nextLong());
1696         }
1697 
1698         /**
1699          * Returns a vector where each lane element is set to a given
1700          * primitive value.
1701          * <p>
1702          * For each vector lane, where {@code N} is the vector lane index, the
1703          * the primitive value at index {@code N} is placed into the resulting
1704          * vector at lane index {@code N}.
1705          *
1706          * @param es the given primitive values
1707          * @return a vector where each lane element is set to a given primitive
1708          * value
1709          * @throws IndexOutOfBoundsException if {@code es.length < this.length()}
1710          */
1711         public abstract LongVector scalars(long... es);
1712     }
1713 
1714     /**
1715      * Finds the preferred species for an element type of {@code long}.
1716      * <p>
1717      * A preferred species is a species chosen by the platform that has a
1718      * shape of maximal bit size.  A preferred species for different element
1719      * types will have the same shape, and therefore vectors, masks, and
1720      * shuffles created from such species will be shape compatible.
1721      *
1722      * @return the preferred species for an element type of {@code long}
1723      */
1724     @SuppressWarnings("unchecked")
1725     public static LongSpecies preferredSpecies() {
1726         return (LongSpecies) Species.ofPreferred(long.class);
1727     }
1728 
1729     /**
1730      * Finds a species for an element type of {@code long} and shape.
1731      *
1732      * @param s the shape
1733      * @return a species for an element type of {@code long} and shape
1734      * @throws IllegalArgumentException if no such species exists for the shape
1735      */
1736     @SuppressWarnings("unchecked")
1737     public static LongSpecies species(Vector.Shape s) {
1738         Objects.requireNonNull(s);
1739         switch (s) {
1740             case S_64_BIT: return Long64Vector.SPECIES;
1741             case S_128_BIT: return Long128Vector.SPECIES;
1742             case S_256_BIT: return Long256Vector.SPECIES;
1743             case S_512_BIT: return Long512Vector.SPECIES;
1744             case S_Max_BIT: return LongMaxVector.SPECIES;
1745             default: throw new IllegalArgumentException("Bad shape: " + s);
1746         }
1747     }
1748 }