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