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.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 short} values. 43 */ 44 @SuppressWarnings("cast") 45 public abstract class ShortVector extends Vector<Short> { 46 47 ShortVector() {} 48 49 private static final int ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_SHORT_INDEX_SCALE); 50 51 // Unary operator 52 53 interface FUnOp { 54 short apply(int i, short a); 55 } 56 57 abstract ShortVector uOp(FUnOp f); 58 59 abstract ShortVector uOp(VectorMask<Short> m, FUnOp f); 60 61 // Binary operator 62 63 interface FBinOp { 64 short apply(int i, short a, short b); 65 } 66 67 abstract ShortVector bOp(Vector<Short> v, FBinOp f); 68 69 abstract ShortVector bOp(Vector<Short> v, VectorMask<Short> m, FBinOp f); 70 71 // Trinary operator 72 73 interface FTriOp { 74 short apply(int i, short a, short b, short c); 75 } 76 77 abstract ShortVector tOp(Vector<Short> v1, Vector<Short> v2, FTriOp f); 78 79 abstract ShortVector tOp(Vector<Short> v1, Vector<Short> v2, VectorMask<Short> m, FTriOp f); 80 81 // Reduction operator 82 83 abstract short rOp(short v, FBinOp f); 84 85 // Binary test 86 87 interface FBinTest { 88 boolean apply(int i, short a, short b); 89 } 90 91 abstract VectorMask<Short> bTest(Vector<Short> v, FBinTest f); 92 93 // Foreach 94 95 interface FUnCon { 96 void apply(int i, short a); 97 } 98 99 abstract void forEach(FUnCon f); 100 101 abstract void forEach(VectorMask<Short> 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 ShortVector zero(VectorSpecies<Short> species) { 115 return VectorIntrinsics.broadcastCoerced((Class<ShortVector>) species.boxType(), short.class, species.length(), 116 0, species, 117 ((bits, s) -> ((ShortSpecies)s).op(i -> (short)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 ShortVector fromByteArray(VectorSpecies<Short> 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<ShortVector>) species.boxType(), short.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 ShortBuffer tb = bbc.asShortBuffer(); 151 return ((ShortSpecies)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 ShortVector fromByteArray(VectorSpecies<Short> species, byte[] a, int offset, VectorMask<Short> 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 ShortVector fromArray(VectorSpecies<Short> species, short[] a, int offset){ 201 Objects.requireNonNull(a); 202 offset = VectorIntrinsics.checkIndex(offset, a.length, species.length()); 203 return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(), 204 a, (((long) offset) << ARRAY_SHIFT) + Unsafe.ARRAY_SHORT_BASE_OFFSET, 205 a, offset, 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 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 ShortVector fromArray(VectorSpecies<Short> species, short[] a, int offset, VectorMask<Short> 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 public static ShortVector fromArray(VectorSpecies<Short> species, short[] a, int a_offset, int[] indexMap, int i_offset) { 255 return ((ShortSpecies)species).op(n -> a[a_offset + indexMap[i_offset + 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 a_offset + indexMap[i_offset + 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 a_offset 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 i_offset the offset into the index map 274 * @return the vector loaded from an array 275 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 276 * {@code i_offset > indexMap.length - species.length()}, 277 * or for any vector lane index {@code N} where the mask at lane 278 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is 279 * {@code < 0} or {@code >= a.length} 280 */ 281 public static ShortVector fromArray(VectorSpecies<Short> species, short[] a, int a_offset, VectorMask<Short> m, int[] indexMap, int i_offset) { 282 return ((ShortSpecies)species).op(m, n -> a[a_offset + indexMap[i_offset + 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(VectorSpecies, ByteBuffer, int, VectorMask)} method} as follows: 295 * <pre>{@code 296 * return fromByteBuffer(b, offset, VectorMask.allTrue()) 297 * }</pre> 298 * 299 * @param species species of desired vector 300 * @param bb the byte buffer 301 * @param offset 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 species.length() * species.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(VectorSpecies<Short> species, ByteBuffer bb, int offset) { 312 if (bb.order() != ByteOrder.nativeOrder()) { 313 throw new IllegalArgumentException(); 314 } 315 offset = VectorIntrinsics.checkIndex(offset, 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) + offset, 318 bb, offset, 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 * {@code EBuffer} is the primitive buffer type, {@code e} is the 337 * primitive element type, and {@code ESpecies} is the primitive 338 * species for {@code e}: 339 * <pre>{@code 340 * EBuffer eb = b.duplicate(). 341 * order(ByteOrder.nativeOrder()).position(offset). 342 * asEBuffer(); 343 * e[] es = new e[species.length()]; 344 * for (int n = 0; n < t.length; n++) { 345 * if (m.isSet(n)) 346 * es[n] = eb.get(n); 347 * } 348 * EVector r = EVector.fromArray(es, 0, m); 349 * }</pre> 350 * 351 * @param species species of desired vector 352 * @param bb the byte buffer 353 * @param offset 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 offset >= b.limit() - (N * species.elementSize() / Byte.SIZE)} 361 */ 362 @ForceInline 363 public static ShortVector fromByteBuffer(VectorSpecies<Short> species, ByteBuffer bb, int offset, VectorMask<Short> m) { 364 return zero(species).blend(fromByteBuffer(species, bb, offset), m); 365 } 366 367 /** 368 * Returns a vector where all lane elements are set to the primitive 369 * value {@code e}. 370 * 371 * @param species species of the desired vector 372 * @param e the value 373 * @return a vector of vector where all lane elements are set to 374 * the primitive value {@code e} 375 */ 376 @ForceInline 377 @SuppressWarnings("unchecked") 378 public static ShortVector broadcast(VectorSpecies<Short> species, short e) { 379 return VectorIntrinsics.broadcastCoerced( 380 (Class<ShortVector>) species.boxType(), short.class, species.length(), 381 e, species, 382 ((bits, sp) -> ((ShortSpecies)sp).op(i -> (short)bits))); 383 } 384 385 /** 386 * Returns a vector where each lane element is set to given 387 * primitive values. 388 * <p> 389 * For each vector lane, where {@code N} is the vector lane index, the 390 * the primitive value at index {@code N} is placed into the resulting 391 * vector at lane index {@code N}. 392 * 393 * @param species species of the desired vector 394 * @param es the given primitive values 395 * @return a vector where each lane element is set to given primitive 396 * values 397 * @throws IndexOutOfBoundsException if {@code es.length < species.length()} 398 */ 399 @ForceInline 400 @SuppressWarnings("unchecked") 401 public static ShortVector scalars(VectorSpecies<Short> species, short... es) { 402 Objects.requireNonNull(es); 403 int ix = VectorIntrinsics.checkIndex(0, es.length, species.length()); 404 return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(), 405 es, Unsafe.ARRAY_SHORT_BASE_OFFSET, 406 es, ix, species, 407 (c, idx, sp) -> ((ShortSpecies)sp).op(n -> c[idx + n])); 408 } 409 410 /** 411 * Returns a vector where the first lane element is set to the primtive 412 * value {@code e}, all other lane elements are set to the default 413 * value. 414 * 415 * @param species species of the desired vector 416 * @param e the value 417 * @return a vector where the first lane element is set to the primitive 418 * value {@code e} 419 */ 420 @ForceInline 421 public static final ShortVector single(VectorSpecies<Short> species, short e) { 422 return zero(species).with(0, e); 423 } 424 425 /** 426 * Returns a vector where each lane element is set to a randomly 427 * generated primitive value. 428 * 429 * The semantics are equivalent to calling 430 * (short){@link ThreadLocalRandom#nextInt()} 431 * 432 * @param species species of the desired vector 433 * @return a vector where each lane elements is set to a randomly 434 * generated primitive value 435 */ 436 public static ShortVector random(VectorSpecies<Short> species) { 437 ThreadLocalRandom r = ThreadLocalRandom.current(); 438 return ((ShortSpecies)species).op(i -> (short) r.nextInt()); 439 } 440 441 // Ops 442 443 /** 444 * {@inheritDoc} 445 */ 446 @Override 447 public abstract ShortVector add(Vector<Short> v); 448 449 /** 450 * Adds this vector to the broadcast of an input scalar. 451 * <p> 452 * This is a lane-wise binary operation which applies the primitive addition operation 453 * ({@code +}) to each lane. 454 * 455 * @param s the input scalar 456 * @return the result of adding this vector to the broadcast of an input 457 * scalar 458 */ 459 public abstract ShortVector add(short s); 460 461 /** 462 * {@inheritDoc} 463 */ 464 @Override 465 public abstract ShortVector add(Vector<Short> v, VectorMask<Short> m); 466 467 /** 468 * Adds this vector to broadcast of an input scalar, 469 * selecting lane elements controlled by a mask. 470 * <p> 471 * This is a lane-wise binary operation which applies the primitive addition operation 472 * ({@code +}) to each lane. 473 * 474 * @param s the input scalar 475 * @param m the mask controlling lane selection 476 * @return the result of adding this vector to the broadcast of an input 477 * scalar 478 */ 479 public abstract ShortVector add(short s, VectorMask<Short> m); 480 481 /** 482 * {@inheritDoc} 483 */ 484 @Override 485 public abstract ShortVector sub(Vector<Short> v); 486 487 /** 488 * Subtracts the broadcast of an input scalar from this vector. 489 * <p> 490 * This is a lane-wise binary operation which applies the primitive subtraction 491 * operation ({@code -}) to each lane. 492 * 493 * @param s the input scalar 494 * @return the result of subtracting the broadcast of an input 495 * scalar from this vector 496 */ 497 public abstract ShortVector sub(short s); 498 499 /** 500 * {@inheritDoc} 501 */ 502 @Override 503 public abstract ShortVector sub(Vector<Short> v, VectorMask<Short> m); 504 505 /** 506 * Subtracts the broadcast of an input scalar from this vector, selecting 507 * lane elements controlled by a mask. 508 * <p> 509 * This is a lane-wise binary operation which applies the primitive subtraction 510 * operation ({@code -}) to each lane. 511 * 512 * @param s the input scalar 513 * @param m the mask controlling lane selection 514 * @return the result of subtracting the broadcast of an input 515 * scalar from this vector 516 */ 517 public abstract ShortVector sub(short s, VectorMask<Short> m); 518 519 /** 520 * {@inheritDoc} 521 */ 522 @Override 523 public abstract ShortVector mul(Vector<Short> v); 524 525 /** 526 * Multiplies this vector with the broadcast of an input scalar. 527 * <p> 528 * This is a lane-wise binary operation which applies the primitive multiplication 529 * operation ({@code *}) to each lane. 530 * 531 * @param s the input scalar 532 * @return the result of multiplying this vector with the broadcast of an 533 * input scalar 534 */ 535 public abstract ShortVector mul(short s); 536 537 /** 538 * {@inheritDoc} 539 */ 540 @Override 541 public abstract ShortVector mul(Vector<Short> v, VectorMask<Short> m); 542 543 /** 544 * Multiplies this vector with the broadcast of an input scalar, selecting 545 * lane elements controlled by a mask. 546 * <p> 547 * This is a lane-wise binary operation which applies the primitive multiplication 548 * operation ({@code *}) to each lane. 549 * 550 * @param s the input scalar 551 * @param m the mask controlling lane selection 552 * @return the result of multiplying this vector with the broadcast of an 553 * input scalar 554 */ 555 public abstract ShortVector mul(short s, VectorMask<Short> m); 556 557 /** 558 * {@inheritDoc} 559 */ 560 @Override 561 public abstract ShortVector neg(); 562 563 /** 564 * {@inheritDoc} 565 */ 566 @Override 567 public abstract ShortVector neg(VectorMask<Short> m); 568 569 /** 570 * {@inheritDoc} 571 */ 572 @Override 573 public abstract ShortVector abs(); 574 575 /** 576 * {@inheritDoc} 577 */ 578 @Override 579 public abstract ShortVector abs(VectorMask<Short> m); 580 581 /** 582 * {@inheritDoc} 583 */ 584 @Override 585 public abstract ShortVector min(Vector<Short> v); 586 587 /** 588 * {@inheritDoc} 589 */ 590 @Override 591 public abstract ShortVector min(Vector<Short> v, VectorMask<Short> m); 592 593 /** 594 * Returns the minimum of this vector and the broadcast of an input scalar. 595 * <p> 596 * This is a lane-wise binary operation which applies the operation 597 * {@code (a, b) -> Math.min(a, b)} to each lane. 598 * 599 * @param s the input scalar 600 * @return the minimum of this vector and the broadcast of an input scalar 601 */ 602 public abstract ShortVector min(short s); 603 604 /** 605 * {@inheritDoc} 606 */ 607 @Override 608 public abstract ShortVector max(Vector<Short> v); 609 610 /** 611 * {@inheritDoc} 612 */ 613 @Override 614 public abstract ShortVector max(Vector<Short> v, VectorMask<Short> m); 615 616 /** 617 * Returns the maximum 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.max(a, b)} to each lane. 621 * 622 * @param s the input scalar 623 * @return the maximum of this vector and the broadcast of an input scalar 624 */ 625 public abstract ShortVector max(short s); 626 627 /** 628 * {@inheritDoc} 629 */ 630 @Override 631 public abstract VectorMask<Short> equal(Vector<Short> v); 632 633 /** 634 * Tests if this vector is equal to the broadcast of an input scalar. 635 * <p> 636 * This is a lane-wise binary test operation which applies the primitive equals 637 * operation ({@code ==}) each lane. 638 * 639 * @param s the input scalar 640 * @return the result mask of testing if this vector is equal to the 641 * broadcast of an input scalar 642 */ 643 public abstract VectorMask<Short> equal(short s); 644 645 /** 646 * {@inheritDoc} 647 */ 648 @Override 649 public abstract VectorMask<Short> notEqual(Vector<Short> v); 650 651 /** 652 * Tests if this vector is not equal to the broadcast of an input scalar. 653 * <p> 654 * This is a lane-wise binary test operation which applies the primitive not equals 655 * operation ({@code !=}) to each lane. 656 * 657 * @param s the input scalar 658 * @return the result mask of testing if this vector is not equal to the 659 * broadcast of an input scalar 660 */ 661 public abstract VectorMask<Short> notEqual(short s); 662 663 /** 664 * {@inheritDoc} 665 */ 666 @Override 667 public abstract VectorMask<Short> lessThan(Vector<Short> v); 668 669 /** 670 * Tests if this vector is less than the broadcast of an input scalar. 671 * <p> 672 * This is a lane-wise binary test operation which applies the primitive less than 673 * operation ({@code <}) to each lane. 674 * 675 * @param s the input scalar 676 * @return the mask result of testing if this vector is less than the 677 * broadcast of an input scalar 678 */ 679 public abstract VectorMask<Short> lessThan(short s); 680 681 /** 682 * {@inheritDoc} 683 */ 684 @Override 685 public abstract VectorMask<Short> lessThanEq(Vector<Short> v); 686 687 /** 688 * Tests if this vector is less or equal to the broadcast of an input scalar. 689 * <p> 690 * This is a lane-wise binary test operation which applies the primitive less than 691 * or equal to operation ({@code <=}) to each lane. 692 * 693 * @param s the input scalar 694 * @return the mask result of testing if this vector is less than or equal 695 * to the broadcast of an input scalar 696 */ 697 public abstract VectorMask<Short> lessThanEq(short s); 698 699 /** 700 * {@inheritDoc} 701 */ 702 @Override 703 public abstract VectorMask<Short> greaterThan(Vector<Short> v); 704 705 /** 706 * Tests if this vector is greater than the broadcast of an input scalar. 707 * <p> 708 * This is a lane-wise binary test operation which applies the primitive greater than 709 * operation ({@code >}) to each lane. 710 * 711 * @param s the input scalar 712 * @return the mask result of testing if this vector is greater than the 713 * broadcast of an input scalar 714 */ 715 public abstract VectorMask<Short> greaterThan(short s); 716 717 /** 718 * {@inheritDoc} 719 */ 720 @Override 721 public abstract VectorMask<Short> greaterThanEq(Vector<Short> v); 722 723 /** 724 * Tests if this vector is greater than or equal to the broadcast of an 725 * input scalar. 726 * <p> 727 * This is a lane-wise binary test operation which applies the primitive greater than 728 * or equal to operation ({@code >=}) to each lane. 729 * 730 * @param s the input scalar 731 * @return the mask result of testing if this vector is greater than or 732 * equal to the broadcast of an input scalar 733 */ 734 public abstract VectorMask<Short> greaterThanEq(short s); 735 736 /** 737 * {@inheritDoc} 738 */ 739 @Override 740 public abstract ShortVector blend(Vector<Short> v, VectorMask<Short> m); 741 742 /** 743 * Blends the lane elements of this vector with those of the broadcast of an 744 * input scalar, selecting lanes controlled by a mask. 745 * <p> 746 * For each lane of the mask, at lane index {@code N}, if the mask lane 747 * is set then the lane element at {@code N} from the input vector is 748 * selected and placed into the resulting vector at {@code N}, 749 * otherwise the the lane element at {@code N} from this input vector is 750 * selected and placed into the resulting vector at {@code N}. 751 * 752 * @param s the input scalar 753 * @param m the mask controlling lane selection 754 * @return the result of blending the lane elements of this vector with 755 * those of the broadcast of an input scalar 756 */ 757 public abstract ShortVector blend(short s, VectorMask<Short> m); 758 759 /** 760 * {@inheritDoc} 761 */ 762 @Override 763 public abstract ShortVector rearrange(Vector<Short> v, 764 VectorShuffle<Short> s, VectorMask<Short> m); 765 766 /** 767 * {@inheritDoc} 768 */ 769 @Override 770 public abstract ShortVector rearrange(VectorShuffle<Short> m); 771 772 /** 773 * {@inheritDoc} 774 */ 775 @Override 776 public abstract ShortVector reshape(VectorSpecies<Short> s); 777 778 /** 779 * {@inheritDoc} 780 */ 781 @Override 782 public abstract ShortVector rotateEL(int i); 783 784 /** 785 * {@inheritDoc} 786 */ 787 @Override 788 public abstract ShortVector rotateER(int i); 789 790 /** 791 * {@inheritDoc} 792 */ 793 @Override 794 public abstract ShortVector shiftEL(int i); 795 796 /** 797 * {@inheritDoc} 798 */ 799 @Override 800 public abstract ShortVector shiftER(int i); 801 802 803 804 /** 805 * Bitwise ANDs this vector with an input vector. 806 * <p> 807 * This is a lane-wise binary operation which applies the primitive bitwise AND 808 * operation ({@code &}) to each lane. 809 * 810 * @param v the input vector 811 * @return the bitwise AND of this vector with the input vector 812 */ 813 public abstract ShortVector and(Vector<Short> v); 814 815 /** 816 * Bitwise ANDs this vector with the broadcast of an input scalar. 817 * <p> 818 * This is a lane-wise binary operation which applies the primitive bitwise AND 819 * operation ({@code &}) to each lane. 820 * 821 * @param s the input scalar 822 * @return the bitwise AND of this vector with the broadcast of an input 823 * scalar 824 */ 825 public abstract ShortVector and(short s); 826 827 /** 828 * Bitwise ANDs this vector with an input vector, selecting lane elements 829 * controlled by a mask. 830 * <p> 831 * This is a lane-wise binary operation which applies the primitive bitwise AND 832 * operation ({@code &}) to each lane. 833 * 834 * @param v the input vector 835 * @param m the mask controlling lane selection 836 * @return the bitwise AND of this vector with the input vector 837 */ 838 public abstract ShortVector and(Vector<Short> v, VectorMask<Short> m); 839 840 /** 841 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting 842 * lane elements controlled by a mask. 843 * <p> 844 * This is a lane-wise binary operation which applies the primitive bitwise AND 845 * operation ({@code &}) to each lane. 846 * 847 * @param s the input scalar 848 * @param m the mask controlling lane selection 849 * @return the bitwise AND of this vector with the broadcast of an input 850 * scalar 851 */ 852 public abstract ShortVector and(short s, VectorMask<Short> m); 853 854 /** 855 * Bitwise ORs this vector with an input vector. 856 * <p> 857 * This is a lane-wise binary operation which applies the primitive bitwise OR 858 * operation ({@code |}) to each lane. 859 * 860 * @param v the input vector 861 * @return the bitwise OR of this vector with the input vector 862 */ 863 public abstract ShortVector or(Vector<Short> v); 864 865 /** 866 * Bitwise ORs this vector with the broadcast of an input scalar. 867 * <p> 868 * This is a lane-wise binary operation which applies the primitive bitwise OR 869 * operation ({@code |}) to each lane. 870 * 871 * @param s the input scalar 872 * @return the bitwise OR of this vector with the broadcast of an input 873 * scalar 874 */ 875 public abstract ShortVector or(short s); 876 877 /** 878 * Bitwise ORs this vector with an input vector, selecting lane elements 879 * controlled by a mask. 880 * <p> 881 * This is a lane-wise binary operation which applies the primitive bitwise OR 882 * operation ({@code |}) to each lane. 883 * 884 * @param v the input vector 885 * @param m the mask controlling lane selection 886 * @return the bitwise OR of this vector with the input vector 887 */ 888 public abstract ShortVector or(Vector<Short> v, VectorMask<Short> m); 889 890 /** 891 * Bitwise ORs this vector with the broadcast of an input scalar, selecting 892 * lane elements controlled by a mask. 893 * <p> 894 * This is a lane-wise binary operation which applies the primitive bitwise OR 895 * operation ({@code |}) to each lane. 896 * 897 * @param s the input scalar 898 * @param m the mask controlling lane selection 899 * @return the bitwise OR of this vector with the broadcast of an input 900 * scalar 901 */ 902 public abstract ShortVector or(short s, VectorMask<Short> m); 903 904 /** 905 * Bitwise XORs this vector with an input vector. 906 * <p> 907 * This is a lane-wise binary operation which applies the primitive bitwise XOR 908 * operation ({@code ^}) to each lane. 909 * 910 * @param v the input vector 911 * @return the bitwise XOR of this vector with the input vector 912 */ 913 public abstract ShortVector xor(Vector<Short> v); 914 915 /** 916 * Bitwise XORs this vector with the broadcast of an input scalar. 917 * <p> 918 * This is a lane-wise binary operation which applies the primitive bitwise XOR 919 * operation ({@code ^}) to each lane. 920 * 921 * @param s the input scalar 922 * @return the bitwise XOR of this vector with the broadcast of an input 923 * scalar 924 */ 925 public abstract ShortVector xor(short s); 926 927 /** 928 * Bitwise XORs this vector with an input vector, selecting lane elements 929 * controlled by a mask. 930 * <p> 931 * This is a lane-wise binary operation which applies the primitive bitwise XOR 932 * operation ({@code ^}) to each lane. 933 * 934 * @param v the input vector 935 * @param m the mask controlling lane selection 936 * @return the bitwise XOR of this vector with the input vector 937 */ 938 public abstract ShortVector xor(Vector<Short> v, VectorMask<Short> m); 939 940 /** 941 * Bitwise XORs this vector with the broadcast of an input scalar, selecting 942 * lane elements controlled by a mask. 943 * <p> 944 * This is a lane-wise binary operation which applies the primitive bitwise XOR 945 * operation ({@code ^}) to each lane. 946 * 947 * @param s the input scalar 948 * @param m the mask controlling lane selection 949 * @return the bitwise XOR of this vector with the broadcast of an input 950 * scalar 951 */ 952 public abstract ShortVector xor(short s, VectorMask<Short> m); 953 954 /** 955 * Bitwise NOTs this vector. 956 * <p> 957 * This is a lane-wise unary operation which applies the primitive bitwise NOT 958 * operation ({@code ~}) to each lane. 959 * 960 * @return the bitwise NOT of this vector 961 */ 962 public abstract ShortVector not(); 963 964 /** 965 * Bitwise NOTs this vector, selecting lane elements controlled by a mask. 966 * <p> 967 * This is a lane-wise unary operation which applies the primitive bitwise NOT 968 * operation ({@code ~}) to each lane. 969 * 970 * @param m the mask controlling lane selection 971 * @return the bitwise NOT of this vector 972 */ 973 public abstract ShortVector not(VectorMask<Short> m); 974 975 /** 976 * Logically left shifts this vector by the broadcast of an input scalar. 977 * <p> 978 * This is a lane-wise binary operation which applies the primitive logical left shift 979 * operation ({@code <<}) to each lane to left shift the 980 * element by shift value as specified by the input scalar. Only the 4 981 * lowest-order bits of shift value are used. It is as if the shift value 982 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 983 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 984 * 985 * @param s the input scalar; the number of the bits to left shift 986 * @return the result of logically left shifting left this vector by the 987 * broadcast of an input scalar 988 */ 989 public abstract ShortVector shiftL(int s); 990 991 /** 992 * Logically left shifts this vector by the broadcast of an input scalar, 993 * selecting lane elements controlled by a mask. 994 * <p> 995 * This is a lane-wise binary operation which applies the primitive logical left shift 996 * operation ({@code <<}) to each lane to left shift the 997 * element by shift value as specified by the input scalar. Only the 4 998 * lowest-order bits of shift value are used. It is as if the shift value 999 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 1000 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 1001 * 1002 * @param s the input scalar; the number of the bits to left shift 1003 * @param m the mask controlling lane selection 1004 * @return the result of logically left shifting left this vector by the 1005 * broadcast of an input scalar 1006 */ 1007 public abstract ShortVector shiftL(int s, VectorMask<Short> m); 1008 1009 1010 // logical, or unsigned, shift right 1011 1012 /** 1013 * Logically right shifts (or unsigned right shifts) this vector by the 1014 * broadcast of an input scalar. 1015 * <p> 1016 * This is a lane-wise binary operation which applies the primitive logical right shift 1017 * operation ({@code >>>}) to each lane to logically right shift the 1018 * element by shift value as specified by the input scalar. Only the 4 1019 * lowest-order bits of shift value are used. It is as if the shift value 1020 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 1021 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 1022 * 1023 * @param s the input scalar; the number of the bits to right shift 1024 * @return the result of logically right shifting this vector by the 1025 * broadcast of an input scalar 1026 */ 1027 public abstract ShortVector shiftR(int s); 1028 1029 /** 1030 * Logically right shifts (or unsigned right shifts) this vector by the 1031 * broadcast of an input scalar, selecting lane elements controlled by a 1032 * mask. 1033 * <p> 1034 * This is a lane-wise binary operation which applies the primitive logical right shift 1035 * operation ({@code >>>}) to each lane to logically right shift the 1036 * element by shift value as specified by the input scalar. Only the 4 1037 * lowest-order bits of shift value are used. It is as if the shift value 1038 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 1039 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 1040 * 1041 * @param s the input scalar; the number of the bits to right shift 1042 * @param m the mask controlling lane selection 1043 * @return the result of logically right shifting this vector by the 1044 * broadcast of an input scalar 1045 */ 1046 public abstract ShortVector shiftR(int s, VectorMask<Short> m); 1047 1048 1049 /** 1050 * Arithmetically right shifts (or signed right shifts) this vector by the 1051 * broadcast of an input scalar. 1052 * <p> 1053 * This is a lane-wise binary operation which applies the primitive arithmetic right 1054 * shift operation ({@code >>}) to each lane to arithmetically 1055 * right shift the element by shift value as specified by the input scalar. 1056 * Only the 4 lowest-order bits of shift value are used. It is as if the shift 1057 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 1058 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 1059 * 1060 * @param s the input scalar; the number of the bits to right shift 1061 * @return the result of arithmetically right shifting this vector by the 1062 * broadcast of an input scalar 1063 */ 1064 public abstract ShortVector aShiftR(int s); 1065 1066 /** 1067 * Arithmetically right shifts (or signed right shifts) this vector by the 1068 * broadcast of an input scalar, selecting lane elements controlled by a 1069 * mask. 1070 * <p> 1071 * This is a lane-wise binary operation which applies the primitive arithmetic right 1072 * shift operation ({@code >>}) to each lane to arithmetically 1073 * right shift the element by shift value as specified by the input scalar. 1074 * Only the 4 lowest-order bits of shift value are used. It is as if the shift 1075 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 1076 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 1077 * 1078 * @param s the input scalar; the number of the bits to right shift 1079 * @param m the mask controlling lane selection 1080 * @return the result of arithmetically right shifting this vector by the 1081 * broadcast of an input scalar 1082 */ 1083 public abstract ShortVector aShiftR(int s, VectorMask<Short> m); 1084 1085 1086 /** 1087 * {@inheritDoc} 1088 */ 1089 @Override 1090 public abstract void intoByteArray(byte[] a, int ix); 1091 1092 /** 1093 * {@inheritDoc} 1094 */ 1095 @Override 1096 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Short> m); 1097 1098 /** 1099 * {@inheritDoc} 1100 */ 1101 @Override 1102 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 1103 1104 /** 1105 * {@inheritDoc} 1106 */ 1107 @Override 1108 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Short> m); 1109 1110 1111 // Type specific horizontal reductions 1112 /** 1113 * Adds all lane elements of this vector. 1114 * <p> 1115 * This is an associative cross-lane reduction operation which applies the addition 1116 * operation ({@code +}) to lane elements, 1117 * and the identity value is {@code 0}. 1118 * 1119 * @return the addition of all the lane elements of this vector 1120 */ 1121 public abstract short addAll(); 1122 1123 /** 1124 * Adds all lane elements of this vector, selecting lane elements 1125 * controlled by a mask. 1126 * <p> 1127 * This is an associative cross-lane reduction operation which applies the addition 1128 * operation ({@code +}) to lane elements, 1129 * and the identity value is {@code 0}. 1130 * 1131 * @param m the mask controlling lane selection 1132 * @return the addition of the selected lane elements of this vector 1133 */ 1134 public abstract short addAll(VectorMask<Short> m); 1135 1136 /** 1137 * Multiplies all lane elements of this vector. 1138 * <p> 1139 * This is an associative cross-lane reduction operation which applies the 1140 * multiplication operation ({@code *}) to lane elements, 1141 * and the identity value is {@code 1}. 1142 * 1143 * @return the multiplication of all the lane elements of this vector 1144 */ 1145 public abstract short mulAll(); 1146 1147 /** 1148 * Multiplies all lane elements of this vector, selecting lane elements 1149 * controlled by a mask. 1150 * <p> 1151 * This is an associative cross-lane reduction operation which applies the 1152 * multiplication operation ({@code *}) to lane elements, 1153 * and the identity value is {@code 1}. 1154 * 1155 * @param m the mask controlling lane selection 1156 * @return the multiplication of all the lane elements of this vector 1157 */ 1158 public abstract short mulAll(VectorMask<Short> m); 1159 1160 /** 1161 * Returns the minimum lane element of this vector. 1162 * <p> 1163 * This is an associative cross-lane reduction operation which applies the operation 1164 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1165 * and the identity value is 1166 * {@link Short#MAX_VALUE}. 1167 * 1168 * @return the minimum lane element of this vector 1169 */ 1170 public abstract short minAll(); 1171 1172 /** 1173 * Returns the minimum lane element of this vector, selecting lane elements 1174 * controlled by a mask. 1175 * <p> 1176 * This is an associative cross-lane reduction operation which applies the operation 1177 * {@code (a, b) -> Math.min(a, b)} to lane elements, 1178 * and the identity value is 1179 * {@link Short#MAX_VALUE}. 1180 * 1181 * @param m the mask controlling lane selection 1182 * @return the minimum lane element of this vector 1183 */ 1184 public abstract short minAll(VectorMask<Short> m); 1185 1186 /** 1187 * Returns the maximum lane element of this vector. 1188 * <p> 1189 * This is an associative cross-lane reduction operation which applies the operation 1190 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1191 * and the identity value is 1192 * {@link Short#MIN_VALUE}. 1193 * 1194 * @return the maximum lane element of this vector 1195 */ 1196 public abstract short maxAll(); 1197 1198 /** 1199 * Returns the maximum lane element of this vector, selecting lane elements 1200 * controlled by a mask. 1201 * <p> 1202 * This is an associative cross-lane reduction operation which applies the operation 1203 * {@code (a, b) -> Math.max(a, b)} to lane elements, 1204 * and the identity value is 1205 * {@link Short#MIN_VALUE}. 1206 * 1207 * @param m the mask controlling lane selection 1208 * @return the maximum lane element of this vector 1209 */ 1210 public abstract short maxAll(VectorMask<Short> m); 1211 1212 /** 1213 * Logically ORs all lane elements of this vector. 1214 * <p> 1215 * This is an associative cross-lane reduction operation which applies the logical OR 1216 * operation ({@code |}) to lane elements, 1217 * and the identity value is {@code 0}. 1218 * 1219 * @return the logical OR all the lane elements of this vector 1220 */ 1221 public abstract short orAll(); 1222 1223 /** 1224 * Logically ORs all lane elements of this vector, selecting lane elements 1225 * controlled by a mask. 1226 * <p> 1227 * This is an associative cross-lane reduction operation which applies the logical OR 1228 * operation ({@code |}) to lane elements, 1229 * and the identity value is {@code 0}. 1230 * 1231 * @param m the mask controlling lane selection 1232 * @return the logical OR all the lane elements of this vector 1233 */ 1234 public abstract short orAll(VectorMask<Short> m); 1235 1236 /** 1237 * Logically ANDs all lane elements of this vector. 1238 * <p> 1239 * This is an associative cross-lane reduction operation which applies the logical AND 1240 * operation ({@code |}) to lane elements, 1241 * and the identity value is {@code -1}. 1242 * 1243 * @return the logical AND all the lane elements of this vector 1244 */ 1245 public abstract short andAll(); 1246 1247 /** 1248 * Logically ANDs all lane elements of this vector, selecting lane elements 1249 * controlled by a mask. 1250 * <p> 1251 * This is an associative cross-lane reduction operation which applies the logical AND 1252 * operation ({@code |}) to lane elements, 1253 * and the identity value is {@code -1}. 1254 * 1255 * @param m the mask controlling lane selection 1256 * @return the logical AND all the lane elements of this vector 1257 */ 1258 public abstract short andAll(VectorMask<Short> m); 1259 1260 /** 1261 * Logically XORs all lane elements of this vector. 1262 * <p> 1263 * This is an associative cross-lane reduction operation which applies the logical XOR 1264 * operation ({@code ^}) to lane elements, 1265 * and the identity value is {@code 0}. 1266 * 1267 * @return the logical XOR all the lane elements of this vector 1268 */ 1269 public abstract short xorAll(); 1270 1271 /** 1272 * Logically XORs all lane elements of this vector, selecting lane elements 1273 * controlled by a mask. 1274 * <p> 1275 * This is an associative cross-lane reduction operation which applies the logical XOR 1276 * operation ({@code ^}) to lane elements, 1277 * and the identity value is {@code 0}. 1278 * 1279 * @param m the mask controlling lane selection 1280 * @return the logical XOR all the lane elements of this vector 1281 */ 1282 public abstract short xorAll(VectorMask<Short> m); 1283 1284 // Type specific accessors 1285 1286 /** 1287 * Gets the lane element at lane index {@code i} 1288 * 1289 * @param i the lane index 1290 * @return the lane element at lane index {@code i} 1291 * @throws IllegalArgumentException if the index is is out of range 1292 * ({@code < 0 || >= length()}) 1293 */ 1294 public abstract short lane(int i); 1295 1296 /** 1297 * Replaces the lane element of this vector at lane index {@code i} with 1298 * value {@code e}. 1299 * <p> 1300 * This is a cross-lane operation and behaves as if it returns the result 1301 * of blending this vector with an input vector that is the result of 1302 * broadcasting {@code e} and a mask that has only one lane set at lane 1303 * index {@code i}. 1304 * 1305 * @param i the lane index of the lane element to be replaced 1306 * @param e the value to be placed 1307 * @return the result of replacing the lane element of this vector at lane 1308 * index {@code i} with value {@code e}. 1309 * @throws IllegalArgumentException if the index is is out of range 1310 * ({@code < 0 || >= length()}) 1311 */ 1312 public abstract ShortVector with(int i, short e); 1313 1314 // Type specific extractors 1315 1316 /** 1317 * Returns an array containing the lane elements of this vector. 1318 * <p> 1319 * This method behaves as if it {@link #intoArray(short[], int)} stores} 1320 * this vector into an allocated array and returns the array as follows: 1321 * <pre>{@code 1322 * short[] a = new short[this.length()]; 1323 * this.intoArray(a, 0); 1324 * return a; 1325 * }</pre> 1326 * 1327 * @return an array containing the the lane elements of this vector 1328 */ 1329 @ForceInline 1330 public final short[] toArray() { 1331 short[] a = new short[species().length()]; 1332 intoArray(a, 0); 1333 return a; 1334 } 1335 1336 /** 1337 * Stores this vector into an array starting at offset. 1338 * <p> 1339 * For each vector lane, where {@code N} is the vector lane index, 1340 * the lane element at index {@code N} is stored into the array at index 1341 * {@code offset + N}. 1342 * 1343 * @param a the array 1344 * @param offset the offset into the array 1345 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1346 * {@code offset > a.length - this.length()} 1347 */ 1348 public abstract void intoArray(short[] a, int offset); 1349 1350 /** 1351 * Stores this vector into an array starting at offset and using a mask. 1352 * <p> 1353 * For each vector lane, where {@code N} is the vector lane index, 1354 * if the mask lane at index {@code N} is set then the lane element at 1355 * index {@code N} is stored into the array index {@code offset + N}. 1356 * 1357 * @param a the array 1358 * @param offset the offset into the array 1359 * @param m the mask 1360 * @throws IndexOutOfBoundsException if {@code offset < 0}, or 1361 * for any vector lane index {@code N} where the mask at lane {@code N} 1362 * is set {@code offset >= a.length - N} 1363 */ 1364 public abstract void intoArray(short[] a, int offset, VectorMask<Short> m); 1365 1366 /** 1367 * Stores this vector into an array using indexes obtained from an index 1368 * map. 1369 * <p> 1370 * For each vector lane, where {@code N} is the vector lane index, the 1371 * lane element at index {@code N} is stored into the array at index 1372 * {@code a_offset + indexMap[i_offset + N]}. 1373 * 1374 * @param a the array 1375 * @param a_offset the offset into the array, may be negative if relative 1376 * indexes in the index map compensate to produce a value within the 1377 * array bounds 1378 * @param indexMap the index map 1379 * @param i_offset the offset into the index map 1380 * @throws IndexOutOfBoundsException if {@code i_offset < 0}, or 1381 * {@code i_offset > indexMap.length - this.length()}, 1382 * or for any vector lane index {@code N} the result of 1383 * {@code a_offset + indexMap[i_offset + N]} is {@code < 0} or {@code >= a.length} 1384 */ 1385 public void intoArray(short[] a, int a_offset, int[] indexMap, int i_offset) { 1386 forEach((n, e) -> a[a_offset + indexMap[i_offset + n]] = e); 1387 } 1388 1389 /** 1390 * Stores this vector into an array using indexes obtained from an index 1391 * map and using a mask. 1392 * <p> 1393 * For each vector lane, where {@code N} is the vector lane index, 1394 * if the mask lane at index {@code N} is set then the lane element at 1395 * index {@code N} is stored into the array at index 1396 * {@code a_offset + indexMap[i_offset + N]}. 1397 * 1398 * @param a the array 1399 * @param a_offset the offset into the array, may be negative if relative 1400 * indexes in the index map compensate to produce a value within the 1401 * array bounds 1402 * @param m the mask 1403 * @param indexMap the index map 1404 * @param i_offset the offset into the index map 1405 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1406 * {@code i_offset > indexMap.length - this.length()}, 1407 * or for any vector lane index {@code N} where the mask at lane 1408 * {@code N} is set the result of {@code a_offset + indexMap[i_offset + N]} is 1409 * {@code < 0} or {@code >= a.length} 1410 */ 1411 public void intoArray(short[] a, int a_offset, VectorMask<Short> m, int[] indexMap, int i_offset) { 1412 forEach(m, (n, e) -> a[a_offset + indexMap[i_offset + n]] = e); 1413 } 1414 // Species 1415 1416 /** 1417 * {@inheritDoc} 1418 */ 1419 @Override 1420 public abstract VectorSpecies<Short> species(); 1421 1422 /** 1423 * Class representing {@link ShortVector}'s of the same {@link VectorShape VectorShape}. 1424 */ 1425 static final class ShortSpecies extends AbstractSpecies<Short> { 1426 final Function<short[], ShortVector> vectorFactory; 1427 1428 private ShortSpecies(VectorShape shape, 1429 Class<?> boxType, 1430 Class<?> maskType, 1431 Function<short[], ShortVector> vectorFactory, 1432 Function<boolean[], VectorMask<Short>> maskFactory, 1433 Function<IntUnaryOperator, VectorShuffle<Short>> shuffleFromArrayFactory, 1434 fShuffleFromArray<Short> shuffleFromOpFactory) { 1435 super(shape, short.class, Short.SIZE, boxType, maskType, maskFactory, 1436 shuffleFromArrayFactory, shuffleFromOpFactory); 1437 this.vectorFactory = vectorFactory; 1438 } 1439 1440 interface FOp { 1441 short apply(int i); 1442 } 1443 1444 ShortVector op(FOp f) { 1445 short[] res = new short[length()]; 1446 for (int i = 0; i < length(); i++) { 1447 res[i] = f.apply(i); 1448 } 1449 return vectorFactory.apply(res); 1450 } 1451 1452 ShortVector op(VectorMask<Short> o, FOp f) { 1453 short[] res = new short[length()]; 1454 boolean[] mbits = ((AbstractMask<Short>)o).getBits(); 1455 for (int i = 0; i < length(); i++) { 1456 if (mbits[i]) { 1457 res[i] = f.apply(i); 1458 } 1459 } 1460 return vectorFactory.apply(res); 1461 } 1462 } 1463 1464 /** 1465 * Finds the preferred species for an element type of {@code short}. 1466 * <p> 1467 * A preferred species is a species chosen by the platform that has a 1468 * shape of maximal bit size. A preferred species for different element 1469 * types will have the same shape, and therefore vectors, masks, and 1470 * shuffles created from such species will be shape compatible. 1471 * 1472 * @return the preferred species for an element type of {@code short} 1473 */ 1474 private static ShortSpecies preferredSpecies() { 1475 return (ShortSpecies) VectorSpecies.ofPreferred(short.class); 1476 } 1477 1478 /** 1479 * Finds a species for an element type of {@code short} and shape. 1480 * 1481 * @param s the shape 1482 * @return a species for an element type of {@code short} and shape 1483 * @throws IllegalArgumentException if no such species exists for the shape 1484 */ 1485 static ShortSpecies species(VectorShape s) { 1486 Objects.requireNonNull(s); 1487 switch (s) { 1488 case S_64_BIT: return (ShortSpecies) SPECIES_64; 1489 case S_128_BIT: return (ShortSpecies) SPECIES_128; 1490 case S_256_BIT: return (ShortSpecies) SPECIES_256; 1491 case S_512_BIT: return (ShortSpecies) SPECIES_512; 1492 case S_Max_BIT: return (ShortSpecies) SPECIES_MAX; 1493 default: throw new IllegalArgumentException("Bad shape: " + s); 1494 } 1495 } 1496 1497 /** Species representing {@link ShortVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 1498 public static final VectorSpecies<Short> SPECIES_64 = new ShortSpecies(VectorShape.S_64_BIT, Short64Vector.class, Short64Vector.Short64Mask.class, 1499 Short64Vector::new, Short64Vector.Short64Mask::new, 1500 Short64Vector.Short64Shuffle::new, Short64Vector.Short64Shuffle::new); 1501 1502 /** Species representing {@link ShortVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 1503 public static final VectorSpecies<Short> SPECIES_128 = new ShortSpecies(VectorShape.S_128_BIT, Short128Vector.class, Short128Vector.Short128Mask.class, 1504 Short128Vector::new, Short128Vector.Short128Mask::new, 1505 Short128Vector.Short128Shuffle::new, Short128Vector.Short128Shuffle::new); 1506 1507 /** Species representing {@link ShortVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 1508 public static final VectorSpecies<Short> SPECIES_256 = new ShortSpecies(VectorShape.S_256_BIT, Short256Vector.class, Short256Vector.Short256Mask.class, 1509 Short256Vector::new, Short256Vector.Short256Mask::new, 1510 Short256Vector.Short256Shuffle::new, Short256Vector.Short256Shuffle::new); 1511 1512 /** Species representing {@link ShortVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 1513 public static final VectorSpecies<Short> SPECIES_512 = new ShortSpecies(VectorShape.S_512_BIT, Short512Vector.class, Short512Vector.Short512Mask.class, 1514 Short512Vector::new, Short512Vector.Short512Mask::new, 1515 Short512Vector.Short512Shuffle::new, Short512Vector.Short512Shuffle::new); 1516 1517 /** Species representing {@link ShortVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 1518 public static final VectorSpecies<Short> SPECIES_MAX = new ShortSpecies(VectorShape.S_Max_BIT, ShortMaxVector.class, ShortMaxVector.ShortMaxMask.class, 1519 ShortMaxVector::new, ShortMaxVector.ShortMaxMask::new, 1520 ShortMaxVector.ShortMaxShuffle::new, ShortMaxVector.ShortMaxShuffle::new); 1521 1522 /** 1523 * Preferred species for {@link ShortVector}s. 1524 * A preferred species is a species of maximal bit size for the platform. 1525 */ 1526 public static final VectorSpecies<Short> SPECIES_PREFERRED = (VectorSpecies<Short>) preferredSpecies(); 1527 }