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.nio.ByteOrder;
  29 import java.nio.ReadOnlyBufferException;
  30 import java.util.Arrays;
  31 import java.util.Objects;
  32 import java.util.function.IntUnaryOperator;
  33 
  34 import jdk.internal.misc.Unsafe;
  35 import jdk.internal.vm.annotation.ForceInline;
  36 import static jdk.incubator.vector.VectorIntrinsics.*;
  37 
  38 @SuppressWarnings("cast")
  39 final class ByteMaxVector extends ByteVector {
  40     private static final VectorSpecies<Byte> SPECIES = ByteVector.SPECIES_MAX;
  41 
  42     static final ByteMaxVector ZERO = new ByteMaxVector();
  43 
  44     static final int LENGTH = SPECIES.length();
  45 
  46     private final byte[] vec; // Don't access directly, use getElements() instead.
  47 
  48     private byte[] getElements() {
  49         return VectorIntrinsics.maybeRebox(this).vec;
  50     }
  51 
  52     ByteMaxVector() {
  53         vec = new byte[SPECIES.length()];
  54     }
  55 
  56     ByteMaxVector(byte[] v) {
  57         vec = v;
  58     }
  59 
  60     @Override
  61     public int length() { return LENGTH; }
  62 
  63     // Unary operator
  64 
  65     @Override
  66     ByteMaxVector uOp(FUnOp f) {
  67         byte[] vec = getElements();
  68         byte[] res = new byte[length()];
  69         for (int i = 0; i < length(); i++) {
  70             res[i] = f.apply(i, vec[i]);
  71         }
  72         return new ByteMaxVector(res);
  73     }
  74 
  75     @Override
  76     ByteMaxVector uOp(VectorMask<Byte> o, FUnOp f) {
  77         byte[] vec = getElements();
  78         byte[] res = new byte[length()];
  79         boolean[] mbits = ((ByteMaxMask)o).getBits();
  80         for (int i = 0; i < length(); i++) {
  81             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  82         }
  83         return new ByteMaxVector(res);
  84     }
  85 
  86     // Binary operator
  87 
  88     @Override
  89     ByteMaxVector bOp(Vector<Byte> o, FBinOp f) {
  90         byte[] res = new byte[length()];
  91         byte[] vec1 = this.getElements();
  92         byte[] vec2 = ((ByteMaxVector)o).getElements();
  93         for (int i = 0; i < length(); i++) {
  94             res[i] = f.apply(i, vec1[i], vec2[i]);
  95         }
  96         return new ByteMaxVector(res);
  97     }
  98 
  99     @Override
 100     ByteMaxVector bOp(Vector<Byte> o1, VectorMask<Byte> o2, FBinOp f) {
 101         byte[] res = new byte[length()];
 102         byte[] vec1 = this.getElements();
 103         byte[] vec2 = ((ByteMaxVector)o1).getElements();
 104         boolean[] mbits = ((ByteMaxMask)o2).getBits();
 105         for (int i = 0; i < length(); i++) {
 106             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 107         }
 108         return new ByteMaxVector(res);
 109     }
 110 
 111     // Trinary operator
 112 
 113     @Override
 114     ByteMaxVector tOp(Vector<Byte> o1, Vector<Byte> o2, FTriOp f) {
 115         byte[] res = new byte[length()];
 116         byte[] vec1 = this.getElements();
 117         byte[] vec2 = ((ByteMaxVector)o1).getElements();
 118         byte[] vec3 = ((ByteMaxVector)o2).getElements();
 119         for (int i = 0; i < length(); i++) {
 120             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 121         }
 122         return new ByteMaxVector(res);
 123     }
 124 
 125     @Override
 126     ByteMaxVector tOp(Vector<Byte> o1, Vector<Byte> o2, VectorMask<Byte> o3, FTriOp f) {
 127         byte[] res = new byte[length()];
 128         byte[] vec1 = getElements();
 129         byte[] vec2 = ((ByteMaxVector)o1).getElements();
 130         byte[] vec3 = ((ByteMaxVector)o2).getElements();
 131         boolean[] mbits = ((ByteMaxMask)o3).getBits();
 132         for (int i = 0; i < length(); i++) {
 133             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 134         }
 135         return new ByteMaxVector(res);
 136     }
 137 
 138     @Override
 139     byte rOp(byte v, FBinOp f) {
 140         byte[] vec = getElements();
 141         for (int i = 0; i < length(); i++) {
 142             v = f.apply(i, v, vec[i]);
 143         }
 144         return v;
 145     }
 146 
 147     @Override
 148     @ForceInline
 149     public <F> Vector<F> cast(VectorSpecies<F> s) {
 150         Objects.requireNonNull(s);
 151         if (s.length() != LENGTH)
 152             throw new IllegalArgumentException("Vector length this species length differ");
 153 
 154         return VectorIntrinsics.cast(
 155             ByteMaxVector.class,
 156             byte.class, LENGTH,
 157             s.vectorType(),
 158             s.elementType(), LENGTH,
 159             this, s,
 160             (species, vector) -> vector.castDefault(species)
 161         );
 162     }
 163 
 164     @SuppressWarnings("unchecked")
 165     @ForceInline
 166     private <F> Vector<F> castDefault(VectorSpecies<F> s) {
 167         int limit = s.length();
 168 
 169         Class<?> stype = s.elementType();
 170         if (stype == byte.class) {
 171             byte[] a = new byte[limit];
 172             for (int i = 0; i < limit; i++) {
 173                 a[i] = (byte) this.lane(i);
 174             }
 175             return (Vector) ByteVector.fromArray((VectorSpecies<Byte>) s, a, 0);
 176         } else if (stype == short.class) {
 177             short[] a = new short[limit];
 178             for (int i = 0; i < limit; i++) {
 179                 a[i] = (short) this.lane(i);
 180             }
 181             return (Vector) ShortVector.fromArray((VectorSpecies<Short>) s, a, 0);
 182         } else if (stype == int.class) {
 183             int[] a = new int[limit];
 184             for (int i = 0; i < limit; i++) {
 185                 a[i] = (int) this.lane(i);
 186             }
 187             return (Vector) IntVector.fromArray((VectorSpecies<Integer>) s, a, 0);
 188         } else if (stype == long.class) {
 189             long[] a = new long[limit];
 190             for (int i = 0; i < limit; i++) {
 191                 a[i] = (long) this.lane(i);
 192             }
 193             return (Vector) LongVector.fromArray((VectorSpecies<Long>) s, a, 0);
 194         } else if (stype == float.class) {
 195             float[] a = new float[limit];
 196             for (int i = 0; i < limit; i++) {
 197                 a[i] = (float) this.lane(i);
 198             }
 199             return (Vector) FloatVector.fromArray((VectorSpecies<Float>) s, a, 0);
 200         } else if (stype == double.class) {
 201             double[] a = new double[limit];
 202             for (int i = 0; i < limit; i++) {
 203                 a[i] = (double) this.lane(i);
 204             }
 205             return (Vector) DoubleVector.fromArray((VectorSpecies<Double>) s, a, 0);
 206         } else {
 207             throw new UnsupportedOperationException("Bad lane type for casting.");
 208         }
 209     }
 210 
 211     @Override
 212     @ForceInline
 213     @SuppressWarnings("unchecked")
 214     public <F> Vector<F> reinterpret(VectorSpecies<F> s) {
 215         Objects.requireNonNull(s);
 216 
 217         if(s.elementType().equals(byte.class)) {
 218             return (Vector<F>) reshape((VectorSpecies<Byte>)s);
 219         }
 220         if(s.bitSize() == bitSize()) {
 221             return reinterpretType(s);
 222         }
 223 
 224         return defaultReinterpret(s);
 225     }
 226 
 227     @ForceInline
 228     private <F> Vector<F> reinterpretType(VectorSpecies<F> s) {
 229         Objects.requireNonNull(s);
 230 
 231         Class<?> stype = s.elementType();
 232         if (stype == byte.class) {
 233             return VectorIntrinsics.reinterpret(
 234                 ByteMaxVector.class,
 235                 byte.class, LENGTH,
 236                 ByteMaxVector.class,
 237                 byte.class, ByteMaxVector.LENGTH,
 238                 this, s,
 239                 (species, vector) -> vector.defaultReinterpret(species)
 240             );
 241         } else if (stype == short.class) {
 242             return VectorIntrinsics.reinterpret(
 243                 ByteMaxVector.class,
 244                 byte.class, LENGTH,
 245                 ShortMaxVector.class,
 246                 short.class, ShortMaxVector.LENGTH,
 247                 this, s,
 248                 (species, vector) -> vector.defaultReinterpret(species)
 249             );
 250         } else if (stype == int.class) {
 251             return VectorIntrinsics.reinterpret(
 252                 ByteMaxVector.class,
 253                 byte.class, LENGTH,
 254                 IntMaxVector.class,
 255                 int.class, IntMaxVector.LENGTH,
 256                 this, s,
 257                 (species, vector) -> vector.defaultReinterpret(species)
 258             );
 259         } else if (stype == long.class) {
 260             return VectorIntrinsics.reinterpret(
 261                 ByteMaxVector.class,
 262                 byte.class, LENGTH,
 263                 LongMaxVector.class,
 264                 long.class, LongMaxVector.LENGTH,
 265                 this, s,
 266                 (species, vector) -> vector.defaultReinterpret(species)
 267             );
 268         } else if (stype == float.class) {
 269             return VectorIntrinsics.reinterpret(
 270                 ByteMaxVector.class,
 271                 byte.class, LENGTH,
 272                 FloatMaxVector.class,
 273                 float.class, FloatMaxVector.LENGTH,
 274                 this, s,
 275                 (species, vector) -> vector.defaultReinterpret(species)
 276             );
 277         } else if (stype == double.class) {
 278             return VectorIntrinsics.reinterpret(
 279                 ByteMaxVector.class,
 280                 byte.class, LENGTH,
 281                 DoubleMaxVector.class,
 282                 double.class, DoubleMaxVector.LENGTH,
 283                 this, s,
 284                 (species, vector) -> vector.defaultReinterpret(species)
 285             );
 286         } else {
 287             throw new UnsupportedOperationException("Bad lane type for casting.");
 288         }
 289     }
 290 
 291     @Override
 292     @ForceInline
 293     public ByteVector reshape(VectorSpecies<Byte> s) {
 294         Objects.requireNonNull(s);
 295         if (s.bitSize() == 64 && (s.vectorType() == Byte64Vector.class)) {
 296             return VectorIntrinsics.reinterpret(
 297                 ByteMaxVector.class,
 298                 byte.class, LENGTH,
 299                 Byte64Vector.class,
 300                 byte.class, Byte64Vector.LENGTH,
 301                 this, s,
 302                 (species, vector) -> (ByteVector) vector.defaultReinterpret(species)
 303             );
 304         } else if (s.bitSize() == 128 && (s.vectorType() == Byte128Vector.class)) {
 305             return VectorIntrinsics.reinterpret(
 306                 ByteMaxVector.class,
 307                 byte.class, LENGTH,
 308                 Byte128Vector.class,
 309                 byte.class, Byte128Vector.LENGTH,
 310                 this, s,
 311                 (species, vector) -> (ByteVector) vector.defaultReinterpret(species)
 312             );
 313         } else if (s.bitSize() == 256 && (s.vectorType() == Byte256Vector.class)) {
 314             return VectorIntrinsics.reinterpret(
 315                 ByteMaxVector.class,
 316                 byte.class, LENGTH,
 317                 Byte256Vector.class,
 318                 byte.class, Byte256Vector.LENGTH,
 319                 this, s,
 320                 (species, vector) -> (ByteVector) vector.defaultReinterpret(species)
 321             );
 322         } else if (s.bitSize() == 512 && (s.vectorType() == Byte512Vector.class)) {
 323             return VectorIntrinsics.reinterpret(
 324                 ByteMaxVector.class,
 325                 byte.class, LENGTH,
 326                 Byte512Vector.class,
 327                 byte.class, Byte512Vector.LENGTH,
 328                 this, s,
 329                 (species, vector) -> (ByteVector) vector.defaultReinterpret(species)
 330             );
 331         } else if ((s.bitSize() > 0) && (s.bitSize() <= 2048)
 332                 && (s.bitSize() % 128 == 0) && (s.vectorType() == ByteMaxVector.class)) {
 333             return VectorIntrinsics.reinterpret(
 334                 ByteMaxVector.class,
 335                 byte.class, LENGTH,
 336                 ByteMaxVector.class,
 337                 byte.class, ByteMaxVector.LENGTH,
 338                 this, s,
 339                 (species, vector) -> (ByteVector) vector.defaultReinterpret(species)
 340             );
 341         } else {
 342             throw new InternalError("Unimplemented size");
 343         }
 344     }
 345 
 346     // Binary operations with scalars
 347 
 348     @Override
 349     @ForceInline
 350     public ByteVector add(byte o) {
 351         return add((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 352     }
 353 
 354     @Override
 355     @ForceInline
 356     public ByteVector add(byte o, VectorMask<Byte> m) {
 357         return add((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 358     }
 359 
 360     @Override
 361     @ForceInline
 362     public ByteVector sub(byte o) {
 363         return sub((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 364     }
 365 
 366     @Override
 367     @ForceInline
 368     public ByteVector sub(byte o, VectorMask<Byte> m) {
 369         return sub((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 370     }
 371 
 372     @Override
 373     @ForceInline
 374     public ByteVector mul(byte o) {
 375         return mul((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 376     }
 377 
 378     @Override
 379     @ForceInline
 380     public ByteVector mul(byte o, VectorMask<Byte> m) {
 381         return mul((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 382     }
 383 
 384     @Override
 385     @ForceInline
 386     public ByteVector min(byte o) {
 387         return min((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 388     }
 389 
 390     @Override
 391     @ForceInline
 392     public ByteVector max(byte o) {
 393         return max((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 394     }
 395 
 396     @Override
 397     @ForceInline
 398     public VectorMask<Byte> equal(byte o) {
 399         return equal((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 400     }
 401 
 402     @Override
 403     @ForceInline
 404     public VectorMask<Byte> notEqual(byte o) {
 405         return notEqual((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 406     }
 407 
 408     @Override
 409     @ForceInline
 410     public VectorMask<Byte> lessThan(byte o) {
 411         return lessThan((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 412     }
 413 
 414     @Override
 415     @ForceInline
 416     public VectorMask<Byte> lessThanEq(byte o) {
 417         return lessThanEq((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 418     }
 419 
 420     @Override
 421     @ForceInline
 422     public VectorMask<Byte> greaterThan(byte o) {
 423         return greaterThan((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 424     }
 425 
 426     @Override
 427     @ForceInline
 428     public VectorMask<Byte> greaterThanEq(byte o) {
 429         return greaterThanEq((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 430     }
 431 
 432     @Override
 433     @ForceInline
 434     public ByteVector blend(byte o, VectorMask<Byte> m) {
 435         return blend((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 436     }
 437 
 438 
 439     @Override
 440     @ForceInline
 441     public ByteVector and(byte o) {
 442         return and((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 443     }
 444 
 445     @Override
 446     @ForceInline
 447     public ByteVector and(byte o, VectorMask<Byte> m) {
 448         return and((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 449     }
 450 
 451     @Override
 452     @ForceInline
 453     public ByteVector or(byte o) {
 454         return or((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 455     }
 456 
 457     @Override
 458     @ForceInline
 459     public ByteVector or(byte o, VectorMask<Byte> m) {
 460         return or((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 461     }
 462 
 463     @Override
 464     @ForceInline
 465     public ByteVector xor(byte o) {
 466         return xor((ByteMaxVector)ByteVector.broadcast(SPECIES, o));
 467     }
 468 
 469     @Override
 470     @ForceInline
 471     public ByteVector xor(byte o, VectorMask<Byte> m) {
 472         return xor((ByteMaxVector)ByteVector.broadcast(SPECIES, o), m);
 473     }
 474 
 475     @Override
 476     @ForceInline
 477     public ByteMaxVector neg() {
 478         return (ByteMaxVector)zero(SPECIES).sub(this);
 479     }
 480 
 481     // Unary operations
 482 
 483     @ForceInline
 484     @Override
 485     public ByteMaxVector neg(VectorMask<Byte> m) {
 486         return blend(neg(), m);
 487     }
 488 
 489     @Override
 490     @ForceInline
 491     public ByteMaxVector abs() {
 492         return VectorIntrinsics.unaryOp(
 493             VECTOR_OP_ABS, ByteMaxVector.class, byte.class, LENGTH,
 494             this,
 495             v1 -> v1.uOp((i, a) -> (byte) Math.abs(a)));
 496     }
 497 
 498     @ForceInline
 499     @Override
 500     public ByteMaxVector abs(VectorMask<Byte> m) {
 501         return blend(abs(), m);
 502     }
 503 
 504 
 505     @Override
 506     @ForceInline
 507     public ByteMaxVector not() {
 508         return VectorIntrinsics.unaryOp(
 509             VECTOR_OP_NOT, ByteMaxVector.class, byte.class, LENGTH,
 510             this,
 511             v1 -> v1.uOp((i, a) -> (byte) ~a));
 512     }
 513 
 514     @ForceInline
 515     @Override
 516     public ByteMaxVector not(VectorMask<Byte> m) {
 517         return blend(not(), m);
 518     }
 519     // Binary operations
 520 
 521     @Override
 522     @ForceInline
 523     public ByteMaxVector add(Vector<Byte> o) {
 524         Objects.requireNonNull(o);
 525         ByteMaxVector v = (ByteMaxVector)o;
 526         return VectorIntrinsics.binaryOp(
 527             VECTOR_OP_ADD, ByteMaxVector.class, byte.class, LENGTH,
 528             this, v,
 529             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte)(a + b)));
 530     }
 531 
 532     @Override
 533     @ForceInline
 534     public ByteMaxVector add(Vector<Byte> v, VectorMask<Byte> m) {
 535         return blend(add(v), m);
 536     }
 537 
 538     @Override
 539     @ForceInline
 540     public ByteMaxVector sub(Vector<Byte> o) {
 541         Objects.requireNonNull(o);
 542         ByteMaxVector v = (ByteMaxVector)o;
 543         return VectorIntrinsics.binaryOp(
 544             VECTOR_OP_SUB, ByteMaxVector.class, byte.class, LENGTH,
 545             this, v,
 546             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte)(a - b)));
 547     }
 548 
 549     @Override
 550     @ForceInline
 551     public ByteMaxVector sub(Vector<Byte> v, VectorMask<Byte> m) {
 552         return blend(sub(v), m);
 553     }
 554 
 555     @Override
 556     @ForceInline
 557     public ByteMaxVector mul(Vector<Byte> o) {
 558         Objects.requireNonNull(o);
 559         ByteMaxVector v = (ByteMaxVector)o;
 560         return VectorIntrinsics.binaryOp(
 561             VECTOR_OP_MUL, ByteMaxVector.class, byte.class, LENGTH,
 562             this, v,
 563             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte)(a * b)));
 564     }
 565 
 566     @Override
 567     @ForceInline
 568     public ByteMaxVector mul(Vector<Byte> v, VectorMask<Byte> m) {
 569         return blend(mul(v), m);
 570     }
 571 
 572     @Override
 573     @ForceInline
 574     public ByteMaxVector min(Vector<Byte> o) {
 575         Objects.requireNonNull(o);
 576         ByteMaxVector v = (ByteMaxVector)o;
 577         return (ByteMaxVector) VectorIntrinsics.binaryOp(
 578             VECTOR_OP_MIN, ByteMaxVector.class, byte.class, LENGTH,
 579             this, v,
 580             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte) Math.min(a, b)));
 581     }
 582 
 583     @Override
 584     @ForceInline
 585     public ByteMaxVector min(Vector<Byte> v, VectorMask<Byte> m) {
 586         return blend(min(v), m);
 587     }
 588 
 589     @Override
 590     @ForceInline
 591     public ByteMaxVector max(Vector<Byte> o) {
 592         Objects.requireNonNull(o);
 593         ByteMaxVector v = (ByteMaxVector)o;
 594         return VectorIntrinsics.binaryOp(
 595             VECTOR_OP_MAX, ByteMaxVector.class, byte.class, LENGTH,
 596             this, v,
 597             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte) Math.max(a, b)));
 598         }
 599 
 600     @Override
 601     @ForceInline
 602     public ByteMaxVector max(Vector<Byte> v, VectorMask<Byte> m) {
 603         return blend(max(v), m);
 604     }
 605 
 606     @Override
 607     @ForceInline
 608     public ByteMaxVector and(Vector<Byte> o) {
 609         Objects.requireNonNull(o);
 610         ByteMaxVector v = (ByteMaxVector)o;
 611         return VectorIntrinsics.binaryOp(
 612             VECTOR_OP_AND, ByteMaxVector.class, byte.class, LENGTH,
 613             this, v,
 614             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte)(a & b)));
 615     }
 616 
 617     @Override
 618     @ForceInline
 619     public ByteMaxVector or(Vector<Byte> o) {
 620         Objects.requireNonNull(o);
 621         ByteMaxVector v = (ByteMaxVector)o;
 622         return VectorIntrinsics.binaryOp(
 623             VECTOR_OP_OR, ByteMaxVector.class, byte.class, LENGTH,
 624             this, v,
 625             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte)(a | b)));
 626     }
 627 
 628     @Override
 629     @ForceInline
 630     public ByteMaxVector xor(Vector<Byte> o) {
 631         Objects.requireNonNull(o);
 632         ByteMaxVector v = (ByteMaxVector)o;
 633         return VectorIntrinsics.binaryOp(
 634             VECTOR_OP_XOR, ByteMaxVector.class, byte.class, LENGTH,
 635             this, v,
 636             (v1, v2) -> v1.bOp(v2, (i, a, b) -> (byte)(a ^ b)));
 637     }
 638 
 639     @Override
 640     @ForceInline
 641     public ByteMaxVector and(Vector<Byte> v, VectorMask<Byte> m) {
 642         return blend(and(v), m);
 643     }
 644 
 645     @Override
 646     @ForceInline
 647     public ByteMaxVector or(Vector<Byte> v, VectorMask<Byte> m) {
 648         return blend(or(v), m);
 649     }
 650 
 651     @Override
 652     @ForceInline
 653     public ByteMaxVector xor(Vector<Byte> v, VectorMask<Byte> m) {
 654         return blend(xor(v), m);
 655     }
 656 
 657     @Override
 658     @ForceInline
 659     public ByteMaxVector shiftLeft(int s) {
 660         return VectorIntrinsics.broadcastInt(
 661             VECTOR_OP_LSHIFT, ByteMaxVector.class, byte.class, LENGTH,
 662             this, s,
 663             (v, i) -> v.uOp((__, a) -> (byte) (a << (i & 0x7))));
 664     }
 665 
 666     @Override
 667     @ForceInline
 668     public ByteMaxVector shiftLeft(int s, VectorMask<Byte> m) {
 669         return blend(shiftLeft(s), m);
 670     }
 671 
 672     @Override
 673     @ForceInline
 674     public ByteMaxVector shiftLeft(Vector<Byte> s) {
 675         ByteMaxVector shiftv = (ByteMaxVector)s;
 676         // As per shift specification for Java, mask the shift count.
 677         shiftv = shiftv.and(ByteVector.broadcast(SPECIES, (byte) 0x7));
 678         return this.bOp(shiftv, (i, a, b) -> (byte) (a << (b & 0x7)));
 679     }
 680 
 681     @Override
 682     @ForceInline
 683     public ByteMaxVector shiftRight(int s) {
 684         return VectorIntrinsics.broadcastInt(
 685             VECTOR_OP_URSHIFT, ByteMaxVector.class, byte.class, LENGTH,
 686             this, s,
 687             (v, i) -> v.uOp((__, a) -> (byte) ((a & 0xFF) >>> (i & 0x7))));
 688     }
 689 
 690     @Override
 691     @ForceInline
 692     public ByteMaxVector shiftRight(int s, VectorMask<Byte> m) {
 693         return blend(shiftRight(s), m);
 694     }
 695 
 696     @Override
 697     @ForceInline
 698     public ByteMaxVector shiftRight(Vector<Byte> s) {
 699         ByteMaxVector shiftv = (ByteMaxVector)s;
 700         // As per shift specification for Java, mask the shift count.
 701         shiftv = shiftv.and(ByteVector.broadcast(SPECIES, (byte) 0x7));
 702         return this.bOp(shiftv, (i, a, b) -> (byte) (a >>> (b & 0x7)));
 703     }
 704 
 705     @Override
 706     @ForceInline
 707     public ByteMaxVector shiftArithmeticRight(int s) {
 708         return VectorIntrinsics.broadcastInt(
 709             VECTOR_OP_RSHIFT, ByteMaxVector.class, byte.class, LENGTH,
 710             this, s,
 711             (v, i) -> v.uOp((__, a) -> (byte) (a >> (i & 0x7))));
 712     }
 713 
 714     @Override
 715     @ForceInline
 716     public ByteMaxVector shiftArithmeticRight(int s, VectorMask<Byte> m) {
 717         return blend(shiftArithmeticRight(s), m);
 718     }
 719 
 720     @Override
 721     @ForceInline
 722     public ByteMaxVector shiftArithmeticRight(Vector<Byte> s) {
 723         ByteMaxVector shiftv = (ByteMaxVector)s;
 724         // As per shift specification for Java, mask the shift count.
 725         shiftv = shiftv.and(ByteVector.broadcast(SPECIES, (byte) 0x7));
 726         return this.bOp(shiftv, (i, a, b) -> (byte) (a >> (b & 0x7)));
 727     }
 728 
 729     // Ternary operations
 730 
 731 
 732     // Type specific horizontal reductions
 733 
 734     @Override
 735     @ForceInline
 736     public byte addLanes() {
 737         return (byte) VectorIntrinsics.reductionCoerced(
 738             VECTOR_OP_ADD, ByteMaxVector.class, byte.class, LENGTH,
 739             this,
 740             v -> (long) v.rOp((byte) 0, (i, a, b) -> (byte) (a + b)));
 741     }
 742 
 743     @Override
 744     @ForceInline
 745     public byte andLanes() {
 746         return (byte) VectorIntrinsics.reductionCoerced(
 747             VECTOR_OP_AND, ByteMaxVector.class, byte.class, LENGTH,
 748             this,
 749             v -> (long) v.rOp((byte) -1, (i, a, b) -> (byte) (a & b)));
 750     }
 751 
 752     @Override
 753     @ForceInline
 754     public byte andLanes(VectorMask<Byte> m) {
 755         return ByteVector.broadcast(SPECIES, (byte) -1).blend(this, m).andLanes();
 756     }
 757 
 758     @Override
 759     @ForceInline
 760     public byte minLanes() {
 761         return (byte) VectorIntrinsics.reductionCoerced(
 762             VECTOR_OP_MIN, ByteMaxVector.class, byte.class, LENGTH,
 763             this,
 764             v -> (long) v.rOp(Byte.MAX_VALUE , (i, a, b) -> (byte) Math.min(a, b)));
 765     }
 766 
 767     @Override
 768     @ForceInline
 769     public byte maxLanes() {
 770         return (byte) VectorIntrinsics.reductionCoerced(
 771             VECTOR_OP_MAX, ByteMaxVector.class, byte.class, LENGTH,
 772             this,
 773             v -> (long) v.rOp(Byte.MIN_VALUE , (i, a, b) -> (byte) Math.max(a, b)));
 774     }
 775 
 776     @Override
 777     @ForceInline
 778     public byte mulLanes() {
 779         return (byte) VectorIntrinsics.reductionCoerced(
 780             VECTOR_OP_MUL, ByteMaxVector.class, byte.class, LENGTH,
 781             this,
 782             v -> (long) v.rOp((byte) 1, (i, a, b) -> (byte) (a * b)));
 783     }
 784 
 785     @Override
 786     @ForceInline
 787     public byte orLanes() {
 788         return (byte) VectorIntrinsics.reductionCoerced(
 789             VECTOR_OP_OR, ByteMaxVector.class, byte.class, LENGTH,
 790             this,
 791             v -> (long) v.rOp((byte) 0, (i, a, b) -> (byte) (a | b)));
 792     }
 793 
 794     @Override
 795     @ForceInline
 796     public byte orLanes(VectorMask<Byte> m) {
 797         return ByteVector.broadcast(SPECIES, (byte) 0).blend(this, m).orLanes();
 798     }
 799 
 800     @Override
 801     @ForceInline
 802     public byte xorLanes() {
 803         return (byte) VectorIntrinsics.reductionCoerced(
 804             VECTOR_OP_XOR, ByteMaxVector.class, byte.class, LENGTH,
 805             this,
 806             v -> (long) v.rOp((byte) 0, (i, a, b) -> (byte) (a ^ b)));
 807     }
 808 
 809     @Override
 810     @ForceInline
 811     public byte xorLanes(VectorMask<Byte> m) {
 812         return ByteVector.broadcast(SPECIES, (byte) 0).blend(this, m).xorLanes();
 813     }
 814 
 815 
 816     @Override
 817     @ForceInline
 818     public byte addLanes(VectorMask<Byte> m) {
 819         return ByteVector.broadcast(SPECIES, (byte) 0).blend(this, m).addLanes();
 820     }
 821 
 822 
 823     @Override
 824     @ForceInline
 825     public byte mulLanes(VectorMask<Byte> m) {
 826         return ByteVector.broadcast(SPECIES, (byte) 1).blend(this, m).mulLanes();
 827     }
 828 
 829     @Override
 830     @ForceInline
 831     public byte minLanes(VectorMask<Byte> m) {
 832         return ByteVector.broadcast(SPECIES, Byte.MAX_VALUE).blend(this, m).minLanes();
 833     }
 834 
 835     @Override
 836     @ForceInline
 837     public byte maxLanes(VectorMask<Byte> m) {
 838         return ByteVector.broadcast(SPECIES, Byte.MIN_VALUE).blend(this, m).maxLanes();
 839     }
 840 
 841     @Override
 842     @ForceInline
 843     public VectorShuffle<Byte> toShuffle() {
 844         byte[] a = toArray();
 845         int[] sa = new int[a.length];
 846         for (int i = 0; i < a.length; i++) {
 847             sa[i] = (int) a[i];
 848         }
 849         return VectorShuffle.fromArray(SPECIES, sa, 0);
 850     }
 851 
 852     // Memory operations
 853 
 854     private static final int ARRAY_SHIFT         = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BYTE_INDEX_SCALE);
 855     private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
 856 
 857     @Override
 858     @ForceInline
 859     public void intoArray(byte[] a, int ix) {
 860         Objects.requireNonNull(a);
 861         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
 862         VectorIntrinsics.store(ByteMaxVector.class, byte.class, LENGTH,
 863                                a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 864                                this,
 865                                a, ix,
 866                                (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
 867     }
 868 
 869     @Override
 870     @ForceInline
 871     public final void intoArray(byte[] a, int ax, VectorMask<Byte> m) {
 872         ByteVector oldVal = ByteVector.fromArray(SPECIES, a, ax);
 873         ByteVector newVal = oldVal.blend(this, m);
 874         newVal.intoArray(a, ax);
 875     }
 876 
 877     @Override
 878     @ForceInline
 879     public void intoByteArray(byte[] a, int ix) {
 880         Objects.requireNonNull(a);
 881         ix = VectorIntrinsics.checkIndex(ix, a.length, bitSize() / Byte.SIZE);
 882         VectorIntrinsics.store(ByteMaxVector.class, byte.class, LENGTH,
 883                                a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
 884                                this,
 885                                a, ix,
 886                                (c, idx, v) -> {
 887                                    ByteBuffer bbc = ByteBuffer.wrap(c, idx, c.length - idx).order(ByteOrder.nativeOrder());
 888                                    ByteBuffer tb = bbc;
 889                                    v.forEach((i, e) -> tb.put(e));
 890                                });
 891     }
 892 
 893     @Override
 894     @ForceInline
 895     public final void intoByteArray(byte[] a, int ix, VectorMask<Byte> m) {
 896         ByteMaxVector oldVal = (ByteMaxVector) ByteVector.fromByteArray(SPECIES, a, ix);
 897         ByteMaxVector newVal = oldVal.blend(this, m);
 898         newVal.intoByteArray(a, ix);
 899     }
 900 
 901     @Override
 902     @ForceInline
 903     public void intoByteBuffer(ByteBuffer bb, int ix) {
 904         if (bb.order() != ByteOrder.nativeOrder()) {
 905             throw new IllegalArgumentException();
 906         }
 907         if (bb.isReadOnly()) {
 908             throw new ReadOnlyBufferException();
 909         }
 910         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), bitSize() / Byte.SIZE);
 911         VectorIntrinsics.store(ByteMaxVector.class, byte.class, LENGTH,
 912                                U.getReference(bb, BYTE_BUFFER_HB), ix + U.getLong(bb, BUFFER_ADDRESS),
 913                                this,
 914                                bb, ix,
 915                                (c, idx, v) -> {
 916                                    ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
 917                                    ByteBuffer tb = bbc;
 918                                    v.forEach((i, e) -> tb.put(e));
 919                                });
 920     }
 921 
 922     @Override
 923     @ForceInline
 924     public void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<Byte> m) {
 925         ByteMaxVector oldVal = (ByteMaxVector) ByteVector.fromByteBuffer(SPECIES, bb, ix);
 926         ByteMaxVector newVal = oldVal.blend(this, m);
 927         newVal.intoByteBuffer(bb, ix);
 928     }
 929 
 930     //
 931 
 932     @Override
 933     public String toString() {
 934         return Arrays.toString(getElements());
 935     }
 936 
 937     @Override
 938     public boolean equals(Object o) {
 939         if (this == o) return true;
 940         if (o == null || this.getClass() != o.getClass()) return false;
 941 
 942         ByteMaxVector that = (ByteMaxVector) o;
 943         return this.equal(that).allTrue();
 944     }
 945 
 946     @Override
 947     public int hashCode() {
 948         return Arrays.hashCode(vec);
 949     }
 950 
 951     // Binary test
 952 
 953     @Override
 954     ByteMaxMask bTest(Vector<Byte> o, FBinTest f) {
 955         byte[] vec1 = getElements();
 956         byte[] vec2 = ((ByteMaxVector)o).getElements();
 957         boolean[] bits = new boolean[length()];
 958         for (int i = 0; i < length(); i++){
 959             bits[i] = f.apply(i, vec1[i], vec2[i]);
 960         }
 961         return new ByteMaxMask(bits);
 962     }
 963 
 964     // Comparisons
 965 
 966     @Override
 967     @ForceInline
 968     public ByteMaxMask equal(Vector<Byte> o) {
 969         Objects.requireNonNull(o);
 970         ByteMaxVector v = (ByteMaxVector)o;
 971 
 972         return VectorIntrinsics.compare(
 973             BT_eq, ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
 974             this, v,
 975             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
 976     }
 977 
 978     @Override
 979     @ForceInline
 980     public ByteMaxMask notEqual(Vector<Byte> o) {
 981         Objects.requireNonNull(o);
 982         ByteMaxVector v = (ByteMaxVector)o;
 983 
 984         return VectorIntrinsics.compare(
 985             BT_ne, ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
 986             this, v,
 987             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
 988     }
 989 
 990     @Override
 991     @ForceInline
 992     public ByteMaxMask lessThan(Vector<Byte> o) {
 993         Objects.requireNonNull(o);
 994         ByteMaxVector v = (ByteMaxVector)o;
 995 
 996         return VectorIntrinsics.compare(
 997             BT_lt, ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
 998             this, v,
 999             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
1000     }
1001 
1002     @Override
1003     @ForceInline
1004     public ByteMaxMask lessThanEq(Vector<Byte> o) {
1005         Objects.requireNonNull(o);
1006         ByteMaxVector v = (ByteMaxVector)o;
1007 
1008         return VectorIntrinsics.compare(
1009             BT_le, ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
1010             this, v,
1011             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
1012     }
1013 
1014     @Override
1015     @ForceInline
1016     public ByteMaxMask greaterThan(Vector<Byte> o) {
1017         Objects.requireNonNull(o);
1018         ByteMaxVector v = (ByteMaxVector)o;
1019 
1020         return (ByteMaxMask) VectorIntrinsics.compare(
1021             BT_gt, ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
1022             this, v,
1023             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
1024     }
1025 
1026     @Override
1027     @ForceInline
1028     public ByteMaxMask greaterThanEq(Vector<Byte> o) {
1029         Objects.requireNonNull(o);
1030         ByteMaxVector v = (ByteMaxVector)o;
1031 
1032         return VectorIntrinsics.compare(
1033             BT_ge, ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
1034             this, v,
1035             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
1036     }
1037 
1038     // Foreach
1039 
1040     @Override
1041     void forEach(FUnCon f) {
1042         byte[] vec = getElements();
1043         for (int i = 0; i < length(); i++) {
1044             f.apply(i, vec[i]);
1045         }
1046     }
1047 
1048     @Override
1049     void forEach(VectorMask<Byte> o, FUnCon f) {
1050         boolean[] mbits = ((ByteMaxMask)o).getBits();
1051         forEach((i, a) -> {
1052             if (mbits[i]) { f.apply(i, a); }
1053         });
1054     }
1055 
1056 
1057 
1058     @Override
1059     @ForceInline
1060     public ByteMaxVector rotateLanesLeft(int j) {
1061       int L = length();
1062       if (j < 0) {
1063          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1064       } else {
1065         j = j & (L-1);
1066         VectorShuffle<Byte> PermMask  = VectorShuffle.shuffleIota(SPECIES, L - j);
1067         return this.rearrange(PermMask);
1068       }
1069     }
1070 
1071     @Override
1072     @ForceInline
1073     public ByteMaxVector rotateLanesRight(int j) {
1074       int L = length();
1075       if (j < 0) {
1076          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1077       } else {
1078         j = j & (L-1);
1079         VectorShuffle<Byte> PermMask = VectorShuffle.shuffleIota(SPECIES, j);
1080         return this.rearrange(PermMask);
1081       }
1082     }
1083 
1084     @Override
1085     @ForceInline
1086     @SuppressWarnings("unchecked")
1087     public ByteMaxVector shiftLanesLeft(int j) {
1088        int L = length();
1089        if (j < 0) {
1090          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1091        } else if ( j >= L ) {
1092          return ZERO;
1093        } else {
1094          ByteMaxShuffle     Iota    = (ByteMaxShuffle)(VectorShuffle.shuffleIota(SPECIES, L-j));
1095          VectorMask<Byte> BlendMask = Iota.toVector().lessThan(ByteMaxVector.broadcast(SPECIES, (byte)(L-j)));
1096          Iota    = (ByteMaxShuffle)(VectorShuffle.shuffleIota(SPECIES, L -j));
1097          return ZERO.blend(this.rearrange(Iota),BlendMask);
1098        }
1099     }
1100 
1101     @Override
1102     @ForceInline
1103     @SuppressWarnings("unchecked")
1104     public ByteMaxVector shiftLanesRight(int j) {
1105        int L = length();
1106        if (j < 0) {
1107          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1108        } else if ( j >= L ) {
1109          return ZERO;
1110        } else {
1111          ByteMaxShuffle     Iota    = (ByteMaxShuffle)(VectorShuffle.shuffleIota(SPECIES, j));
1112          VectorMask<Byte> BlendMask = Iota.toVector().greaterThanEq(ByteMaxVector.broadcast(SPECIES, (byte)(j)));
1113          Iota    = (ByteMaxShuffle)(VectorShuffle.shuffleIota(SPECIES, j));
1114          return ZERO.blend(this.rearrange(Iota),BlendMask);
1115        }
1116     }
1117 
1118     @Override
1119     @ForceInline
1120     public ByteMaxVector rearrange(Vector<Byte> v,
1121                                   VectorShuffle<Byte> s, VectorMask<Byte> m) {
1122         return this.rearrange(s).blend(v.rearrange(s), m);
1123     }
1124 
1125     @Override
1126     @ForceInline
1127     public ByteMaxVector rearrange(VectorShuffle<Byte> o1) {
1128         Objects.requireNonNull(o1);
1129         ByteMaxShuffle s =  (ByteMaxShuffle)o1;
1130 
1131         return VectorIntrinsics.rearrangeOp(
1132             ByteMaxVector.class, ByteMaxShuffle.class, byte.class, LENGTH,
1133             this, s,
1134             (v1, s_) -> v1.uOp((i, a) -> {
1135                 int ei = s_.lane(i);
1136                 return v1.lane(ei);
1137             }));
1138     }
1139 
1140     @Override
1141     @ForceInline
1142     public ByteMaxVector blend(Vector<Byte> o1, VectorMask<Byte> o2) {
1143         Objects.requireNonNull(o1);
1144         Objects.requireNonNull(o2);
1145         ByteMaxVector v = (ByteMaxVector)o1;
1146         ByteMaxMask   m = (ByteMaxMask)o2;
1147 
1148         return VectorIntrinsics.blend(
1149             ByteMaxVector.class, ByteMaxMask.class, byte.class, LENGTH,
1150             this, v, m,
1151             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.lane(i) ? b : a));
1152     }
1153 
1154     // Accessors
1155 
1156     @Override
1157     public byte lane(int i) {
1158         if (i < 0 || i >= LENGTH) {
1159             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1160         }
1161         return (byte) VectorIntrinsics.extract(
1162                                 ByteMaxVector.class, byte.class, LENGTH,
1163                                 this, i,
1164                                 (vec, ix) -> {
1165                                     byte[] vecarr = vec.getElements();
1166                                     return (long)vecarr[ix];
1167                                 });
1168     }
1169 
1170     @Override
1171     public ByteMaxVector with(int i, byte e) {
1172         if (i < 0 || i >= LENGTH) {
1173             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1174         }
1175         return VectorIntrinsics.insert(
1176                                 ByteMaxVector.class, byte.class, LENGTH,
1177                                 this, i, (long)e,
1178                                 (v, ix, bits) -> {
1179                                     byte[] res = v.getElements().clone();
1180                                     res[ix] = (byte)bits;
1181                                     return new ByteMaxVector(res);
1182                                 });
1183     }
1184 
1185     // Mask
1186 
1187     static final class ByteMaxMask extends AbstractMask<Byte> {
1188         static final ByteMaxMask TRUE_MASK = new ByteMaxMask(true);
1189         static final ByteMaxMask FALSE_MASK = new ByteMaxMask(false);
1190 
1191         private final boolean[] bits; // Don't access directly, use getBits() instead.
1192 
1193         public ByteMaxMask(boolean[] bits) {
1194             this(bits, 0);
1195         }
1196 
1197         public ByteMaxMask(boolean[] bits, int offset) {
1198             boolean[] a = new boolean[species().length()];
1199             for (int i = 0; i < a.length; i++) {
1200                 a[i] = bits[offset + i];
1201             }
1202             this.bits = a;
1203         }
1204 
1205         public ByteMaxMask(boolean val) {
1206             boolean[] bits = new boolean[species().length()];
1207             Arrays.fill(bits, val);
1208             this.bits = bits;
1209         }
1210 
1211         boolean[] getBits() {
1212             return VectorIntrinsics.maybeRebox(this).bits;
1213         }
1214 
1215         @Override
1216         ByteMaxMask uOp(MUnOp f) {
1217             boolean[] res = new boolean[species().length()];
1218             boolean[] bits = getBits();
1219             for (int i = 0; i < species().length(); i++) {
1220                 res[i] = f.apply(i, bits[i]);
1221             }
1222             return new ByteMaxMask(res);
1223         }
1224 
1225         @Override
1226         ByteMaxMask bOp(VectorMask<Byte> o, MBinOp f) {
1227             boolean[] res = new boolean[species().length()];
1228             boolean[] bits = getBits();
1229             boolean[] mbits = ((ByteMaxMask)o).getBits();
1230             for (int i = 0; i < species().length(); i++) {
1231                 res[i] = f.apply(i, bits[i], mbits[i]);
1232             }
1233             return new ByteMaxMask(res);
1234         }
1235 
1236         @Override
1237         public VectorSpecies<Byte> species() {
1238             return SPECIES;
1239         }
1240 
1241         @Override
1242         public ByteMaxVector toVector() {
1243             byte[] res = new byte[species().length()];
1244             boolean[] bits = getBits();
1245             for (int i = 0; i < species().length(); i++) {
1246                 // -1 will result in the most significant bit being set in
1247                 // addition to some or all other bits
1248                 res[i] = (byte) (bits[i] ? -1 : 0);
1249             }
1250             return new ByteMaxVector(res);
1251         }
1252 
1253         @Override
1254         @ForceInline
1255         @SuppressWarnings("unchecked")
1256         public <E> VectorMask<E> cast(VectorSpecies<E> species) {
1257             if (length() != species.length())
1258                 throw new IllegalArgumentException("VectorMask length and species length differ");
1259             Class<?> stype = species.elementType();
1260             boolean [] maskArray = toArray();
1261             if (stype == byte.class) {
1262                 return (VectorMask <E>) new ByteMaxVector.ByteMaxMask(maskArray);
1263             } else if (stype == short.class) {
1264                 return (VectorMask <E>) new ShortMaxVector.ShortMaxMask(maskArray);
1265             } else if (stype == int.class) {
1266                 return (VectorMask <E>) new IntMaxVector.IntMaxMask(maskArray);
1267             } else if (stype == long.class) {
1268                 return (VectorMask <E>) new LongMaxVector.LongMaxMask(maskArray);
1269             } else if (stype == float.class) {
1270                 return (VectorMask <E>) new FloatMaxVector.FloatMaxMask(maskArray);
1271             } else if (stype == double.class) {
1272                 return (VectorMask <E>) new DoubleMaxVector.DoubleMaxMask(maskArray);
1273             } else {
1274                 throw new UnsupportedOperationException("Bad lane type for casting.");
1275             }
1276         }
1277 
1278         // Unary operations
1279 
1280         @Override
1281         @ForceInline
1282         public ByteMaxMask not() {
1283             return (ByteMaxMask) VectorIntrinsics.unaryOp(
1284                                              VECTOR_OP_NOT, ByteMaxMask.class, byte.class, LENGTH,
1285                                              this,
1286                                              (m1) -> m1.uOp((i, a) -> !a));
1287         }
1288 
1289         // Binary operations
1290 
1291         @Override
1292         @ForceInline
1293         public ByteMaxMask and(VectorMask<Byte> o) {
1294             Objects.requireNonNull(o);
1295             ByteMaxMask m = (ByteMaxMask)o;
1296             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, ByteMaxMask.class, byte.class, LENGTH,
1297                                              this, m,
1298                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
1299         }
1300 
1301         @Override
1302         @ForceInline
1303         public ByteMaxMask or(VectorMask<Byte> o) {
1304             Objects.requireNonNull(o);
1305             ByteMaxMask m = (ByteMaxMask)o;
1306             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, ByteMaxMask.class, byte.class, LENGTH,
1307                                              this, m,
1308                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
1309         }
1310 
1311         // Reductions
1312 
1313         @Override
1314         @ForceInline
1315         public boolean anyTrue() {
1316             return VectorIntrinsics.test(BT_ne, ByteMaxMask.class, byte.class, LENGTH,
1317                                          this, this,
1318                                          (m, __) -> anyTrueHelper(((ByteMaxMask)m).getBits()));
1319         }
1320 
1321         @Override
1322         @ForceInline
1323         public boolean allTrue() {
1324             return VectorIntrinsics.test(BT_overflow, ByteMaxMask.class, byte.class, LENGTH,
1325                                          this, VectorMask.maskAllTrue(species()),
1326                                          (m, __) -> allTrueHelper(((ByteMaxMask)m).getBits()));
1327         }
1328     }
1329 
1330     // Shuffle
1331 
1332     static final class ByteMaxShuffle extends AbstractShuffle<Byte> {
1333         ByteMaxShuffle(byte[] reorder) {
1334             super(reorder);
1335         }
1336 
1337         public ByteMaxShuffle(int[] reorder) {
1338             super(reorder);
1339         }
1340 
1341         public ByteMaxShuffle(int[] reorder, int i) {
1342             super(reorder, i);
1343         }
1344 
1345         public ByteMaxShuffle(IntUnaryOperator f) {
1346             super(f);
1347         }
1348 
1349         @Override
1350         public VectorSpecies<Byte> species() {
1351             return SPECIES;
1352         }
1353 
1354         private ByteVector toVector_helper() {
1355             byte[] va = new byte[SPECIES.length()];
1356             for (int i = 0; i < va.length; i++) {
1357               va[i] = (byte) lane(i);
1358             }
1359             return ByteVector.fromArray(SPECIES, va, 0);
1360         }
1361 
1362         @Override
1363         @ForceInline
1364         public ByteVector toVector() {
1365             return VectorIntrinsics.shuffleToVector(ByteMaxVector.class, byte.class, ByteMaxShuffle.class, this,
1366                                                     SPECIES.length(), 
1367                                                     (s) -> (((ByteMaxShuffle)(s)).toVector_helper()));
1368         }
1369 
1370         @Override
1371         @ForceInline
1372         @SuppressWarnings("unchecked")
1373         public <F> VectorShuffle<F> cast(VectorSpecies<F> species) {
1374             if (length() != species.length())
1375                 throw new IllegalArgumentException("Shuffle length and species length differ");
1376             Class<?> stype = species.elementType();
1377             int [] shuffleArray = toArray();
1378             if (stype == byte.class) {
1379                 return (VectorShuffle<F>) new ByteMaxVector.ByteMaxShuffle(shuffleArray);
1380             } else if (stype == short.class) {
1381                 return (VectorShuffle<F>) new ShortMaxVector.ShortMaxShuffle(shuffleArray);
1382             } else if (stype == int.class) {
1383                 return (VectorShuffle<F>) new IntMaxVector.IntMaxShuffle(shuffleArray);
1384             } else if (stype == long.class) {
1385                 return (VectorShuffle<F>) new LongMaxVector.LongMaxShuffle(shuffleArray);
1386             } else if (stype == float.class) {
1387                 return (VectorShuffle<F>) new FloatMaxVector.FloatMaxShuffle(shuffleArray);
1388             } else if (stype == double.class) {
1389                 return (VectorShuffle<F>) new DoubleMaxVector.DoubleMaxShuffle(shuffleArray);
1390             } else {
1391                 throw new UnsupportedOperationException("Bad lane type for casting.");
1392             }
1393         }
1394 
1395 
1396         @Override
1397         public ByteMaxShuffle rearrange(VectorShuffle<Byte> o) {
1398             ByteMaxShuffle s = (ByteMaxShuffle) o;
1399             byte[] r = new byte[reorder.length];
1400             for (int i = 0; i < reorder.length; i++) {
1401                 r[i] = reorder[s.reorder[i]];
1402             }
1403             return new ByteMaxShuffle(r);
1404         }
1405     }
1406 
1407     // VectorSpecies
1408 
1409     @Override
1410     public VectorSpecies<Byte> species() {
1411         return SPECIES;
1412     }
1413 }