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     // Memory operations
 447 
 448     @Override
 449     @ForceInline
 450     public void intoArray(byte[] a, int ix) {
 451         Objects.requireNonNull(a);
 452         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 453         VectorIntrinsics.store(Byte512Vector.class, byte.class, LENGTH,
 454                                a, ix, this,
 455                                (arr, idx, v) -> v.forEach((i, a_) -> ((byte[])arr)[idx + i] = a_));
 456     }
 457 
 458     @Override
 459     @ForceInline
 460     public void intoArray(byte[] a, int ax, Mask<Byte, Shapes.S512Bit> m) {
 461         // TODO: use better default impl: forEach(m, (i, a_) -> a[ax + i] = a_);
 462         Byte512Vector oldVal = SPECIES.fromArray(a, ax);
 463         Byte512Vector newVal = oldVal.blend(this, m);
 464         newVal.intoArray(a, ax);
 465     }
 466 
 467     //
 468 
 469     @Override
 470     public String toString() {
 471         return Arrays.toString(getElements());
 472     }
 473 
 474     @Override
 475     public boolean equals(Object o) {
 476         if (this == o) return true;
 477         if (o == null || this.getClass() != o.getClass()) return false;
 478 
 479         Byte512Vector that = (Byte512Vector) o;
 480         return Arrays.equals(this.getElements(), that.getElements());
 481     }
 482 
 483     @Override
 484     public int hashCode() {
 485         return Arrays.hashCode(vec);
 486     }
 487 
 488     // Binary test
 489 
 490     @Override
 491     Byte512Mask bTest(Vector<Byte, Shapes.S512Bit> o, FBinTest f) {
 492         byte[] vec1 = getElements();
 493         byte[] vec2 = ((Byte512Vector)o).getElements();
 494         boolean[] bits = new boolean[length()];
 495         for (int i = 0; i < length(); i++){
 496             bits[i] = f.apply(i, vec1[i], vec2[i]);
 497         }
 498         return new Byte512Mask(bits);
 499     }
 500 
 501     // Comparisons
 502 
 503     @Override
 504     @ForceInline
 505     public Byte512Mask equal(Vector<Byte, Shapes.S512Bit> o) {
 506         Objects.requireNonNull(o);
 507         Byte512Vector v = (Byte512Vector)o;
 508 
 509         return (Byte512Mask) VectorIntrinsics.compare(
 510             BT_eq, Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 511             this, v,
 512             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
 513     }
 514 
 515     @Override
 516     @ForceInline
 517     public Byte512Mask notEqual(Vector<Byte, Shapes.S512Bit> o) {
 518         Objects.requireNonNull(o);
 519         Byte512Vector v = (Byte512Vector)o;
 520 
 521         return (Byte512Mask) VectorIntrinsics.compare(
 522             BT_ne, Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 523             this, v,
 524             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
 525     }
 526 
 527     @Override
 528     @ForceInline
 529     public Byte512Mask lessThan(Vector<Byte, Shapes.S512Bit> o) {
 530         Objects.requireNonNull(o);
 531         Byte512Vector v = (Byte512Vector)o;
 532 
 533         return (Byte512Mask) VectorIntrinsics.compare(
 534             BT_lt, Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 535             this, v,
 536             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
 537     }
 538 
 539     @Override
 540     @ForceInline
 541     public Byte512Mask lessThanEq(Vector<Byte, Shapes.S512Bit> o) {
 542         Objects.requireNonNull(o);
 543         Byte512Vector v = (Byte512Vector)o;
 544 
 545         return (Byte512Mask) VectorIntrinsics.compare(
 546             BT_le, Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 547             this, v,
 548             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
 549     }
 550 
 551     @Override
 552     @ForceInline
 553     public Byte512Mask greaterThan(Vector<Byte, Shapes.S512Bit> o) {
 554         Objects.requireNonNull(o);
 555         Byte512Vector v = (Byte512Vector)o;
 556 
 557         return (Byte512Mask) VectorIntrinsics.compare(
 558             BT_gt, Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 559             this, v,
 560             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
 561     }
 562 
 563     @Override
 564     @ForceInline
 565     public Byte512Mask greaterThanEq(Vector<Byte, Shapes.S512Bit> o) {
 566         Objects.requireNonNull(o);
 567         Byte512Vector v = (Byte512Vector)o;
 568 
 569         return (Byte512Mask) VectorIntrinsics.compare(
 570             BT_ge, Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 571             this, v,
 572             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
 573     }
 574 
 575     // Foreach
 576 
 577     @Override
 578     void forEach(FUnCon f) {
 579         byte[] vec = getElements();
 580         for (int i = 0; i < length(); i++) {
 581             f.apply(i, vec[i]);
 582         }
 583     }
 584 
 585     @Override
 586     void forEach(Mask<Byte, Shapes.S512Bit> o, FUnCon f) {
 587         boolean[] mbits = ((Byte512Mask)o).getBits();
 588         forEach((i, a) -> {
 589             if (mbits[i]) { f.apply(i, a); }
 590         });
 591     }
 592 
 593 
 594 
 595     @Override
 596     public Byte512Vector rotateEL(int j) {
 597         byte[] vec = getElements();
 598         byte[] res = new byte[length()];
 599         for (int i = 0; i < length(); i++){
 600             res[(j + i) % length()] = vec[i];
 601         }
 602         return new Byte512Vector(res);
 603     }
 604 
 605     @Override
 606     public Byte512Vector rotateER(int j) {
 607         byte[] vec = getElements();
 608         byte[] res = new byte[length()];
 609         for (int i = 0; i < length(); i++){
 610             int z = i - j;
 611             if(j < 0) {
 612                 res[length() + z] = vec[i];
 613             } else {
 614                 res[z] = vec[i];
 615             }
 616         }
 617         return new Byte512Vector(res);
 618     }
 619 
 620     @Override
 621     public Byte512Vector shiftEL(int j) {
 622         byte[] vec = getElements();
 623         byte[] res = new byte[length()];
 624         for (int i = 0; i < length() - j; i++) {
 625             res[i] = vec[i + j];
 626         }
 627         return new Byte512Vector(res);
 628     }
 629 
 630     @Override
 631     public Byte512Vector shiftER(int j) {
 632         byte[] vec = getElements();
 633         byte[] res = new byte[length()];
 634         for (int i = 0; i < length() - j; i++){
 635             res[i + j] = vec[i];
 636         }
 637         return new Byte512Vector(res);
 638     }
 639 
 640     @Override
 641     public Byte512Vector shuffle(Vector<Byte, Shapes.S512Bit> o, Shuffle<Byte, Shapes.S512Bit> s) {
 642         Byte512Vector v = (Byte512Vector) o;
 643         return uOp((i, a) -> {
 644             byte[] vec = this.getElements();
 645             int e = s.getElement(i);
 646             if(e >= 0 && e < length()) {
 647                 //from this
 648                 return vec[e];
 649             } else if(e < length() * 2) {
 650                 //from o
 651                 return v.getElements()[e - length()];
 652             } else {
 653                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 654             }
 655         });
 656     }
 657 
 658     @Override
 659     public Byte512Vector swizzle(Shuffle<Byte, Shapes.S512Bit> s) {
 660         return uOp((i, a) -> {
 661             byte[] vec = this.getElements();
 662             int e = s.getElement(i);
 663             if(e >= 0 && e < length()) {
 664                 return vec[e];
 665             } else {
 666                 throw new ArrayIndexOutOfBoundsException("Bad reordering for shuffle");
 667             }
 668         });
 669     }
 670 
 671     @Override
 672     @ForceInline
 673     public Byte512Vector blend(Vector<Byte, Shapes.S512Bit> o1, Mask<Byte, Shapes.S512Bit> o2) {
 674         Objects.requireNonNull(o1);
 675         Objects.requireNonNull(o2);
 676         Byte512Vector v = (Byte512Vector)o1;
 677         Byte512Mask   m = (Byte512Mask)o2;
 678 
 679         return (Byte512Vector) VectorIntrinsics.blend(
 680             Byte512Vector.class, Byte512Mask.class, byte.class, LENGTH,
 681             this, v, m,
 682             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.getElement(i) ? b : a));
 683     }
 684 
 685     // Accessors
 686 
 687     @Override
 688     public byte get(int i) {
 689         byte[] vec = getElements();
 690         return vec[i];
 691     }
 692 
 693     @Override
 694     public Byte512Vector with(int i, byte e) {
 695         byte[] res = vec.clone();
 696         res[i] = e;
 697         return new Byte512Vector(res);
 698     }
 699 
 700     // Mask
 701 
 702     static final class Byte512Mask extends AbstractMask<Byte, Shapes.S512Bit> {
 703         static final Byte512Mask TRUE_MASK = new Byte512Mask(true);
 704         static final Byte512Mask FALSE_MASK = new Byte512Mask(false);
 705 
 706         // FIXME: was temporarily put here to simplify rematerialization support in the JVM
 707         private final boolean[] bits; // Don't access directly, use getBits() instead.
 708 
 709         public Byte512Mask(boolean[] bits) {
 710             this(bits, 0);
 711         }
 712 
 713         public Byte512Mask(boolean[] bits, int i) {
 714             this.bits = Arrays.copyOfRange(bits, i, i + species().length());
 715         }
 716 
 717         public Byte512Mask(boolean val) {
 718             boolean[] bits = new boolean[species().length()];
 719             Arrays.fill(bits, val);
 720             this.bits = bits;
 721         }
 722 
 723         boolean[] getBits() {
 724             return VectorIntrinsics.maybeRebox(this).bits;
 725         }
 726 
 727         @Override
 728         Byte512Mask uOp(MUnOp f) {
 729             boolean[] res = new boolean[species().length()];
 730             boolean[] bits = getBits();
 731             for (int i = 0; i < species().length(); i++) {
 732                 res[i] = f.apply(i, bits[i]);
 733             }
 734             return new Byte512Mask(res);
 735         }
 736 
 737         @Override
 738         Byte512Mask bOp(Mask<Byte, Shapes.S512Bit> o, MBinOp f) {
 739             boolean[] res = new boolean[species().length()];
 740             boolean[] bits = getBits();
 741             boolean[] mbits = ((Byte512Mask)o).getBits();
 742             for (int i = 0; i < species().length(); i++) {
 743                 res[i] = f.apply(i, bits[i], mbits[i]);
 744             }
 745             return new Byte512Mask(res);
 746         }
 747 
 748         @Override
 749         public Byte512Species species() {
 750             return SPECIES;
 751         }
 752 
 753         @Override
 754         public Byte512Vector toVector() {
 755             byte[] res = new byte[species().length()];
 756             boolean[] bits = getBits();
 757             for (int i = 0; i < species().length(); i++) {
 758                 res[i] = (byte) (bits[i] ? -1 : 0);
 759             }
 760             return new Byte512Vector(res);
 761         }
 762 
 763         @Override
 764         @ForceInline
 765         @SuppressWarnings("unchecked")
 766         public <Z> Mask<Z, Shapes.S512Bit> rebracket(Species<Z, Shapes.S512Bit> species) {
 767             Objects.requireNonNull(species);
 768             // TODO: check proper element type
 769             return VectorIntrinsics.reinterpret(
 770                 Byte512Mask.class, byte.class, LENGTH,
 771                 species.elementType(), species.length(), this,
 772                 (m, t) -> m.reshape(species)
 773             );
 774         }
 775 
 776         // Unary operations
 777 
 778         //Mask<E, S> not();
 779 
 780         // Binary operations
 781 
 782         @Override
 783         @ForceInline
 784         public Byte512Mask and(Mask<Byte,Shapes.S512Bit> o) {
 785             Objects.requireNonNull(o);
 786             Byte512Mask m = (Byte512Mask)o;
 787             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, Byte512Mask.class, byte.class, LENGTH,
 788                                              this, m,
 789                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
 790         }
 791 
 792         @Override
 793         @ForceInline
 794         public Byte512Mask or(Mask<Byte,Shapes.S512Bit> o) {
 795             Objects.requireNonNull(o);
 796             Byte512Mask m = (Byte512Mask)o;
 797             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, Byte512Mask.class, byte.class, LENGTH,
 798                                              this, m,
 799                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
 800         }
 801 
 802         // Reductions
 803 
 804         @Override
 805         @ForceInline
 806         public boolean anyTrue() {
 807             return VectorIntrinsics.test(COND_notZero, Byte512Mask.class, byte.class, LENGTH,
 808                                          this, this,
 809                                          (m1, m2) -> super.anyTrue());
 810         }
 811 
 812         @Override
 813         @ForceInline
 814         public boolean allTrue() {
 815             return VectorIntrinsics.test(COND_carrySet, Byte512Mask.class, byte.class, LENGTH,
 816                                          this, species().maskAllTrue(),
 817                                          (m1, m2) -> super.allTrue());
 818         }
 819     }
 820 
 821     // Shuffle
 822 
 823     static final class Byte512Shuffle extends AbstractShuffle<Byte, Shapes.S512Bit> {
 824         static final IntVector.IntSpecies<Shapes.S512Bit> INT_SPECIES = IntVector.speciesInstance(Shapes.S_512_BIT);
 825 
 826         public Byte512Shuffle(int[] reorder) {
 827             super(reorder);
 828         }
 829 
 830         public Byte512Shuffle(int[] reorder, int i) {
 831             super(reorder, i);
 832         }
 833 
 834         @Override
 835         public Byte512Species species() {
 836             return SPECIES;
 837         }
 838 
 839         @Override
 840         public IntVector.IntSpecies<Shapes.S512Bit> intSpecies() {
 841             return INT_SPECIES;
 842         }
 843     }
 844 
 845     // Species
 846 
 847     @Override
 848     public Byte512Species species() {
 849         return SPECIES;
 850     }
 851 
 852     static final class Byte512Species extends ByteSpecies<Shapes.S512Bit> {
 853         static final int BIT_SIZE = Shapes.S_512_BIT.bitSize();
 854 
 855         static final int LENGTH = BIT_SIZE / Byte.SIZE;
 856 
 857         @Override
 858         public String toString() {
 859            StringBuilder sb = new StringBuilder("Shape[");
 860            sb.append(bitSize()).append(" bits, ");
 861            sb.append(length()).append(" ").append(byte.class.getSimpleName()).append("s x ");
 862            sb.append(elementSize()).append(" bits");
 863            sb.append("]");
 864            return sb.toString();
 865         }
 866 
 867         @Override
 868         @ForceInline
 869         public int bitSize() {
 870             return BIT_SIZE;
 871         }
 872 
 873         @Override
 874         @ForceInline
 875         public int length() {
 876             return LENGTH;
 877         }
 878 
 879         @Override
 880         @ForceInline
 881         public Class<Byte> elementType() {
 882             return byte.class;
 883         }
 884 
 885         @Override
 886         @ForceInline
 887         public int elementSize() {
 888             return Byte.SIZE;
 889         }
 890 
 891         @Override
 892         @ForceInline
 893         public Shapes.S512Bit shape() {
 894             return Shapes.S_512_BIT;
 895         }
 896 
 897         @Override
 898         Byte512Vector op(FOp f) {
 899             byte[] res = new byte[length()];
 900             for (int i = 0; i < length(); i++) {
 901                 res[i] = f.apply(i);
 902             }
 903             return new Byte512Vector(res);
 904         }
 905 
 906         @Override
 907         Byte512Vector op(Mask<Byte, Shapes.S512Bit> o, FOp f) {
 908             byte[] res = new byte[length()];
 909             boolean[] mbits = ((Byte512Mask)o).getBits();
 910             for (int i = 0; i < length(); i++) {
 911                 if (mbits[i]) {
 912                     res[i] = f.apply(i);
 913                 }
 914             }
 915             return new Byte512Vector(res);
 916         }
 917 
 918         // Factories
 919 
 920         @Override
 921         public Byte512Mask maskFromValues(boolean... bits) {
 922             return new Byte512Mask(bits);
 923         }
 924 
 925         @Override
 926         public Byte512Mask maskFromArray(boolean[] bits, int i) {
 927             return new Byte512Mask(bits, i);
 928         }
 929 
 930         @Override
 931         public Byte512Shuffle shuffleFromValues(int... ixs) {
 932             return new Byte512Shuffle(ixs);
 933         }
 934 
 935         @Override
 936         public Byte512Shuffle shuffleFromArray(int[] ixs, int i) {
 937             return new Byte512Shuffle(ixs, i);
 938         }
 939 
 940         @Override
 941         public Byte512Shuffle shuffleFromVector(Vector<Integer, Shapes.S512Bit> v) {
 942             int[] a = ((IntVector<Shapes.S512Bit>) v).toArray();
 943             return new Byte512Shuffle(a, 0);
 944         }
 945 
 946         @Override
 947         @ForceInline
 948         public Byte512Vector zero() {
 949             return VectorIntrinsics.broadcastCoerced(Byte512Vector.class, byte.class, LENGTH,
 950                                                      0,
 951                                                      (z -> ZERO));
 952         }
 953 
 954         @Override
 955         @ForceInline
 956         public Byte512Vector broadcast(byte e) {
 957             return VectorIntrinsics.broadcastCoerced(
 958                 Byte512Vector.class, byte.class, LENGTH,
 959                 e,
 960                 ((long bits) -> SPECIES.op(i -> (byte)bits)));
 961         }
 962 
 963         @Override
 964         @ForceInline
 965         public Byte512Mask maskAllTrue() {
 966             return VectorIntrinsics.broadcastCoerced(Byte512Mask.class, byte.class, LENGTH,
 967                                                      (byte)-1,
 968                                                      (z -> Byte512Mask.TRUE_MASK));
 969         }
 970 
 971         @Override
 972         @ForceInline
 973         public Byte512Mask maskAllFalse() {
 974             return VectorIntrinsics.broadcastCoerced(Byte512Mask.class, byte.class, LENGTH,
 975                                                      0,
 976                                                      (z -> Byte512Mask.FALSE_MASK));
 977         }
 978 
 979         @Override
 980         @ForceInline
 981         public Byte512Vector fromArray(byte[] a, int ix) {
 982             Objects.requireNonNull(a);
 983             ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 984             return (Byte512Vector) VectorIntrinsics.load(Byte512Vector.class, byte.class, LENGTH,
 985                                                         a, ix,
 986                                                         (arr, idx) -> super.fromArray((byte[]) arr, idx));
 987         }
 988 
 989         @Override
 990         @ForceInline
 991         public Byte512Vector fromArray(byte[] a, int ax, Mask<Byte, Shapes.S512Bit> m) {
 992             return zero().blend(fromArray(a, ax), m); // TODO: use better default impl: op(m, i -> a[ax + i]);
 993         }
 994 
 995         @Override
 996         @ForceInline
 997         @SuppressWarnings("unchecked")
 998         public <F> Byte512Vector rebracket(Vector<F, Shapes.S512Bit> o) {
 999             Objects.requireNonNull(o);
1000             if (o.elementType() == byte.class) {
1001                 Byte512Vector so = (Byte512Vector)o;
1002                 return VectorIntrinsics.reinterpret(
1003                     Byte512Vector.class, byte.class, so.length(),
1004                     byte.class, LENGTH, so,
1005                     (v, t) -> (Byte512Vector)reshape(v)
1006                 );
1007             } else if (o.elementType() == short.class) {
1008                 Short512Vector so = (Short512Vector)o;
1009                 return VectorIntrinsics.reinterpret(
1010                     Short512Vector.class, short.class, so.length(),
1011                     byte.class, LENGTH, so,
1012                     (v, t) -> (Byte512Vector)reshape(v)
1013                 );
1014             } else if (o.elementType() == int.class) {
1015                 Int512Vector so = (Int512Vector)o;
1016                 return VectorIntrinsics.reinterpret(
1017                     Int512Vector.class, int.class, so.length(),
1018                     byte.class, LENGTH, so,
1019                     (v, t) -> (Byte512Vector)reshape(v)
1020                 );
1021             } else if (o.elementType() == long.class) {
1022                 Long512Vector so = (Long512Vector)o;
1023                 return VectorIntrinsics.reinterpret(
1024                     Long512Vector.class, long.class, so.length(),
1025                     byte.class, LENGTH, so,
1026                     (v, t) -> (Byte512Vector)reshape(v)
1027                 );
1028             } else if (o.elementType() == float.class) {
1029                 Float512Vector so = (Float512Vector)o;
1030                 return VectorIntrinsics.reinterpret(
1031                     Float512Vector.class, float.class, so.length(),
1032                     byte.class, LENGTH, so,
1033                     (v, t) -> (Byte512Vector)reshape(v)
1034                 );
1035             } else if (o.elementType() == double.class) {
1036                 Double512Vector so = (Double512Vector)o;
1037                 return VectorIntrinsics.reinterpret(
1038                     Double512Vector.class, double.class, so.length(),
1039                     byte.class, LENGTH, so,
1040                     (v, t) -> (Byte512Vector)reshape(v)
1041                 );
1042             } else {
1043                 throw new InternalError("Unimplemented size");
1044             }
1045         }
1046 
1047         @Override
1048         @ForceInline
1049         @SuppressWarnings("unchecked")
1050         public <T extends Shape> Byte512Vector resize(Vector<Byte, T> o) {
1051             Objects.requireNonNull(o);
1052             if (o.bitSize() == 64) {
1053                 Byte64Vector so = (Byte64Vector)o;
1054                 return VectorIntrinsics.reinterpret(
1055                     Byte64Vector.class, byte.class, so.length(),
1056                     byte.class, LENGTH, so,
1057                     (v, t) -> (Byte512Vector)reshape(v)
1058                 );
1059             } else if (o.bitSize() == 128) {
1060                 Byte128Vector so = (Byte128Vector)o;
1061                 return VectorIntrinsics.reinterpret(
1062                     Byte128Vector.class, byte.class, so.length(),
1063                     byte.class, LENGTH, so,
1064                     (v, t) -> (Byte512Vector)reshape(v)
1065                 );
1066             } else if (o.bitSize() == 256) {
1067                 Byte256Vector so = (Byte256Vector)o;
1068                 return VectorIntrinsics.reinterpret(
1069                     Byte256Vector.class, byte.class, so.length(),
1070                     byte.class, LENGTH, so,
1071                     (v, t) -> (Byte512Vector)reshape(v)
1072                 );
1073             } else if (o.bitSize() == 512) {
1074                 Byte512Vector so = (Byte512Vector)o;
1075                 return VectorIntrinsics.reinterpret(
1076                     Byte512Vector.class, byte.class, so.length(),
1077                     byte.class, LENGTH, so,
1078                     (v, t) -> (Byte512Vector)reshape(v)
1079                 );
1080             } else {
1081                 throw new InternalError("Unimplemented size");
1082             }
1083         }
1084     }
1085 }