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