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