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