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.util.Arrays;
  29 import java.util.Objects;
  30 import jdk.internal.vm.annotation.ForceInline;
  31 import static jdk.incubator.vector.VectorIntrinsics.*;
  32 
  33 @SuppressWarnings("cast")
  34 final class Short64Vector extends ShortVector<Shapes.S64Bit> {
  35     static final Short64Species SPECIES = new Short64Species();
  36 
  37     static final Short64Vector ZERO = new Short64Vector();
  38 
  39     static final int LENGTH = SPECIES.length();
  40 
  41     private final short[] vec; // Don't access directly, use getElements() instead.
  42 
  43     private short[] getElements() {
  44         return VectorIntrinsics.maybeRebox(this).vec;
  45     }
  46 
  47     Short64Vector() {
  48         vec = new short[SPECIES.length()];
  49     }
  50 
  51     Short64Vector(short[] v) {
  52         vec = v;
  53     }
  54 
  55     @Override
  56     public int length() { return LENGTH; }
  57 
  58     // Unary operator
  59 
  60     @Override
  61     Short64Vector uOp(FUnOp f) {
  62         short[] vec = getElements();
  63         short[] res = new short[length()];
  64         for (int i = 0; i < length(); i++) {
  65             res[i] = f.apply(i, vec[i]);
  66         }
  67         return new Short64Vector(res);
  68     }
  69 
  70     @Override
  71     Short64Vector uOp(Mask<Short, Shapes.S64Bit> o, FUnOp f) {
  72         short[] vec = getElements();
  73         short[] res = new short[length()];
  74         boolean[] mbits = ((Short64Mask)o).getBits();
  75         for (int i = 0; i < length(); i++) {
  76             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  77         }
  78         return new Short64Vector(res);
  79     }
  80 
  81     // Binary operator
  82 
  83     @Override
  84     Short64Vector bOp(Vector<Short, Shapes.S64Bit> o, FBinOp f) {
  85         short[] res = new short[length()];
  86         short[] vec1 = this.getElements();
  87         short[] vec2 = ((Short64Vector)o).getElements();
  88         for (int i = 0; i < length(); i++) {
  89             res[i] = f.apply(i, vec1[i], vec2[i]);
  90         }
  91         return new Short64Vector(res);
  92     }
  93 
  94     @Override
  95     Short64Vector bOp(Vector<Short, Shapes.S64Bit> o1, Mask<Short, Shapes.S64Bit> o2, FBinOp f) {
  96         short[] res = new short[length()];
  97         short[] vec1 = this.getElements();
  98         short[] vec2 = ((Short64Vector)o1).getElements();
  99         boolean[] mbits = ((Short64Mask)o2).getBits();
 100         for (int i = 0; i < length(); i++) {
 101             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 102         }
 103         return new Short64Vector(res);
 104     }
 105 
 106     // Trinary operator
 107 
 108     @Override
 109     Short64Vector tOp(Vector<Short, Shapes.S64Bit> o1, Vector<Short, Shapes.S64Bit> o2, FTriOp f) {
 110         short[] res = new short[length()];
 111         short[] vec1 = this.getElements();
 112         short[] vec2 = ((Short64Vector)o1).getElements();
 113         short[] vec3 = ((Short64Vector)o2).getElements();
 114         for (int i = 0; i < length(); i++) {
 115             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 116         }
 117         return new Short64Vector(res);
 118     }
 119 
 120     @Override
 121     Short64Vector tOp(Vector<Short, Shapes.S64Bit> o1, Vector<Short, Shapes.S64Bit> o2, Mask<Short, Shapes.S64Bit> o3, FTriOp f) {
 122         short[] res = new short[length()];
 123         short[] vec1 = getElements();
 124         short[] vec2 = ((Short64Vector)o1).getElements();
 125         short[] vec3 = ((Short64Vector)o2).getElements();
 126         boolean[] mbits = ((Short64Mask)o3).getBits();
 127         for (int i = 0; i < length(); i++) {
 128             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 129         }
 130         return new Short64Vector(res);
 131     }
 132 
 133     @Override
 134     short rOp(short v, FBinOp f) {
 135         short[] vec = getElements();
 136         for (int i = 0; i < length(); i++) {
 137             v = f.apply(i, v, vec[i]);
 138         }
 139         return v;
 140     }
 141 
 142     // Binary operations with scalars
 143 
 144     @Override
 145     @ForceInline
 146     public ShortVector<Shapes.S64Bit> add(short o) {
 147         return add(SPECIES.broadcast(o));
 148     }
 149 
 150     @Override
 151     @ForceInline
 152     public ShortVector<Shapes.S64Bit> add(short o, Mask<Short,Shapes.S64Bit> m) {
 153         return add(SPECIES.broadcast(o), m);
 154     }
 155 
 156     @Override
 157     @ForceInline
 158     public ShortVector<Shapes.S64Bit> addSaturate(short o) {
 159         return addSaturate(SPECIES.broadcast(o));
 160     }
 161 
 162     @Override
 163     @ForceInline
 164     public ShortVector<Shapes.S64Bit> addSaturate(short o, Mask<Short,Shapes.S64Bit> m) {
 165         return addSaturate(SPECIES.broadcast(o), m);
 166     }
 167 
 168     @Override
 169     @ForceInline
 170     public ShortVector<Shapes.S64Bit> sub(short o) {
 171         return sub(SPECIES.broadcast(o));
 172     }
 173 
 174     @Override
 175     @ForceInline
 176     public ShortVector<Shapes.S64Bit> sub(short o, Mask<Short,Shapes.S64Bit> m) {
 177         return sub(SPECIES.broadcast(o), m);
 178     }
 179 
 180     @Override
 181     @ForceInline
 182     public ShortVector<Shapes.S64Bit> subSaturate(short o) {
 183         return subSaturate(SPECIES.broadcast(o));
 184     }
 185 
 186     @Override
 187     @ForceInline
 188     public ShortVector<Shapes.S64Bit> subSaturate(short o, Mask<Short,Shapes.S64Bit> m) {
 189         return subSaturate(SPECIES.broadcast(o), m);
 190     }
 191 
 192     @Override
 193     @ForceInline
 194     public ShortVector<Shapes.S64Bit> mul(short o) {
 195         return mul(SPECIES.broadcast(o));
 196     }
 197 
 198     @Override
 199     @ForceInline
 200     public ShortVector<Shapes.S64Bit> mul(short o, Mask<Short,Shapes.S64Bit> m) {
 201         return mul(SPECIES.broadcast(o), m);
 202     }
 203 
 204     @Override
 205     @ForceInline
 206     public ShortVector<Shapes.S64Bit> min(short o) {
 207         return min(SPECIES.broadcast(o));
 208     }
 209 
 210     @Override
 211     @ForceInline
 212     public ShortVector<Shapes.S64Bit> max(short o) {
 213         return max(SPECIES.broadcast(o));
 214     }
 215 
 216     @Override
 217     @ForceInline
 218     public Mask<Short, Shapes.S64Bit> equal(short o) {
 219         return equal(SPECIES.broadcast(o));
 220     }
 221 
 222     @Override
 223     @ForceInline
 224     public Mask<Short, Shapes.S64Bit> notEqual(short o) {
 225         return notEqual(SPECIES.broadcast(o));
 226     }
 227 
 228     @Override
 229     @ForceInline
 230     public Mask<Short, Shapes.S64Bit> lessThan(short o) {
 231         return lessThan(SPECIES.broadcast(o));
 232     }
 233 
 234     @Override
 235     @ForceInline
 236     public Mask<Short, Shapes.S64Bit> lessThanEq(short o) {
 237         return lessThanEq(SPECIES.broadcast(o));
 238     }
 239 
 240     @Override
 241     @ForceInline
 242     public Mask<Short, Shapes.S64Bit> greaterThan(short o) {
 243         return greaterThan(SPECIES.broadcast(o));
 244     }
 245 
 246     @Override
 247     @ForceInline
 248     public Mask<Short, Shapes.S64Bit> greaterThanEq(short o) {
 249         return greaterThanEq(SPECIES.broadcast(o));
 250     }
 251 
 252     @Override
 253     @ForceInline
 254     public ShortVector<Shapes.S64Bit> blend(short o, Mask<Short,Shapes.S64Bit> m) {
 255         return blend(SPECIES.broadcast(o), m);
 256     }
 257 
 258 
 259     @Override
 260     @ForceInline
 261     public ShortVector<Shapes.S64Bit> and(short o) {
 262         return and(SPECIES.broadcast(o));
 263     }
 264 
 265     @Override
 266     @ForceInline
 267     public ShortVector<Shapes.S64Bit> and(short o, Mask<Short,Shapes.S64Bit> m) {
 268         return and(SPECIES.broadcast(o), m);
 269     }
 270 
 271     @Override
 272     @ForceInline
 273     public ShortVector<Shapes.S64Bit> or(short o) {
 274         return or(SPECIES.broadcast(o));
 275     }
 276 
 277     @Override
 278     @ForceInline
 279     public ShortVector<Shapes.S64Bit> or(short o, Mask<Short,Shapes.S64Bit> m) {
 280         return or(SPECIES.broadcast(o), m);
 281     }
 282 
 283     @Override
 284     @ForceInline
 285     public ShortVector<Shapes.S64Bit> xor(short o) {
 286         return xor(SPECIES.broadcast(o));
 287     }
 288 
 289     @Override
 290     @ForceInline
 291     public ShortVector<Shapes.S64Bit> xor(short o, Mask<Short,Shapes.S64Bit> m) {
 292         return xor(SPECIES.broadcast(o), m);
 293     }
 294 
 295 
 296     // Unary operations
 297 
 298 
 299 
 300     @Override
 301     @ForceInline
 302     public Short64Vector not() {
 303         return (Short64Vector) VectorIntrinsics.unaryOp(
 304             VECTOR_OP_NOT, Short64Vector.class, short.class, LENGTH,
 305             this,
 306             v1 -> ((Short64Vector)v1).uOp((i, a) -> (short) ~a));
 307     }
 308     // Binary operations
 309 
 310     @Override
 311     @ForceInline
 312     public Short64Vector add(Vector<Short,Shapes.S64Bit> o) {
 313         Objects.requireNonNull(o);
 314         Short64Vector v = (Short64Vector)o;
 315         return (Short64Vector) VectorIntrinsics.binaryOp(
 316             VECTOR_OP_ADD, Short64Vector.class, short.class, LENGTH,
 317             this, v,
 318             (v1, v2) -> ((Short64Vector)v1).bOp(v2, (i, a, b) -> (short)(a + b)));
 319     }
 320 
 321     @Override
 322     @ForceInline
 323     public Short64Vector sub(Vector<Short,Shapes.S64Bit> o) {
 324         Objects.requireNonNull(o);
 325         Short64Vector v = (Short64Vector)o;
 326         return (Short64Vector) VectorIntrinsics.binaryOp(
 327             VECTOR_OP_SUB, Short64Vector.class, short.class, LENGTH,
 328             this, v,
 329             (v1, v2) -> ((Short64Vector)v1).bOp(v2, (i, a, b) -> (short)(a - b)));
 330     }
 331 
 332     @Override
 333     @ForceInline
 334     public Short64Vector mul(Vector<Short,Shapes.S64Bit> o) {
 335         Objects.requireNonNull(o);
 336         Short64Vector v = (Short64Vector)o;
 337         return (Short64Vector) VectorIntrinsics.binaryOp(
 338             VECTOR_OP_MUL, Short64Vector.class, short.class, LENGTH,
 339             this, v,
 340             (v1, v2) -> ((Short64Vector)v1).bOp(v2, (i, a, b) -> (short)(a * b)));
 341     }
 342 
 343 
 344 
 345     @Override
 346     @ForceInline
 347     public Short64Vector and(Vector<Short,Shapes.S64Bit> o) {
 348         Objects.requireNonNull(o);
 349         Short64Vector v = (Short64Vector)o;
 350         return (Short64Vector) VectorIntrinsics.binaryOp(
 351             VECTOR_OP_AND, Short64Vector.class, short.class, LENGTH,
 352             this, v,
 353             (v1, v2) -> ((Short64Vector)v1).bOp(v2, (i, a, b) -> (short)(a & b)));
 354     }
 355 
 356     @Override
 357     @ForceInline
 358     public Short64Vector or(Vector<Short,Shapes.S64Bit> o) {
 359         Objects.requireNonNull(o);
 360         Short64Vector v = (Short64Vector)o;
 361         return (Short64Vector) VectorIntrinsics.binaryOp(
 362             VECTOR_OP_OR, Short64Vector.class, short.class, LENGTH,
 363             this, v,
 364             (v1, v2) -> ((Short64Vector)v1).bOp(v2, (i, a, b) -> (short)(a | b)));
 365     }
 366 
 367     @Override
 368     @ForceInline
 369     public Short64Vector xor(Vector<Short,Shapes.S64Bit> o) {
 370         Objects.requireNonNull(o);
 371         Short64Vector v = (Short64Vector)o;
 372         return (Short64Vector) VectorIntrinsics.binaryOp(
 373             VECTOR_OP_XOR, Short64Vector.class, short.class, LENGTH,
 374             this, v,
 375             (v1, v2) -> ((Short64Vector)v1).bOp(v2, (i, a, b) -> (short)(a ^ b)));
 376     }
 377 
 378     @Override
 379     @ForceInline
 380     public Short64Vector and(Vector<Short,Shapes.S64Bit> v, Mask<Short, Shapes.S64Bit> m) {
 381         return blend(and(v), m);
 382     }
 383 
 384     @Override
 385     @ForceInline
 386     public Short64Vector or(Vector<Short,Shapes.S64Bit> v, Mask<Short, Shapes.S64Bit> m) {
 387         return blend(or(v), m);
 388     }
 389 
 390     @Override
 391     @ForceInline
 392     public Short64Vector xor(Vector<Short,Shapes.S64Bit> v, Mask<Short, Shapes.S64Bit> m) {
 393         return blend(xor(v), m);
 394     }
 395 
 396     @Override
 397     @ForceInline
 398     public Short64Vector shiftL(int s) {
 399         return (Short64Vector) VectorIntrinsics.broadcastInt(
 400             VECTOR_OP_LSHIFT, Short64Vector.class, short.class, LENGTH,
 401             this, s,
 402             (v, i) -> v.uOp((__, a) -> (short) (a << i)));
 403     }
 404 
 405     @Override
 406     @ForceInline
 407     public Short64Vector shiftR(int s) {
 408         return (Short64Vector) VectorIntrinsics.broadcastInt(
 409             VECTOR_OP_URSHIFT, Short64Vector.class, short.class, LENGTH,
 410             this, s,
 411             (v, i) -> v.uOp((__, a) -> (short) (a >>> i)));
 412     }
 413 
 414     @Override
 415     @ForceInline
 416     public Short64Vector aShiftR(int s) {
 417         return (Short64Vector) VectorIntrinsics.broadcastInt(
 418             VECTOR_OP_RSHIFT, Short64Vector.class, short.class, LENGTH,
 419             this, s,
 420             (v, i) -> v.uOp((__, a) -> (short) (a >> i)));
 421     }
 422 
 423     // Ternary operations
 424 
 425 
 426     // Type specific horizontal reductions
 427 
 428 
 429     // Memory operations
 430 
 431     @Override
 432     @ForceInline
 433     public void intoArray(short[] a, int ix) {
 434         Objects.requireNonNull(a);
 435         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 436         VectorIntrinsics.store(Short64Vector.class, short.class, LENGTH,
 437                                a, ix, this,
 438                                (arr, idx, v) -> v.forEach((i, a_) -> ((short[])arr)[idx + i] = a_));
 439     }
 440 
 441     @Override
 442     @ForceInline
 443     public void intoArray(short[] a, int ax, Mask<Short, Shapes.S64Bit> m) {
 444         // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_);
 445         Short64Vector oldVal = SPECIES.fromArray(a, ax);
 446         Short64Vector newVal = oldVal.blend(this, m);
 447         newVal.intoArray(a, ax);
 448     }
 449 
 450     //
 451 
 452     @Override
 453     public String toString() {
 454         return Arrays.toString(getElements());
 455     }
 456 
 457     @Override
 458     public boolean equals(Object o) {
 459         if (this == o) return true;
 460         if (o == null || this.getClass() != o.getClass()) return false;
 461 
 462         Short64Vector that = (Short64Vector) o;
 463         return Arrays.equals(this.getElements(), that.getElements());
 464     }
 465 
 466     @Override
 467     public int hashCode() {
 468         return Arrays.hashCode(vec);
 469     }
 470 
 471     // Binary test
 472 
 473     @Override
 474     Short64Mask bTest(Vector<Short, Shapes.S64Bit> o, FBinTest f) {
 475         short[] vec1 = getElements();
 476         short[] vec2 = ((Short64Vector)o).getElements();
 477         boolean[] bits = new boolean[length()];
 478         for (int i = 0; i < length(); i++){
 479             bits[i] = f.apply(i, vec1[i], vec2[i]);
 480         }
 481         return new Short64Mask(bits);
 482     }
 483 
 484     // Comparisons
 485 
 486     @Override
 487     @ForceInline
 488     public Short64Mask equal(Vector<Short, Shapes.S64Bit> o) {
 489         Objects.requireNonNull(o);
 490         Short64Vector v = (Short64Vector)o;
 491 
 492         return (Short64Mask) VectorIntrinsics.compare(
 493             BT_eq, Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 494             this, v,
 495             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
 496     }
 497 
 498     @Override
 499     @ForceInline
 500     public Short64Mask notEqual(Vector<Short, Shapes.S64Bit> o) {
 501         Objects.requireNonNull(o);
 502         Short64Vector v = (Short64Vector)o;
 503 
 504         return (Short64Mask) VectorIntrinsics.compare(
 505             BT_ne, Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 506             this, v,
 507             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
 508     }
 509 
 510     @Override
 511     @ForceInline
 512     public Short64Mask lessThan(Vector<Short, Shapes.S64Bit> o) {
 513         Objects.requireNonNull(o);
 514         Short64Vector v = (Short64Vector)o;
 515 
 516         return (Short64Mask) VectorIntrinsics.compare(
 517             BT_lt, Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 518             this, v,
 519             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
 520     }
 521 
 522     @Override
 523     @ForceInline
 524     public Short64Mask lessThanEq(Vector<Short, Shapes.S64Bit> o) {
 525         Objects.requireNonNull(o);
 526         Short64Vector v = (Short64Vector)o;
 527 
 528         return (Short64Mask) VectorIntrinsics.compare(
 529             BT_le, Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 530             this, v,
 531             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
 532     }
 533 
 534     @Override
 535     @ForceInline
 536     public Short64Mask greaterThan(Vector<Short, Shapes.S64Bit> o) {
 537         Objects.requireNonNull(o);
 538         Short64Vector v = (Short64Vector)o;
 539 
 540         return (Short64Mask) VectorIntrinsics.compare(
 541             BT_gt, Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 542             this, v,
 543             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
 544     }
 545 
 546     @Override
 547     @ForceInline
 548     public Short64Mask greaterThanEq(Vector<Short, Shapes.S64Bit> o) {
 549         Objects.requireNonNull(o);
 550         Short64Vector v = (Short64Vector)o;
 551 
 552         return (Short64Mask) VectorIntrinsics.compare(
 553             BT_ge, Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 554             this, v,
 555             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
 556     }
 557 
 558     // Foreach
 559 
 560     @Override
 561     void forEach(FUnCon f) {
 562         short[] vec = getElements();
 563         for (int i = 0; i < length(); i++) {
 564             f.apply(i, vec[i]);
 565         }
 566     }
 567 
 568     @Override
 569     void forEach(Mask<Short, Shapes.S64Bit> o, FUnCon f) {
 570         boolean[] mbits = ((Short64Mask)o).getBits();
 571         forEach((i, a) -> {
 572             if (mbits[i]) { f.apply(i, a); }
 573         });
 574     }
 575 
 576 
 577 
 578     @Override
 579     public Short64Vector rotateEL(int j) {
 580         short[] vec = getElements();
 581         short[] res = new short[length()];
 582         for (int i = 0; i < length(); i++){
 583             res[j + i % length()] = vec[i];
 584         }
 585         return new Short64Vector(res);
 586     }
 587 
 588     @Override
 589     public Short64Vector rotateER(int j) {
 590         short[] vec = getElements();
 591         short[] res = new short[length()];
 592         for (int i = 0; i < length(); i++){
 593             int z = i - j;
 594             if(j < 0) {
 595                 res[length() + z] = vec[i];
 596             } else {
 597                 res[z] = vec[i];
 598             }
 599         }
 600         return new Short64Vector(res);
 601     }
 602 
 603     @Override
 604     public Short64Vector shiftEL(int j) {
 605         short[] vec = getElements();
 606         short[] res = new short[length()];
 607         for (int i = 0; i < length() - j; i++) {
 608             res[i] = vec[i + j];
 609         }
 610         return new Short64Vector(res);
 611     }
 612 
 613     @Override
 614     public Short64Vector shiftER(int j) {
 615         short[] vec = getElements();
 616         short[] res = new short[length()];
 617         for (int i = 0; i < length() - j; i++){
 618             res[i + j] = vec[i];
 619         }
 620         return new Short64Vector(res);
 621     }
 622 
 623     @Override
 624     public Short64Vector shuffle(Vector<Short, Shapes.S64Bit> o, Shuffle<Short, Shapes.S64Bit> s) {
 625         Short64Vector v = (Short64Vector) o;
 626         return uOp((i, a) -> {
 627             short[] vec = this.getElements();
 628             int e = s.getElement(i);
 629             if(e >= 0 && e < length()) {
 630                 //from this
 631                 return vec[e];
 632             } else if(e < length() * 2) {
 633                 //from o
 634                 return v.getElements()[e - length()];
 635             } else {
 636                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 637             }
 638         });
 639     }
 640 
 641     @Override
 642     public Short64Vector swizzle(Shuffle<Short, Shapes.S64Bit> s) {
 643         return uOp((i, a) -> {
 644             short[] vec = this.getElements();
 645             int e = s.getElement(i);
 646             if(e >= 0 && e < length()) {
 647                 return vec[e];
 648             } else {
 649                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 650             }
 651         });
 652     }
 653 
 654     @Override
 655     @ForceInline
 656     public Short64Vector blend(Vector<Short, Shapes.S64Bit> o1, Mask<Short, Shapes.S64Bit> o2) {
 657         Objects.requireNonNull(o1);
 658         Objects.requireNonNull(o2);
 659         Short64Vector v = (Short64Vector)o1;
 660         Short64Mask   m = (Short64Mask)o2;
 661 
 662         return (Short64Vector) VectorIntrinsics.blend(
 663             Short64Vector.class, Short64Mask.class, short.class, LENGTH,
 664             this, v, m,
 665             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
 666     }
 667 
 668     @Override
 669     @ForceInline
 670     @SuppressWarnings("unchecked")
 671     public <F> Vector<F, Shapes.S64Bit> rebracket(Species<F, Shapes.S64Bit> species) {
 672         Objects.requireNonNull(species);
 673         // TODO: check proper element type
 674         // TODO: update to pass the two species as an arguments and ideally
 675         // push down intrinsic call into species implementation
 676         return VectorIntrinsics.reinterpret(
 677             Short64Vector.class, short.class, LENGTH,
 678             species.elementType(), species.length(), this,
 679             (v, t) -> species.reshape(v)
 680         );
 681     }
 682 
 683     // Accessors
 684 
 685     @Override
 686     public short get(int i) {
 687         short[] vec = getElements();
 688         return vec[i];
 689     }
 690 
 691     @Override
 692     public Short64Vector with(int i, short e) {
 693         short[] res = vec.clone();
 694         res[i] = e;
 695         return new Short64Vector(res);
 696     }
 697 
 698     // Mask
 699 
 700     static final class Short64Mask extends AbstractMask<Short, Shapes.S64Bit> {
 701         static final Short64Mask TRUE_MASK = new Short64Mask(true);
 702         static final Short64Mask FALSE_MASK = new Short64Mask(false);
 703 
 704         // FIXME: was temporarily put here to simplify rematerialization support in the JVM
 705         private final boolean[] bits; // Don't access directly, use getBits() instead.
 706 
 707         public Short64Mask(boolean[] bits) {
 708             this(bits, 0);
 709         }
 710 
 711         public Short64Mask(boolean[] bits, int i) {
 712             this.bits = Arrays.copyOfRange(bits, i, i + species().length());
 713         }
 714 
 715         public Short64Mask(boolean val) {
 716             boolean[] bits = new boolean[species().length()];
 717             Arrays.fill(bits, val);
 718             this.bits = bits;
 719         }
 720 
 721         boolean[] getBits() {
 722             return VectorIntrinsics.maybeRebox(this).bits;
 723         }
 724 
 725         @Override
 726         Short64Mask uOp(MUnOp f) {
 727             boolean[] res = new boolean[species().length()];
 728             boolean[] bits = getBits();
 729             for (int i = 0; i < species().length(); i++) {
 730                 res[i] = f.apply(i, bits[i]);
 731             }
 732             return new Short64Mask(res);
 733         }
 734 
 735         @Override
 736         Short64Mask bOp(Mask<Short, Shapes.S64Bit> o, MBinOp f) {
 737             boolean[] res = new boolean[species().length()];
 738             boolean[] bits = getBits();
 739             boolean[] mbits = ((Short64Mask)o).getBits();
 740             for (int i = 0; i < species().length(); i++) {
 741                 res[i] = f.apply(i, bits[i], mbits[i]);
 742             }
 743             return new Short64Mask(res);
 744         }
 745 
 746         @Override
 747         public Short64Species species() {
 748             return SPECIES;
 749         }
 750 
 751         @Override
 752         public Short64Vector toVector() {
 753             short[] res = new short[species().length()];
 754             boolean[] bits = getBits();
 755             for (int i = 0; i < species().length(); i++) {
 756                 res[i] = (short) (bits[i] ? -1 : 0);
 757             }
 758             return new Short64Vector(res);
 759         }
 760 
 761         @Override
 762         @ForceInline
 763         @SuppressWarnings("unchecked")
 764         public <Z> Mask<Z, Shapes.S64Bit> rebracket(Species<Z, Shapes.S64Bit> species) {
 765             Objects.requireNonNull(species);
 766             // TODO: check proper element type
 767             return VectorIntrinsics.reinterpret(
 768                 Short64Mask.class, short.class, LENGTH,
 769                 species.elementType(), species.length(), this,
 770                 (m, t) -> m.reshape(species)
 771             );
 772         }
 773 
 774         // Unary operations
 775 
 776         //Mask<E, S> not();
 777 
 778         // Binary operations
 779 
 780         @Override
 781         @ForceInline
 782         public Short64Mask and(Mask<Short,Shapes.S64Bit> o) {
 783             Objects.requireNonNull(o);
 784             Short64Mask m = (Short64Mask)o;
 785             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Short64Mask.class, short.class, LENGTH,
 786                                              this, m,
 787                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
 788         }
 789 
 790         @Override
 791         @ForceInline
 792         public Short64Mask or(Mask<Short,Shapes.S64Bit> o) {
 793             Objects.requireNonNull(o);
 794             Short64Mask m = (Short64Mask)o;
 795             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Short64Mask.class, short.class, LENGTH,
 796                                              this, m,
 797                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
 798         }
 799 
 800         // Reductions
 801 
 802         @Override
 803         @ForceInline
 804         public boolean anyTrue() {
 805             return VectorIntrinsics.test(COND_notZero, Short64Mask.class, short.class, LENGTH,
 806                                          this, this,
 807                                          (m1, m2) -> super.anyTrue());
 808         }
 809 
 810         @Override
 811         @ForceInline
 812         public boolean allTrue() {
 813             return VectorIntrinsics.test(COND_carrySet, Short64Mask.class, short.class, LENGTH,
 814                                          this, species().maskAllTrue(),
 815                                          (m1, m2) -> super.allTrue());
 816         }
 817     }
 818 
 819     // Shuffle
 820 
 821     static final class Short64Shuffle extends AbstractShuffle<Short, Shapes.S64Bit> {
 822         static final IntVector.IntSpecies<Shapes.S64Bit> INT_SPECIES = (IntVector.IntSpecies<Shapes.S64Bit>) Vector.speciesInstance(Integer.class, Shapes.S_64_BIT);
 823 
 824         public Short64Shuffle(int[] reorder) {
 825             super(reorder);
 826         }
 827 
 828         public Short64Shuffle(int[] reorder, int i) {
 829             super(reorder, i);
 830         }
 831 
 832         @Override
 833         public Short64Species species() {
 834             return SPECIES;
 835         }
 836 
 837         @Override
 838         public IntVector.IntSpecies<Shapes.S64Bit> intSpecies() {
 839             return INT_SPECIES;
 840         }
 841     }
 842 
 843     // Species
 844 
 845     @Override
 846     public Short64Species species() {
 847         return SPECIES;
 848     }
 849 
 850     static final class Short64Species extends ShortSpecies<Shapes.S64Bit> {
 851         static final int BIT_SIZE = Shapes.S_64_BIT.bitSize();
 852 
 853         static final int LENGTH = BIT_SIZE / Short.SIZE;
 854 
 855         @Override
 856         public String toString() {
 857            StringBuilder sb = new StringBuilder("Shape[");
 858            sb.append(bitSize()).append(" bits, ");
 859            sb.append(length()).append(" ").append(short.class.getSimpleName()).append("s x ");
 860            sb.append(elementSize()).append(" bits");
 861            sb.append("]");
 862            return sb.toString();
 863         }
 864 
 865         @Override
 866         @ForceInline
 867         public int bitSize() {
 868             return BIT_SIZE;
 869         }
 870 
 871         @Override
 872         @ForceInline
 873         public int length() {
 874             return LENGTH;
 875         }
 876 
 877         @Override
 878         @ForceInline
 879         public Class<Short> elementType() {
 880             return Short.class;
 881         }
 882 
 883         @Override
 884         @ForceInline
 885         public int elementSize() {
 886             return Short.SIZE;
 887         }
 888 
 889         @Override
 890         @ForceInline
 891         public Shapes.S64Bit shape() {
 892             return Shapes.S_64_BIT;
 893         }
 894 
 895         @Override
 896         Short64Vector op(FOp f) {
 897             short[] res = new short[length()];
 898             for (int i = 0; i < length(); i++) {
 899                 res[i] = f.apply(i);
 900             }
 901             return new Short64Vector(res);
 902         }
 903 
 904         @Override
 905         Short64Vector op(Mask<Short, Shapes.S64Bit> o, FOp f) {
 906             short[] res = new short[length()];
 907             boolean[] mbits = ((Short64Mask)o).getBits();
 908             for (int i = 0; i < length(); i++) {
 909                 if (mbits[i]) {
 910                     res[i] = f.apply(i);
 911                 }
 912             }
 913             return new Short64Vector(res);
 914         }
 915 
 916         // Factories
 917 
 918         @Override
 919         public Short64Mask maskFromValues(boolean... bits) {
 920             return new Short64Mask(bits);
 921         }
 922 
 923         @Override
 924         public Short64Mask maskFromArray(boolean[] bits, int i) {
 925             return new Short64Mask(bits, i);
 926         }
 927 
 928         @Override
 929         public Short64Shuffle shuffleFromValues(int... ixs) {
 930             return new Short64Shuffle(ixs);
 931         }
 932 
 933         @Override
 934         public Short64Shuffle shuffleFromArray(int[] ixs, int i) {
 935             return new Short64Shuffle(ixs, i);
 936         }
 937 
 938         @Override
 939         @ForceInline
 940         public Short64Vector zero() {
 941             return VectorIntrinsics.broadcastCoerced(Short64Vector.class, short.class, LENGTH,
 942                                                      0,
 943                                                      (z -> ZERO));
 944         }
 945 
 946         @Override
 947         @ForceInline
 948         public Short64Vector broadcast(short e) {
 949             return VectorIntrinsics.broadcastCoerced(
 950                 Short64Vector.class, short.class, LENGTH,
 951                 e,
 952                 ((long bits) -> SPECIES.op(i -> (short)bits)));
 953         }
 954 
 955         @Override
 956         @ForceInline
 957         public Short64Mask maskAllTrue() {
 958             return VectorIntrinsics.broadcastCoerced(Short64Mask.class, short.class, LENGTH,
 959                                                      (short)-1,
 960                                                      (z -> Short64Mask.TRUE_MASK));
 961         }
 962 
 963         @Override
 964         @ForceInline
 965         public Short64Mask maskAllFalse() {
 966             return VectorIntrinsics.broadcastCoerced(Short64Mask.class, short.class, LENGTH,
 967                                                      0,
 968                                                      (z -> Short64Mask.FALSE_MASK));
 969         }
 970 
 971         @Override
 972         @ForceInline
 973         public Short64Vector fromArray(short[] a, int ix) {
 974             Objects.requireNonNull(a);
 975             ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 976             return (Short64Vector) VectorIntrinsics.load(Short64Vector.class, short.class, LENGTH,
 977                                                         a, ix,
 978                                                         (arr, idx) -> super.fromArray((short[]) arr, idx));
 979         }
 980 
 981         @Override
 982         @ForceInline
 983         public Short64Vector fromArray(short[] a, int ax, Mask<Short, Shapes.S64Bit> m) {
 984             return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]);
 985         }
 986 
 987         @Override
 988         @ForceInline
 989         @SuppressWarnings("unchecked")
 990         public <T extends Shape> Short64Vector resize(Vector<Short, T> o) {
 991             Objects.requireNonNull(o);
 992             if (o.bitSize() == 64) {
 993                 Short64Vector so = (Short64Vector)o;
 994                 return VectorIntrinsics.reinterpret(
 995                     Short64Vector.class, short.class, so.length(),
 996                     Short.class, LENGTH, so,
 997                     (v, t) -> (Short64Vector)reshape(v)
 998                 );
 999             } else if (o.bitSize() == 128) {
1000                 Short128Vector so = (Short128Vector)o;
1001                 return VectorIntrinsics.reinterpret(
1002                     Short128Vector.class, short.class, so.length(),
1003                     Short.class, LENGTH, so,
1004                     (v, t) -> (Short64Vector)reshape(v)
1005                 );
1006             } else if (o.bitSize() == 256) {
1007                 Short256Vector so = (Short256Vector)o;
1008                 return VectorIntrinsics.reinterpret(
1009                     Short256Vector.class, short.class, so.length(),
1010                     Short.class, LENGTH, so,
1011                     (v, t) -> (Short64Vector)reshape(v)
1012                 );
1013             } else if (o.bitSize() == 512) {
1014                 Short512Vector so = (Short512Vector)o;
1015                 return VectorIntrinsics.reinterpret(
1016                     Short512Vector.class, short.class, so.length(),
1017                     Short.class, LENGTH, so,
1018                     (v, t) -> (Short64Vector)reshape(v)
1019                 );
1020             } else {
1021                 throw new InternalError("Unimplemented size");
1022             }
1023         }
1024     }
1025 }