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