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