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 #if[!byte]
  30 import java.nio.$Type$Buffer;
  31 #end[!byte]
  32 import java.nio.ReadOnlyBufferException;
  33 import java.util.Arrays;
  34 import java.util.Objects;
  35 import java.util.function.IntUnaryOperator;
  36 
  37 import jdk.internal.misc.Unsafe;
  38 import jdk.internal.vm.annotation.ForceInline;
  39 import static jdk.incubator.vector.VectorIntrinsics.*;
  40 
  41 @SuppressWarnings("cast")
  42 final class $vectortype$ extends $abstractvectortype$ {
  43     private static final VectorSpecies<$Boxtype$> SPECIES = $Type$Vector.SPECIES_$BITS$;
  44 
  45     static final $vectortype$ ZERO = new $vectortype$();
  46 
  47     static final int LENGTH = SPECIES.length();
  48 
  49 #if[!byteOrShort]
  50     // Index vector species
  51     private static final IntVector.IntSpecies INDEX_SPECIES;
  52 
  53     static {
  54 #if[longOrDouble64]
  55         INDEX_SPECIES = (IntVector.IntSpecies) IntVector.species(VectorShape.S_64_BIT);
  56 #else[longOrDouble64]
  57         int bitSize = Vector.bitSizeForVectorLength(int.class, LENGTH);
  58         INDEX_SPECIES = (IntVector.IntSpecies) IntVector.species(VectorShape.forBitSize(bitSize));
  59 #end[longOrDouble64]
  60     }
  61 
  62 #end[!byteOrShort]
  63     private final $type$[] vec; // Don't access directly, use getElements() instead.
  64 
  65     private $type$[] getElements() {
  66         return VectorIntrinsics.maybeRebox(this).vec;
  67     }
  68 
  69     $vectortype$() {
  70         vec = new $type$[SPECIES.length()];
  71     }
  72 
  73     $vectortype$($type$[] v) {
  74         vec = v;
  75     }
  76 
  77     @Override
  78     public int length() { return LENGTH; }
  79 
  80     // Unary operator
  81 
  82     @Override
  83     $vectortype$ uOp(FUnOp f) {
  84         $type$[] vec = getElements();
  85         $type$[] res = new $type$[length()];
  86         for (int i = 0; i < length(); i++) {
  87             res[i] = f.apply(i, vec[i]);
  88         }
  89         return new $vectortype$(res);
  90     }
  91 
  92     @Override
  93     $vectortype$ uOp(VectorMask<$Boxtype$> o, FUnOp f) {
  94         $type$[] vec = getElements();
  95         $type$[] res = new $type$[length()];
  96         boolean[] mbits = (($masktype$)o).getBits();
  97         for (int i = 0; i < length(); i++) {
  98             res[i] = mbits[i] ? f.apply(i, vec[i]) : vec[i];
  99         }
 100         return new $vectortype$(res);
 101     }
 102 
 103     // Binary operator
 104 
 105     @Override
 106     $vectortype$ bOp(Vector<$Boxtype$> o, FBinOp f) {
 107         $type$[] res = new $type$[length()];
 108         $type$[] vec1 = this.getElements();
 109         $type$[] vec2 = (($vectortype$)o).getElements();
 110         for (int i = 0; i < length(); i++) {
 111             res[i] = f.apply(i, vec1[i], vec2[i]);
 112         }
 113         return new $vectortype$(res);
 114     }
 115 
 116     @Override
 117     $vectortype$ bOp(Vector<$Boxtype$> o1, VectorMask<$Boxtype$> o2, FBinOp f) {
 118         $type$[] res = new $type$[length()];
 119         $type$[] vec1 = this.getElements();
 120         $type$[] vec2 = (($vectortype$)o1).getElements();
 121         boolean[] mbits = (($masktype$)o2).getBits();
 122         for (int i = 0; i < length(); i++) {
 123             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i]) : vec1[i];
 124         }
 125         return new $vectortype$(res);
 126     }
 127 
 128     // Trinary operator
 129 
 130     @Override
 131     $vectortype$ tOp(Vector<$Boxtype$> o1, Vector<$Boxtype$> o2, FTriOp f) {
 132         $type$[] res = new $type$[length()];
 133         $type$[] vec1 = this.getElements();
 134         $type$[] vec2 = (($vectortype$)o1).getElements();
 135         $type$[] vec3 = (($vectortype$)o2).getElements();
 136         for (int i = 0; i < length(); i++) {
 137             res[i] = f.apply(i, vec1[i], vec2[i], vec3[i]);
 138         }
 139         return new $vectortype$(res);
 140     }
 141 
 142     @Override
 143     $vectortype$ tOp(Vector<$Boxtype$> o1, Vector<$Boxtype$> o2, VectorMask<$Boxtype$> o3, FTriOp f) {
 144         $type$[] res = new $type$[length()];
 145         $type$[] vec1 = getElements();
 146         $type$[] vec2 = (($vectortype$)o1).getElements();
 147         $type$[] vec3 = (($vectortype$)o2).getElements();
 148         boolean[] mbits = (($masktype$)o3).getBits();
 149         for (int i = 0; i < length(); i++) {
 150             res[i] = mbits[i] ? f.apply(i, vec1[i], vec2[i], vec3[i]) : vec1[i];
 151         }
 152         return new $vectortype$(res);
 153     }
 154 
 155     @Override
 156     $type$ rOp($type$ v, FBinOp f) {
 157         $type$[] vec = getElements();
 158         for (int i = 0; i < length(); i++) {
 159             v = f.apply(i, v, vec[i]);
 160         }
 161         return v;
 162     }
 163 
 164     @Override
 165     @ForceInline
 166     public <F> Vector<F> cast(VectorSpecies<F> s) {
 167         Objects.requireNonNull(s);
 168         if (s.length() != LENGTH)
 169             throw new IllegalArgumentException("Vector length this species length differ");
 170 
 171         return VectorIntrinsics.cast(
 172             $vectortype$.class,
 173             $type$.class, LENGTH,
 174             s.vectorType(),
 175             s.elementType(), LENGTH,
 176             this, s,
 177             (species, vector) -> vector.castDefault(species)
 178         );
 179     }
 180 
 181     @SuppressWarnings("unchecked")
 182     @ForceInline
 183     private <F> Vector<F> castDefault(VectorSpecies<F> s) {
 184         int limit = s.length();
 185 
 186         Class<?> stype = s.elementType();
 187         if (stype == byte.class) {
 188             byte[] a = new byte[limit];
 189             for (int i = 0; i < limit; i++) {
 190                 a[i] = (byte) this.lane(i);
 191             }
 192             return (Vector) ByteVector.fromArray((VectorSpecies<Byte>) s, a, 0);
 193         } else if (stype == short.class) {
 194             short[] a = new short[limit];
 195             for (int i = 0; i < limit; i++) {
 196                 a[i] = (short) this.lane(i);
 197             }
 198             return (Vector) ShortVector.fromArray((VectorSpecies<Short>) s, a, 0);
 199         } else if (stype == int.class) {
 200             int[] a = new int[limit];
 201             for (int i = 0; i < limit; i++) {
 202                 a[i] = (int) this.lane(i);
 203             }
 204             return (Vector) IntVector.fromArray((VectorSpecies<Integer>) s, a, 0);
 205         } else if (stype == long.class) {
 206             long[] a = new long[limit];
 207             for (int i = 0; i < limit; i++) {
 208                 a[i] = (long) this.lane(i);
 209             }
 210             return (Vector) LongVector.fromArray((VectorSpecies<Long>) s, a, 0);
 211         } else if (stype == float.class) {
 212             float[] a = new float[limit];
 213             for (int i = 0; i < limit; i++) {
 214                 a[i] = (float) this.lane(i);
 215             }
 216             return (Vector) FloatVector.fromArray((VectorSpecies<Float>) s, a, 0);
 217         } else if (stype == double.class) {
 218             double[] a = new double[limit];
 219             for (int i = 0; i < limit; i++) {
 220                 a[i] = (double) this.lane(i);
 221             }
 222             return (Vector) DoubleVector.fromArray((VectorSpecies<Double>) s, a, 0);
 223         } else {
 224             throw new UnsupportedOperationException("Bad lane type for casting.");
 225         }
 226     }
 227 
 228     @Override
 229     @ForceInline
 230     @SuppressWarnings("unchecked")
 231     public <F> Vector<F> reinterpret(VectorSpecies<F> s) {
 232         Objects.requireNonNull(s);
 233 
 234         if(s.elementType().equals($type$.class)) {
 235             return (Vector<F>) reshape((VectorSpecies<$Boxtype$>)s);
 236         }
 237         if(s.bitSize() == bitSize()) {
 238             return reinterpretType(s);
 239         }
 240 
 241         return defaultReinterpret(s);
 242     }
 243 
 244     @ForceInline
 245     private <F> Vector<F> reinterpretType(VectorSpecies<F> s) {
 246         Objects.requireNonNull(s);
 247 
 248         Class<?> stype = s.elementType();
 249         if (stype == byte.class) {
 250             return VectorIntrinsics.reinterpret(
 251                 $vectortype$.class,
 252                 $type$.class, LENGTH,
 253                 Byte$bits$Vector.class,
 254                 byte.class, Byte$bits$Vector.LENGTH,
 255                 this, s,
 256                 (species, vector) -> vector.defaultReinterpret(species)
 257             );
 258         } else if (stype == short.class) {
 259             return VectorIntrinsics.reinterpret(
 260                 $vectortype$.class,
 261                 $type$.class, LENGTH,
 262                 Short$bits$Vector.class,
 263                 short.class, Short$bits$Vector.LENGTH,
 264                 this, s,
 265                 (species, vector) -> vector.defaultReinterpret(species)
 266             );
 267         } else if (stype == int.class) {
 268             return VectorIntrinsics.reinterpret(
 269                 $vectortype$.class,
 270                 $type$.class, LENGTH,
 271                 Int$bits$Vector.class,
 272                 int.class, Int$bits$Vector.LENGTH,
 273                 this, s,
 274                 (species, vector) -> vector.defaultReinterpret(species)
 275             );
 276         } else if (stype == long.class) {
 277             return VectorIntrinsics.reinterpret(
 278                 $vectortype$.class,
 279                 $type$.class, LENGTH,
 280                 Long$bits$Vector.class,
 281                 long.class, Long$bits$Vector.LENGTH,
 282                 this, s,
 283                 (species, vector) -> vector.defaultReinterpret(species)
 284             );
 285         } else if (stype == float.class) {
 286             return VectorIntrinsics.reinterpret(
 287                 $vectortype$.class,
 288                 $type$.class, LENGTH,
 289                 Float$bits$Vector.class,
 290                 float.class, Float$bits$Vector.LENGTH,
 291                 this, s,
 292                 (species, vector) -> vector.defaultReinterpret(species)
 293             );
 294         } else if (stype == double.class) {
 295             return VectorIntrinsics.reinterpret(
 296                 $vectortype$.class,
 297                 $type$.class, LENGTH,
 298                 Double$bits$Vector.class,
 299                 double.class, Double$bits$Vector.LENGTH,
 300                 this, s,
 301                 (species, vector) -> vector.defaultReinterpret(species)
 302             );
 303         } else {
 304             throw new UnsupportedOperationException("Bad lane type for casting.");
 305         }
 306     }
 307 
 308     @Override
 309     @ForceInline
 310     public $abstractvectortype$ reshape(VectorSpecies<$Boxtype$> s) {
 311         Objects.requireNonNull(s);
 312         if (s.bitSize() == 64 && (s.vectorType() == $Type$64Vector.class)) {
 313             return VectorIntrinsics.reinterpret(
 314                 $vectortype$.class,
 315                 $type$.class, LENGTH,
 316                 $Type$64Vector.class,
 317                 $type$.class, $Type$64Vector.LENGTH,
 318                 this, s,
 319                 (species, vector) -> ($abstractvectortype$) vector.defaultReinterpret(species)
 320             );
 321         } else if (s.bitSize() == 128 && (s.vectorType() == $Type$128Vector.class)) {
 322             return VectorIntrinsics.reinterpret(
 323                 $vectortype$.class,
 324                 $type$.class, LENGTH,
 325                 $Type$128Vector.class,
 326                 $type$.class, $Type$128Vector.LENGTH,
 327                 this, s,
 328                 (species, vector) -> ($abstractvectortype$) vector.defaultReinterpret(species)
 329             );
 330         } else if (s.bitSize() == 256 && (s.vectorType() == $Type$256Vector.class)) {
 331             return VectorIntrinsics.reinterpret(
 332                 $vectortype$.class,
 333                 $type$.class, LENGTH,
 334                 $Type$256Vector.class,
 335                 $type$.class, $Type$256Vector.LENGTH,
 336                 this, s,
 337                 (species, vector) -> ($abstractvectortype$) vector.defaultReinterpret(species)
 338             );
 339         } else if (s.bitSize() == 512 && (s.vectorType() == $Type$512Vector.class)) {
 340             return VectorIntrinsics.reinterpret(
 341                 $vectortype$.class,
 342                 $type$.class, LENGTH,
 343                 $Type$512Vector.class,
 344                 $type$.class, $Type$512Vector.LENGTH,
 345                 this, s,
 346                 (species, vector) -> ($abstractvectortype$) vector.defaultReinterpret(species)
 347             );
 348         } else if ((s.bitSize() > 0) && (s.bitSize() <= 2048)
 349                 && (s.bitSize() % 128 == 0) && (s.vectorType() == $Type$MaxVector.class)) {
 350             return VectorIntrinsics.reinterpret(
 351                 $vectortype$.class,
 352                 $type$.class, LENGTH,
 353                 $Type$MaxVector.class,
 354                 $type$.class, $Type$MaxVector.LENGTH,
 355                 this, s,
 356                 (species, vector) -> ($abstractvectortype$) vector.defaultReinterpret(species)
 357             );
 358         } else {
 359             throw new InternalError("Unimplemented size");
 360         }
 361     }
 362 
 363     // Binary operations with scalars
 364 
 365     @Override
 366     @ForceInline
 367     public $abstractvectortype$ add($type$ o) {
 368         return add(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 369     }
 370 
 371     @Override
 372     @ForceInline
 373     public $abstractvectortype$ add($type$ o, VectorMask<$Boxtype$> m) {
 374         return add(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 375     }
 376 
 377     @Override
 378     @ForceInline
 379     public $abstractvectortype$ sub($type$ o) {
 380         return sub(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 381     }
 382 
 383     @Override
 384     @ForceInline
 385     public $abstractvectortype$ sub($type$ o, VectorMask<$Boxtype$> m) {
 386         return sub(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 387     }
 388 
 389     @Override
 390     @ForceInline
 391     public $abstractvectortype$ mul($type$ o) {
 392         return mul(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 393     }
 394 
 395     @Override
 396     @ForceInline
 397     public $abstractvectortype$ mul($type$ o, VectorMask<$Boxtype$> m) {
 398         return mul(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 399     }
 400 
 401     @Override
 402     @ForceInline
 403     public $abstractvectortype$ min($type$ o) {
 404         return min(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 405     }
 406 
 407     @Override
 408     @ForceInline
 409     public $abstractvectortype$ max($type$ o) {
 410         return max(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 411     }
 412 
 413     @Override
 414     @ForceInline
 415     public VectorMask<$Boxtype$> equal($type$ o) {
 416         return equal(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 417     }
 418 
 419     @Override
 420     @ForceInline
 421     public VectorMask<$Boxtype$> notEqual($type$ o) {
 422         return notEqual(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 423     }
 424 
 425     @Override
 426     @ForceInline
 427     public VectorMask<$Boxtype$> lessThan($type$ o) {
 428         return lessThan(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 429     }
 430 
 431     @Override
 432     @ForceInline
 433     public VectorMask<$Boxtype$> lessThanEq($type$ o) {
 434         return lessThanEq(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 435     }
 436 
 437     @Override
 438     @ForceInline
 439     public VectorMask<$Boxtype$> greaterThan($type$ o) {
 440         return greaterThan(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 441     }
 442 
 443     @Override
 444     @ForceInline
 445     public VectorMask<$Boxtype$> greaterThanEq($type$ o) {
 446         return greaterThanEq(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 447     }
 448 
 449     @Override
 450     @ForceInline
 451     public $abstractvectortype$ blend($type$ o, VectorMask<$Boxtype$> m) {
 452         return blend(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 453     }
 454 
 455 #if[FP]
 456     @Override
 457     @ForceInline
 458     public $abstractvectortype$ div($type$ o) {
 459         return div(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 460     }
 461 
 462     @Override
 463     @ForceInline
 464     public $abstractvectortype$ div($type$ o, VectorMask<$Boxtype$> m) {
 465         return div(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 466     }
 467 
 468     @Override
 469     @ForceInline
 470     public $vectortype$ div(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 471         return blend(div(v), m);
 472     }
 473 
 474     @Override
 475     @ForceInline
 476     public $abstractvectortype$ atan2($type$ o) {
 477         return atan2(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 478     }
 479 
 480     @Override
 481     @ForceInline
 482     public $abstractvectortype$ atan2($type$ o, VectorMask<$Boxtype$> m) {
 483         return atan2(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 484     }
 485 
 486     @Override
 487     @ForceInline
 488     public $abstractvectortype$ pow($type$ o) {
 489         return pow(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 490     }
 491 
 492     @Override
 493     @ForceInline
 494     public $abstractvectortype$ pow($type$ o, VectorMask<$Boxtype$> m) {
 495         return pow(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 496     }
 497 
 498     @Override
 499     @ForceInline
 500     public $abstractvectortype$ fma($type$ o1, $type$ o2) {
 501         return fma(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o1), ($vectortype$)$abstractvectortype$.broadcast(SPECIES, o2));
 502     }
 503 
 504     @Override
 505     @ForceInline
 506     public $abstractvectortype$ fma($type$ o1, $type$ o2, VectorMask<$Boxtype$> m) {
 507         return fma(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o1), ($vectortype$)$abstractvectortype$.broadcast(SPECIES, o2), m);
 508     }
 509 
 510     @Override
 511     @ForceInline
 512     public $abstractvectortype$ hypot($type$ o) {
 513         return hypot(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 514     }
 515 
 516     @Override
 517     @ForceInline
 518     public $abstractvectortype$ hypot($type$ o, VectorMask<$Boxtype$> m) {
 519         return hypot(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 520     }
 521 #end[FP]
 522 
 523 #if[BITWISE]
 524     @Override
 525     @ForceInline
 526     public $abstractvectortype$ and($type$ o) {
 527         return and(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 528     }
 529 
 530     @Override
 531     @ForceInline
 532     public $abstractvectortype$ and($type$ o, VectorMask<$Boxtype$> m) {
 533         return and(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 534     }
 535 
 536     @Override
 537     @ForceInline
 538     public $abstractvectortype$ or($type$ o) {
 539         return or(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 540     }
 541 
 542     @Override
 543     @ForceInline
 544     public $abstractvectortype$ or($type$ o, VectorMask<$Boxtype$> m) {
 545         return or(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 546     }
 547 
 548     @Override
 549     @ForceInline
 550     public $abstractvectortype$ xor($type$ o) {
 551         return xor(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o));
 552     }
 553 
 554     @Override
 555     @ForceInline
 556     public $abstractvectortype$ xor($type$ o, VectorMask<$Boxtype$> m) {
 557         return xor(($vectortype$)$abstractvectortype$.broadcast(SPECIES, o), m);
 558     }
 559 
 560     @Override
 561     @ForceInline
 562     public $vectortype$ neg() {
 563         return ($vectortype$)zero(SPECIES).sub(this);
 564     }
 565 #end[BITWISE]
 566 
 567     // Unary operations
 568 
 569     @ForceInline
 570     @Override
 571     public $vectortype$ neg(VectorMask<$Boxtype$> m) {
 572         return blend(neg(), m);
 573     }
 574 
 575     @Override
 576     @ForceInline
 577     public $vectortype$ abs() {
 578         return VectorIntrinsics.unaryOp(
 579             VECTOR_OP_ABS, $vectortype$.class, $type$.class, LENGTH,
 580             this,
 581             v1 -> v1.uOp((i, a) -> ($type$) Math.abs(a)));
 582     }
 583 
 584     @ForceInline
 585     @Override
 586     public $vectortype$ abs(VectorMask<$Boxtype$> m) {
 587         return blend(abs(), m);
 588     }
 589 
 590 #if[FP]
 591     @Override
 592     @ForceInline
 593     public $vectortype$ neg() {
 594         return VectorIntrinsics.unaryOp(
 595             VECTOR_OP_NEG, $vectortype$.class, $type$.class, LENGTH,
 596             this,
 597             v1 -> v1.uOp((i, a) -> ($type$) -a));
 598     }
 599 
 600     @Override
 601     @ForceInline
 602     public $vectortype$ div(Vector<$Boxtype$> o) {
 603         Objects.requireNonNull(o);
 604         $vectortype$ v = ($vectortype$)o;
 605         return VectorIntrinsics.binaryOp(
 606             VECTOR_OP_DIV, $vectortype$.class, $type$.class, LENGTH,
 607             this, v,
 608             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a / b)));
 609     }
 610 
 611     @Override
 612     @ForceInline
 613     public $vectortype$ sqrt() {
 614         return VectorIntrinsics.unaryOp(
 615             VECTOR_OP_SQRT, $vectortype$.class, $type$.class, LENGTH,
 616             this,
 617             v1 -> v1.uOp((i, a) -> ($type$) Math.sqrt((double) a)));
 618     }
 619 
 620     @Override
 621     @ForceInline
 622     public $vectortype$ exp() {
 623         return ($vectortype$) VectorIntrinsics.unaryOp(
 624             VECTOR_OP_EXP, $vectortype$.class, $type$.class, LENGTH,
 625             this,
 626             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.exp((double) a)));
 627     }
 628 
 629     @Override
 630     @ForceInline
 631     public $vectortype$ log1p() {
 632         return ($vectortype$) VectorIntrinsics.unaryOp(
 633             VECTOR_OP_LOG1P, $vectortype$.class, $type$.class, LENGTH,
 634             this,
 635             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.log1p((double) a)));
 636     }
 637 
 638     @Override
 639     @ForceInline
 640     public $vectortype$ log() {
 641         return ($vectortype$) VectorIntrinsics.unaryOp(
 642             VECTOR_OP_LOG, $vectortype$.class, $type$.class, LENGTH,
 643             this,
 644             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.log((double) a)));
 645     }
 646 
 647     @Override
 648     @ForceInline
 649     public $vectortype$ log10() {
 650         return ($vectortype$) VectorIntrinsics.unaryOp(
 651             VECTOR_OP_LOG10, $vectortype$.class, $type$.class, LENGTH,
 652             this,
 653             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.log10((double) a)));
 654     }
 655 
 656     @Override
 657     @ForceInline
 658     public $vectortype$ expm1() {
 659         return ($vectortype$) VectorIntrinsics.unaryOp(
 660             VECTOR_OP_EXPM1, $vectortype$.class, $type$.class, LENGTH,
 661             this,
 662             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.expm1((double) a)));
 663     }
 664 
 665     @Override
 666     @ForceInline
 667     public $vectortype$ cbrt() {
 668         return ($vectortype$) VectorIntrinsics.unaryOp(
 669             VECTOR_OP_CBRT, $vectortype$.class, $type$.class, LENGTH,
 670             this,
 671             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.cbrt((double) a)));
 672     }
 673 
 674     @Override
 675     @ForceInline
 676     public $vectortype$ sin() {
 677         return ($vectortype$) VectorIntrinsics.unaryOp(
 678             VECTOR_OP_SIN, $vectortype$.class, $type$.class, LENGTH,
 679             this,
 680             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.sin((double) a)));
 681     }
 682 
 683     @Override
 684     @ForceInline
 685     public $vectortype$ cos() {
 686         return ($vectortype$) VectorIntrinsics.unaryOp(
 687             VECTOR_OP_COS, $vectortype$.class, $type$.class, LENGTH,
 688             this,
 689             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.cos((double) a)));
 690     }
 691 
 692     @Override
 693     @ForceInline
 694     public $vectortype$ tan() {
 695         return ($vectortype$) VectorIntrinsics.unaryOp(
 696             VECTOR_OP_TAN, $vectortype$.class, $type$.class, LENGTH,
 697             this,
 698             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.tan((double) a)));
 699     }
 700 
 701     @Override
 702     @ForceInline
 703     public $vectortype$ asin() {
 704         return ($vectortype$) VectorIntrinsics.unaryOp(
 705             VECTOR_OP_ASIN, $vectortype$.class, $type$.class, LENGTH,
 706             this,
 707             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.asin((double) a)));
 708     }
 709 
 710     @Override
 711     @ForceInline
 712     public $vectortype$ acos() {
 713         return ($vectortype$) VectorIntrinsics.unaryOp(
 714             VECTOR_OP_ACOS, $vectortype$.class, $type$.class, LENGTH,
 715             this,
 716             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.acos((double) a)));
 717     }
 718 
 719     @Override
 720     @ForceInline
 721     public $vectortype$ atan() {
 722         return ($vectortype$) VectorIntrinsics.unaryOp(
 723             VECTOR_OP_ATAN, $vectortype$.class, $type$.class, LENGTH,
 724             this,
 725             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.atan((double) a)));
 726     }
 727 
 728     @Override
 729     @ForceInline
 730     public $vectortype$ sinh() {
 731         return ($vectortype$) VectorIntrinsics.unaryOp(
 732             VECTOR_OP_SINH, $vectortype$.class, $type$.class, LENGTH,
 733             this,
 734             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.sinh((double) a)));
 735     }
 736 
 737     @Override
 738     @ForceInline
 739     public $vectortype$ cosh() {
 740         return ($vectortype$) VectorIntrinsics.unaryOp(
 741             VECTOR_OP_COSH, $vectortype$.class, $type$.class, LENGTH,
 742             this,
 743             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.cosh((double) a)));
 744     }
 745 
 746     @Override
 747     @ForceInline
 748     public $vectortype$ tanh() {
 749         return ($vectortype$) VectorIntrinsics.unaryOp(
 750             VECTOR_OP_TANH, $vectortype$.class, $type$.class, LENGTH,
 751             this,
 752             v1 -> (($vectortype$)v1).uOp((i, a) -> ($type$) Math.tanh((double) a)));
 753     }
 754 
 755     @Override
 756     @ForceInline
 757     public $vectortype$ pow(Vector<$Boxtype$> o) {
 758         Objects.requireNonNull(o);
 759         $vectortype$ v = ($vectortype$)o;
 760         return ($vectortype$) VectorIntrinsics.binaryOp(
 761             VECTOR_OP_POW, $vectortype$.class, $type$.class, LENGTH,
 762             this, v,
 763             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(Math.pow(a,b))));
 764     }
 765 
 766     @Override
 767     @ForceInline
 768     public $vectortype$ hypot(Vector<$Boxtype$> o) {
 769         Objects.requireNonNull(o);
 770         $vectortype$ v = ($vectortype$)o;
 771         return ($vectortype$) VectorIntrinsics.binaryOp(
 772             VECTOR_OP_HYPOT, $vectortype$.class, $type$.class, LENGTH,
 773             this, v,
 774             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(Math.hypot(a,b))));
 775     }
 776 
 777     @Override
 778     @ForceInline
 779     public $vectortype$ atan2(Vector<$Boxtype$> o) {
 780         Objects.requireNonNull(o);
 781         $vectortype$ v = ($vectortype$)o;
 782         return ($vectortype$) VectorIntrinsics.binaryOp(
 783             VECTOR_OP_ATAN2, $vectortype$.class, $type$.class, LENGTH,
 784             this, v,
 785             (v1, v2) -> (($vectortype$)v1).bOp(v2, (i, a, b) -> ($type$)(Math.atan2(a,b))));
 786     }
 787 
 788 #end[FP]
 789 
 790 #if[BITWISE]
 791     @Override
 792     @ForceInline
 793     public $vectortype$ not() {
 794         return VectorIntrinsics.unaryOp(
 795             VECTOR_OP_NOT, $vectortype$.class, $type$.class, LENGTH,
 796             this,
 797             v1 -> v1.uOp((i, a) -> ($type$) ~a));
 798     }
 799 
 800     @ForceInline
 801     @Override
 802     public $vectortype$ not(VectorMask<$Boxtype$> m) {
 803         return blend(not(), m);
 804     }
 805 #end[BITWISE]
 806     // Binary operations
 807 
 808     @Override
 809     @ForceInline
 810     public $vectortype$ add(Vector<$Boxtype$> o) {
 811         Objects.requireNonNull(o);
 812         $vectortype$ v = ($vectortype$)o;
 813         return VectorIntrinsics.binaryOp(
 814             VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH,
 815             this, v,
 816             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a + b)));
 817     }
 818 
 819     @Override
 820     @ForceInline
 821     public $vectortype$ add(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 822         return blend(add(v), m);
 823     }
 824 
 825     @Override
 826     @ForceInline
 827     public $vectortype$ sub(Vector<$Boxtype$> o) {
 828         Objects.requireNonNull(o);
 829         $vectortype$ v = ($vectortype$)o;
 830         return VectorIntrinsics.binaryOp(
 831             VECTOR_OP_SUB, $vectortype$.class, $type$.class, LENGTH,
 832             this, v,
 833             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a - b)));
 834     }
 835 
 836     @Override
 837     @ForceInline
 838     public $vectortype$ sub(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 839         return blend(sub(v), m);
 840     }
 841 
 842     @Override
 843     @ForceInline
 844     public $vectortype$ mul(Vector<$Boxtype$> o) {
 845         Objects.requireNonNull(o);
 846         $vectortype$ v = ($vectortype$)o;
 847         return VectorIntrinsics.binaryOp(
 848             VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH,
 849             this, v,
 850             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a * b)));
 851     }
 852 
 853     @Override
 854     @ForceInline
 855     public $vectortype$ mul(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 856         return blend(mul(v), m);
 857     }
 858 
 859     @Override
 860     @ForceInline
 861     public $vectortype$ min(Vector<$Boxtype$> o) {
 862         Objects.requireNonNull(o);
 863         $vectortype$ v = ($vectortype$)o;
 864         return ($vectortype$) VectorIntrinsics.binaryOp(
 865             VECTOR_OP_MIN, $vectortype$.class, $type$.class, LENGTH,
 866             this, v,
 867             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$) Math.min(a, b)));
 868     }
 869 
 870     @Override
 871     @ForceInline
 872     public $vectortype$ min(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 873         return blend(min(v), m);
 874     }
 875 
 876     @Override
 877     @ForceInline
 878     public $vectortype$ max(Vector<$Boxtype$> o) {
 879         Objects.requireNonNull(o);
 880         $vectortype$ v = ($vectortype$)o;
 881         return VectorIntrinsics.binaryOp(
 882             VECTOR_OP_MAX, $vectortype$.class, $type$.class, LENGTH,
 883             this, v,
 884             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$) Math.max(a, b)));
 885         }
 886 
 887     @Override
 888     @ForceInline
 889     public $vectortype$ max(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 890         return blend(max(v), m);
 891     }
 892 
 893 #if[BITWISE]
 894     @Override
 895     @ForceInline
 896     public $vectortype$ and(Vector<$Boxtype$> o) {
 897         Objects.requireNonNull(o);
 898         $vectortype$ v = ($vectortype$)o;
 899         return VectorIntrinsics.binaryOp(
 900             VECTOR_OP_AND, $vectortype$.class, $type$.class, LENGTH,
 901             this, v,
 902             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a & b)));
 903     }
 904 
 905     @Override
 906     @ForceInline
 907     public $vectortype$ or(Vector<$Boxtype$> o) {
 908         Objects.requireNonNull(o);
 909         $vectortype$ v = ($vectortype$)o;
 910         return VectorIntrinsics.binaryOp(
 911             VECTOR_OP_OR, $vectortype$.class, $type$.class, LENGTH,
 912             this, v,
 913             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a | b)));
 914     }
 915 
 916     @Override
 917     @ForceInline
 918     public $vectortype$ xor(Vector<$Boxtype$> o) {
 919         Objects.requireNonNull(o);
 920         $vectortype$ v = ($vectortype$)o;
 921         return VectorIntrinsics.binaryOp(
 922             VECTOR_OP_XOR, $vectortype$.class, $type$.class, LENGTH,
 923             this, v,
 924             (v1, v2) -> v1.bOp(v2, (i, a, b) -> ($type$)(a ^ b)));
 925     }
 926 
 927     @Override
 928     @ForceInline
 929     public $vectortype$ and(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 930         return blend(and(v), m);
 931     }
 932 
 933     @Override
 934     @ForceInline
 935     public $vectortype$ or(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 936         return blend(or(v), m);
 937     }
 938 
 939     @Override
 940     @ForceInline
 941     public $vectortype$ xor(Vector<$Boxtype$> v, VectorMask<$Boxtype$> m) {
 942         return blend(xor(v), m);
 943     }
 944 #end[BITWISE]
 945 
 946 #if[byte]
 947     @Override
 948     @ForceInline
 949     public $vectortype$ shiftLeft(int s) {
 950         return VectorIntrinsics.broadcastInt(
 951             VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH,
 952             this, s,
 953             (v, i) -> v.uOp((__, a) -> ($type$) (a << (i & 0x7))));
 954     }
 955 
 956     @Override
 957     @ForceInline
 958     public $vectortype$ shiftLeft(int s, VectorMask<$Boxtype$> m) {
 959         return blend(shiftLeft(s), m);
 960     }
 961 
 962     @Override
 963     @ForceInline
 964     public $vectortype$ shiftLeft(Vector<$Boxtype$> s) {
 965         $vectortype$ shiftv = ($vectortype$)s;
 966         // As per shift specification for Java, mask the shift count.
 967         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, ($type$) 0x7));
 968         return this.bOp(shiftv, (i, a, b) -> ($type$) (a << (b & 0x7)));
 969     }
 970 
 971     @Override
 972     @ForceInline
 973     public $vectortype$ shiftRight(int s) {
 974         return VectorIntrinsics.broadcastInt(
 975             VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH,
 976             this, s,
 977             (v, i) -> v.uOp((__, a) -> ($type$) ((a & 0xFF) >>> (i & 0x7))));
 978     }
 979 
 980     @Override
 981     @ForceInline
 982     public $vectortype$ shiftRight(int s, VectorMask<$Boxtype$> m) {
 983         return blend(shiftRight(s), m);
 984     }
 985 
 986     @Override
 987     @ForceInline
 988     public $vectortype$ shiftRight(Vector<$Boxtype$> s) {
 989         $vectortype$ shiftv = ($vectortype$)s;
 990         // As per shift specification for Java, mask the shift count.
 991         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, ($type$) 0x7));
 992         return this.bOp(shiftv, (i, a, b) -> ($type$) (a >>> (b & 0x7)));
 993     }
 994 
 995     @Override
 996     @ForceInline
 997     public $vectortype$ shiftArithmeticRight(int s) {
 998         return VectorIntrinsics.broadcastInt(
 999             VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH,
1000             this, s,
1001             (v, i) -> v.uOp((__, a) -> ($type$) (a >> (i & 0x7))));
1002     }
1003 
1004     @Override
1005     @ForceInline
1006     public $vectortype$ shiftArithmeticRight(int s, VectorMask<$Boxtype$> m) {
1007         return blend(shiftArithmeticRight(s), m);
1008     }
1009 
1010     @Override
1011     @ForceInline
1012     public $vectortype$ shiftArithmeticRight(Vector<$Boxtype$> s) {
1013         $vectortype$ shiftv = ($vectortype$)s;
1014         // As per shift specification for Java, mask the shift count.
1015         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, ($type$) 0x7));
1016         return this.bOp(shiftv, (i, a, b) -> ($type$) (a >> (b & 0x7)));
1017     }
1018 
1019 #end[byte]
1020 #if[short]
1021     @Override
1022     @ForceInline
1023     public $vectortype$ shiftLeft(int s) {
1024         return VectorIntrinsics.broadcastInt(
1025             VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH,
1026             this, s,
1027             (v, i) -> v.uOp((__, a) -> ($type$) (a << (i & 0xF))));
1028     }
1029 
1030     @Override
1031     @ForceInline
1032     public $vectortype$ shiftLeft(int s, VectorMask<$Boxtype$> m) {
1033         return blend(shiftLeft(s), m);
1034     }
1035 
1036     @Override
1037     @ForceInline
1038     public $vectortype$ shiftLeft(Vector<$Boxtype$> s) {
1039         $vectortype$ shiftv = ($vectortype$)s;
1040         // As per shift specification for Java, mask the shift count.
1041         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, ($type$) 0xF));
1042         return this.bOp(shiftv, (i, a, b) -> ($type$) (a << (b & 0xF)));
1043     }
1044 
1045     @Override
1046     @ForceInline
1047     public $vectortype$ shiftRight(int s) {
1048         return VectorIntrinsics.broadcastInt(
1049             VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH,
1050             this, s,
1051             (v, i) -> v.uOp((__, a) -> ($type$) ((a & 0xFFFF) >>> (i & 0xF))));
1052     }
1053 
1054     @Override
1055     @ForceInline
1056     public $vectortype$ shiftRight(int s, VectorMask<$Boxtype$> m) {
1057         return blend(shiftRight(s), m);
1058     }
1059 
1060     @Override
1061     @ForceInline
1062     public $vectortype$ shiftRight(Vector<$Boxtype$> s) {
1063         $vectortype$ shiftv = ($vectortype$)s;
1064         // As per shift specification for Java, mask the shift count.
1065         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, ($type$) 0xF));
1066         return this.bOp(shiftv, (i, a, b) -> ($type$) (a >>> (b & 0xF)));
1067     }
1068 
1069     @Override
1070     @ForceInline
1071     public $vectortype$ shiftArithmeticRight(int s) {
1072         return VectorIntrinsics.broadcastInt(
1073             VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH,
1074             this, s,
1075             (v, i) -> v.uOp((__, a) -> ($type$) (a >> (i & 0xF))));
1076     }
1077 
1078     @Override
1079     @ForceInline
1080     public $vectortype$ shiftArithmeticRight(int s, VectorMask<$Boxtype$> m) {
1081         return blend(shiftArithmeticRight(s), m);
1082     }
1083 
1084     @Override
1085     @ForceInline
1086     public $vectortype$ shiftArithmeticRight(Vector<$Boxtype$> s) {
1087         $vectortype$ shiftv = ($vectortype$)s;
1088         // As per shift specification for Java, mask the shift count.
1089         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, ($type$) 0xF));
1090         return this.bOp(shiftv, (i, a, b) -> ($type$) (a >> (b & 0xF)));
1091     }
1092 #end[short]
1093 #if[intOrLong]
1094     @Override
1095     @ForceInline
1096     public $vectortype$ shiftLeft(int s) {
1097         return VectorIntrinsics.broadcastInt(
1098             VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH,
1099             this, s,
1100             (v, i) -> v.uOp((__, a) -> ($type$) (a << i)));
1101     }
1102 
1103     @Override
1104     @ForceInline
1105     public $vectortype$ shiftLeft(int s, VectorMask<$Boxtype$> m) {
1106         return blend(shiftLeft(s), m);
1107     }
1108 
1109     @Override
1110     @ForceInline
1111     public $vectortype$ shiftRight(int s) {
1112         return VectorIntrinsics.broadcastInt(
1113             VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH,
1114             this, s,
1115             (v, i) -> v.uOp((__, a) -> ($type$) (a >>> i)));
1116     }
1117 
1118     @Override
1119     @ForceInline
1120     public $vectortype$ shiftRight(int s, VectorMask<$Boxtype$> m) {
1121         return blend(shiftRight(s), m);
1122     }
1123 
1124     @Override
1125     @ForceInline
1126     public $vectortype$ shiftArithmeticRight(int s) {
1127         return VectorIntrinsics.broadcastInt(
1128             VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH,
1129             this, s,
1130             (v, i) -> v.uOp((__, a) -> ($type$) (a >> i)));
1131     }
1132 
1133     @Override
1134     @ForceInline
1135     public $vectortype$ shiftArithmeticRight(int s, VectorMask<$Boxtype$> m) {
1136         return blend(shiftArithmeticRight(s), m);
1137     }
1138 
1139     @Override
1140     @ForceInline
1141     public $vectortype$ shiftLeft(Vector<$Boxtype$> s) {
1142         $vectortype$ shiftv = ($vectortype$)s;
1143         // As per shift specification for Java, mask the shift count.
1144         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, {#if[int]?0x1f:0x3f}));
1145         return VectorIntrinsics.binaryOp(
1146             VECTOR_OP_LSHIFT, $vectortype$.class, $type$.class, LENGTH,
1147             this, shiftv,
1148             (v1, v2) -> v1.bOp(v2,(i,a, b) -> ($type$) (a << b)));
1149     }
1150 
1151     @Override
1152     @ForceInline
1153     public $vectortype$ shiftRight(Vector<$Boxtype$> s) {
1154         $vectortype$ shiftv = ($vectortype$)s;
1155         // As per shift specification for Java, mask the shift count.
1156         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, {#if[int]?0x1f:0x3f}));
1157         return VectorIntrinsics.binaryOp(
1158             VECTOR_OP_URSHIFT, $vectortype$.class, $type$.class, LENGTH,
1159             this, shiftv,
1160             (v1, v2) -> v1.bOp(v2,(i,a, b) -> ($type$) (a >>> b)));
1161     }
1162 
1163     @Override
1164     @ForceInline
1165     public $vectortype$ shiftArithmeticRight(Vector<$Boxtype$> s) {
1166         $vectortype$ shiftv = ($vectortype$)s;
1167         // As per shift specification for Java, mask the shift count.
1168         shiftv = shiftv.and($abstractvectortype$.broadcast(SPECIES, {#if[int]?0x1f:0x3f}));
1169         return VectorIntrinsics.binaryOp(
1170             VECTOR_OP_RSHIFT, $vectortype$.class, $type$.class, LENGTH,
1171             this, shiftv,
1172             (v1, v2) -> v1.bOp(v2,(i,a, b) -> ($type$) (a >> b)));
1173     }
1174 #end[intOrLong]
1175     // Ternary operations
1176 
1177 #if[FP]
1178     @Override
1179     @ForceInline
1180     public $vectortype$ fma(Vector<$Boxtype$> o1, Vector<$Boxtype$> o2) {
1181         Objects.requireNonNull(o1);
1182         Objects.requireNonNull(o2);
1183         $vectortype$ v1 = ($vectortype$)o1;
1184         $vectortype$ v2 = ($vectortype$)o2;
1185         return VectorIntrinsics.ternaryOp(
1186             VECTOR_OP_FMA, $vectortype$.class, $type$.class, LENGTH,
1187             this, v1, v2,
1188             (w1, w2, w3) -> w1.tOp(w2, w3, (i, a, b, c) -> Math.fma(a, b, c)));
1189     }
1190 #end[FP]
1191 
1192     // Type specific horizontal reductions
1193 #if[BITWISE]
1194 
1195     @Override
1196     @ForceInline
1197     public $type$ addLanes() {
1198         return ($type$) VectorIntrinsics.reductionCoerced(
1199             VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH,
1200             this,
1201             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a + b)));
1202     }
1203 
1204     @Override
1205     @ForceInline
1206     public $type$ andLanes() {
1207         return ($type$) VectorIntrinsics.reductionCoerced(
1208             VECTOR_OP_AND, $vectortype$.class, $type$.class, LENGTH,
1209             this,
1210             v -> (long) v.rOp(($type$) -1, (i, a, b) -> ($type$) (a & b)));
1211     }
1212 
1213     @Override
1214     @ForceInline
1215     public $type$ andLanes(VectorMask<$Boxtype$> m) {
1216         return $abstractvectortype$.broadcast(SPECIES, ($type$) -1).blend(this, m).andLanes();
1217     }
1218 
1219     @Override
1220     @ForceInline
1221     public $type$ minLanes() {
1222         return ($type$) VectorIntrinsics.reductionCoerced(
1223             VECTOR_OP_MIN, $vectortype$.class, $type$.class, LENGTH,
1224             this,
1225             v -> (long) v.rOp($Boxtype$.MAX_VALUE , (i, a, b) -> ($type$) Math.min(a, b)));
1226     }
1227 
1228     @Override
1229     @ForceInline
1230     public $type$ maxLanes() {
1231         return ($type$) VectorIntrinsics.reductionCoerced(
1232             VECTOR_OP_MAX, $vectortype$.class, $type$.class, LENGTH,
1233             this,
1234             v -> (long) v.rOp($Boxtype$.MIN_VALUE , (i, a, b) -> ($type$) Math.max(a, b)));
1235     }
1236 
1237     @Override
1238     @ForceInline
1239     public $type$ mulLanes() {
1240         return ($type$) VectorIntrinsics.reductionCoerced(
1241             VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH,
1242             this,
1243             v -> (long) v.rOp(($type$) 1, (i, a, b) -> ($type$) (a * b)));
1244     }
1245 
1246     @Override
1247     @ForceInline
1248     public $type$ orLanes() {
1249         return ($type$) VectorIntrinsics.reductionCoerced(
1250             VECTOR_OP_OR, $vectortype$.class, $type$.class, LENGTH,
1251             this,
1252             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a | b)));
1253     }
1254 
1255     @Override
1256     @ForceInline
1257     public $type$ orLanes(VectorMask<$Boxtype$> m) {
1258         return $abstractvectortype$.broadcast(SPECIES, ($type$) 0).blend(this, m).orLanes();
1259     }
1260 
1261     @Override
1262     @ForceInline
1263     public $type$ xorLanes() {
1264         return ($type$) VectorIntrinsics.reductionCoerced(
1265             VECTOR_OP_XOR, $vectortype$.class, $type$.class, LENGTH,
1266             this,
1267             v -> (long) v.rOp(($type$) 0, (i, a, b) -> ($type$) (a ^ b)));
1268     }
1269 
1270     @Override
1271     @ForceInline
1272     public $type$ xorLanes(VectorMask<$Boxtype$> m) {
1273         return $abstractvectortype$.broadcast(SPECIES, ($type$) 0).blend(this, m).xorLanes();
1274     }
1275 #end[BITWISE]
1276 
1277 #if[FP]
1278     @Override
1279     @ForceInline
1280     public $type$ addLanes() {
1281         $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced(
1282                                 VECTOR_OP_ADD, $vectortype$.class, $type$.class, LENGTH,
1283                                 this,
1284                                 v -> {
1285                                     $type$ r = v.rOp(($type$) 0, (i, a, b) -> ($type$) (a + b));
1286                                     return (long)$Type$.$type$To$Bitstype$Bits(r);
1287                                 });
1288         return $Type$.$bitstype$BitsTo$Fptype$(bits);
1289     }
1290 
1291     @Override
1292     @ForceInline
1293     public $type$ mulLanes() {
1294         $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced(
1295                                 VECTOR_OP_MUL, $vectortype$.class, $type$.class, LENGTH,
1296                                 this,
1297                                 v -> {
1298                                     $type$ r = v.rOp(($type$) 1, (i, a, b) -> ($type$) (a * b));
1299                                     return (long)$Type$.$type$To$Bitstype$Bits(r);
1300                                 });
1301         return $Type$.$bitstype$BitsTo$Fptype$(bits);
1302     }
1303 
1304     @Override
1305     @ForceInline
1306     public $type$ minLanes() {
1307         $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced(
1308                                 VECTOR_OP_MIN, $vectortype$.class, $type$.class, LENGTH,
1309                                 this,
1310                                 v -> {
1311                                     $type$ r = v.rOp($Boxtype$.POSITIVE_INFINITY , (i, a, b) -> ($type$) Math.min(a, b));
1312                                     return (long)$Type$.$type$To$Bitstype$Bits(r);
1313                                 });
1314         return $Type$.$bitstype$BitsTo$Fptype$(bits);
1315     }
1316 
1317     @Override
1318     @ForceInline
1319     public $type$ maxLanes() {
1320         $bitstype$ bits = ($bitstype$) VectorIntrinsics.reductionCoerced(
1321                                 VECTOR_OP_MAX, $vectortype$.class, $type$.class, LENGTH,
1322                                 this,
1323                                 v -> {
1324                                     $type$ r = v.rOp($Boxtype$.NEGATIVE_INFINITY, (i, a, b) -> ($type$) Math.max(a, b));
1325                                     return (long)$Type$.$type$To$Bitstype$Bits(r);
1326                                 });
1327         return $Type$.$bitstype$BitsTo$Fptype$(bits);
1328     }
1329 
1330 #end[FP]
1331 
1332     @Override
1333     @ForceInline
1334     public $type$ addLanes(VectorMask<$Boxtype$> m) {
1335         return $abstractvectortype$.broadcast(SPECIES, ($type$) 0).blend(this, m).addLanes();
1336     }
1337 
1338 
1339     @Override
1340     @ForceInline
1341     public $type$ mulLanes(VectorMask<$Boxtype$> m) {
1342         return $abstractvectortype$.broadcast(SPECIES, ($type$) 1).blend(this, m).mulLanes();
1343     }
1344 
1345     @Override
1346     @ForceInline
1347     public $type$ minLanes(VectorMask<$Boxtype$> m) {
1348         return $abstractvectortype$.broadcast(SPECIES, $Boxtype$.MAX_VALUE).blend(this, m).minLanes();
1349     }
1350 
1351     @Override
1352     @ForceInline
1353     public $type$ maxLanes(VectorMask<$Boxtype$> m) {
1354         return $abstractvectortype$.broadcast(SPECIES, $Boxtype$.MIN_VALUE).blend(this, m).maxLanes();
1355     }
1356 
1357     @Override
1358     @ForceInline
1359     public VectorShuffle<$Boxtype$> toShuffle() {
1360         $type$[] a = toArray();
1361         int[] sa = new int[a.length];
1362         for (int i = 0; i < a.length; i++) {
1363             sa[i] = (int) a[i];
1364         }
1365         return VectorShuffle.fromArray(SPECIES, sa, 0);
1366     }
1367 
1368     // Memory operations
1369 
1370     private static final int ARRAY_SHIFT         = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_$TYPE$_INDEX_SCALE);
1371     private static final int BOOLEAN_ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(Unsafe.ARRAY_BOOLEAN_INDEX_SCALE);
1372 
1373     @Override
1374     @ForceInline
1375     public void intoArray($type$[] a, int ix) {
1376         Objects.requireNonNull(a);
1377         ix = VectorIntrinsics.checkIndex(ix, a.length, LENGTH);
1378         VectorIntrinsics.store($vectortype$.class, $type$.class, LENGTH,
1379                                a, (((long) ix) << ARRAY_SHIFT) + Unsafe.ARRAY_$TYPE$_BASE_OFFSET,
1380                                this,
1381                                a, ix,
1382                                (arr, idx, v) -> v.forEach((i, e) -> arr[idx + i] = e));
1383     }
1384 
1385     @Override
1386     @ForceInline
1387     public final void intoArray($type$[] a, int ax, VectorMask<$Boxtype$> m) {
1388         $abstractvectortype$ oldVal = $abstractvectortype$.fromArray(SPECIES, a, ax);
1389         $abstractvectortype$ newVal = oldVal.blend(this, m);
1390         newVal.intoArray(a, ax);
1391     }
1392 #if[!byteOrShort]
1393     @Override
1394     @ForceInline
1395     public void intoArray($type$[] a, int ix, int[] b, int iy) {
1396 #if[longOrDouble64]
1397         this.intoArray(a, ix + b[iy]);
1398 #else[longOrDouble64]
1399         Objects.requireNonNull(a);
1400         Objects.requireNonNull(b);
1401 
1402         // Index vector: vix[0:n] = i -> ix + indexMap[iy + i]
1403         IntVector vix = IntVector.fromArray(INDEX_SPECIES, b, iy).add(ix);
1404 
1405         vix = VectorIntrinsics.checkIndex(vix, a.length);
1406 
1407         VectorIntrinsics.storeWithMap($vectortype$.class, $type$.class, LENGTH, $vectorindextype$,
1408                                a, Unsafe.ARRAY_$TYPE$_BASE_OFFSET, vix,
1409                                this,
1410                                a, ix, b, iy,
1411                                (arr, idx, v, indexMap, idy) -> v.forEach((i, e) -> arr[idx+indexMap[idy+i]] = e));
1412 #end[longOrDouble64]
1413     }
1414 
1415      @Override
1416      @ForceInline
1417      public final void intoArray($type$[] a, int ax, VectorMask<$Boxtype$> m, int[] b, int iy) {
1418          // @@@ This can result in out of bounds errors for unset mask lanes
1419          $abstractvectortype$ oldVal = $abstractvectortype$.fromArray(SPECIES, a, ax, b, iy);
1420          $abstractvectortype$ newVal = oldVal.blend(this, m);
1421          newVal.intoArray(a, ax, b, iy);
1422      }
1423 #end[!byteOrShort]
1424 
1425     @Override
1426     @ForceInline
1427     public void intoByteArray(byte[] a, int ix) {
1428         Objects.requireNonNull(a);
1429         ix = VectorIntrinsics.checkIndex(ix, a.length, bitSize() / Byte.SIZE);
1430         VectorIntrinsics.store($vectortype$.class, $type$.class, LENGTH,
1431                                a, ((long) ix) + Unsafe.ARRAY_BYTE_BASE_OFFSET,
1432                                this,
1433                                a, ix,
1434                                (c, idx, v) -> {
1435                                    ByteBuffer bbc = ByteBuffer.wrap(c, idx, c.length - idx).order(ByteOrder.nativeOrder());
1436                                    $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
1437                                    v.forEach((i, e) -> tb.put(e));
1438                                });
1439     }
1440 
1441     @Override
1442     @ForceInline
1443     public final void intoByteArray(byte[] a, int ix, VectorMask<$Boxtype$> m) {
1444         $vectortype$ oldVal = ($vectortype$) $abstractvectortype$.fromByteArray(SPECIES, a, ix);
1445         $vectortype$ newVal = oldVal.blend(this, m);
1446         newVal.intoByteArray(a, ix);
1447     }
1448 
1449     @Override
1450     @ForceInline
1451     public void intoByteBuffer(ByteBuffer bb, int ix) {
1452         if (bb.order() != ByteOrder.nativeOrder()) {
1453             throw new IllegalArgumentException();
1454         }
1455         if (bb.isReadOnly()) {
1456             throw new ReadOnlyBufferException();
1457         }
1458         ix = VectorIntrinsics.checkIndex(ix, bb.limit(), bitSize() / Byte.SIZE);
1459         VectorIntrinsics.store($vectortype$.class, $type$.class, LENGTH,
1460                                U.getReference(bb, BYTE_BUFFER_HB), ix + U.getLong(bb, BUFFER_ADDRESS),
1461                                this,
1462                                bb, ix,
1463                                (c, idx, v) -> {
1464                                    ByteBuffer bbc = c.duplicate().position(idx).order(ByteOrder.nativeOrder());
1465                                    $Type$Buffer tb = bbc{#if[byte]?;:.as$Type$Buffer();}
1466                                    v.forEach((i, e) -> tb.put(e));
1467                                });
1468     }
1469 
1470     @Override
1471     @ForceInline
1472     public void intoByteBuffer(ByteBuffer bb, int ix, VectorMask<$Boxtype$> m) {
1473         $vectortype$ oldVal = ($vectortype$) $abstractvectortype$.fromByteBuffer(SPECIES, bb, ix);
1474         $vectortype$ newVal = oldVal.blend(this, m);
1475         newVal.intoByteBuffer(bb, ix);
1476     }
1477 
1478     //
1479 
1480     @Override
1481     public String toString() {
1482         return Arrays.toString(getElements());
1483     }
1484 
1485     @Override
1486     public boolean equals(Object o) {
1487         if (this == o) return true;
1488         if (o == null || this.getClass() != o.getClass()) return false;
1489 
1490         $vectortype$ that = ($vectortype$) o;
1491         return this.equal(that).allTrue();
1492     }
1493 
1494     @Override
1495     public int hashCode() {
1496         return Arrays.hashCode(vec);
1497     }
1498 
1499     // Binary test
1500 
1501     @Override
1502     $masktype$ bTest(Vector<$Boxtype$> o, FBinTest f) {
1503         $type$[] vec1 = getElements();
1504         $type$[] vec2 = (($vectortype$)o).getElements();
1505         boolean[] bits = new boolean[length()];
1506         for (int i = 0; i < length(); i++){
1507             bits[i] = f.apply(i, vec1[i], vec2[i]);
1508         }
1509         return new $masktype$(bits);
1510     }
1511 
1512     // Comparisons
1513 
1514     @Override
1515     @ForceInline
1516     public $masktype$ equal(Vector<$Boxtype$> o) {
1517         Objects.requireNonNull(o);
1518         $vectortype$ v = ($vectortype$)o;
1519 
1520         return VectorIntrinsics.compare(
1521             BT_eq, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1522             this, v,
1523             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a == b));
1524     }
1525 
1526     @Override
1527     @ForceInline
1528     public $masktype$ notEqual(Vector<$Boxtype$> o) {
1529         Objects.requireNonNull(o);
1530         $vectortype$ v = ($vectortype$)o;
1531 
1532         return VectorIntrinsics.compare(
1533             BT_ne, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1534             this, v,
1535             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a != b));
1536     }
1537 
1538     @Override
1539     @ForceInline
1540     public $masktype$ lessThan(Vector<$Boxtype$> o) {
1541         Objects.requireNonNull(o);
1542         $vectortype$ v = ($vectortype$)o;
1543 
1544         return VectorIntrinsics.compare(
1545             BT_lt, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1546             this, v,
1547             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a < b));
1548     }
1549 
1550     @Override
1551     @ForceInline
1552     public $masktype$ lessThanEq(Vector<$Boxtype$> o) {
1553         Objects.requireNonNull(o);
1554         $vectortype$ v = ($vectortype$)o;
1555 
1556         return VectorIntrinsics.compare(
1557             BT_le, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1558             this, v,
1559             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a <= b));
1560     }
1561 
1562     @Override
1563     @ForceInline
1564     public $masktype$ greaterThan(Vector<$Boxtype$> o) {
1565         Objects.requireNonNull(o);
1566         $vectortype$ v = ($vectortype$)o;
1567 
1568         return ($masktype$) VectorIntrinsics.compare(
1569             BT_gt, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1570             this, v,
1571             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a > b));
1572     }
1573 
1574     @Override
1575     @ForceInline
1576     public $masktype$ greaterThanEq(Vector<$Boxtype$> o) {
1577         Objects.requireNonNull(o);
1578         $vectortype$ v = ($vectortype$)o;
1579 
1580         return VectorIntrinsics.compare(
1581             BT_ge, $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1582             this, v,
1583             (v1, v2) -> v1.bTest(v2, (i, a, b) -> a >= b));
1584     }
1585 
1586     // Foreach
1587 
1588     @Override
1589     void forEach(FUnCon f) {
1590         $type$[] vec = getElements();
1591         for (int i = 0; i < length(); i++) {
1592             f.apply(i, vec[i]);
1593         }
1594     }
1595 
1596     @Override
1597     void forEach(VectorMask<$Boxtype$> o, FUnCon f) {
1598         boolean[] mbits = (($masktype$)o).getBits();
1599         forEach((i, a) -> {
1600             if (mbits[i]) { f.apply(i, a); }
1601         });
1602     }
1603 
1604 #if[FP]
1605     $bitsvectortype$ toBits() {
1606         $type$[] vec = getElements();
1607         $bitstype$[] res = new $bitstype$[this.species().length()];
1608         for(int i = 0; i < this.species().length(); i++){
1609             res[i] = $Type$.$type$To$Bitstype$Bits(vec[i]);
1610         }
1611         return new $bitsvectortype$(res);
1612     }
1613 #end[FP]
1614 
1615 #if[intOrLong]
1616     $fpvectortype$ toFP() {
1617         $type$[] vec = getElements();
1618         $fptype$[] res = new $fptype$[this.species().length()];
1619         for(int i = 0; i < this.species().length(); i++){
1620             res[i] = $Boxfptype$.$bitstype$BitsTo$Fptype$(vec[i]);
1621         }
1622         return new $fpvectortype$(res);
1623     }
1624 #end[intOrLong]
1625 
1626     @Override
1627     @ForceInline
1628     public $vectortype$ rotateLanesLeft(int j) {
1629       int L = length();
1630       if (j < 0) {
1631          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1632       } else {
1633         j = j & (L-1);
1634         VectorShuffle<$Boxtype$> PermMask  = VectorShuffle.shuffleIota(SPECIES, L - j);
1635         return this.rearrange(PermMask);
1636       }
1637     }
1638 
1639     @Override
1640     @ForceInline
1641     public $vectortype$ rotateLanesRight(int j) {
1642       int L = length();
1643       if (j < 0) {
1644          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1645       } else {
1646         j = j & (L-1);
1647         VectorShuffle<$Boxtype$> PermMask = VectorShuffle.shuffleIota(SPECIES, j);
1648         return this.rearrange(PermMask);
1649       }
1650     }
1651 
1652     @Override
1653     @ForceInline
1654     @SuppressWarnings("unchecked")
1655     public $vectortype$ shiftLanesLeft(int j) {
1656        int L = length();
1657        if (j < 0) {
1658          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1659        } else if ( j >= L ) {
1660          return ZERO;
1661        } else {
1662          $shuffletype$     Iota    = ($shuffletype$)(VectorShuffle.shuffleIota(SPECIES, L-j));
1663          VectorMask<$Boxtype$> BlendMask = Iota.toVector().lessThan($vectortype$.broadcast(SPECIES, ($type$)(L-j)));
1664          Iota    = ($shuffletype$)(VectorShuffle.shuffleIota(SPECIES, L -j));
1665          return ZERO.blend(this.rearrange(Iota),BlendMask);
1666        }
1667     }
1668 
1669     @Override
1670     @ForceInline
1671     @SuppressWarnings("unchecked")
1672     public $vectortype$ shiftLanesRight(int j) {
1673        int L = length();
1674        if (j < 0) {
1675          throw new IllegalArgumentException("Index " + j + " must be zero or positive");
1676        } else if ( j >= L ) {
1677          return ZERO;
1678        } else {
1679          $shuffletype$     Iota    = ($shuffletype$)(VectorShuffle.shuffleIota(SPECIES, j));
1680          VectorMask<$Boxtype$> BlendMask = Iota.toVector().greaterThanEq($vectortype$.broadcast(SPECIES, ($type$)(j)));
1681          Iota    = ($shuffletype$)(VectorShuffle.shuffleIota(SPECIES, j));
1682          return ZERO.blend(this.rearrange(Iota),BlendMask);
1683        }
1684     }
1685 
1686     @Override
1687     @ForceInline
1688     public $vectortype$ rearrange(Vector<$Boxtype$> v,
1689                                   VectorShuffle<$Boxtype$> s, VectorMask<$Boxtype$> m) {
1690         return this.rearrange(s).blend(v.rearrange(s), m);
1691     }
1692 
1693     @Override
1694     @ForceInline
1695     public $vectortype$ rearrange(VectorShuffle<$Boxtype$> o1) {
1696         Objects.requireNonNull(o1);
1697         $shuffletype$ s =  ($shuffletype$)o1;
1698 
1699         return VectorIntrinsics.rearrangeOp(
1700             $vectortype$.class, $shuffletype$.class, $type$.class, LENGTH,
1701             this, s,
1702             (v1, s_) -> v1.uOp((i, a) -> {
1703                 int ei = s_.lane(i);
1704                 return v1.lane(ei);
1705             }));
1706     }
1707 
1708     @Override
1709     @ForceInline
1710     public $vectortype$ blend(Vector<$Boxtype$> o1, VectorMask<$Boxtype$> o2) {
1711         Objects.requireNonNull(o1);
1712         Objects.requireNonNull(o2);
1713         $vectortype$ v = ($vectortype$)o1;
1714         $masktype$   m = ($masktype$)o2;
1715 
1716         return VectorIntrinsics.blend(
1717             $vectortype$.class, $masktype$.class, $type$.class, LENGTH,
1718             this, v, m,
1719             (v1, v2, m_) -> v1.bOp(v2, (i, a, b) -> m_.lane(i) ? b : a));
1720     }
1721 
1722     // Accessors
1723 
1724 #if[FP]
1725     @Override
1726     public $type$ lane(int i) {
1727         if (i < 0 || i >= LENGTH) {
1728             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1729         }
1730         $bitstype$ bits = ($bitstype$) VectorIntrinsics.extract(
1731                                 $vectortype$.class, $type$.class, LENGTH,
1732                                 this, i,
1733                                 (vec, ix) -> {
1734                                     $type$[] vecarr = vec.getElements();
1735                                     return (long)$Type$.$type$To$Bitstype$Bits(vecarr[ix]);
1736                                 });
1737         return $Type$.$bitstype$BitsTo$Fptype$(bits);
1738     }
1739 
1740     @Override
1741     public $vectortype$ with(int i, $type$ e) {
1742         if (i < 0 || i >= LENGTH) {
1743             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1744         }
1745         return VectorIntrinsics.insert(
1746                                 $vectortype$.class, $type$.class, LENGTH,
1747                                 this, i, (long)$Type$.$type$To$Bitstype$Bits(e),
1748                                 (v, ix, bits) -> {
1749                                     $type$[] res = v.getElements().clone();
1750                                     res[ix] = $Type$.$bitstype$BitsTo$Type$(($bitstype$)bits);
1751                                     return new $vectortype$(res);
1752                                 });
1753     }
1754 #else[FP]
1755     @Override
1756     public $type$ lane(int i) {
1757         if (i < 0 || i >= LENGTH) {
1758             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1759         }
1760         return ($type$) VectorIntrinsics.extract(
1761                                 $vectortype$.class, $type$.class, LENGTH,
1762                                 this, i,
1763                                 (vec, ix) -> {
1764                                     $type$[] vecarr = vec.getElements();
1765                                     return (long)vecarr[ix];
1766                                 });
1767     }
1768 
1769     @Override
1770     public $vectortype$ with(int i, $type$ e) {
1771         if (i < 0 || i >= LENGTH) {
1772             throw new IllegalArgumentException("Index " + i + " must be zero or positive, and less than " + LENGTH);
1773         }
1774         return VectorIntrinsics.insert(
1775                                 $vectortype$.class, $type$.class, LENGTH,
1776                                 this, i, (long)e,
1777                                 (v, ix, bits) -> {
1778                                     $type$[] res = v.getElements().clone();
1779                                     res[ix] = ($type$)bits;
1780                                     return new $vectortype$(res);
1781                                 });
1782     }
1783 #end[FP]
1784 
1785     // Mask
1786 
1787     static final class $masktype$ extends AbstractMask<$Boxtype$> {
1788         static final $masktype$ TRUE_MASK = new $masktype$(true);
1789         static final $masktype$ FALSE_MASK = new $masktype$(false);
1790 
1791         private final boolean[] bits; // Don't access directly, use getBits() instead.
1792 
1793         public $masktype$(boolean[] bits) {
1794             this(bits, 0);
1795         }
1796 
1797         public $masktype$(boolean[] bits, int offset) {
1798             boolean[] a = new boolean[species().length()];
1799             for (int i = 0; i < a.length; i++) {
1800                 a[i] = bits[offset + i];
1801             }
1802             this.bits = a;
1803         }
1804 
1805         public $masktype$(boolean val) {
1806             boolean[] bits = new boolean[species().length()];
1807             Arrays.fill(bits, val);
1808             this.bits = bits;
1809         }
1810 
1811         boolean[] getBits() {
1812             return VectorIntrinsics.maybeRebox(this).bits;
1813         }
1814 
1815         @Override
1816         $masktype$ uOp(MUnOp f) {
1817             boolean[] res = new boolean[species().length()];
1818             boolean[] bits = getBits();
1819             for (int i = 0; i < species().length(); i++) {
1820                 res[i] = f.apply(i, bits[i]);
1821             }
1822             return new $masktype$(res);
1823         }
1824 
1825         @Override
1826         $masktype$ bOp(VectorMask<$Boxtype$> o, MBinOp f) {
1827             boolean[] res = new boolean[species().length()];
1828             boolean[] bits = getBits();
1829             boolean[] mbits = (($masktype$)o).getBits();
1830             for (int i = 0; i < species().length(); i++) {
1831                 res[i] = f.apply(i, bits[i], mbits[i]);
1832             }
1833             return new $masktype$(res);
1834         }
1835 
1836         @Override
1837         public VectorSpecies<$Boxtype$> species() {
1838             return SPECIES;
1839         }
1840 
1841         @Override
1842         public $vectortype$ toVector() {
1843             $type$[] res = new $type$[species().length()];
1844             boolean[] bits = getBits();
1845             for (int i = 0; i < species().length(); i++) {
1846                 // -1 will result in the most significant bit being set in
1847                 // addition to some or all other bits
1848                 res[i] = ($type$) (bits[i] ? -1 : 0);
1849             }
1850             return new $vectortype$(res);
1851         }
1852 
1853         @Override
1854         @ForceInline
1855         @SuppressWarnings("unchecked")
1856         public <E> VectorMask<E> cast(VectorSpecies<E> species) {
1857             if (length() != species.length())
1858                 throw new IllegalArgumentException("VectorMask length and species length differ");
1859             Class<?> stype = species.elementType();
1860             boolean [] maskArray = toArray();
1861             if (stype == byte.class) {
1862                 return (VectorMask <E>) new Byte$bits$Vector.Byte$bits$Mask(maskArray);
1863             } else if (stype == short.class) {
1864                 return (VectorMask <E>) new Short$bits$Vector.Short$bits$Mask(maskArray);
1865             } else if (stype == int.class) {
1866                 return (VectorMask <E>) new Int$bits$Vector.Int$bits$Mask(maskArray);
1867             } else if (stype == long.class) {
1868                 return (VectorMask <E>) new Long$bits$Vector.Long$bits$Mask(maskArray);
1869             } else if (stype == float.class) {
1870                 return (VectorMask <E>) new Float$bits$Vector.Float$bits$Mask(maskArray);
1871             } else if (stype == double.class) {
1872                 return (VectorMask <E>) new Double$bits$Vector.Double$bits$Mask(maskArray);
1873             } else {
1874                 throw new UnsupportedOperationException("Bad lane type for casting.");
1875             }
1876         }
1877 
1878         // Unary operations
1879 
1880         @Override
1881         @ForceInline
1882         public $masktype$ not() {
1883             return ($masktype$) VectorIntrinsics.unaryOp(
1884                                              VECTOR_OP_NOT, $masktype$.class, $bitstype$.class, LENGTH,
1885                                              this,
1886                                              (m1) -> m1.uOp((i, a) -> !a));
1887         }
1888 
1889         // Binary operations
1890 
1891         @Override
1892         @ForceInline
1893         public $masktype$ and(VectorMask<$Boxtype$> o) {
1894             Objects.requireNonNull(o);
1895             $masktype$ m = ($masktype$)o;
1896             return VectorIntrinsics.binaryOp(VECTOR_OP_AND, $masktype$.class, $bitstype$.class, LENGTH,
1897                                              this, m,
1898                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a & b));
1899         }
1900 
1901         @Override
1902         @ForceInline
1903         public $masktype$ or(VectorMask<$Boxtype$> o) {
1904             Objects.requireNonNull(o);
1905             $masktype$ m = ($masktype$)o;
1906             return VectorIntrinsics.binaryOp(VECTOR_OP_OR, $masktype$.class, $bitstype$.class, LENGTH,
1907                                              this, m,
1908                                              (m1, m2) -> m1.bOp(m2, (i, a, b) -> a | b));
1909         }
1910 
1911         // Reductions
1912 
1913         @Override
1914         @ForceInline
1915         public boolean anyTrue() {
1916             return VectorIntrinsics.test(BT_ne, $masktype$.class, $bitstype$.class, LENGTH,
1917                                          this, this,
1918                                          (m, __) -> anyTrueHelper((($masktype$)m).getBits()));
1919         }
1920 
1921         @Override
1922         @ForceInline
1923         public boolean allTrue() {
1924             return VectorIntrinsics.test(BT_overflow, $masktype$.class, $bitstype$.class, LENGTH,
1925                                          this, VectorMask.maskAllTrue(species()),
1926                                          (m, __) -> allTrueHelper((($masktype$)m).getBits()));
1927         }
1928     }
1929 
1930     // Shuffle
1931 
1932     static final class $shuffletype$ extends AbstractShuffle<$Boxtype$> {
1933         $shuffletype$(byte[] reorder) {
1934             super(reorder);
1935         }
1936 
1937         public $shuffletype$(int[] reorder) {
1938             super(reorder);
1939         }
1940 
1941         public $shuffletype$(int[] reorder, int i) {
1942             super(reorder, i);
1943         }
1944 
1945         public $shuffletype$(IntUnaryOperator f) {
1946             super(f);
1947         }
1948 
1949         @Override
1950         public VectorSpecies<$Boxtype$> species() {
1951             return SPECIES;
1952         }
1953 
1954         private $abstractvectortype$ toVector_helper() {
1955             $type$[] va = new $type$[SPECIES.length()];
1956             for (int i = 0; i < va.length; i++) {
1957               va[i] = ($type$) lane(i);
1958             }
1959             return $abstractvectortype$.fromArray(SPECIES, va, 0);
1960         }
1961 
1962         @Override
1963         @ForceInline
1964         public $abstractvectortype$ toVector() {
1965             return VectorIntrinsics.shuffleToVector($vectortype$.class, $type$.class, $shuffletype$.class, this,
1966                                                     SPECIES.length(), 
1967                                                     (s) -> ((($shuffletype$)(s)).toVector_helper()));
1968         }
1969 
1970         @Override
1971         @ForceInline
1972         @SuppressWarnings("unchecked")
1973         public <F> VectorShuffle<F> cast(VectorSpecies<F> species) {
1974             if (length() != species.length())
1975                 throw new IllegalArgumentException("Shuffle length and species length differ");
1976             Class<?> stype = species.elementType();
1977             int [] shuffleArray = toArray();
1978             if (stype == byte.class) {
1979                 return (VectorShuffle<F>) new Byte$bits$Vector.Byte$bits$Shuffle(shuffleArray);
1980             } else if (stype == short.class) {
1981                 return (VectorShuffle<F>) new Short$bits$Vector.Short$bits$Shuffle(shuffleArray);
1982             } else if (stype == int.class) {
1983                 return (VectorShuffle<F>) new Int$bits$Vector.Int$bits$Shuffle(shuffleArray);
1984             } else if (stype == long.class) {
1985                 return (VectorShuffle<F>) new Long$bits$Vector.Long$bits$Shuffle(shuffleArray);
1986             } else if (stype == float.class) {
1987                 return (VectorShuffle<F>) new Float$bits$Vector.Float$bits$Shuffle(shuffleArray);
1988             } else if (stype == double.class) {
1989                 return (VectorShuffle<F>) new Double$bits$Vector.Double$bits$Shuffle(shuffleArray);
1990             } else {
1991                 throw new UnsupportedOperationException("Bad lane type for casting.");
1992             }
1993         }
1994 
1995 
1996         @Override
1997         public $shuffletype$ rearrange(VectorShuffle<$Boxtype$> o) {
1998             $shuffletype$ s = ($shuffletype$) o;
1999             byte[] r = new byte[reorder.length];
2000             for (int i = 0; i < reorder.length; i++) {
2001                 r[i] = reorder[s.reorder[i]];
2002             }
2003             return new $shuffletype$(r);
2004         }
2005     }
2006 
2007     // VectorSpecies
2008 
2009     @Override
2010     public VectorSpecies<$Boxtype$> species() {
2011         return SPECIES;
2012     }
2013 }