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 jdk.internal.vm.annotation.ForceInline;
  28 
  29 import java.nio.ByteBuffer;
  30 import java.nio.ByteOrder;
  31 import java.nio.ShortBuffer;
  32 import java.util.Objects;
  33 import java.util.concurrent.ThreadLocalRandom;
  34 
  35 
  36 /**
  37  * A specialized {@link Vector} representing an ordered immutable sequence of
  38  * {@code short} values.
  39  *
  40  * @param <S> the type of shape of this vector
  41  */
  42 @SuppressWarnings("cast")
  43 public abstract class ShortVector<S extends Vector.Shape> extends Vector<Short,S> {
  44 
  45     ShortVector() {}
  46 
  47     // Unary operator
  48 
  49     interface FUnOp {
  50         short apply(int i, short a);
  51     }
  52 
  53     abstract ShortVector<S> uOp(FUnOp f);
  54 
  55     abstract ShortVector<S> uOp(Mask<Short, S> m, FUnOp f);
  56 
  57     // Binary operator
  58 
  59     interface FBinOp {
  60         short apply(int i, short a, short b);
  61     }
  62 
  63     abstract ShortVector<S> bOp(Vector<Short,S> v, FBinOp f);
  64 
  65     abstract ShortVector<S> bOp(Vector<Short,S> v, Mask<Short, S> m, FBinOp f);
  66 
  67     // Trinary operator
  68 
  69     interface FTriOp {
  70         short apply(int i, short a, short b, short c);
  71     }
  72 
  73     abstract ShortVector<S> tOp(Vector<Short,S> v1, Vector<Short,S> v2, FTriOp f);
  74 
  75     abstract ShortVector<S> tOp(Vector<Short,S> v1, Vector<Short,S> v2, Mask<Short, S> m, FTriOp f);
  76 
  77     // Reduction operator
  78 
  79     abstract short rOp(short v, FBinOp f);
  80 
  81     // Binary test
  82 
  83     interface FBinTest {
  84         boolean apply(int i, short a, short b);
  85     }
  86 
  87     abstract Mask<Short, S> bTest(Vector<Short,S> v, FBinTest f);
  88 
  89     // Foreach
  90 
  91     interface FUnCon {
  92         void apply(int i, short a);
  93     }
  94 
  95     abstract void forEach(FUnCon f);
  96 
  97     abstract void forEach(Mask<Short, S> m, FUnCon f);
  98 
  99     //
 100 
 101     @Override
 102     public abstract ShortVector<S> add(Vector<Short,S> v);
 103 
 104     /**
 105      * Adds this vector to the broadcast of an input scalar.
 106      * <p>
 107      * This is a vector binary operation where the primitive addition operation
 108      * ({@code +}) is applied to lane elements.
 109      *
 110      * @param s the input scalar
 111      * @return the result of adding this vector to the broadcast of an input
 112      * scalar
 113      */
 114     public abstract ShortVector<S> add(short s);
 115 
 116     @Override
 117     public abstract ShortVector<S> add(Vector<Short,S> v, Mask<Short, S> m);
 118 
 119     /**
 120      * Adds this vector to broadcast of an input scalar,
 121      * selecting lane elements controlled by a mask.
 122      * <p>
 123      * This is a vector binary operation where the primitive addition operation
 124      * ({@code +}) is applied to lane elements.
 125      *
 126      * @param s the input scalar
 127      * @param m the mask controlling lane selection
 128      * @return the result of adding this vector to the broadcast of an input
 129      * scalar
 130      */
 131     public abstract ShortVector<S> add(short s, Mask<Short, S> m);
 132 
 133     @Override
 134     public abstract ShortVector<S> sub(Vector<Short,S> v);
 135 
 136     /**
 137      * Subtracts the broadcast of an input scalar from this vector.
 138      * <p>
 139      * This is a vector binary operation where the primitive subtraction
 140      * operation ({@code -}) is applied to lane elements.
 141      *
 142      * @param s the input scalar
 143      * @return the result of subtracting the broadcast of an input
 144      * scalar from this vector
 145      */
 146     public abstract ShortVector<S> sub(short s);
 147 
 148     @Override
 149     public abstract ShortVector<S> sub(Vector<Short,S> v, Mask<Short, S> m);
 150 
 151     /**
 152      * Subtracts the broadcast of an input scalar from this vector, selecting
 153      * lane elements controlled by a mask.
 154      * <p>
 155      * This is a vector binary operation where the primitive subtraction
 156      * operation ({@code -}) is applied to lane elements.
 157      *
 158      * @param s the input scalar
 159      * @param m the mask controlling lane selection
 160      * @return the result of subtracting the broadcast of an input
 161      * scalar from this vector
 162      */
 163     public abstract ShortVector<S> sub(short s, Mask<Short, S> m);
 164 
 165     @Override
 166     public abstract ShortVector<S> mul(Vector<Short,S> v);
 167 
 168     /**
 169      * Multiplies this vector with the broadcast of an input scalar.
 170      * <p>
 171      * This is a vector binary operation where the primitive multiplication
 172      * operation ({@code *}) is applied to lane elements.
 173      *
 174      * @param s the input scalar
 175      * @return the result of multiplying this vector with the broadcast of an
 176      * input scalar
 177      */
 178     public abstract ShortVector<S> mul(short s);
 179 
 180     @Override
 181     public abstract ShortVector<S> mul(Vector<Short,S> v, Mask<Short, S> m);
 182 
 183     /**
 184      * Multiplies this vector with the broadcast of an input scalar, selecting
 185      * lane elements controlled by a mask.
 186      * <p>
 187      * This is a vector binary operation where the primitive multiplication
 188      * operation ({@code *}) is applied to lane elements.
 189      *
 190      * @param s the input scalar
 191      * @param m the mask controlling lane selection
 192      * @return the result of multiplying this vector with the broadcast of an
 193      * input scalar
 194      */
 195     public abstract ShortVector<S> mul(short s, Mask<Short, S> m);
 196 
 197     @Override
 198     public abstract ShortVector<S> neg();
 199 
 200     @Override
 201     public abstract ShortVector<S> neg(Mask<Short, S> m);
 202 
 203     @Override
 204     public abstract ShortVector<S> abs();
 205 
 206     @Override
 207     public abstract ShortVector<S> abs(Mask<Short, S> m);
 208 
 209     @Override
 210     public abstract ShortVector<S> min(Vector<Short,S> v);
 211 
 212     /**
 213      * Returns the minimum of this vector and the broadcast of an input scalar.
 214      * <p>
 215      * This is a vector binary operation where the operation
 216      * {@code (a, b) -> a < b ? a : b}  is applied to lane elements.
 217      *
 218      * @param s the input scalar
 219      * @return the minimum of this vector and the broadcast of an input scalar
 220      */
 221     public abstract ShortVector<S> min(short s);
 222 
 223     @Override
 224     public abstract ShortVector<S> max(Vector<Short,S> v);
 225 
 226     /**
 227      * Returns the maximum of this vector and the broadcast of an input scalar.
 228      * <p>
 229      * This is a vector binary operation where the operation
 230      * {@code (a, b) -> a > b ? a : b}  is applied to lane elements.
 231      *
 232      * @param s the input scalar
 233      * @return the maximum of this vector and the broadcast of an input scalar
 234      */
 235     public abstract ShortVector<S> max(short s);
 236 
 237     @Override
 238     public abstract Mask<Short, S> equal(Vector<Short,S> v);
 239 
 240     /**
 241      * Tests if this vector is equal to the broadcast of an input scalar.
 242      * <p>
 243      * This is a vector binary test operation where the primitive equals
 244      * operation ({@code ==}) is applied to lane elements.
 245      *
 246      * @param s the input scalar
 247      * @return the result mask of testing if this vector is equal to the
 248      * broadcast of an input scalar
 249      */
 250     public abstract Mask<Short, S> equal(short s);
 251 
 252     @Override
 253     public abstract Mask<Short, S> notEqual(Vector<Short,S> v);
 254 
 255     /**
 256      * Tests if this vector is not equal to the broadcast of an input scalar.
 257      * <p>
 258      * This is a vector binary test operation where the primitive not equals
 259      * operation ({@code !=}) is applied to lane elements.
 260      *
 261      * @param s the input scalar
 262      * @return the result mask of testing if this vector is not equal to the
 263      * broadcast of an input scalar
 264      */
 265     public abstract Mask<Short, S> notEqual(short s);
 266 
 267     @Override
 268     public abstract Mask<Short, S> lessThan(Vector<Short,S> v);
 269 
 270     /**
 271      * Tests if this vector is less than the broadcast of an input scalar.
 272      * <p>
 273      * This is a vector binary test operation where the primitive less than
 274      * operation ({@code <}) is applied to lane elements.
 275      *
 276      * @param s the input scalar
 277      * @return the mask result of testing if this vector is less than the
 278      * broadcast of an input scalar
 279      */
 280     public abstract Mask<Short, S> lessThan(short s);
 281 
 282     @Override
 283     public abstract Mask<Short, S> lessThanEq(Vector<Short,S> v);
 284 
 285     /**
 286      * Tests if this vector is less or equal to the broadcast of an input scalar.
 287      * <p>
 288      * This is a vector binary test operation where the primitive less than
 289      * or equal to operation ({@code <=}) is applied to lane elements.
 290      *
 291      * @param s the input scalar
 292      * @return the mask result of testing if this vector is less than or equal
 293      * to the broadcast of an input scalar
 294      */
 295     public abstract Mask<Short, S> lessThanEq(short s);
 296 
 297     @Override
 298     public abstract Mask<Short, S> greaterThan(Vector<Short,S> v);
 299 
 300     /**
 301      * Tests if this vector is greater than the broadcast of an input scalar.
 302      * <p>
 303      * This is a vector binary test operation where the primitive greater than
 304      * operation ({@code >}) is applied to lane elements.
 305      *
 306      * @param s the input scalar
 307      * @return the mask result of testing if this vector is greater than the
 308      * broadcast of an input scalar
 309      */
 310     public abstract Mask<Short, S> greaterThan(short s);
 311 
 312     @Override
 313     public abstract Mask<Short, S> greaterThanEq(Vector<Short,S> v);
 314 
 315     /**
 316      * Tests if this vector is greater than or equal to the broadcast of an
 317      * input scalar.
 318      * <p>
 319      * This is a vector binary test operation where the primitive greater than
 320      * or equal to operation ({@code >=}) is applied to lane elements.
 321      *
 322      * @param s the input scalar
 323      * @return the mask result of testing if this vector is greater than or
 324      * equal to the broadcast of an input scalar
 325      */
 326     public abstract Mask<Short, S> greaterThanEq(short s);
 327 
 328     @Override
 329     public abstract ShortVector<S> blend(Vector<Short,S> v, Mask<Short, S> m);
 330 
 331     /**
 332      * Blends the lane elements of this vector with those of the broadcast of an
 333      * input scalar, selecting lanes controlled by a mask.
 334      * <p>
 335      * For each lane of the mask, at lane index {@code N}, if the mask lane
 336      * is set then the lane element at {@code N} from the input vector is
 337      * selected and placed into the resulting vector at {@code N},
 338      * otherwise the the lane element at {@code N} from this input vector is
 339      * selected and placed into the resulting vector at {@code N}.
 340      *
 341      * @param s the input scalar
 342      * @param m the mask controlling lane selection
 343      * @return the result of blending the lane elements of this vector with
 344      * those of the broadcast of an input scalar
 345      */
 346     public abstract ShortVector<S> blend(short s, Mask<Short, S> m);
 347 
 348     @Override
 349     public abstract ShortVector<S> rearrange(Vector<Short, S> v,
 350                                                       Shuffle<Short, S> s, Mask<Short, S> m);
 351 
 352     @Override
 353     public abstract ShortVector<S> rearrange(Shuffle<Short, S> m);
 354 
 355     @Override
 356     @ForceInline
 357     public <T extends Shape> ShortVector<T> resize(Species<Short, T> species) {
 358         return (ShortVector<T>) species.resize(this);
 359     }
 360 
 361     @Override
 362     public abstract ShortVector<S> rotateEL(int i);
 363 
 364     @Override
 365     public abstract ShortVector<S> rotateER(int i);
 366 
 367     @Override
 368     public abstract ShortVector<S> shiftEL(int i);
 369 
 370     @Override
 371     public abstract ShortVector<S> shiftER(int i);
 372 
 373 
 374 
 375     /**
 376      * Bitwise ANDs this vector with an input vector.
 377      * <p>
 378      * This is a vector binary operation where the primitive bitwise AND
 379      * operation ({@code &}) is applied to lane elements.
 380      *
 381      * @param v the input vector
 382      * @return the bitwise AND of this vector with the input vector
 383      */
 384     public abstract ShortVector<S> and(Vector<Short,S> v);
 385 
 386     /**
 387      * Bitwise ANDs this vector with the broadcast of an input scalar.
 388      * <p>
 389      * This is a vector binary operation where the primitive bitwise AND
 390      * operation ({@code &}) is applied to lane elements.
 391      *
 392      * @param s the input scalar
 393      * @return the bitwise AND of this vector with the broadcast of an input
 394      * scalar
 395      */
 396     public abstract ShortVector<S> and(short s);
 397 
 398     /**
 399      * Bitwise ANDs this vector with an input vector, selecting lane elements
 400      * controlled by a mask.
 401      * <p>
 402      * This is a vector binary operation where the primitive bitwise AND
 403      * operation ({@code &}) is applied to lane elements.
 404      *
 405      * @param v the input vector
 406      * @param m the mask controlling lane selection
 407      * @return the bitwise AND of this vector with the input vector
 408      */
 409     public abstract ShortVector<S> and(Vector<Short,S> v, Mask<Short, S> m);
 410 
 411     /**
 412      * Bitwise ANDs this vector with the broadcast of an input scalar, selecting
 413      * lane elements controlled by a mask.
 414      * <p>
 415      * This is a vector binary operation where the primitive bitwise AND
 416      * operation ({@code &}) is applied to lane elements.
 417      *
 418      * @param s the input scalar
 419      * @param m the mask controlling lane selection
 420      * @return the bitwise AND of this vector with the broadcast of an input
 421      * scalar
 422      */
 423     public abstract ShortVector<S> and(short s, Mask<Short, S> m);
 424 
 425     /**
 426      * Bitwise ORs this vector with an input vector.
 427      * <p>
 428      * This is a vector binary operation where the primitive bitwise OR
 429      * operation ({@code |}) is applied to lane elements.
 430      *
 431      * @param v the input vector
 432      * @return the bitwise OR of this vector with the input vector
 433      */
 434     public abstract ShortVector<S> or(Vector<Short,S> v);
 435 
 436     /**
 437      * Bitwise ORs this vector with the broadcast of an input scalar.
 438      * <p>
 439      * This is a vector binary operation where the primitive bitwise OR
 440      * operation ({@code |}) is applied to lane elements.
 441      *
 442      * @param s the input scalar
 443      * @return the bitwise OR of this vector with the broadcast of an input
 444      * scalar
 445      */
 446     public abstract ShortVector<S> or(short s);
 447 
 448     /**
 449      * Bitwise ORs this vector with an input vector, selecting lane elements
 450      * controlled by a mask.
 451      * <p>
 452      * This is a vector binary operation where the primitive bitwise OR
 453      * operation ({@code |}) is applied to lane elements.
 454      *
 455      * @param v the input vector
 456      * @param m the mask controlling lane selection
 457      * @return the bitwise OR of this vector with the input vector
 458      */
 459     public abstract ShortVector<S> or(Vector<Short,S> v, Mask<Short, S> m);
 460 
 461     /**
 462      * Bitwise ORs this vector with the broadcast of an input scalar, selecting
 463      * lane elements controlled by a mask.
 464      * <p>
 465      * This is a vector binary operation where the primitive bitwise OR
 466      * operation ({@code |}) is applied to lane elements.
 467      *
 468      * @param s the input scalar
 469      * @param m the mask controlling lane selection
 470      * @return the bitwise OR of this vector with the broadcast of an input
 471      * scalar
 472      */
 473     public abstract ShortVector<S> or(short s, Mask<Short, S> m);
 474 
 475     /**
 476      * Bitwise XORs this vector with an input vector.
 477      * <p>
 478      * This is a vector binary operation where the primitive bitwise XOR
 479      * operation ({@code ^}) is applied to lane elements.
 480      *
 481      * @param v the input vector
 482      * @return the bitwise XOR of this vector with the input vector
 483      */
 484     public abstract ShortVector<S> xor(Vector<Short,S> v);
 485 
 486     /**
 487      * Bitwise XORs this vector with the broadcast of an input scalar.
 488      * <p>
 489      * This is a vector binary operation where the primitive bitwise XOR
 490      * operation ({@code ^}) is applied to lane elements.
 491      *
 492      * @param s the input scalar
 493      * @return the bitwise XOR of this vector with the broadcast of an input
 494      * scalar
 495      */
 496     public abstract ShortVector<S> xor(short s);
 497 
 498     /**
 499      * Bitwise XORs this vector with an input vector, selecting lane elements
 500      * controlled by a mask.
 501      * <p>
 502      * This is a vector binary operation where the primitive bitwise XOR
 503      * operation ({@code ^}) is applied to lane elements.
 504      *
 505      * @param v the input vector
 506      * @param m the mask controlling lane selection
 507      * @return the bitwise XOR of this vector with the input vector
 508      */
 509     public abstract ShortVector<S> xor(Vector<Short,S> v, Mask<Short, S> m);
 510 
 511     /**
 512      * Bitwise XORs this vector with the broadcast of an input scalar, selecting
 513      * lane elements controlled by a mask.
 514      * <p>
 515      * This is a vector binary operation where the primitive bitwise XOR
 516      * operation ({@code ^}) is applied to lane elements.
 517      *
 518      * @param s the input scalar
 519      * @param m the mask controlling lane selection
 520      * @return the bitwise XOR of this vector with the broadcast of an input
 521      * scalar
 522      */
 523     public abstract ShortVector<S> xor(short s, Mask<Short, S> m);
 524 
 525     /**
 526      * Bitwise NOTs this vector.
 527      * <p>
 528      * This is a vector unary operation where the primitive bitwise NOT
 529      * operation ({@code ~}) is applied to lane elements.
 530      *
 531      * @return the bitwise NOT of this vector
 532      */
 533     public abstract ShortVector<S> not();
 534 
 535     /**
 536      * Bitwise NOTs this vector, selecting lane elements controlled by a mask.
 537      * <p>
 538      * This is a vector unary operation where the primitive bitwise NOT
 539      * operation ({@code ~}) is applied to lane elements.
 540      *
 541      * @param m the mask controlling lane selection
 542      * @return the bitwise NOT of this vector
 543      */
 544     public abstract ShortVector<S> not(Mask<Short, S> m);
 545 
 546 /*
 547 @@@ Check the shift operations against the JLS definition and vector
 548     instructions.
 549 
 550     For int values the low 5 bits of s are used.
 551     For long values the low 6 bits of s are used.
 552  */
 553 
 554 
 555     @Override
 556     public abstract void intoByteArray(byte[] a, int ix);
 557 
 558     @Override
 559     public abstract void intoByteArray(byte[] a, int ix, Mask<Short, S> m);
 560 
 561     @Override
 562     public abstract void intoByteBuffer(ByteBuffer bb, int ix);
 563 
 564     @Override
 565     public abstract void intoByteBuffer(ByteBuffer bb, int ix, Mask<Short, S> m);
 566 
 567 
 568     // Type specific horizontal reductions
 569 
 570 // @@@ For floating point vectors order matters for reproducibility
 571 //     with equivalent sequential reduction. Some order needs to be specified
 572 //     by default. If that default is sequential encounter order then there
 573 //     could be a "go faster" option that is unspecified, essentially giving
 574 //     implementation flexibility at the expense of reproducibility and/or
 575 //     accuracy.
 576 // @@@ Mask versions?
 577 
 578     /**
 579      * Adds all lane elements of this vector.
 580      * <p>
 581      * This is an associative vector reduction operation where the addition
 582      * operation ({@code +}) is applied to lane elements,
 583      * and the identity value is {@code 0}.
 584      *
 585      * @return the addition of all the lane elements of this vector
 586      */
 587     public abstract short addAll();
 588 
 589     /**
 590      * Adds all lane elements of this vector, selecting lane elements
 591      * controlled by a mask.
 592      * <p>
 593      * This is an associative vector reduction operation where the addition
 594      * operation ({@code +}) is applied to lane elements,
 595      * and the identity value is {@code 0}.
 596      *
 597      * @param m the mask controlling lane selection
 598      * @return the addition of all the lane elements of this vector
 599      */
 600     public abstract short addAll(Mask<Short, S> m);
 601 
 602     /**
 603      * Subtracts all lane elements of this vector.
 604      * <p>
 605      * This is an associative vector reduction operation where the subtraction
 606      * operation ({@code -}) is applied to lane elements,
 607      * and the identity value is {@code 0}.
 608      *
 609      * @return the subtraction of all the lane elements of this vector
 610      */
 611     public abstract short subAll();
 612 
 613     /**
 614      * Subtracts all lane elements of this vector, selecting lane elements
 615      * controlled by a mask.
 616      * <p>
 617      * This is an associative vector reduction operation where the subtraction
 618      * operation ({@code -}) is applied to lane elements,
 619      * and the identity value is {@code 0}.
 620      *
 621      * @param m the mask controlling lane selection
 622      * @return the subtraction of all the lane elements of this vector
 623      */
 624     public abstract short subAll(Mask<Short, S> m);
 625 
 626     /**
 627      * Multiplies all lane elements of this vector.
 628      * <p>
 629      * This is an associative vector reduction operation where the
 630      * multiplication operation ({@code *}) is applied to lane elements,
 631      * and the identity value is {@code 1}.
 632      *
 633      * @return the multiplication of all the lane elements of this vector
 634      */
 635     public abstract short mulAll();
 636 
 637     /**
 638      * Multiplies all lane elements of this vector, selecting lane elements
 639      * controlled by a mask.
 640      * <p>
 641      * This is an associative vector reduction operation where the
 642      * multiplication operation ({@code *}) is applied to lane elements,
 643      * and the identity value is {@code 1}.
 644      *
 645      * @param m the mask controlling lane selection
 646      * @return the multiplication of all the lane elements of this vector
 647      */
 648     public abstract short mulAll(Mask<Short, S> m);
 649 
 650     /**
 651      * Returns the minimum lane element of this vector.
 652      * <p>
 653      * This is an associative vector reduction operation where the operation
 654      * {@code (a, b) -> a > b ? b : a} is applied to lane elements,
 655      * and the identity value is {@link Short.MAX_VALUE}.
 656      *
 657      * @return the minimum lane element of this vector
 658      */
 659     public abstract short minAll();
 660 
 661     /**
 662      * Returns the minimum lane element of this vector, selecting lane elements
 663      * controlled by a mask.
 664      * <p>
 665      * This is an associative vector reduction operation where the operation
 666      * {@code (a, b) -> a > b ? b : a} is applied to lane elements,
 667      * and the identity value is {@link Short.MAX_VALUE}.
 668      *
 669      * @param m the mask controlling lane selection
 670      * @return the minimum lane element of this vector
 671      */
 672     public abstract short minAll(Mask<Short, S> m);
 673 
 674     /**
 675      * Returns the maximum lane element of this vector.
 676      * <p>
 677      * This is an associative vector reduction operation where the operation
 678      * {@code (a, b) -> a < b ? b : a} is applied to lane elements,
 679      * and the identity value is {@link Short.MIN_VALUE}.
 680      *
 681      * @return the maximum lane element of this vector
 682      */
 683     public abstract short maxAll();
 684 
 685     /**
 686      * Returns the maximum lane element of this vector, selecting lane elements
 687      * controlled by a mask.
 688      * <p>
 689      * This is an associative vector reduction operation where the operation
 690      * {@code (a, b) -> a < b ? b : a} is applied to lane elements,
 691      * and the identity value is {@link Short.MIN_VALUE}.
 692      *
 693      * @param m the mask controlling lane selection
 694      * @return the maximum lane element of this vector
 695      */
 696     public abstract short maxAll(Mask<Short, S> m);
 697 
 698     /**
 699      * Logically ORs all lane elements of this vector.
 700      * <p>
 701      * This is an associative vector reduction operation where the logical OR
 702      * operation ({@code |}) is applied to lane elements,
 703      * and the identity value is {@code 0}.
 704      *
 705      * @return the logical OR all the lane elements of this vector
 706      */
 707     public abstract short orAll();
 708 
 709     /**
 710      * Logically ORs all lane elements of this vector, selecting lane elements
 711      * controlled by a mask.
 712      * <p>
 713      * This is an associative vector reduction operation where the logical OR
 714      * operation ({@code |}) is applied to lane elements,
 715      * and the identity value is {@code 0}.
 716      *
 717      * @param m the mask controlling lane selection
 718      * @return the logical OR all the lane elements of this vector
 719      */
 720     public abstract short orAll(Mask<Short, S> m);
 721 
 722     /**
 723      * Logically ANDs all lane elements of this vector.
 724      * <p>
 725      * This is an associative vector reduction operation where the logical AND
 726      * operation ({@code |}) is applied to lane elements,
 727      * and the identity value is {@code -1}.
 728      *
 729      * @return the logical AND all the lane elements of this vector
 730      */
 731     public abstract short andAll();
 732 
 733     /**
 734      * Logically ANDs all lane elements of this vector, selecting lane elements
 735      * controlled by a mask.
 736      * <p>
 737      * This is an associative vector reduction operation where the logical AND
 738      * operation ({@code |}) is applied to lane elements,
 739      * and the identity value is {@code -1}.
 740      *
 741      * @param m the mask controlling lane selection
 742      * @return the logical AND all the lane elements of this vector
 743      */
 744     public abstract short andAll(Mask<Short, S> m);
 745 
 746     /**
 747      * Logically XORs all lane elements of this vector.
 748      * <p>
 749      * This is an associative vector reduction operation where the logical XOR
 750      * operation ({@code ^}) is applied to lane elements,
 751      * and the identity value is {@code 0}.
 752      *
 753      * @return the logical XOR all the lane elements of this vector
 754      */
 755     public abstract short xorAll();
 756 
 757     /**
 758      * Logically XORs all lane elements of this vector, selecting lane elements
 759      * controlled by a mask.
 760      * <p>
 761      * This is an associative vector reduction operation where the logical XOR
 762      * operation ({@code ^}) is applied to lane elements,
 763      * and the identity value is {@code 0}.
 764      *
 765      * @param m the mask controlling lane selection
 766      * @return the logical XOR all the lane elements of this vector
 767      */
 768     public abstract short xorAll(Mask<Short, S> m);
 769 
 770     // Type specific accessors
 771 
 772     /**
 773      * Gets the lane element at lane index {@code i}
 774      *
 775      * @param i the lane index
 776      * @return the lane element at lane index {@code i}
 777      * @throws IllegalArgumentException if the index is is out of range
 778      * ({@code < 0 || >= length()})
 779      */
 780     public abstract short get(int i);
 781 
 782     /**
 783      * Replaces the lane element of this vector at lane index {@code i} with
 784      * value {@code e}.
 785      * <p>
 786      * This is a cross-lane operation and behaves as if it returns the result
 787      * of blending this vector with an input vector that is the result of
 788      * broadcasting {@code e} and a mask that has only one lane set at lane
 789      * index {@code i}.
 790      *
 791      * @param i the lane index of the lane element to be replaced
 792      * @param e the value to be placed
 793      * @return the result of replacing the lane element of this vector at lane
 794      * index {@code i} with value {@code e}.
 795      * @throws IllegalArgumentException if the index is is out of range
 796      * ({@code < 0 || >= length()})
 797      */
 798     public abstract ShortVector<S> with(int i, short e);
 799 
 800     // Type specific extractors
 801 
 802     /**
 803      * Returns an array containing the lane elements of this vector.
 804      * <p>
 805      * This method behaves as if it {@link #intoArray(short[], int)} stores}
 806      * this vector into an allocated array and returns the array as follows:
 807      * <pre>{@code
 808      *   short[] a = new short[this.length()];
 809      *   this.intoArray(a, 0);
 810      *   return a;
 811      * }</pre>
 812      *
 813      * @return an array containing the the lane elements of this vector
 814      */
 815     @ForceInline
 816     public final short[] toArray() {
 817         // @@@ could allocate without zeroing, see Unsafe.allocateUninitializedArray
 818         short[] a = new short[species().length()];
 819         intoArray(a, 0);
 820         return a;
 821     }
 822 
 823     /**
 824      * Stores this vector into an array starting at offset.
 825      * <p>
 826      * For each vector lane, where {@code N} is the vector lane index,
 827      * the lane element at index {@code N} is stored into the array at index
 828      * {@code i + N}.
 829      *
 830      * @param a the array
 831      * @param i the offset into the array
 832      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 833      * {@code i > a.length - this.length()}
 834      */
 835     public abstract void intoArray(short[] a, int i);
 836 
 837     /**
 838      * Stores this vector into an array starting at offset and using a mask.
 839      * <p>
 840      * For each vector lane, where {@code N} is the vector lane index,
 841      * if the mask lane at index {@code N} is set then the lane element at
 842      * index {@code N} is stored into the array index {@code i + N}.
 843      *
 844      * @param a the array
 845      * @param i the offset into the array
 846      * @param m the mask
 847      * @throws IndexOutOfBoundsException if {@code i < 0}, or
 848      * for any vector lane index {@code N} where the mask at lane {@code N}
 849      * is set {@code i >= a.length - N}
 850      */
 851     public abstract void intoArray(short[] a, int i, Mask<Short, S> m);
 852 
 853     /**
 854      * Stores this vector into an array using indexes obtained from an index
 855      * map.
 856      * <p>
 857      * For each vector lane, where {@code N} is the vector lane index, the
 858      * lane element at index {@code N} is stored into the array at index
 859      * {@code i + indexMap[j + N]}.
 860      *
 861      * @param a the array
 862      * @param i the offset into the array, may be negative if relative
 863      * indexes in the index map compensate to produce a value within the
 864      * array bounds
 865      * @param indexMap the index map
 866      * @param j the offset into the index map
 867      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 868      * {@code j > indexMap.length - this.length()},
 869      * or for any vector lane index {@code N} the result of
 870      * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
 871      */
 872     public void intoArray(short[] a, int i, int[] indexMap, int j) {
 873         forEach((n, e) -> a[i + indexMap[j + n]] = e);
 874     }
 875 
 876     /**
 877      * Stores this vector into an array using indexes obtained from an index
 878      * map and using a mask.
 879      * <p>
 880      * For each vector lane, where {@code N} is the vector lane index,
 881      * if the mask lane at index {@code N} is set then the lane element at
 882      * index {@code N} is stored into the array at index
 883      * {@code i + indexMap[j + N]}.
 884      *
 885      * @param a the array
 886      * @param i the offset into the array, may be negative if relative
 887      * indexes in the index map compensate to produce a value within the
 888      * array bounds
 889      * @param m the mask
 890      * @param indexMap the index map
 891      * @param j the offset into the index map
 892      * @throws IndexOutOfBoundsException if {@code j < 0}, or
 893      * {@code j > indexMap.length - this.length()},
 894      * or for any vector lane index {@code N} where the mask at lane
 895      * {@code N} is set the result of {@code i + indexMap[j + N]} is
 896      * {@code < 0} or {@code >= a.length}
 897      */
 898     public void intoArray(short[] a, int i, Mask<Short, S> m, int[] indexMap, int j) {
 899         forEach(m, (n, e) -> a[i + indexMap[j + n]] = e);
 900     }
 901 
 902     // Species
 903 
 904     @Override
 905     public abstract ShortSpecies<S> species();
 906 
 907     /**
 908      * A specialized factory for creating {@link ShortVector} value of the same
 909      * shape, and a {@link Mask} and {@link Shuffle} values of the same shape
 910      * and {@code int} element type.
 911      *
 912      * @param <S> the type of shape of this species
 913      */
 914     public static abstract class ShortSpecies<S extends Vector.Shape> extends Vector.Species<Short, S> {
 915         interface FOp {
 916             short apply(int i);
 917         }
 918 
 919         abstract ShortVector<S> op(FOp f);
 920 
 921         abstract ShortVector<S> op(Mask<Short, S> m, FOp f);
 922 
 923         // Factories
 924 
 925         @Override
 926         public abstract ShortVector<S> zero();
 927 
 928         /**
 929          * Returns a vector where all lane elements are set to the primitive
 930          * value {@code e}.
 931          *
 932          * @param e the value
 933          * @return a vector of vector where all lane elements are set to
 934          * the primitive value {@code e}
 935          */
 936         public abstract ShortVector<S> broadcast(short e);
 937 
 938         /**
 939          * Returns a vector where the first lane element is set to the primtive
 940          * value {@code e}, all other lane elements are set to the default
 941          * value.
 942          *
 943          * @param e the value
 944          * @return a vector where the first lane element is set to the primitive
 945          * value {@code e}
 946          */
 947         @ForceInline
 948         public final ShortVector<S> single(short e) {
 949             return zero().with(0, e);
 950         }
 951 
 952         /**
 953          * Returns a vector where each lane element is set to a randomly
 954          * generated primitive value.
 955          * @@@ what are the properties of the random number generator?
 956          *
 957          * @return a vector where each lane elements is set to a randomly
 958          * generated primitive value
 959          */
 960         public ShortVector<S> random() {
 961             ThreadLocalRandom r = ThreadLocalRandom.current();
 962             return op(i -> (short) r.nextInt());
 963         }
 964 
 965         /**
 966          * Returns a vector where each lane element is set to a given
 967          * primitive value.
 968          * <p>
 969          * For each vector lane, where {@code N} is the vector lane index, the
 970          * the primitive value at index {@code N} is placed into the resulting
 971          * vector at lane index {@code N}.
 972          *
 973          * @@@ What should happen if es.length < this.length() ? use the default
 974          * value or throw IndexOutOfBoundsException
 975          *
 976          * @param es the given primitive values
 977          * @return a vector where each lane element is set to a given primitive
 978          * value
 979          */
 980         public abstract ShortVector<S> scalars(short... es);
 981 
 982         /**
 983          * Loads a vector from an array starting at offset.
 984          * <p>
 985          * For each vector lane, where {@code N} is the vector lane index, the
 986          * array element at index {@code i + N} is placed into the
 987          * resulting vector at lane index {@code N}.
 988          *
 989          * @param a the array
 990          * @param i the offset into the array
 991          * @return the vector loaded from an array
 992          * @throws IndexOutOfBoundsException if {@code i < 0}, or
 993          * {@code i > a.length - this.length()}
 994          */
 995         public abstract ShortVector<S> fromArray(short[] a, int i);
 996 
 997         /**
 998          * Loads a vector from an array starting at offset and using a mask.
 999          * <p>
1000          * For each vector lane, where {@code N} is the vector lane index,
1001          * if the mask lane at index {@code N} is set then the array element at
1002          * index {@code i + N} is placed into the resulting vector at lane index
1003          * {@code N}, otherwise the default element value is placed into the
1004          * resulting vector at lane index {@code N}.
1005          *
1006          * @param a the array
1007          * @param i the offset into the array
1008          * @param m the mask
1009          * @return the vector loaded from an array
1010          * @throws IndexOutOfBoundsException if {@code i < 0}, or
1011          * for any vector lane index {@code N} where the mask at lane {@code N}
1012          * is set {@code i > a.length - N}
1013          */
1014         public abstract ShortVector<S> fromArray(short[] a, int i, Mask<Short, S> m);
1015 
1016         /**
1017          * Loads a vector from an array using indexes obtained from an index
1018          * map.
1019          * <p>
1020          * For each vector lane, where {@code N} is the vector lane index, the
1021          * array element at index {@code i + indexMap[j + N]} is placed into the
1022          * resulting vector at lane index {@code N}.
1023          *
1024          * @param a the array
1025          * @param i the offset into the array, may be negative if relative
1026          * indexes in the index map compensate to produce a value within the
1027          * array bounds
1028          * @param indexMap the index map
1029          * @param j the offset into the index map
1030          * @return the vector loaded from an array
1031          * @throws IndexOutOfBoundsException if {@code j < 0}, or
1032          * {@code j > indexMap.length - this.length()},
1033          * or for any vector lane index {@code N} the result of
1034          * {@code i + indexMap[j + N]} is {@code < 0} or {@code >= a.length}
1035          */
1036         public ShortVector<S> fromArray(short[] a, int i, int[] indexMap, int j) {
1037             return op(n -> a[i + indexMap[j + n]]);
1038         }
1039 
1040         /**
1041          * Loads a vector from an array using indexes obtained from an index
1042          * map and using a mask.
1043          * <p>
1044          * For each vector lane, where {@code N} is the vector lane index,
1045          * if the mask lane at index {@code N} is set then the array element at
1046          * index {@code i + indexMap[j + N]} is placed into the resulting vector
1047          * at lane index {@code N}.
1048          *
1049          * @param a the array
1050          * @param i the offset into the array, may be negative if relative
1051          * indexes in the index map compensate to produce a value within the
1052          * array bounds
1053          * @param indexMap the index map
1054          * @param j the offset into the index map
1055          * @return the vector loaded from an array
1056          * @throws IndexOutOfBoundsException if {@code j < 0}, or
1057          * {@code j > indexMap.length - this.length()},
1058          * or for any vector lane index {@code N} where the mask at lane
1059          * {@code N} is set the result of {@code i + indexMap[j + N]} is
1060          * {@code < 0} or {@code >= a.length}
1061          */
1062         public ShortVector<S> fromArray(short[] a, int i, Mask<Short, S> m, int[] indexMap, int j) {
1063             return op(m, n -> a[i + indexMap[j + n]]);
1064         }
1065 
1066         @Override
1067         public abstract ShortVector<S> fromByteArray(byte[] a, int ix);
1068 
1069         @Override
1070         public abstract ShortVector<S> fromByteArray(byte[] a, int ix, Mask<Short, S> m);
1071 
1072         @Override
1073         public abstract ShortVector<S> fromByteBuffer(ByteBuffer bb, int ix);
1074 
1075         @Override
1076         public abstract ShortVector<S> fromByteBuffer(ByteBuffer bb, int ix, Mask<Short, S> m);
1077 
1078         @Override
1079         public <F, T extends Shape> ShortVector<S> reshape(Vector<F, T> o) {
1080             int blen = Math.max(o.species().bitSize(), bitSize()) / Byte.SIZE;
1081             ByteBuffer bb = ByteBuffer.allocate(blen).order(ByteOrder.nativeOrder());
1082             o.intoByteBuffer(bb, 0);
1083             return fromByteBuffer(bb, 0);
1084         }
1085 
1086         @Override
1087         public abstract <F> ShortVector<S> rebracket(Vector<F, S> o);
1088 
1089         @Override
1090         public abstract <T extends Shape> ShortVector<S> resize(Vector<Short, T> o);
1091 
1092         @Override
1093         public abstract <F, T extends Shape> ShortVector<S> cast(Vector<F, T> v);
1094 
1095     }
1096 
1097     /**
1098      * Finds the preferred species for an element type of {@code short}.
1099      * <p>
1100      * A preferred species is a species chosen by the platform that has a
1101      * shape of maximal bit size.  A preferred species for different element
1102      * types will have the same shape, and therefore vectors, masks, and
1103      * shuffles created from such species will be shape compatible.
1104      *
1105      * @return the preferred species for an element type of {@code short}
1106      */
1107     @SuppressWarnings("unchecked")
1108     public static ShortSpecies<?> preferredSpecies() {
1109         return (ShortSpecies<?>) Vector.preferredSpecies(short.class);
1110     }
1111 
1112     /**
1113      * Finds a species for an element type of {@code short} and shape.
1114      *
1115      * @param s the shape
1116      * @param <S> the type of shape
1117      * @return a species for an element type of {@code short} and shape
1118      * @throws IllegalArgumentException if no such species exists for the shape
1119      */
1120     @SuppressWarnings("unchecked")
1121     public static <S extends Shape> ShortSpecies<S> species(S s) {
1122         Objects.requireNonNull(s);
1123         if (s == Shapes.S_64_BIT) {
1124             return (ShortSpecies<S>) Short64Vector.SPECIES;
1125         } else if (s == Shapes.S_128_BIT) {
1126             return (ShortSpecies<S>) Short128Vector.SPECIES;
1127         } else if (s == Shapes.S_256_BIT) {
1128             return (ShortSpecies<S>) Short256Vector.SPECIES;
1129         } else if (s == Shapes.S_512_BIT) {
1130             return (ShortSpecies<S>) Short512Vector.SPECIES;
1131         } else {
1132             throw new IllegalArgumentException("Bad shape: " + s);
1133         }
1134     }
1135 }