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