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.boxType(), 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.boxType(), 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.boxType(), 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.boxType(), long.class, species.length(),
 270                                             IntVector.species(species.indexShape()).boxType(), 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.boxType(), 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
 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.boxType(), 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.boxType(), 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 rotateEL(int i);
 806 
 807     /**
 808      * {@inheritDoc}
 809      */
 810     @Override
 811     public abstract LongVector rotateER(int i);
 812 
 813     /**
 814      * {@inheritDoc}
 815      */
 816     @Override
 817     public abstract LongVector shiftEL(int i);
 818 
 819     /**
 820      * {@inheritDoc}
 821      */
 822     @Override
 823     public abstract LongVector shiftER(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.
1003      *
1004      * @param s the input scalar; the number of the bits to left shift
1005      * @return the result of logically left shifting left this vector by the
1006      * broadcast of an input scalar
1007      */
1008     public abstract LongVector shiftL(int s);
1009 
1010     /**
1011      * Logically left shifts this vector by the broadcast of an input scalar,
1012      * selecting lane elements controlled by a mask.
1013      * <p>
1014      * This is a lane-wise binary operation which applies the primitive logical left shift
1015      * operation ({@code <<}) to each lane.
1016      *
1017      * @param s the input scalar; the number of the bits to left shift
1018      * @param m the mask controlling lane selection
1019      * @return the result of logically left shifting this vector by the
1020      * broadcast of an input scalar
1021      */
1022     public abstract LongVector shiftL(int s, VectorMask<Long> m);
1023 
1024     /**
1025      * Logically left shifts this vector by an input vector.
1026      * <p>
1027      * This is a lane-wise binary operation which applies the primitive logical left shift
1028      * operation ({@code <<}) to each lane.
1029      *
1030      * @param v the input vector
1031      * @return the result of logically left shifting this vector by the input
1032      * vector
1033      */
1034     public abstract LongVector shiftL(Vector<Long> v);
1035 
1036     /**
1037      * Logically left shifts this vector by an input vector, selecting lane
1038      * elements controlled by a mask.
1039      * <p>
1040      * This is a lane-wise binary operation which applies the primitive logical left shift
1041      * operation ({@code <<}) to each lane.
1042      *
1043      * @param v the input vector
1044      * @param m the mask controlling lane selection
1045      * @return the result of logically left shifting this vector by the input
1046      * vector
1047      */
1048     public LongVector shiftL(Vector<Long> v, VectorMask<Long> m) {
1049         return bOp(v, m, (i, a, b) -> (long) (a << b));
1050     }
1051 
1052     // logical, or unsigned, shift right
1053 
1054     /**
1055      * Logically right shifts (or unsigned right shifts) this vector by the
1056      * broadcast of an input scalar.
1057      * <p>
1058      * This is a lane-wise binary operation which applies the primitive logical right shift
1059      * operation ({@code >>>}) to each lane.
1060      *
1061      * @param s the input scalar; the number of the bits to right shift
1062      * @return the result of logically right shifting this vector by the
1063      * broadcast of an input scalar
1064      */
1065     public abstract LongVector shiftR(int s);
1066 
1067     /**
1068      * Logically right shifts (or unsigned right shifts) this vector by the
1069      * broadcast of an input scalar, selecting lane elements controlled by a
1070      * mask.
1071      * <p>
1072      * This is a lane-wise binary operation which applies the primitive logical right shift
1073      * operation ({@code >>>}) to each lane.
1074      *
1075      * @param s the input scalar; the number of the bits to right shift
1076      * @param m the mask controlling lane selection
1077      * @return the result of logically right shifting this vector by the
1078      * broadcast of an input scalar
1079      */
1080     public abstract LongVector shiftR(int s, VectorMask<Long> m);
1081 
1082     /**
1083      * Logically right shifts (or unsigned right shifts) this vector by an
1084      * input vector.
1085      * <p>
1086      * This is a lane-wise binary operation which applies the primitive logical right shift
1087      * operation ({@code >>>}) to each lane.
1088      *
1089      * @param v the input vector
1090      * @return the result of logically right shifting this vector by the
1091      * input vector
1092      */
1093     public abstract LongVector shiftR(Vector<Long> v);
1094 
1095     /**
1096      * Logically right shifts (or unsigned right shifts) this vector by an
1097      * input vector, selecting lane elements controlled by a mask.
1098      * <p>
1099      * This is a lane-wise binary operation which applies the primitive logical right shift
1100      * operation ({@code >>>}) to each lane.
1101      *
1102      * @param v the input vector
1103      * @param m the mask controlling lane selection
1104      * @return the result of logically right shifting this vector by the
1105      * input vector
1106      */
1107     public LongVector shiftR(Vector<Long> v, VectorMask<Long> m) {
1108         return bOp(v, m, (i, a, b) -> (long) (a >>> b));
1109     }
1110 
1111     /**
1112      * Arithmetically right shifts (or signed right shifts) this vector by the
1113      * broadcast of an input scalar.
1114      * <p>
1115      * This is a lane-wise binary operation which applies the primitive arithmetic right
1116      * shift operation ({@code >>}) to each lane.
1117      *
1118      * @param s the input scalar; the number of the bits to right shift
1119      * @return the result of arithmetically right shifting this vector by the
1120      * broadcast of an input scalar
1121      */
1122     public abstract LongVector aShiftR(int s);
1123 
1124     /**
1125      * Arithmetically right shifts (or signed right shifts) this vector by the
1126      * broadcast of an input scalar, selecting lane elements controlled by a
1127      * mask.
1128      * <p>
1129      * This is a lane-wise binary operation which applies the primitive arithmetic right
1130      * shift operation ({@code >>}) to each lane.
1131      *
1132      * @param s the input scalar; the number of the bits to right shift
1133      * @param m the mask controlling lane selection
1134      * @return the result of arithmetically right shifting this vector by the
1135      * broadcast of an input scalar
1136      */
1137     public abstract LongVector aShiftR(int s, VectorMask<Long> m);
1138 
1139     /**
1140      * Arithmetically right shifts (or signed right shifts) this vector by an
1141      * input vector.
1142      * <p>
1143      * This is a lane-wise binary operation which applies the primitive arithmetic right
1144      * shift operation ({@code >>}) to each lane.
1145      *
1146      * @param v the input vector
1147      * @return the result of arithmetically right shifting this vector by the
1148      * input vector
1149      */
1150     public abstract LongVector aShiftR(Vector<Long> v);
1151 
1152     /**
1153      * Arithmetically right shifts (or signed right shifts) this vector by an
1154      * input vector, selecting lane elements controlled by a mask.
1155      * <p>
1156      * This is a lane-wise binary operation which applies the primitive arithmetic right
1157      * shift operation ({@code >>}) to each lane.
1158      *
1159      * @param v the input vector
1160      * @param m the mask controlling lane selection
1161      * @return the result of arithmetically right shifting this vector by the
1162      * input vector
1163      */
1164     public LongVector aShiftR(Vector<Long> v, VectorMask<Long> m) {
1165         return bOp(v, m, (i, a, b) -> (long) (a >> b));
1166     }
1167 
1168     /**
1169      * Rotates left this vector by the broadcast of an input scalar.
1170      * <p>
1171      * This is a lane-wise binary operation which applies the operation
1172      * {@link Long#rotateLeft} to each lane and where
1173      * lane elements of this vector apply to the first argument, and lane
1174      * elements of the broadcast vector apply to the second argument (the
1175      * rotation distance).
1176      *
1177      * @param s the input scalar; the number of the bits to rotate left
1178      * @return the result of rotating left this vector by the broadcast of an
1179      * input scalar
1180      */
1181     @ForceInline
1182     public final LongVector rotateL(int s) {
1183         return shiftL(s).or(shiftR(-s));
1184     }
1185 
1186     /**
1187      * Rotates left this vector by the broadcast of an input scalar, selecting
1188      * lane elements controlled by a mask.
1189      * <p>
1190      * This is a lane-wise binary operation which applies the operation
1191      * {@link Long#rotateLeft} to each lane and where
1192      * lane elements of this vector apply to the first argument, and lane
1193      * elements of the broadcast vector apply to the second argument (the
1194      * rotation distance).
1195      *
1196      * @param s the input scalar; the number of the bits to rotate left
1197      * @param m the mask controlling lane selection
1198      * @return the result of rotating left this vector by the broadcast of an
1199      * input scalar
1200      */
1201     @ForceInline
1202     public final LongVector rotateL(int s, VectorMask<Long> m) {
1203         return shiftL(s, m).or(shiftR(-s, m), m);
1204     }
1205 
1206     /**
1207      * Rotates right this vector by the broadcast of an input scalar.
1208      * <p>
1209      * This is a lane-wise binary operation which applies the operation
1210      * {@link Long#rotateRight} to each lane and where
1211      * lane elements of this vector apply to the first argument, and lane
1212      * elements of the broadcast vector apply to the second argument (the
1213      * rotation distance).
1214      *
1215      * @param s the input scalar; the number of the bits to rotate right
1216      * @return the result of rotating right this vector by the broadcast of an
1217      * input scalar
1218      */
1219     @ForceInline
1220     public final LongVector rotateR(int s) {
1221         return shiftR(s).or(shiftL(-s));
1222     }
1223 
1224     /**
1225      * Rotates right this vector by the broadcast of an input scalar, selecting
1226      * lane elements controlled by a mask.
1227      * <p>
1228      * This is a lane-wise binary operation which applies the operation
1229      * {@link Long#rotateRight} to each lane and where
1230      * lane elements of this vector apply to the first argument, and lane
1231      * elements of the broadcast vector apply to the second argument (the
1232      * rotation distance).
1233      *
1234      * @param s the input scalar; the number of the bits to rotate right
1235      * @param m the mask controlling lane selection
1236      * @return the result of rotating right this vector by the broadcast of an
1237      * input scalar
1238      */
1239     @ForceInline
1240     public final LongVector rotateR(int s, VectorMask<Long> m) {
1241         return shiftR(s, m).or(shiftL(-s, m), m);
1242     }
1243 
1244     /**
1245      * {@inheritDoc}
1246      */
1247     @Override
1248     public abstract void intoByteArray(byte[] a, int ix);
1249 
1250     /**
1251      * {@inheritDoc}
1252      */
1253     @Override
1254     public abstract void intoByteArray(byte[] a, int ix, VectorMask<Long> m);
1255 
1256     /**
1257      * {@inheritDoc}
1258      */
1259     @Override
1260     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
1261 
1262     /**
1263      * {@inheritDoc}
1264      */
1265     @Override
1266     public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Long> m);
1267 
1268 
1269     // Type specific horizontal reductions
1270     /**
1271      * Adds all lane elements of this vector.
1272      * <p>
1273      * This is an associative cross-lane reduction operation which applies the addition
1274      * operation ({@code +}) to lane elements,
1275      * and the identity value is {@code 0}.
1276      *
1277      * @return the addition of all the lane elements of this vector
1278      */
1279     public abstract long addAll();
1280 
1281     /**
1282      * Adds all lane elements of this vector, selecting lane elements
1283      * controlled by a mask.
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      * @param m the mask controlling lane selection
1290      * @return the addition of the selected lane elements of this vector
1291      */
1292     public abstract long addAll(VectorMask<Long> m);
1293 
1294     /**
1295      * Multiplies all lane elements of this vector.
1296      * <p>
1297      * This is an associative cross-lane reduction operation which applies the
1298      * multiplication operation ({@code *}) to lane elements,
1299      * and the identity value is {@code 1}.
1300      *
1301      * @return the multiplication of all the lane elements of this vector
1302      */
1303     public abstract long mulAll();
1304 
1305     /**
1306      * Multiplies all lane elements of this vector, selecting lane elements
1307      * controlled by a mask.
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      * @param m the mask controlling lane selection
1314      * @return the multiplication of all the lane elements of this vector
1315      */
1316     public abstract long mulAll(VectorMask<Long> m);
1317 
1318     /**
1319      * Returns the minimum lane element of this vector.
1320      * <p>
1321      * This is an associative cross-lane reduction operation which applies the operation
1322      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1323      * and the identity value is
1324      * {@link Long#MAX_VALUE}.
1325      *
1326      * @return the minimum lane element of this vector
1327      */
1328     public abstract long minAll();
1329 
1330     /**
1331      * Returns the minimum lane element of this vector, selecting lane elements
1332      * controlled by a mask.
1333      * <p>
1334      * This is an associative cross-lane reduction operation which applies the operation
1335      * {@code (a, b) -> Math.min(a, b)} to lane elements,
1336      * and the identity value is
1337      * {@link Long#MAX_VALUE}.
1338      *
1339      * @param m the mask controlling lane selection
1340      * @return the minimum lane element of this vector
1341      */
1342     public abstract long minAll(VectorMask<Long> m);
1343 
1344     /**
1345      * Returns the maximum lane element of this vector.
1346      * <p>
1347      * This is an associative cross-lane reduction operation which applies the operation
1348      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1349      * and the identity value is
1350      * {@link Long#MIN_VALUE}.
1351      *
1352      * @return the maximum lane element of this vector
1353      */
1354     public abstract long maxAll();
1355 
1356     /**
1357      * Returns the maximum lane element of this vector, selecting lane elements
1358      * controlled by a mask.
1359      * <p>
1360      * This is an associative cross-lane reduction operation which applies the operation
1361      * {@code (a, b) -> Math.max(a, b)} to lane elements,
1362      * and the identity value is
1363      * {@link Long#MIN_VALUE}.
1364      *
1365      * @param m the mask controlling lane selection
1366      * @return the maximum lane element of this vector
1367      */
1368     public abstract long maxAll(VectorMask<Long> m);
1369 
1370     /**
1371      * Logically ORs all lane elements of this vector.
1372      * <p>
1373      * This is an associative cross-lane reduction operation which applies the logical OR
1374      * operation ({@code |}) to lane elements,
1375      * and the identity value is {@code 0}.
1376      *
1377      * @return the logical OR all the lane elements of this vector
1378      */
1379     public abstract long orAll();
1380 
1381     /**
1382      * Logically ORs all lane elements of this vector, selecting lane elements
1383      * controlled by a mask.
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      * @param m the mask controlling lane selection
1390      * @return the logical OR all the lane elements of this vector
1391      */
1392     public abstract long orAll(VectorMask<Long> m);
1393 
1394     /**
1395      * Logically ANDs all lane elements of this vector.
1396      * <p>
1397      * This is an associative cross-lane reduction operation which applies the logical AND
1398      * operation ({@code |}) to lane elements,
1399      * and the identity value is {@code -1}.
1400      *
1401      * @return the logical AND all the lane elements of this vector
1402      */
1403     public abstract long andAll();
1404 
1405     /**
1406      * Logically ANDs all lane elements of this vector, selecting lane elements
1407      * controlled by a mask.
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      * @param m the mask controlling lane selection
1414      * @return the logical AND all the lane elements of this vector
1415      */
1416     public abstract long andAll(VectorMask<Long> m);
1417 
1418     /**
1419      * Logically XORs all lane elements of this vector.
1420      * <p>
1421      * This is an associative cross-lane reduction operation which applies the logical XOR
1422      * operation ({@code ^}) to lane elements,
1423      * and the identity value is {@code 0}.
1424      *
1425      * @return the logical XOR all the lane elements of this vector
1426      */
1427     public abstract long xorAll();
1428 
1429     /**
1430      * Logically XORs all lane elements of this vector, selecting lane elements
1431      * controlled by a mask.
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      * @param m the mask controlling lane selection
1438      * @return the logical XOR all the lane elements of this vector
1439      */
1440     public abstract long xorAll(VectorMask<Long> m);
1441 
1442     // Type specific accessors
1443 
1444     /**
1445      * Gets the lane element at lane index {@code i}
1446      *
1447      * @param i the lane index
1448      * @return the lane element at lane index {@code i}
1449      * @throws IllegalArgumentException if the index is is out of range
1450      * ({@code < 0 || >= length()})
1451      */
1452     public abstract long lane(int i);
1453 
1454     /**
1455      * Replaces the lane element of this vector at lane index {@code i} with
1456      * value {@code e}.
1457      * <p>
1458      * This is a cross-lane operation and behaves as if it returns the result
1459      * of blending this vector with an input vector that is the result of
1460      * broadcasting {@code e} and a mask that has only one lane set at lane
1461      * index {@code i}.
1462      *
1463      * @param i the lane index of the lane element to be replaced
1464      * @param e the value to be placed
1465      * @return the result of replacing the lane element of this vector at lane
1466      * index {@code i} with value {@code e}.
1467      * @throws IllegalArgumentException if the index is is out of range
1468      * ({@code < 0 || >= length()})
1469      */
1470     public abstract LongVector with(int i, long e);
1471 
1472     // Type specific extractors
1473 
1474     /**
1475      * Returns an array containing the lane elements of this vector.
1476      * <p>
1477      * This method behaves as if it {@link #intoArray(long[], int)} stores}
1478      * this vector into an allocated array and returns the array as follows:
1479      * <pre>{@code
1480      *   long[] a = new long[this.length()];
1481      *   this.intoArray(a, 0);
1482      *   return a;
1483      * }</pre>
1484      *
1485      * @return an array containing the the lane elements of this vector
1486      */
1487     @ForceInline
1488     public final long[] toArray() {
1489         long[] a = new long[species().length()];
1490         intoArray(a, 0);
1491         return a;
1492     }
1493 
1494     /**
1495      * Stores this vector into an array starting at offset.
1496      * <p>
1497      * For each vector lane, where {@code N} is the vector lane index,
1498      * the lane element at index {@code N} is stored into the array at index
1499      * {@code offset + N}.
1500      *
1501      * @param a the array
1502      * @param offset the offset into the array
1503      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1504      * {@code offset > a.length - this.length()}
1505      */
1506     public abstract void intoArray(long[] a, int offset);
1507 
1508     /**
1509      * Stores this vector into an array starting at offset and using a mask.
1510      * <p>
1511      * For each vector lane, where {@code N} is the vector lane index,
1512      * if the mask lane at index {@code N} is set then the lane element at
1513      * index {@code N} is stored into the array index {@code offset + N}.
1514      *
1515      * @param a the array
1516      * @param offset the offset into the array
1517      * @param m the mask
1518      * @throws IndexOutOfBoundsException if {@code offset < 0}, or
1519      * for any vector lane index {@code N} where the mask at lane {@code N}
1520      * is set {@code offset >= a.length - N}
1521      */
1522     public abstract void intoArray(long[] a, int offset, VectorMask<Long> m);
1523 
1524     /**
1525      * Stores this vector into an array using indexes obtained from an index
1526      * map.
1527      * <p>
1528      * For each vector lane, where {@code N} is the vector lane index, the
1529      * lane element at index {@code N} is stored into the array at index
1530      * {@code a_offset + indexMap[i_offset + N]}.
1531      *
1532      * @param a the array
1533      * @param a_offset the offset into the array, may be negative if relative
1534      * indexes in the index map compensate to produce a value within the
1535      * array bounds
1536      * @param indexMap the index map
1537      * @param i_offset the offset into the index map
1538      * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or
1539      * {@code i_offset > indexMap.length - this.length()},
1540      * or for any vector lane index {@code N} the result of
1541      * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length}
1542      */
1543     public abstract void intoArray(long[] a, int a_offset, int[] indexMap, int i_offset);
1544 
1545     /**
1546      * Stores this vector into an array using indexes obtained from an index
1547      * map and using a mask.
1548      * <p>
1549      * For each vector lane, where {@code N} is the vector lane index,
1550      * if the mask lane at index {@code N} is set then the lane element at
1551      * index {@code N} is stored into the array at index
1552      * {@code a_offset + indexMap[i_offset + N]}.
1553      *
1554      * @param a the array
1555      * @param a_offset the offset into the array, may be negative if relative
1556      * indexes in the index map compensate to produce a value within the
1557      * array bounds
1558      * @param m the mask
1559      * @param indexMap the index map
1560      * @param i_offset the offset into the index map
1561      * @throws IndexOutOfBoundsException if {@code j < 0}, or
1562      * {@code i_offset > indexMap.length - this.length()},
1563      * or for any vector lane index {@code N} where the mask at lane
1564      * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is
1565      * {@code < 0} or {@code >= a.length}
1566      */
1567     public abstract void intoArray(long[] a, int a_offset, VectorMask<Long> m, int[] indexMap, int i_offset);
1568     // Species
1569 
1570     /**
1571      * {@inheritDoc}
1572      */
1573     @Override
1574     public abstract VectorSpecies<Long> species();
1575 
1576     /**
1577      * Class representing {@link LongVector}'s of the same {@link VectorShape VectorShape}.
1578      */
1579     static final class LongSpecies extends AbstractSpecies<Long> {
1580         final Function<long[], LongVector> vectorFactory;
1581 
1582         private LongSpecies(VectorShape shape,
1583                           Class<?> boxType,
1584                           Class<?> maskType,
1585                           Function<long[], LongVector> vectorFactory,
1586                           Function<boolean[], VectorMask<Long>> maskFactory,
1587                           Function<IntUnaryOperator, VectorShuffle<Long>> shuffleFromArrayFactory,
1588                           fShuffleFromArray<Long> shuffleFromOpFactory) {
1589             super(shape, long.class, Long.SIZE, boxType, maskType, maskFactory,
1590                   shuffleFromArrayFactory, shuffleFromOpFactory);
1591             this.vectorFactory = vectorFactory;
1592         }
1593 
1594         interface FOp {
1595             long apply(int i);
1596         }
1597 
1598         LongVector op(FOp f) {
1599             long[] res = new long[length()];
1600             for (int i = 0; i < length(); i++) {
1601                 res[i] = f.apply(i);
1602             }
1603             return vectorFactory.apply(res);
1604         }
1605 
1606         LongVector op(VectorMask<Long> o, FOp f) {
1607             long[] res = new long[length()];
1608             boolean[] mbits = ((AbstractMask<Long>)o).getBits();
1609             for (int i = 0; i < length(); i++) {
1610                 if (mbits[i]) {
1611                     res[i] = f.apply(i);
1612                 }
1613             }
1614             return vectorFactory.apply(res);
1615         }
1616     }
1617 
1618     /**
1619      * Finds the preferred species for an element type of {@code long}.
1620      * <p>
1621      * A preferred species is a species chosen by the platform that has a
1622      * shape of maximal bit size.  A preferred species for different element
1623      * types will have the same shape, and therefore vectors, masks, and
1624      * shuffles created from such species will be shape compatible.
1625      *
1626      * @return the preferred species for an element type of {@code long}
1627      */
1628     private static LongSpecies preferredSpecies() {
1629         return (LongSpecies) VectorSpecies.ofPreferred(long.class);
1630     }
1631 
1632     /**
1633      * Finds a species for an element type of {@code long} and shape.
1634      *
1635      * @param s the shape
1636      * @return a species for an element type of {@code long} and shape
1637      * @throws IllegalArgumentException if no such species exists for the shape
1638      */
1639     static LongSpecies species(VectorShape s) {
1640         Objects.requireNonNull(s);
1641         switch (s) {
1642             case S_64_BIT: return (LongSpecies) SPECIES_64;
1643             case S_128_BIT: return (LongSpecies) SPECIES_128;
1644             case S_256_BIT: return (LongSpecies) SPECIES_256;
1645             case S_512_BIT: return (LongSpecies) SPECIES_512;
1646             case S_Max_BIT: return (LongSpecies) SPECIES_MAX;
1647             default: throw new IllegalArgumentException("Bad shape: " + s);
1648         }
1649     }
1650 
1651     /** Species representing {@link LongVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */
1652     public static final VectorSpecies<Long> SPECIES_64 = new LongSpecies(VectorShape.S_64_BIT, Long64Vector.class, Long64Vector.Long64Mask.class,
1653                                                                      Long64Vector::new, Long64Vector.Long64Mask::new,
1654                                                                      Long64Vector.Long64Shuffle::new, Long64Vector.Long64Shuffle::new);
1655 
1656     /** Species representing {@link LongVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */
1657     public static final VectorSpecies<Long> SPECIES_128 = new LongSpecies(VectorShape.S_128_BIT, Long128Vector.class, Long128Vector.Long128Mask.class,
1658                                                                       Long128Vector::new, Long128Vector.Long128Mask::new,
1659                                                                       Long128Vector.Long128Shuffle::new, Long128Vector.Long128Shuffle::new);
1660 
1661     /** Species representing {@link LongVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */
1662     public static final VectorSpecies<Long> SPECIES_256 = new LongSpecies(VectorShape.S_256_BIT, Long256Vector.class, Long256Vector.Long256Mask.class,
1663                                                                       Long256Vector::new, Long256Vector.Long256Mask::new,
1664                                                                       Long256Vector.Long256Shuffle::new, Long256Vector.Long256Shuffle::new);
1665 
1666     /** Species representing {@link LongVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */
1667     public static final VectorSpecies<Long> SPECIES_512 = new LongSpecies(VectorShape.S_512_BIT, Long512Vector.class, Long512Vector.Long512Mask.class,
1668                                                                       Long512Vector::new, Long512Vector.Long512Mask::new,
1669                                                                       Long512Vector.Long512Shuffle::new, Long512Vector.Long512Shuffle::new);
1670 
1671     /** Species representing {@link LongVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */
1672     public static final VectorSpecies<Long> SPECIES_MAX = new LongSpecies(VectorShape.S_Max_BIT, LongMaxVector.class, LongMaxVector.LongMaxMask.class,
1673                                                                       LongMaxVector::new, LongMaxVector.LongMaxMask::new,
1674                                                                       LongMaxVector.LongMaxShuffle::new, LongMaxVector.LongMaxShuffle::new);
1675 
1676     /**
1677      * Preferred species for {@link LongVector}s.
1678      * A preferred species is a species of maximal bit size for the platform.
1679      */
1680     public static final VectorSpecies<Long> SPECIES_PREFERRED = (VectorSpecies<Long>) preferredSpecies();
1681 }