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<Short>, ByteBuffer, int, VectorMask) method} as follows: 129 * <pre>{@code 130 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, this.maskAllTrue()); 131 * }</pre> 132 * 133 * @param species species of desired vector 134 * @param a the byte array 135 * @param ix the offset into the array 136 * @return a vector loaded from a byte array 137 * @throws IndexOutOfBoundsException if {@code i < 0} or 138 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)} 139 */ 140 @ForceInline 141 @SuppressWarnings("unchecked") 142 public static ShortVector fromByteArray(VectorSpecies<Short> species, byte[] a, int ix) { 143 Objects.requireNonNull(a); 144 ix = VectorIntrinsics.checkIndex(ix, a.length, species.bitSize() / Byte.SIZE); 145 return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(), 146 a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET, 147 a, ix, 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<Short>, ByteBuffer, int, VectorMask) method} as follows: 165 * <pre>{@code 166 * return this.fromByteBuffer(ByteBuffer.wrap(a), i, m); 167 * }</pre> 168 * 169 * @param species species of desired vector 170 * @param a the byte array 171 * @param ix the offset into the array 172 * @param m the mask 173 * @return a vector loaded from a byte array 174 * @throws IndexOutOfBoundsException if {@code i < 0} or 175 * {@code i > a.length - (this.length() * this.elementSize() / Byte.SIZE)} 176 * @throws IndexOutOfBoundsException if the offset is {@code < 0}, 177 * or {@code > a.length}, 178 * for any vector lane index {@code N} where the mask at lane {@code N} 179 * is set 180 * {@code i >= a.length - (N * this.elementSize() / Byte.SIZE)} 181 */ 182 @ForceInline 183 public static ShortVector fromByteArray(VectorSpecies<Short> species, byte[] a, int ix, VectorMask<Short> m) { 184 return zero(species).blend(fromByteArray(species, a, ix), m); 185 } 186 187 /** 188 * Loads a vector from an array starting at offset. 189 * <p> 190 * For each vector lane, where {@code N} is the vector lane index, the 191 * array element at index {@code i + N} is placed into the 192 * resulting vector at lane index {@code N}. 193 * 194 * @param species species of desired vector 195 * @param a the array 196 * @param i the offset into the array 197 * @return the vector loaded from an array 198 * @throws IndexOutOfBoundsException if {@code i < 0}, or 199 * {@code i > a.length - this.length()} 200 */ 201 @ForceInline 202 @SuppressWarnings("unchecked") 203 public static ShortVector fromArray(VectorSpecies<Short> species, short[] a, int i){ 204 Objects.requireNonNull(a); 205 i = VectorIntrinsics.checkIndex(i, a.length, species.length()); 206 return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(), 207 a, (((long) i) << ARRAY_SHIFT) + Unsafe.ARRAY_SHORT_BASE_OFFSET, 208 a, i, species, 209 (c, idx, s) -> ((ShortSpecies)s).op(n -> c[idx + n])); 210 } 211 212 213 /** 214 * Loads a vector from an array starting at offset and using a mask. 215 * <p> 216 * For each vector lane, where {@code N} is the vector lane index, 217 * if the mask lane at index {@code N} is set then the array element at 218 * index {@code i + N} is placed into the resulting vector at lane index 219 * {@code N}, otherwise the default element value is placed into the 220 * resulting vector at lane index {@code N}. 221 * 222 * @param species species of desired vector 223 * @param a the array 224 * @param i the offset into the array 225 * @param m the mask 226 * @return the vector loaded from an array 227 * @throws IndexOutOfBoundsException if {@code i < 0}, or 228 * for any vector lane index {@code N} where the mask at lane {@code N} 229 * is set {@code i > a.length - N} 230 */ 231 @ForceInline 232 public static ShortVector fromArray(VectorSpecies<Short> species, short[] a, int i, VectorMask<Short> m) { 233 return zero(species).blend(fromArray(species, a, i), m); 234 } 235 236 /** 237 * Loads a vector from an array using indexes obtained from an index 238 * map. 239 * <p> 240 * For each vector lane, where {@code N} is the vector lane index, the 241 * array element at index {@code i + indexMap[j + N]} is placed into the 242 * resulting vector at lane index {@code N}. 243 * 244 * @param species species of desired vector 245 * @param a the array 246 * @param i the offset into the array, may be negative if relative 247 * indexes in the index map compensate to produce a value within the 248 * array bounds 249 * @param indexMap the index map 250 * @param j the offset into the index map 251 * @return the vector loaded from an array 252 * @throws IndexOutOfBoundsException if {@code j < 0}, or 253 * {@code j > indexMap.length - this.length()}, 254 * or for any vector lane index {@code N} the result of 255 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 256 */ 257 public static ShortVector fromArray(VectorSpecies<Short> species, short[] a, int i, int[] indexMap, int j) { 258 return ((ShortSpecies)species).op(n -> a[i + indexMap[j + n]]); 259 } 260 /** 261 * Loads a vector from an array using indexes obtained from an index 262 * map and using a mask. 263 * <p> 264 * For each vector lane, where {@code N} is the vector lane index, 265 * if the mask lane at index {@code N} is set then the array element at 266 * index {@code i + indexMap[j + N]} is placed into the resulting vector 267 * at lane index {@code N}. 268 * 269 * @param species species of desired vector 270 * @param a the array 271 * @param i the offset into the array, may be negative if relative 272 * indexes in the index map compensate to produce a value within the 273 * array bounds 274 * @param m the mask 275 * @param indexMap the index map 276 * @param j the offset into the index map 277 * @return the vector loaded from an array 278 * @throws IndexOutOfBoundsException if {@code j < 0}, or 279 * {@code j > indexMap.length - this.length()}, 280 * or for any vector lane index {@code N} where the mask at lane 281 * {@code N} is set the result of {@code i + indexMap[j + N]} is 282 * {@code < 0} or {@code >= a.length} 283 */ 284 public static ShortVector fromArray(VectorSpecies<Short> species, short[] a, int i, VectorMask<Short> m, int[] indexMap, int j) { 285 return ((ShortSpecies)species).op(m, n -> a[i + indexMap[j + n]]); 286 } 287 288 /** 289 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an 290 * offset into the byte buffer. 291 * <p> 292 * Bytes are composed into primitive lane elements according to the 293 * native byte order of the underlying platform. 294 * <p> 295 * This method behaves as if it returns the result of calling the 296 * byte buffer, offset, and mask accepting 297 * {@link #fromByteBuffer(VectorSpecies<Short>, ByteBuffer, int, VectorMask)} method} as follows: 298 * <pre>{@code 299 * return this.fromByteBuffer(b, i, this.maskAllTrue()) 300 * }</pre> 301 * 302 * @param species species of desired vector 303 * @param bb the byte buffer 304 * @param ix the offset into the byte buffer 305 * @return a vector loaded from a byte buffer 306 * @throws IndexOutOfBoundsException if the offset is {@code < 0}, 307 * or {@code > b.limit()}, 308 * or if there are fewer than 309 * {@code this.length() * this.elementSize() / Byte.SIZE} bytes 310 * remaining in the byte buffer from the given offset 311 */ 312 @ForceInline 313 @SuppressWarnings("unchecked") 314 public static ShortVector fromByteBuffer(VectorSpecies<Short> species, ByteBuffer bb, int ix) { 315 if (bb.order() != ByteOrder.nativeOrder()) { 316 throw new IllegalArgumentException(); 317 } 318 ix = VectorIntrinsics.checkIndex(ix, bb.limit(), species.bitSize() / Byte.SIZE); 319 return VectorIntrinsics.load((Class<ShortVector>) species.boxType(), short.class, species.length(), 320 U.getReference(bb, BYTE_BUFFER_HB), U.getLong(bb, BUFFER_ADDRESS) + ix, 321 bb, ix, species, 322 (c, idx, s) -> { 323 ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder()); 324 ShortBuffer tb = bbc.asShortBuffer(); 325 return ((ShortSpecies)s).op(i -> tb.get()); 326 }); 327 } 328 329 /** 330 * Loads a vector from a {@link ByteBuffer byte buffer} starting at an 331 * offset into the byte buffer and using a mask. 332 * <p> 333 * This method behaves as if the byte buffer is viewed as a primitive 334 * {@link java.nio.Buffer buffer} for the primitive element type, 335 * according to the native byte order of the underlying platform, and 336 * the returned vector is loaded with a mask from a primitive array 337 * obtained from the primitive buffer. 338 * The following pseudocode expresses the behaviour, where 339 * {@coce EBuffer} is the primitive buffer type, {@code e} is the 340 * primitive element type, and {@code ESpecies<S>} is the primitive 341 * species for {@code e}: 342 * <pre>{@code 343 * EBuffer eb = b.duplicate(). 344 * order(ByteOrder.nativeOrder()).position(i). 345 * asEBuffer(); 346 * e[] es = new e[this.length()]; 347 * for (int n = 0; n < t.length; n++) { 348 * if (m.isSet(n)) 349 * es[n] = eb.get(n); 350 * } 351 * Vector<E> r = ((ESpecies<S>)this).fromArray(es, 0, m); 352 * }</pre> 353 * 354 * @param species species of desired vector 355 * @param bb the byte buffer 356 * @param ix the offset into the byte buffer 357 * @param m the mask 358 * @return a vector loaded from a byte buffer 359 * @throws IndexOutOfBoundsException if the offset is {@code < 0}, 360 * or {@code > b.limit()}, 361 * for any vector lane index {@code N} where the mask at lane {@code N} 362 * is set 363 * {@code i >= b.limit() - (N * this.elementSize() / Byte.SIZE)} 364 */ 365 @ForceInline 366 public static ShortVector fromByteBuffer(VectorSpecies<Short> species, ByteBuffer bb, int ix, VectorMask<Short> m) { 367 return zero(species).blend(fromByteBuffer(species, bb, ix), m); 368 } 369 370 /** 371 * Returns a vector where all lane elements are set to the primitive 372 * value {@code e}. 373 * 374 * @param s species of the desired vector 375 * @param e the value 376 * @return a vector of vector where all lane elements are set to 377 * the primitive value {@code e} 378 */ 379 @ForceInline 380 @SuppressWarnings("unchecked") 381 public static ShortVector broadcast(VectorSpecies<Short> s, short e) { 382 return VectorIntrinsics.broadcastCoerced( 383 (Class<ShortVector>) s.boxType(), short.class, s.length(), 384 e, s, 385 ((bits, sp) -> ((ShortSpecies)sp).op(i -> (short)bits))); 386 } 387 388 /** 389 * Returns a vector where each lane element is set to a given 390 * primitive value. 391 * <p> 392 * For each vector lane, where {@code N} is the vector lane index, the 393 * the primitive value at index {@code N} is placed into the resulting 394 * vector at lane index {@code N}. 395 * 396 * @param s species of the desired vector 397 * @param es the given primitive values 398 * @return a vector where each lane element is set to a given primitive 399 * value 400 * @throws IndexOutOfBoundsException if {@code es.length < this.length()} 401 */ 402 @ForceInline 403 @SuppressWarnings("unchecked") 404 public static ShortVector scalars(VectorSpecies<Short> s, short... es) { 405 Objects.requireNonNull(es); 406 int ix = VectorIntrinsics.checkIndex(0, es.length, s.length()); 407 return VectorIntrinsics.load((Class<ShortVector>) s.boxType(), short.class, s.length(), 408 es, Unsafe.ARRAY_SHORT_BASE_OFFSET, 409 es, ix, s, 410 (c, idx, sp) -> ((ShortSpecies)sp).op(n -> c[idx + n])); 411 } 412 413 /** 414 * Returns a vector where the first lane element is set to the primtive 415 * value {@code e}, all other lane elements are set to the default 416 * value. 417 * 418 * @param s species of the desired vector 419 * @param e the value 420 * @return a vector where the first lane element is set to the primitive 421 * value {@code e} 422 */ 423 @ForceInline 424 public static final ShortVector single(VectorSpecies<Short> s, short e) { 425 return zero(s).with(0, e); 426 } 427 428 /** 429 * Returns a vector where each lane element is set to a randomly 430 * generated primitive value. 431 * 432 * The semantics are equivalent to calling 433 * (short){@link ThreadLocalRandom#nextInt()} 434 * 435 * @param s species of the desired vector 436 * @return a vector where each lane elements is set to a randomly 437 * generated primitive value 438 */ 439 public static ShortVector random(VectorSpecies<Short> s) { 440 ThreadLocalRandom r = ThreadLocalRandom.current(); 441 return ((ShortSpecies)s).op(i -> (short) r.nextInt()); 442 } 443 444 // Ops 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 vector binary operation where the primitive addition operation 453 * ({@code +}) is applied to lane elements. 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 @Override 462 public abstract ShortVector add(Vector<Short> v, VectorMask<Short> m); 463 464 /** 465 * Adds this vector to broadcast of an input scalar, 466 * selecting lane elements controlled by a mask. 467 * <p> 468 * This is a vector binary operation where the primitive addition operation 469 * ({@code +}) is applied to lane elements. 470 * 471 * @param s the input scalar 472 * @param m the mask controlling lane selection 473 * @return the result of adding this vector to the broadcast of an input 474 * scalar 475 */ 476 public abstract ShortVector add(short s, VectorMask<Short> m); 477 478 @Override 479 public abstract ShortVector sub(Vector<Short> v); 480 481 /** 482 * Subtracts the broadcast of an input scalar from this vector. 483 * <p> 484 * This is a vector binary operation where the primitive subtraction 485 * operation ({@code -}) is applied to lane elements. 486 * 487 * @param s the input scalar 488 * @return the result of subtracting the broadcast of an input 489 * scalar from this vector 490 */ 491 public abstract ShortVector sub(short s); 492 493 @Override 494 public abstract ShortVector sub(Vector<Short> v, VectorMask<Short> m); 495 496 /** 497 * Subtracts the broadcast of an input scalar from this vector, selecting 498 * lane elements controlled by a mask. 499 * <p> 500 * This is a vector binary operation where the primitive subtraction 501 * operation ({@code -}) is applied to lane elements. 502 * 503 * @param s the input scalar 504 * @param m the mask controlling lane selection 505 * @return the result of subtracting the broadcast of an input 506 * scalar from this vector 507 */ 508 public abstract ShortVector sub(short s, VectorMask<Short> m); 509 510 @Override 511 public abstract ShortVector mul(Vector<Short> v); 512 513 /** 514 * Multiplies this vector with the broadcast of an input scalar. 515 * <p> 516 * This is a vector binary operation where the primitive multiplication 517 * operation ({@code *}) is applied to lane elements. 518 * 519 * @param s the input scalar 520 * @return the result of multiplying this vector with the broadcast of an 521 * input scalar 522 */ 523 public abstract ShortVector mul(short s); 524 525 @Override 526 public abstract ShortVector mul(Vector<Short> v, VectorMask<Short> m); 527 528 /** 529 * Multiplies this vector with the broadcast of an input scalar, selecting 530 * lane elements controlled by a mask. 531 * <p> 532 * This is a vector binary operation where the primitive multiplication 533 * operation ({@code *}) is applied to lane elements. 534 * 535 * @param s the input scalar 536 * @param m the mask controlling lane selection 537 * @return the result of multiplying this vector with the broadcast of an 538 * input scalar 539 */ 540 public abstract ShortVector mul(short s, VectorMask<Short> m); 541 542 @Override 543 public abstract ShortVector neg(); 544 545 @Override 546 public abstract ShortVector neg(VectorMask<Short> m); 547 548 @Override 549 public abstract ShortVector abs(); 550 551 @Override 552 public abstract ShortVector abs(VectorMask<Short> m); 553 554 @Override 555 public abstract ShortVector min(Vector<Short> v); 556 557 @Override 558 public abstract ShortVector min(Vector<Short> v, VectorMask<Short> m); 559 560 /** 561 * Returns the minimum of this vector and the broadcast of an input scalar. 562 * <p> 563 * This is a vector binary operation where the operation 564 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements. 565 * 566 * @param s the input scalar 567 * @return the minimum of this vector and the broadcast of an input scalar 568 */ 569 public abstract ShortVector min(short s); 570 571 @Override 572 public abstract ShortVector max(Vector<Short> v); 573 574 @Override 575 public abstract ShortVector max(Vector<Short> v, VectorMask<Short> m); 576 577 /** 578 * Returns the maximum of this vector and the broadcast of an input scalar. 579 * <p> 580 * This is a vector binary operation where the operation 581 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements. 582 * 583 * @param s the input scalar 584 * @return the maximum of this vector and the broadcast of an input scalar 585 */ 586 public abstract ShortVector max(short s); 587 588 @Override 589 public abstract VectorMask<Short> equal(Vector<Short> v); 590 591 /** 592 * Tests if this vector is equal to the broadcast of an input scalar. 593 * <p> 594 * This is a vector binary test operation where the primitive equals 595 * operation ({@code ==}) is applied to lane elements. 596 * 597 * @param s the input scalar 598 * @return the result mask of testing if this vector is equal to the 599 * broadcast of an input scalar 600 */ 601 public abstract VectorMask<Short> equal(short s); 602 603 @Override 604 public abstract VectorMask<Short> notEqual(Vector<Short> v); 605 606 /** 607 * Tests if this vector is not equal to the broadcast of an input scalar. 608 * <p> 609 * This is a vector binary test operation where the primitive not equals 610 * operation ({@code !=}) is applied to lane elements. 611 * 612 * @param s the input scalar 613 * @return the result mask of testing if this vector is not equal to the 614 * broadcast of an input scalar 615 */ 616 public abstract VectorMask<Short> notEqual(short s); 617 618 @Override 619 public abstract VectorMask<Short> lessThan(Vector<Short> v); 620 621 /** 622 * Tests if this vector is less than the broadcast of an input scalar. 623 * <p> 624 * This is a vector binary test operation where the primitive less than 625 * operation ({@code <}) is applied to lane elements. 626 * 627 * @param s the input scalar 628 * @return the mask result of testing if this vector is less than the 629 * broadcast of an input scalar 630 */ 631 public abstract VectorMask<Short> lessThan(short s); 632 633 @Override 634 public abstract VectorMask<Short> lessThanEq(Vector<Short> v); 635 636 /** 637 * Tests if this vector is less or equal to the broadcast of an input scalar. 638 * <p> 639 * This is a vector binary test operation where the primitive less than 640 * or equal to operation ({@code <=}) is applied to lane elements. 641 * 642 * @param s the input scalar 643 * @return the mask result of testing if this vector is less than or equal 644 * to the broadcast of an input scalar 645 */ 646 public abstract VectorMask<Short> lessThanEq(short s); 647 648 @Override 649 public abstract VectorMask<Short> greaterThan(Vector<Short> v); 650 651 /** 652 * Tests if this vector is greater than the broadcast of an input scalar. 653 * <p> 654 * This is a vector binary test operation where the primitive greater than 655 * operation ({@code >}) is applied to lane elements. 656 * 657 * @param s the input scalar 658 * @return the mask result of testing if this vector is greater than the 659 * broadcast of an input scalar 660 */ 661 public abstract VectorMask<Short> greaterThan(short s); 662 663 @Override 664 public abstract VectorMask<Short> greaterThanEq(Vector<Short> v); 665 666 /** 667 * Tests if this vector is greater than or equal to the broadcast of an 668 * input scalar. 669 * <p> 670 * This is a vector binary test operation where the primitive greater than 671 * or equal to operation ({@code >=}) is applied to lane elements. 672 * 673 * @param s the input scalar 674 * @return the mask result of testing if this vector is greater than or 675 * equal to the broadcast of an input scalar 676 */ 677 public abstract VectorMask<Short> greaterThanEq(short s); 678 679 @Override 680 public abstract ShortVector blend(Vector<Short> v, VectorMask<Short> m); 681 682 /** 683 * Blends the lane elements of this vector with those of the broadcast of an 684 * input scalar, selecting lanes controlled by a mask. 685 * <p> 686 * For each lane of the mask, at lane index {@code N}, if the mask lane 687 * is set then the lane element at {@code N} from the input vector is 688 * selected and placed into the resulting vector at {@code N}, 689 * otherwise the the lane element at {@code N} from this input vector is 690 * selected and placed into the resulting vector at {@code N}. 691 * 692 * @param s the input scalar 693 * @param m the mask controlling lane selection 694 * @return the result of blending the lane elements of this vector with 695 * those of the broadcast of an input scalar 696 */ 697 public abstract ShortVector blend(short s, VectorMask<Short> m); 698 699 @Override 700 public abstract ShortVector rearrange(Vector<Short> v, 701 VectorShuffle<Short> s, VectorMask<Short> m); 702 703 @Override 704 public abstract ShortVector rearrange(VectorShuffle<Short> m); 705 706 @Override 707 public abstract ShortVector reshape(VectorSpecies<Short> s); 708 709 @Override 710 public abstract ShortVector rotateEL(int i); 711 712 @Override 713 public abstract ShortVector rotateER(int i); 714 715 @Override 716 public abstract ShortVector shiftEL(int i); 717 718 @Override 719 public abstract ShortVector shiftER(int i); 720 721 722 723 /** 724 * Bitwise ANDs this vector with an input vector. 725 * <p> 726 * This is a vector binary operation where the primitive bitwise AND 727 * operation ({@code &}) is applied to lane elements. 728 * 729 * @param v the input vector 730 * @return the bitwise AND of this vector with the input vector 731 */ 732 public abstract ShortVector and(Vector<Short> v); 733 734 /** 735 * Bitwise ANDs this vector with the broadcast of an input scalar. 736 * <p> 737 * This is a vector binary operation where the primitive bitwise AND 738 * operation ({@code &}) is applied to lane elements. 739 * 740 * @param s the input scalar 741 * @return the bitwise AND of this vector with the broadcast of an input 742 * scalar 743 */ 744 public abstract ShortVector and(short s); 745 746 /** 747 * Bitwise ANDs this vector with an input vector, selecting lane elements 748 * controlled by a mask. 749 * <p> 750 * This is a vector binary operation where the primitive bitwise AND 751 * operation ({@code &}) is applied to lane elements. 752 * 753 * @param v the input vector 754 * @param m the mask controlling lane selection 755 * @return the bitwise AND of this vector with the input vector 756 */ 757 public abstract ShortVector and(Vector<Short> v, VectorMask<Short> m); 758 759 /** 760 * Bitwise ANDs this vector with the broadcast of an input scalar, selecting 761 * lane elements controlled by a mask. 762 * <p> 763 * This is a vector binary operation where the primitive bitwise AND 764 * operation ({@code &}) is applied to lane elements. 765 * 766 * @param s the input scalar 767 * @param m the mask controlling lane selection 768 * @return the bitwise AND of this vector with the broadcast of an input 769 * scalar 770 */ 771 public abstract ShortVector and(short s, VectorMask<Short> m); 772 773 /** 774 * Bitwise ORs this vector with an input vector. 775 * <p> 776 * This is a vector binary operation where the primitive bitwise OR 777 * operation ({@code |}) is applied to lane elements. 778 * 779 * @param v the input vector 780 * @return the bitwise OR of this vector with the input vector 781 */ 782 public abstract ShortVector or(Vector<Short> v); 783 784 /** 785 * Bitwise ORs this vector with the broadcast of an input scalar. 786 * <p> 787 * This is a vector binary operation where the primitive bitwise OR 788 * operation ({@code |}) is applied to lane elements. 789 * 790 * @param s the input scalar 791 * @return the bitwise OR of this vector with the broadcast of an input 792 * scalar 793 */ 794 public abstract ShortVector or(short s); 795 796 /** 797 * Bitwise ORs this vector with an input vector, selecting lane elements 798 * controlled by a mask. 799 * <p> 800 * This is a vector binary operation where the primitive bitwise OR 801 * operation ({@code |}) is applied to lane elements. 802 * 803 * @param v the input vector 804 * @param m the mask controlling lane selection 805 * @return the bitwise OR of this vector with the input vector 806 */ 807 public abstract ShortVector or(Vector<Short> v, VectorMask<Short> m); 808 809 /** 810 * Bitwise ORs this vector with the broadcast of an input scalar, selecting 811 * lane elements controlled by a mask. 812 * <p> 813 * This is a vector binary operation where the primitive bitwise OR 814 * operation ({@code |}) is applied to lane elements. 815 * 816 * @param s the input scalar 817 * @param m the mask controlling lane selection 818 * @return the bitwise OR of this vector with the broadcast of an input 819 * scalar 820 */ 821 public abstract ShortVector or(short s, VectorMask<Short> m); 822 823 /** 824 * Bitwise XORs this vector with an input vector. 825 * <p> 826 * This is a vector binary operation where the primitive bitwise XOR 827 * operation ({@code ^}) is applied to lane elements. 828 * 829 * @param v the input vector 830 * @return the bitwise XOR of this vector with the input vector 831 */ 832 public abstract ShortVector xor(Vector<Short> v); 833 834 /** 835 * Bitwise XORs this vector with the broadcast of an input scalar. 836 * <p> 837 * This is a vector binary operation where the primitive bitwise XOR 838 * operation ({@code ^}) is applied to lane elements. 839 * 840 * @param s the input scalar 841 * @return the bitwise XOR of this vector with the broadcast of an input 842 * scalar 843 */ 844 public abstract ShortVector xor(short s); 845 846 /** 847 * Bitwise XORs this vector with an input vector, selecting lane elements 848 * controlled by a mask. 849 * <p> 850 * This is a vector binary operation where the primitive bitwise XOR 851 * operation ({@code ^}) is applied to lane elements. 852 * 853 * @param v the input vector 854 * @param m the mask controlling lane selection 855 * @return the bitwise XOR of this vector with the input vector 856 */ 857 public abstract ShortVector xor(Vector<Short> v, VectorMask<Short> m); 858 859 /** 860 * Bitwise XORs this vector with the broadcast of an input scalar, selecting 861 * lane elements controlled by a mask. 862 * <p> 863 * This is a vector binary operation where the primitive bitwise XOR 864 * operation ({@code ^}) is applied to lane elements. 865 * 866 * @param s the input scalar 867 * @param m the mask controlling lane selection 868 * @return the bitwise XOR of this vector with the broadcast of an input 869 * scalar 870 */ 871 public abstract ShortVector xor(short s, VectorMask<Short> m); 872 873 /** 874 * Bitwise NOTs this vector. 875 * <p> 876 * This is a vector unary operation where the primitive bitwise NOT 877 * operation ({@code ~}) is applied to lane elements. 878 * 879 * @return the bitwise NOT of this vector 880 */ 881 public abstract ShortVector not(); 882 883 /** 884 * Bitwise NOTs this vector, selecting lane elements controlled by a mask. 885 * <p> 886 * This is a vector unary operation where the primitive bitwise NOT 887 * operation ({@code ~}) is applied to lane elements. 888 * 889 * @param m the mask controlling lane selection 890 * @return the bitwise NOT of this vector 891 */ 892 public abstract ShortVector not(VectorMask<Short> m); 893 894 /** 895 * Logically left shifts this vector by the broadcast of an input scalar. 896 * <p> 897 * This is a vector binary operation where the primitive logical left shift 898 * operation ({@code <<}) is applied to lane elements to left shift the 899 * element by shift value as specified by the input scalar. Only the 4 900 * lowest-order bits of shift value are used. It is as if the shift value 901 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 902 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 903 * 904 * @param s the input scalar; the number of the bits to left shift 905 * @return the result of logically left shifting left this vector by the 906 * broadcast of an input scalar 907 */ 908 public abstract ShortVector shiftL(int s); 909 910 /** 911 * Logically left shifts this vector by the broadcast of an input scalar, 912 * selecting lane elements controlled by a mask. 913 * <p> 914 * This is a vector binary operation where the primitive logical left shift 915 * operation ({@code <<}) is applied to lane elements to left shift the 916 * element by shift value as specified by the input scalar. Only the 4 917 * lowest-order bits of shift value are used. It is as if the shift value 918 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 919 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 920 * 921 * @param s the input scalar; the number of the bits to left shift 922 * @param m the mask controlling lane selection 923 * @return the result of logically left shifting left this vector by the 924 * broadcast of an input scalar 925 */ 926 public abstract ShortVector shiftL(int s, VectorMask<Short> m); 927 928 929 // logical, or unsigned, shift right 930 931 /** 932 * Logically right shifts (or unsigned right shifts) this vector by the 933 * broadcast of an input scalar. 934 * <p> 935 * This is a vector binary operation where the primitive logical right shift 936 * operation ({@code >>>}) is applied to lane elements to logically right shift the 937 * element by shift value as specified by the input scalar. Only the 4 938 * lowest-order bits of shift value are used. It is as if the shift value 939 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 940 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 941 * 942 * @param s the input scalar; the number of the bits to right shift 943 * @return the result of logically right shifting this vector by the 944 * broadcast of an input scalar 945 */ 946 public abstract ShortVector shiftR(int s); 947 948 /** 949 * Logically right shifts (or unsigned right shifts) this vector by the 950 * broadcast of an input scalar, selecting lane elements controlled by a 951 * mask. 952 * <p> 953 * This is a vector binary operation where the primitive logical right shift 954 * operation ({@code >>>}) is applied to lane elements to logically right shift the 955 * element by shift value as specified by the input scalar. Only the 4 956 * lowest-order bits of shift value are used. It is as if the shift value 957 * were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 958 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 959 * 960 * @param s the input scalar; the number of the bits to right shift 961 * @param m the mask controlling lane selection 962 * @return the result of logically right shifting this vector by the 963 * broadcast of an input scalar 964 */ 965 public abstract ShortVector shiftR(int s, VectorMask<Short> m); 966 967 968 /** 969 * Arithmetically right shifts (or signed right shifts) this vector by the 970 * broadcast of an input scalar. 971 * <p> 972 * This is a vector binary operation where the primitive arithmetic right 973 * shift operation ({@code >>}) is applied to lane elements to arithmetically 974 * right shift the element by shift value as specified by the input scalar. 975 * Only the 4 lowest-order bits of shift value are used. It is as if the shift 976 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 977 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 978 * 979 * @param s the input scalar; the number of the bits to right shift 980 * @return the result of arithmetically right shifting this vector by the 981 * broadcast of an input scalar 982 */ 983 public abstract ShortVector aShiftR(int s); 984 985 /** 986 * Arithmetically right shifts (or signed right shifts) this vector by the 987 * broadcast of an input scalar, selecting lane elements controlled by a 988 * mask. 989 * <p> 990 * This is a vector binary operation where the primitive arithmetic right 991 * shift operation ({@code >>}) is applied to lane elements to arithmetically 992 * right shift the element by shift value as specified by the input scalar. 993 * Only the 4 lowest-order bits of shift value are used. It is as if the shift 994 * value were subjected to a bitwise logical AND operator ({@code &}) with the mask value 0xF. 995 * The shift distance actually used is therefore always in the range 0 to 15, inclusive. 996 * 997 * @param s the input scalar; the number of the bits to right shift 998 * @param m the mask controlling lane selection 999 * @return the result of arithmetically right shifting this vector by the 1000 * broadcast of an input scalar 1001 */ 1002 public abstract ShortVector aShiftR(int s, VectorMask<Short> m); 1003 1004 1005 @Override 1006 public abstract void intoByteArray(byte[] a, int ix); 1007 1008 @Override 1009 public abstract void intoByteArray(byte[] a, int ix, VectorMask<Short> m); 1010 1011 @Override 1012 public abstract void intoByteBuffer(ByteBuffer bb, int ix); 1013 1014 @Override 1015 public abstract void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Short> m); 1016 1017 1018 // Type specific horizontal reductions 1019 /** 1020 * Adds all lane elements of this vector. 1021 * <p> 1022 * This is an associative vector reduction operation where the addition 1023 * operation ({@code +}) is applied to lane elements, 1024 * and the identity value is {@code 0}. 1025 * 1026 * @return the addition of all the lane elements of this vector 1027 */ 1028 public abstract short addAll(); 1029 1030 /** 1031 * Adds all lane elements of this vector, selecting lane elements 1032 * controlled by a mask. 1033 * <p> 1034 * This is an associative vector reduction operation where the addition 1035 * operation ({@code +}) is applied to lane elements, 1036 * and the identity value is {@code 0}. 1037 * 1038 * @param m the mask controlling lane selection 1039 * @return the addition of the selected lane elements of this vector 1040 */ 1041 public abstract short addAll(VectorMask<Short> m); 1042 1043 /** 1044 * Multiplies all lane elements of this vector. 1045 * <p> 1046 * This is an associative vector reduction operation where the 1047 * multiplication operation ({@code *}) is applied to lane elements, 1048 * and the identity value is {@code 1}. 1049 * 1050 * @return the multiplication of all the lane elements of this vector 1051 */ 1052 public abstract short mulAll(); 1053 1054 /** 1055 * Multiplies all lane elements of this vector, selecting lane elements 1056 * controlled by a mask. 1057 * <p> 1058 * This is an associative vector reduction operation where the 1059 * multiplication operation ({@code *}) is applied to lane elements, 1060 * and the identity value is {@code 1}. 1061 * 1062 * @param m the mask controlling lane selection 1063 * @return the multiplication of all the lane elements of this vector 1064 */ 1065 public abstract short mulAll(VectorMask<Short> m); 1066 1067 /** 1068 * Returns the minimum lane element of this vector. 1069 * <p> 1070 * This is an associative vector reduction operation where the operation 1071 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements, 1072 * and the identity value is 1073 * {@link Short#MAX_VALUE}. 1074 * 1075 * @return the minimum lane element of this vector 1076 */ 1077 public abstract short minAll(); 1078 1079 /** 1080 * Returns the minimum lane element of this vector, selecting lane elements 1081 * controlled by a mask. 1082 * <p> 1083 * This is an associative vector reduction operation where the operation 1084 * {@code (a, b) -> Math.min(a, b)} is applied to lane elements, 1085 * and the identity value is 1086 * {@link Short#MAX_VALUE}. 1087 * 1088 * @param m the mask controlling lane selection 1089 * @return the minimum lane element of this vector 1090 */ 1091 public abstract short minAll(VectorMask<Short> m); 1092 1093 /** 1094 * Returns the maximum lane element of this vector. 1095 * <p> 1096 * This is an associative vector reduction operation where the operation 1097 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements, 1098 * and the identity value is 1099 * {@link Short#MIN_VALUE}. 1100 * 1101 * @return the maximum lane element of this vector 1102 */ 1103 public abstract short maxAll(); 1104 1105 /** 1106 * Returns the maximum lane element of this vector, selecting lane elements 1107 * controlled by a mask. 1108 * <p> 1109 * This is an associative vector reduction operation where the operation 1110 * {@code (a, b) -> Math.max(a, b)} is applied to lane elements, 1111 * and the identity value is 1112 * {@link Short#MIN_VALUE}. 1113 * 1114 * @param m the mask controlling lane selection 1115 * @return the maximum lane element of this vector 1116 */ 1117 public abstract short maxAll(VectorMask<Short> m); 1118 1119 /** 1120 * Logically ORs all lane elements of this vector. 1121 * <p> 1122 * This is an associative vector reduction operation where the logical OR 1123 * operation ({@code |}) is applied to lane elements, 1124 * and the identity value is {@code 0}. 1125 * 1126 * @return the logical OR all the lane elements of this vector 1127 */ 1128 public abstract short orAll(); 1129 1130 /** 1131 * Logically ORs all lane elements of this vector, selecting lane elements 1132 * controlled by a mask. 1133 * <p> 1134 * This is an associative vector reduction operation where the logical OR 1135 * operation ({@code |}) is applied to lane elements, 1136 * and the identity value is {@code 0}. 1137 * 1138 * @param m the mask controlling lane selection 1139 * @return the logical OR all the lane elements of this vector 1140 */ 1141 public abstract short orAll(VectorMask<Short> m); 1142 1143 /** 1144 * Logically ANDs all lane elements of this vector. 1145 * <p> 1146 * This is an associative vector reduction operation where the logical AND 1147 * operation ({@code |}) is applied to lane elements, 1148 * and the identity value is {@code -1}. 1149 * 1150 * @return the logical AND all the lane elements of this vector 1151 */ 1152 public abstract short andAll(); 1153 1154 /** 1155 * Logically ANDs all lane elements of this vector, selecting lane elements 1156 * controlled by a mask. 1157 * <p> 1158 * This is an associative vector reduction operation where the logical AND 1159 * operation ({@code |}) is applied to lane elements, 1160 * and the identity value is {@code -1}. 1161 * 1162 * @param m the mask controlling lane selection 1163 * @return the logical AND all the lane elements of this vector 1164 */ 1165 public abstract short andAll(VectorMask<Short> m); 1166 1167 /** 1168 * Logically XORs all lane elements of this vector. 1169 * <p> 1170 * This is an associative vector reduction operation where the logical XOR 1171 * operation ({@code ^}) is applied to lane elements, 1172 * and the identity value is {@code 0}. 1173 * 1174 * @return the logical XOR all the lane elements of this vector 1175 */ 1176 public abstract short xorAll(); 1177 1178 /** 1179 * Logically XORs 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 logical XOR 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 logical XOR all the lane elements of this vector 1188 */ 1189 public abstract short xorAll(VectorMask<Short> m); 1190 1191 // Type specific accessors 1192 1193 /** 1194 * Gets the lane element at lane index {@code i} 1195 * 1196 * @param i the lane index 1197 * @return the lane element at lane index {@code i} 1198 * @throws IllegalArgumentException if the index is is out of range 1199 * ({@code < 0 || >= length()}) 1200 */ 1201 public abstract short get(int i); 1202 1203 /** 1204 * Replaces the lane element of this vector at lane index {@code i} with 1205 * value {@code e}. 1206 * <p> 1207 * This is a cross-lane operation and behaves as if it returns the result 1208 * of blending this vector with an input vector that is the result of 1209 * broadcasting {@code e} and a mask that has only one lane set at lane 1210 * index {@code i}. 1211 * 1212 * @param i the lane index of the lane element to be replaced 1213 * @param e the value to be placed 1214 * @return the result of replacing the lane element of this vector at lane 1215 * index {@code i} with value {@code e}. 1216 * @throws IllegalArgumentException if the index is is out of range 1217 * ({@code < 0 || >= length()}) 1218 */ 1219 public abstract ShortVector with(int i, short e); 1220 1221 // Type specific extractors 1222 1223 /** 1224 * Returns an array containing the lane elements of this vector. 1225 * <p> 1226 * This method behaves as if it {@link #intoArray(short[], int)} stores} 1227 * this vector into an allocated array and returns the array as follows: 1228 * <pre>{@code 1229 * short[] a = new short[this.length()]; 1230 * this.intoArray(a, 0); 1231 * return a; 1232 * }</pre> 1233 * 1234 * @return an array containing the the lane elements of this vector 1235 */ 1236 @ForceInline 1237 public final short[] toArray() { 1238 short[] a = new short[species().length()]; 1239 intoArray(a, 0); 1240 return a; 1241 } 1242 1243 /** 1244 * Stores this vector into an array starting at offset. 1245 * <p> 1246 * For each vector lane, where {@code N} is the vector lane index, 1247 * the lane element at index {@code N} is stored into the array at index 1248 * {@code i + N}. 1249 * 1250 * @param a the array 1251 * @param i the offset into the array 1252 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1253 * {@code i > a.length - this.length()} 1254 */ 1255 public abstract void intoArray(short[] a, int i); 1256 1257 /** 1258 * Stores this vector into an array starting at offset and using a mask. 1259 * <p> 1260 * For each vector lane, where {@code N} is the vector lane index, 1261 * if the mask lane at index {@code N} is set then the lane element at 1262 * index {@code N} is stored into the array index {@code i + N}. 1263 * 1264 * @param a the array 1265 * @param i the offset into the array 1266 * @param m the mask 1267 * @throws IndexOutOfBoundsException if {@code i < 0}, or 1268 * for any vector lane index {@code N} where the mask at lane {@code N} 1269 * is set {@code i >= a.length - N} 1270 */ 1271 public abstract void intoArray(short[] a, int i, VectorMask<Short> m); 1272 1273 /** 1274 * Stores this vector into an array using indexes obtained from an index 1275 * map. 1276 * <p> 1277 * For each vector lane, where {@code N} is the vector lane index, the 1278 * lane element at index {@code N} is stored into the array at index 1279 * {@code i + indexMap[j + N]}. 1280 * 1281 * @param a the array 1282 * @param i the offset into the array, may be negative if relative 1283 * indexes in the index map compensate to produce a value within the 1284 * array bounds 1285 * @param indexMap the index map 1286 * @param j the offset into the index map 1287 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1288 * {@code j > indexMap.length - this.length()}, 1289 * or for any vector lane index {@code N} the result of 1290 * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length} 1291 */ 1292 public void intoArray(short[] a, int i, int[] indexMap, int j) { 1293 forEach((n, e) -> a[i + indexMap[j + n]] = e); 1294 } 1295 1296 /** 1297 * Stores this vector into an array using indexes obtained from an index 1298 * map and using a mask. 1299 * <p> 1300 * For each vector lane, where {@code N} is the vector lane index, 1301 * if the mask lane at index {@code N} is set then the lane element at 1302 * index {@code N} is stored into the array at index 1303 * {@code i + indexMap[j + N]}. 1304 * 1305 * @param a the array 1306 * @param i the offset into the array, may be negative if relative 1307 * indexes in the index map compensate to produce a value within the 1308 * array bounds 1309 * @param m the mask 1310 * @param indexMap the index map 1311 * @param j the offset into the index map 1312 * @throws IndexOutOfBoundsException if {@code j < 0}, or 1313 * {@code j > indexMap.length - this.length()}, 1314 * or for any vector lane index {@code N} where the mask at lane 1315 * {@code N} is set the result of {@code i + indexMap[j + N]} is 1316 * {@code < 0} or {@code >= a.length} 1317 */ 1318 public void intoArray(short[] a, int i, VectorMask<Short> m, int[] indexMap, int j) { 1319 forEach(m, (n, e) -> a[i + indexMap[j + n]] = e); 1320 } 1321 // Species 1322 1323 @Override 1324 public abstract VectorSpecies<Short> species(); 1325 1326 /** 1327 * Class representing {@link ShortVector}'s of the same {@link VectorShape VectorShape}. 1328 */ 1329 static final class ShortSpecies extends AbstractSpecies<Short> { 1330 final Function<short[], ShortVector> vectorFactory; 1331 1332 private ShortSpecies(VectorShape shape, 1333 Class<?> boxType, 1334 Class<?> maskType, 1335 Function<short[], ShortVector> vectorFactory, 1336 Function<boolean[], VectorMask<Short>> maskFactory, 1337 Function<IntUnaryOperator, VectorShuffle<Short>> shuffleFromArrayFactory, 1338 fShuffleFromArray<Short> shuffleFromOpFactory) { 1339 super(shape, short.class, Short.SIZE, boxType, maskType, maskFactory, 1340 shuffleFromArrayFactory, shuffleFromOpFactory); 1341 this.vectorFactory = vectorFactory; 1342 } 1343 1344 interface FOp { 1345 short apply(int i); 1346 } 1347 1348 ShortVector op(FOp f) { 1349 short[] res = new short[length()]; 1350 for (int i = 0; i < length(); i++) { 1351 res[i] = f.apply(i); 1352 } 1353 return vectorFactory.apply(res); 1354 } 1355 1356 ShortVector op(VectorMask<Short> o, FOp f) { 1357 short[] res = new short[length()]; 1358 boolean[] mbits = ((AbstractMask<Short>)o).getBits(); 1359 for (int i = 0; i < length(); i++) { 1360 if (mbits[i]) { 1361 res[i] = f.apply(i); 1362 } 1363 } 1364 return vectorFactory.apply(res); 1365 } 1366 } 1367 1368 /** 1369 * Finds the preferred species for an element type of {@code short}. 1370 * <p> 1371 * A preferred species is a species chosen by the platform that has a 1372 * shape of maximal bit size. A preferred species for different element 1373 * types will have the same shape, and therefore vectors, masks, and 1374 * shuffles created from such species will be shape compatible. 1375 * 1376 * @return the preferred species for an element type of {@code short} 1377 */ 1378 private static ShortSpecies preferredSpecies() { 1379 return (ShortSpecies) VectorSpecies.ofPreferred(short.class); 1380 } 1381 1382 /** 1383 * Finds a species for an element type of {@code short} and shape. 1384 * 1385 * @param s the shape 1386 * @return a species for an element type of {@code short} and shape 1387 * @throws IllegalArgumentException if no such species exists for the shape 1388 */ 1389 static ShortSpecies species(VectorShape s) { 1390 Objects.requireNonNull(s); 1391 switch (s) { 1392 case S_64_BIT: return (ShortSpecies) SPECIES_64; 1393 case S_128_BIT: return (ShortSpecies) SPECIES_128; 1394 case S_256_BIT: return (ShortSpecies) SPECIES_256; 1395 case S_512_BIT: return (ShortSpecies) SPECIES_512; 1396 case S_Max_BIT: return (ShortSpecies) SPECIES_MAX; 1397 default: throw new IllegalArgumentException("Bad shape: " + s); 1398 } 1399 } 1400 1401 /** Species representing {@link ShortVector}s of {@link VectorShape#S_64_BIT VectorShape.S_64_BIT}. */ 1402 public static final VectorSpecies<Short> SPECIES_64 = new ShortSpecies(VectorShape.S_64_BIT, Short64Vector.class, Short64Vector.Short64Mask.class, 1403 Short64Vector::new, Short64Vector.Short64Mask::new, 1404 Short64Vector.Short64Shuffle::new, Short64Vector.Short64Shuffle::new); 1405 1406 /** Species representing {@link ShortVector}s of {@link VectorShape#S_128_BIT VectorShape.S_128_BIT}. */ 1407 public static final VectorSpecies<Short> SPECIES_128 = new ShortSpecies(VectorShape.S_128_BIT, Short128Vector.class, Short128Vector.Short128Mask.class, 1408 Short128Vector::new, Short128Vector.Short128Mask::new, 1409 Short128Vector.Short128Shuffle::new, Short128Vector.Short128Shuffle::new); 1410 1411 /** Species representing {@link ShortVector}s of {@link VectorShape#S_256_BIT VectorShape.S_256_BIT}. */ 1412 public static final VectorSpecies<Short> SPECIES_256 = new ShortSpecies(VectorShape.S_256_BIT, Short256Vector.class, Short256Vector.Short256Mask.class, 1413 Short256Vector::new, Short256Vector.Short256Mask::new, 1414 Short256Vector.Short256Shuffle::new, Short256Vector.Short256Shuffle::new); 1415 1416 /** Species representing {@link ShortVector}s of {@link VectorShape#S_512_BIT VectorShape.S_512_BIT}. */ 1417 public static final VectorSpecies<Short> SPECIES_512 = new ShortSpecies(VectorShape.S_512_BIT, Short512Vector.class, Short512Vector.Short512Mask.class, 1418 Short512Vector::new, Short512Vector.Short512Mask::new, 1419 Short512Vector.Short512Shuffle::new, Short512Vector.Short512Shuffle::new); 1420 1421 /** Species representing {@link ShortVector}s of {@link VectorShape#S_Max_BIT VectorShape.S_Max_BIT}. */ 1422 public static final VectorSpecies<Short> SPECIES_MAX = new ShortSpecies(VectorShape.S_Max_BIT, ShortMaxVector.class, ShortMaxVector.ShortMaxMask.class, 1423 ShortMaxVector::new, ShortMaxVector.ShortMaxMask::new, 1424 ShortMaxVector.ShortMaxShuffle::new, ShortMaxVector.ShortMaxShuffle::new); 1425 1426 /** 1427 * Preferred species for {@link ShortVector}s. 1428 * A preferred species is a species of maximal bit size for the platform. 1429 */ 1430 public static final VectorSpecies<Short> SPECIES_PREFERRED = (VectorSpecies<Short>) preferredSpecies(); 1431 }