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