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